ambrop7 544a2838cb ncd/modules/net_ipv4_addr.c: port to func_new2 13 năm trước cách đây
..
examples 3cc3f7de00 examples/network.ncd: fix typo 13 năm trước cách đây
modules 544a2838cb ncd/modules/net_ipv4_addr.c: port to func_new2 13 năm trước cách đây
tests 959e22f1ba ncd: modules: parse: add parse_ipv4_cidr_addr() 13 năm trước cách đây
BEventLock.c 0d99d6a26a switch to using the New BSD License 14 năm trước cách đây
BEventLock.h 0d99d6a26a switch to using the New BSD License 14 năm trước cách đây
CMakeLists.txt 18a9a5b7bc ncd: NCDInterpBlock: rename to NCDInterpProcess 13 năm trước cách đây
NCDAst.c 1637bd7583 ncd: NCDAst: add Foreach syntax 13 năm trước cách đây
NCDAst.h 1637bd7583 ncd: NCDAst: add Foreach syntax 13 năm trước cách đây
NCDConfigParser.c eb8e79cc13 ncd: implement Foreach clause 13 năm trước cách đây
NCDConfigParser.h dd25051125 ncd: refactor parsing and implement if clauses 13 năm trước cách đây
NCDConfigParser_parse.y c3012b08c0 ncd: avoid unused variable warning in Lemon parsers 13 năm trước cách đây
NCDConfigTokenizer.c b638437014 ncd: NCDConfigTokenizer: recognize Elif and Else with capital first letter to be consistent 13 năm trước cách đây
NCDConfigTokenizer.h 698c757010 ncd: NCDConfigTokenizer: recognize Foreach and As tokens 13 năm trước cách đây
NCDIfConfig.c 0d99d6a26a switch to using the New BSD License 14 năm trước cách đây
NCDIfConfig.h 0d99d6a26a switch to using the New BSD License 14 năm trước cách đây
NCDInterfaceMonitor.c 131fe33bb9 misc/ipaddr6.h: complete implementation 13 năm trước cách đây
NCDInterfaceMonitor.h 131fe33bb9 misc/ipaddr6.h: complete implementation 13 năm trước cách đây
NCDInterpProcess.c 9576769d4e ncd: NCDInterpProcess: cosmetic changes 13 năm trước cách đây
NCDInterpProcess.h 9576769d4e ncd: NCDInterpProcess: cosmetic changes 13 năm trước cách đây
NCDInterpProcess_trie.h 18a9a5b7bc ncd: NCDInterpBlock: rename to NCDInterpProcess 13 năm trước cách đây
NCDInterpProg.c 98b90be2b7 ncd: NCDInterpProg: remove unused variable 13 năm trước cách đây
NCDInterpProg.h 98b90be2b7 ncd: NCDInterpProg: remove unused variable 13 năm trước cách đây
NCDInterpProg_hash.h 79f824fb65 structure: CHash: rework, remove unused features 13 năm trước cách đây
NCDMethodIndex.c 471dadd637 ncd: NCDMethodIndex: fix crash from keeping old pointer after resizing an array 13 năm trước cách đây
NCDMethodIndex.h 0ef729228f ncd: speed up module lookup when initializing statements. For non-method statements, cache the module pointer in NCDInterpBlock. For 13 năm trước cách đây
NCDMethodIndex_hash.h 0ef729228f ncd: speed up module lookup when initializing statements. For non-method statements, cache the module pointer in NCDInterpBlock. For 13 năm trước cách đây
NCDModule.c 24cfb65686 cosmetic changes 13 năm trước cách đây
NCDModule.h d95c751389 ncd: NCDModule: make interpreter-side process functions call the process creator callbacks directly, and remove a bunch ofstates made redundant 13 năm trước cách đây
NCDModuleIndex.c 0ef729228f ncd: speed up module lookup when initializing statements. For non-method statements, cache the module pointer in NCDInterpBlock. For 13 năm trước cách đây
NCDModuleIndex.h 0ef729228f ncd: speed up module lookup when initializing statements. For non-method statements, cache the module pointer in NCDInterpBlock. For 13 năm trước cách đây
NCDModuleIndex_mhash.h 79f824fb65 structure: CHash: rework, remove unused features 13 năm trước cách đây
NCDModuleInst.svg 1e195eb96c ncd: add state chart for NCDModuleInst 13 năm trước cách đây
NCDModuleInst.uxf 1e195eb96c ncd: add state chart for NCDModuleInst 13 năm trước cách đây
NCDObject.c fcf1046513 cosmetic changes 13 năm trước cách đây
NCDObject.h 3d71336ec3 ncd: store variable names as strings one after another, instead of with arrays of pointers. Also make 13 năm trước cách đây
NCDPlaceholderDb.c 3d71336ec3 ncd: store variable names as strings one after another, instead of with arrays of pointers. Also make 13 năm trước cách đây
NCDPlaceholderDb.h 18a9a5b7bc ncd: NCDInterpBlock: rename to NCDInterpProcess 13 năm trước cách đây
NCDRequestClient.c a21e23fe8a port to compile with MSVC 13 năm trước cách đây
NCDRequestClient.h ac24badeb6 ncd: NCDRequestClient: don't crash if the user allows jobs pushed by NCDRequestClientRequest_Free() to execute after a connection-wide 14 năm trước cách đây
NCDRfkillMonitor.c 0d99d6a26a switch to using the New BSD License 14 năm trước cách đây
NCDRfkillMonitor.h 0d99d6a26a switch to using the New BSD License 14 năm trước cách đây
NCDSugar.c eb8e79cc13 ncd: implement Foreach clause 13 năm trước cách đây
NCDSugar.h 2d98231088 add some missing file headers 13 năm trước cách đây
NCDVal.c 7e22cd7a6b ncd: small optimization 13 năm trước cách đây
NCDVal.h 7e22cd7a6b ncd: small optimization 13 năm trước cách đây
NCDValCompat.c 27c36e7859 ncd: make a new more efficient value storage object NCDVal, and migrate things from NCDValue to NCDVal 13 năm trước cách đây
NCDValCompat.h 27c36e7859 ncd: make a new more efficient value storage object NCDVal, and migrate things from NCDValue to NCDVal 13 năm trước cách đây
NCDVal_maptree.h c14d248662 structure: CAvl: add option to not have lookup operations 13 năm trước cách đây
NCDValue.c cf40e1671e ncd: NCDValue: port to SAvl 13 năm trước cách đây
NCDValue.h cf40e1671e ncd: NCDValue: port to SAvl 13 năm trước cách đây
NCDValueGenerator.c 276905d47c ncd: NCDVal: Add documentation. Rename NCDVal_Map{First,Next} to NCDVal_MapOrdered{First,Next}, and implement the former 13 năm trước cách đây
NCDValueGenerator.h 27c36e7859 ncd: make a new more efficient value storage object NCDVal, and migrate things from NCDValue to NCDVal 13 năm trước cách đây
NCDValueParser.c b1f6e3f1d6 ncd: NCDValueParser: refactor to how NCDConfigParser is implemented, and avoid using the old NCDConfig 13 năm trước cách đây
NCDValueParser.h 27c36e7859 ncd: make a new more efficient value storage object NCDVal, and migrate things from NCDValue to NCDVal 13 năm trước cách đây
NCDValueParser_parse.y c3012b08c0 ncd: avoid unused variable warning in Lemon parsers 13 năm trước cách đây
NCDValue_maptree.h cf40e1671e ncd: NCDValue: port to SAvl 13 năm trước cách đây
README e3c7ceb3fc ncd: update README 14 năm trước cách đây
include_linux_input.c 550b936ff9 compile with PathScale compiler 13 năm trước cách đây
ncd.c 2da1df12c9 ncd: ncd.c: remove redundant declaration 13 năm trước cách đây
ncd.h 0d99d6a26a switch to using the New BSD License 14 năm trước cách đây
parse_linux_input.sh 37020bce35 ncd: add sys.evdev module 15 năm trước cách đây

README

# This file contains some examples of using NCD, the Network Configuration Daemon.
#
# A short introduction to NCD follows.
#
# NCD is a general-purpose system configuration system, operated with a unique programming language.
# The configuration consists of one or more so-called processes that can be considered executing in
# parallel. Further, each process consists of one or more statements, representing the individual
# actions. Statements are implemented as modules built into NCD.
#
# Inside a process, statements can be considered "executed" one after another. That is, when NCD
# starts up, it initializes the first statement, putting it in the DOWN state. When the statement
# reports having transitioned into the UP state, it initializes the next statement in the DOWN state,
# and so on.
#
# However, execution can go in the other direction too. A statement in the UP state can, at any time,
# report having transitioned into the DOWN state. At this point, any statements after that one will
# automatically be de-initialized. The de-initiazation is done from the bottom up. First the last
# initialized statement after the problematic statement is requested to terminate and enters the
# DYING state. After it terminates, its preceding statement enters the DYING state, and so on, until
# all statements following the problematic statement have been de-initiazed.
#
# The backward-execution is the key feature of NCD, and is particularly well suited for programming
# system configurations. Read on to see why.
#
# Statements in NCD can be divided into two categories:
# - Statements that configure something. These statements transition into the UP state "immediately".
# On de-initialization, such statements perform the reverse operation of what they did when initialized.
# Imaginary example: a statement that turn a light on intialization, and turns if off on de-initialization.
# - Statements that wait for something. These statements may remain in the DOWN state indefinitely.
# They enter the UP state when the waited-for condition is satisfied, and also go back into the DOWN
# state when it is no longer satisfied.
# Imaginary example: a statement that is UP when a switch is turned on, and DOWN when it is turned off.
#
# Using the two example statements, we can constuct a process that controls the light based on the switch:
# (these are not really implemented in NCD :)
#
# process light {
# wait_switch();
# turn_light();
# }
#
# When the switch is turned on, wait_switch() will transition to UP, initializing turn_light(), turning the
# light on. When the switch is turned off, wait_switch() will transition to DOWN, causing the de-initialization
# of turn_light(), turning the light off.
# We can add another turn_light() at the end to make the switch control two lights.
#
# A more complex example: We have a christmas three with lights on it. There are multiple "regular" lights,
# controlled with switches, and a special "top" light. The regular lights take a long time to turn on, and
# each takes a different, unpredictable time. We want the top light to be turned on if and only if all the regular
# lights are completely on.
#
# This problem can easily be solved using dependencies. NCD has built-in support for dependencies, provided
# in the form of provide() and depend() statements. A depend() statement is DOWN when its corresponding
# provide() statement is not initialized, and UP when it is. When a provide() is requested to de-initialize, it
# transitions the depend() statements back into the DOWN state, and, before actually dying, waits for any
# statements following them to de-initialize.
#
# The christmas three problem can then be programmed as follows:
#
# process light1 {
# wait_switch1();
# turn_light1();
# provide("L1");
# }
#
# process light2 {
# wait_switch2();
# turn_light2();
# provide("L2");
# }
#
# process top_light {
# depend("L1");
# depend("L2");
# turn_top_light();
# }
#
# Follow some real examples of network configuration using NCD.
# For a list of implemented statements and their descriptions, take a look at the BadVPN source code, in
# the ncd/modules/ folder.
#

#
# Network card using DHCP.
#

process lan {
# Make the interface name a variable so we can refer to it.
# The NCD language has no notion of assigning a variable. Instead variables are
# provided by statements preceding the statement where they are used.
# The built-in var() statement can be used to make an alias.
var("eth0") dev;

# Wait for the network card to appear, set it up and wait for the cable to be
# plugged it.
net.backend.waitdevice(dev);
net.up(dev);
net.backend.waitlink(dev);

# Start DHCP.
net.ipv4.dhcp(dev) dhcp;

# DHCP has obtained an address.
# Because net.ipv4.dhcp does no checks of the IP address, as a safety measure, do not proceed
# if the address is local.
ip_in_network(dhcp.addr, "127.0.0.0", "8") test_local;
ifnot(test_local);

# Assign the obtained address to the interface.
net.ipv4.addr(dev, dhcp.addr, dhcp.prefix);

# Add a default route.
#
net.ipv4.route("0.0.0.0", "0", dhcp.gateway, "20", dev);

# Add DNS servers, as provided by DHCP.
# "20" is the priority of the servers. When applying DNS servers, NCD collects the servers
# from all active net.dns() statements, sorts them by priority ascending (stable), and writes
# them to /etc/resolv.conf, overwriting anything that was previously there.
net.dns(dhcp.dns_servers, "20");
}

#
# Network card with static configuration.
#

process lan2 {
# Make the interface name a variable so we can refer to it.
var("eth1") dev;

# Wait for the network card to appear, set it up and wait for the cable to be
# plugged it.
net.backend.waitdevice(dev);
net.up(dev);
net.backend.waitlink(dev);

# Assign an IP address.
# "24" is prefix length, i.e. subnet mask 255.255.255.0
net.ipv4.addr(dev, "192.168.62.3", "24");

# Add a default route.
net.ipv4.route("0.0.0.0", "0", "192.168.62.3", "20", dev);

# Build a list of DNS servers.
# The NCD language does not support "expressions" - statement arguments must be
# constant strings or variables referring to preceding statements.
# A list can be constructed using the built-in list() statement.
list("192.168.62.5", "192.168.62.6") dns_servers;

# Add the DNS servers.
net.dns(dns_servers, "20");
}

#
# Wireless network interface using wpa_supplicant.
#

process WLAN {
# Set device.
var("wlan0") dev;

# Wait for device and rfkill switch.
net.backend.waitdevice(dev);
net.backend.rfkill("wlan", dev);

# Start wpa_supplicant on this interface, using configuration in /etc/wpa_supplicant/all.conf .
list() args;
net.backend.wpa_supplicant(dev, "/etc/wpa_supplicant/all.conf", "/usr/sbin/wpa_supplicant", args) sup;

# wpa_supplicant tells us what network we connected to. Look below for how this can be used to
# have different configurations, "BadVPN, but configured differently based on what network we're in".
println("connected to wireless network: bssid=", sup.bssid, " ssid=", sup.ssid);

# Wireless connection successful, here comes network config (DHCP/static/whatever) ...
}

#
# A BadVPN VPN interface for access to the virtual network (only).
#

process lan {
... (something like above) ...

# Alias our IP address for easy access from the "vpn" process (or, for a static address, alias
# it before assigning it, and assign it using the alias).
var(dhcp.addr) ipaddr;

# Allow VPN to start at this point.
# (and require it to stop before deconfiguring the interface if e.g. the cable is plugged out)
provide("LAN");
}

process vpn {
# Need the local interface to be working in order start VPN.
depend("LAN") landep;

# Choose the name of the network interface.
var("tap3") dev;

# Construct command line arguments for badvpn-client. Adapt according to your setup.
# "--tapdev" will be provided automatically.

# Alias the port number that the VPN process will bind to.
var("6000") port;

# Construct dynamic parts of command line options.
# The VPN client program needs to know some IP addresses in order to tell other peers where to connect to.
# Obtain this informations from variables in the "lan" process through the depend() statement.

# Construct the local address (addr + port).
concat(landep.ipaddr, ":", port) local_addr_arg;

# Construct the Internet address (assuming we are behind a NAT).
# Need to know the NAT's external address here. But we could queried it somehow.
# That is if we have preconfigured the NAT router to forward ports. But we could implement a statement
# that obtains the mappings dynamically with UPnP!
concat("1.2.3.4", ":", port) internet_addr_arg;

# Finally construct the complete arguments, using the above address arguments.
list(
"--logger", "syslog", "--syslog-ident", "badvpn",
"--server-addr", "badvpn.example.com:7000",
"--ssl", "--nssdb", "sql:/home/badvpn/nssdb", "--client-cert-name", "peer-someone",
"--transport-mode", "udp", "--encryption-mode", "blowfish", "--hash-mode", "md5", "--otp", "blowfish", "3000", "2000",
"--scope", "mylan", "--scope", "internet",
"--bind-addr", "0.0.0.0:6000", "--num-ports", "20",
"--ext-addr", local_addr_arg, "mylan",
"--ext-addr", internet_addr_arg, "internet"
) args;

# Start the BadVPN backend.
# "badvpn" is the user account which the VPN client will run as.
# If you use SSL, the NSS database must be accessible to this user.
net.backend.badvpn(dev, "badvpn", "/usr/bin/badvpn-client-26", args);

# Assign an IP address to the VPN interface.
# (we could easily use DHCP here!)
net.ipv4.addr(dev, "10.0.0.1", "24");
}

#
# BadVPN, but configured differently based on what network we're in.
# The network is identified based on the IP address we were assigned by DHCP.
# The different configuration provide specific arguents to badvpn-client.
#

process lan {
... (interface config stuff using DHCP, see above) ...
... (the 'ipaddr' variable holds the local IP address) ...

# Match the address to various known networks.
ip_in_network(ipaddr, "192.168.4.0", "24") is_lan1;
ip_in_network(ipaddr, "192.168.7.0", "24") is_lan2;

# Allow VPN to start at this point.
provide("LAN");
}

process vpn {
...

# Construct common arguments here ...
list( ... ) common_args;

# Choose appropriate configuration by waking up the configuration processes
# and waiting for one to complete.
provide("VPN_CONF_START");
depend("VPN_CONF_END") config;

# Concatenate common and configuration-specific arguments.
concatlist(common_args, config.args) args;

...
}

process vpn_config_lan1 {
depend("VPN_CONF_START") dep;

# Proceed only if we're in lan1.
if(dep.landep.is_lan1);

list(
...
) args;

provide("VPN_CONF_END");
}

process vpn_config_lan2 {
depend("VPN_CONF_START") dep;

# Proceed only if we're in lan2.
if(dep.landep.is_lan2);

list(
...
) args;

provide("VPN_CONF_END");
}

process vpn_config_inet {
depend("VPN_CONF_START") dep;

# Proceed only if we're not in any known network.
ifnot(dep.landep.is_lan1);
ifnot(dep.landep.is_lan2);

list(
...
) args;

provide("VPN_CONF_END");
}

#
# Two wired network interfaces (eth0, eth1), both of which may be used for Internet access.
# When both are working, give priority to eth1 (e.g. if eth0 is up, but later eth1 also comes
# up, the configuration will be changed to use eth1 for Internet access).
#

process eth0 {
# Set device.
var("eth0") dev;

# Wait for device.
net.backend.waitdevice(dev);
net.up(dev);
net.backend.waitlink(dev);

# DHCP configuration.
net.ipv4.dhcp(dev) dhcp;
ip_in_network(dhcp.addr, "127.0.0.0", "8") test_local;
ifnot(test_local);
var(dhcp.addr) addr;
var(dhcp.prefix) addr_prefix;
var(dhcp.gateway) gateway;
var(dhcp.dns_servers) dns_servers;

# Assign IP address.
net.ipv4.addr(dev, addr, addr_prefix);

# Go on configuring the network.
multiprovide("NET-eth0");
}

process eth1 {
# Set device.
var("eth1") dev;

# Wait for device.
net.backend.waitdevice(dev);
net.up(dev);
net.backend.waitlink(dev);

# Static configuration.
var("192.168.111.116") addr;
var("24") addr_prefix;
var("192.168.111.1") gateway;
list("192.168.111.14", "193.2.1.66") dns_servers;

# Assign IP address.
net.ipv4.addr(dev, addr, addr_prefix);

# Go on configuring the network.
multiprovide("NET-eth1");
}

process NETCONF {
# Wait for some network connection. Prefer eth1 by putting it in front of eth0.
list("NET-eth1", "NET-eth0") pnames;
multidepend(pnames) ifdep;

# Alias device values.
var(ifdep.dev) dev;
var(ifdep.addr) addr;
var(ifdep.addr_prefix) addr_prefix;
var(ifdep.gateway) gateway;
var(ifdep.dns_servers) dns_servers;

# Add default route.
net.ipv4.route("0.0.0.0", "0", gateway, "20", dev);

# Configure DNS servers.
net.dns(dns_servers, "20");
}