├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── doc ├── Concepts.md ├── Debugging.md ├── Plugins.md ├── Tunneling.md ├── Usage.md └── images │ ├── bmx7.png │ └── routing.png └── src ├── Android.mk ├── Application.mk ├── Common.mk ├── Makefile ├── allocate.c ├── allocate.h ├── avl.c ├── avl.h ├── bmx.c ├── bmx.h ├── content.c ├── content.h ├── control.c ├── control.h ├── crypt.c ├── crypt.h ├── desc.c ├── desc.h ├── dump.c ├── dump.h ├── hna.c ├── hna.h ├── iid.c ├── iid.h ├── ip.c ├── ip.h ├── iptools.c ├── iptools.h ├── key.c ├── key.h ├── lib ├── Makefile ├── bmx7_evil │ ├── Makefile │ ├── evil.c │ └── evil.h ├── bmx7_http_info │ ├── HOWTO │ ├── Makefile │ ├── http_info.c │ └── http_info.h ├── bmx7_iwinfo │ ├── Makefile │ ├── bmx7_iwinfo.c │ └── bmx7_iwinfo.h ├── bmx7_json │ ├── Makefile │ ├── README.md │ ├── json.c │ └── json.h ├── bmx7_sms │ ├── Makefile │ ├── sms.c │ └── sms.h ├── bmx7_table │ ├── Makefile │ ├── table.c │ └── table.h ├── bmx7_topology │ ├── Makefile │ ├── topology.c │ └── topology.h ├── bmx7_tun │ ├── Makefile │ └── tun.c └── bmx7_uci_config │ ├── HOWTO.md │ ├── Makefile │ ├── etc_config │ ├── bmx7-advanced │ └── bmx7-simple │ ├── uci_config.c │ └── uci_config.h ├── link.c ├── link.h ├── list.c ├── list.h ├── metrics.c ├── metrics.h ├── msg.c ├── msg.h ├── node.c ├── node.h ├── ogm.c ├── ogm.h ├── plugin.c ├── plugin.h ├── prof.c ├── prof.h ├── redist.c ├── redist.h ├── schedule.c ├── schedule.h ├── sec.c ├── sec.h ├── tools.c ├── tools.h ├── tun.h ├── z.c └── z.h /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | # Unix-style newlines with a newline ending every file. 5 | [*] 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | charset = utf-8 9 | indent_style = tab 10 | indent_size = 8 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | bmx6 4 | core 5 | gmon.out 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![alt text](https://github.com/bmx-routing/bmx7/blob/a2a361eb994879371d13551a65496ed779ca0c44/doc/images/bmx7.png "BMX7 Logo") 2 | 3 | BMX7 is a mesh routing protocol for Linux based operating systems. 4 | The academic paper with more theoretical details can be found [here](http://dsg.ac.upc.edu/node/843). 5 | 6 | ## Content 7 | 8 | * [Installation](#installation) 9 | * [Installing in OpenWRT](#installing-in-openwrt) 10 | * [Packages](#Packages) 11 | * [FAQ](#faq) 12 | * [Usage](doc/Usage.md) 13 | * [Concepts](doc/Concepts.md) 14 | * [Autoconfiguration](doc/Usage.md#address-auto-and-manual-configuration) 15 | * [Unicast Host Network Announcements (UHNA)](doc/Usage.md#unicast-host-network-announcements-uhna) 16 | * [Tunnel Announcements](doc/Tunneling.md) 17 | * [BMX7 Plugins](doc/Plugins.md) 18 | * [Debugging](doc/Debugging.md) 19 | 20 | 21 | [github]: https://github.com/bmx-routing/bmx7 22 | 23 | ## Installation ## 24 | 25 | ### Requirements ### 26 | 27 | The following tools and libraries are needed to obtain, compile, and install bmx7: 28 | * git (debian package: git-core) 29 | * gcc 30 | * make 31 | * build-essential 32 | * libjson-c-dev zlib1g-dev libiw-dev 33 | * libmbedtls-dev ( or mbedtls-2.4.0 from https://tls.mbed.org/download/mbedtls-2.4.0-gpl.tgz) 34 | 35 | Optional for static configuration: 36 | * uci-0.7.5 from http://downloads.openwrt.org/sources/uci-0.7.5.tar.gz 37 | 38 | The following Linux-kernel modules are needed (depending on used bmx7 features) 39 | * ipv6 40 | * tunnel6 41 | * ip6_tunnel 42 | 43 | The mbed TLS or PolarSSL crypto library is needed for cryptographic operations: 44 | Most tested with debian or mbedtls-2.4.0: 45 | ``` 46 | wget https://tls.mbed.org/download/mbedtls-2.4.0-gpl.tgz 47 | tar xzvf mbedtls-2.4.0-gpl.tgz 48 | cd mbedtls-2.4.0 49 | make 50 | sudo make install 51 | # compile bmx7 with: make EXTRA_CFLAGS="-DCRYPTLIB=MBEDTLS_2_4_0" 52 | ``` 53 | 54 | ### Downloading 55 | 56 | Latest development sources are available from bmx7 git repository: 57 | 58 | ``` 59 | git clone https://github.com/bmx-routing/bmx7.git 60 | cd bmx7 61 | ``` 62 | 63 | ### Compile and Install 64 | 65 | To only compile the main bmx7 daemon (no bmx7 plugins): 66 | ``` 67 | make EXTRA_CFLAGS="-DCRYPTLIB=MBEDTLS_2_4_0" 68 | sudo make install 69 | ``` 70 | 71 | ## Installing in OpenWRT 72 | 73 | BMX7 is currently in the official OpenWRT-routing feed, so to install it from a existing system you can use opkg: 74 | ``` 75 | opkg install bmx7 bmx7-uci-config 76 | ``` 77 | 78 | If you are compiling your own OpenWRT, you can add the routing feed (already enabled by default) which can be found here: https://github.com/openwrt-routing/packages 79 | 80 | Then run "make menuconfig" and select the bmx7 package in Networking -> Routing and redirection 81 | 82 | It is recommended to select also, at least, the uci plugin (bmx7-uci-config) 83 | 84 | You can select "luci-app-bmx7" to have a nice web interface for manage and monitorize the routing daemon. 85 | 86 | Finally type "make" to build the image. 87 | 88 | ## Packages 89 | Available packages exist for the following distributions: 90 | - Arch Linux package(AUR): https://aur.archlinux.org/packages/bmx7/ 91 | - Debian Linux package(deb): **Coming soon** 92 | 93 | ## FAQ 94 | 1. How does BMX7 work and on which OSI layer? 95 | - BMX7 is a routing protocol that operates on layer 3 of the OSI layer; it 96 | extends the concept of **receiver-driven routing** and the principles of 97 | DSDV routing. The routing update of BMX7 (in contrast to traditional DSDV) 98 | contains a single and verifiable heartbeat value which unambiguously 99 | identifies a particular node of the network and a specific version of this 100 | nodes' self-defined description and routing-update version. 101 | 102 | 2. The goal of BMX7/SEMTOR? 103 | - The goal of BMX7 is to provide secure mechanisms to ensure that 104 | non-trusted nodes in an open network are effectively prevented from 105 | disrupting the routing between trusted nodes. 106 | - It's achieved by enforcing the exclusion of a given set of identified faulty nodes. 107 | 108 | 3. Differences with bmx6 109 | - TBD 110 | 111 | 4. Similar Software 112 | - AODV, 113 | - Babel, 114 | - BMX6, 115 | - OLSR, 116 | - batman-adv 117 | -------------------------------------------------------------------------------- /doc/Concepts.md: -------------------------------------------------------------------------------- 1 | ## Concepts ## 2 | 3 | ### Global ID ### 4 | 5 | Each bmx7 node creates during its initialization (booting) a global ID 6 | for itself. This ID is created based on the public key which is also 7 | created during the first launch of bmx7 and stored permanently in 8 | /etc/bmx/rsa.der. 9 | 10 | ### Descriptions ### 11 | 12 | Instead of propagating individual routing updates for each announced 13 | network and interface address, each bmx7 daemon summarizes this and 14 | other node-specific attributes into a node-specific description. A 15 | specific description is propagated only once to all other 16 | nodes. Subsequent routing updates are referencing to the corresponding 17 | description with it's hash. If a node is reconfigured, for example 18 | because its interfaces change or a new network shall be announced, 19 | than also the node's description changes. Other nodes are becoming 20 | aware of the changed attributes of a reconfigured node by receiving a 21 | corresponding description update. Subsequent references to this node 22 | will use the hash of the new description. 23 | 24 | Because the description is designed very generic it can be easily used 25 | to piggyback other non-routing specific data. For example the bmx7-sms 26 | plugin is taking advantage of this option by adding arbitrary short 27 | messages data to the node's description. 28 | 29 | ### Blocked Nodes ### 30 | 31 | Nodes may be blocked by other nodes. When a node is blocked no 32 | routing updates (OGMs) of the blocked node are propagated by the 33 | blocking node. The decision for blocking another node is done locally 34 | based on the detection of more than one node announcing the same 35 | unique resource. This happens if two nodes are declaring themselves 36 | as the owner of a unique resource. Then one of those two nodes 37 | (usually the latter) is blocked to avoid the propagation of 38 | conflicting allocations (and ambiguous forwarding state). Duplicate 39 | address usage is the most common reason for such events which happens 40 | if two nodes are using (and announcing) the same primary IPs. 41 | 42 | 43 | ## Dynamic Reconfiguration 44 | 45 | Most bmx7 parameters can be applied not only at startup, but also dynamically to an already running main daemon, using the `--connect` command. 46 | For example interfaces can be added, removed, or specified with more details: 47 | The following example removes interface eth1 and adds eth2 with a max rate of 100 Mbits (overwriting the default assumption of 1000Mbits for ethernet interfaces). 48 | 49 | ``` 50 | bmx7 -c dev=-eth1 dev=eth2 /rateMax=100000 51 | bmx7 -cd8 52 | ``` 53 | 54 | Checking new status of interfaces, links, and originator: 55 | 56 | ``` 57 | root@mlc1001:~# bmx7 -cd8 58 | ``` 59 | 60 | It can be seen that: 61 | 62 | * Interface eth1 has been replaced by eth2 with a lower rate. 63 | * The old links (via eth1) are removed and a single new link via eth2 to mlc1000 has been detected 64 | * All routes are now going via eth2 65 | 66 | 67 | ## Address auto and manual configuration 68 | 69 | By default bmx7 autoconfigures all configred interface by combining a default prefix (fd70::/16) with 70 | the SHA224 hash of each nodes' public rsa key. 71 | 72 | 73 | 74 | ## Unicast Host Network Announcements 75 | 76 | A Host Network Announcements (HNA) describes the advertisement of IP addresses and networks by a node to other nodes in the mesh. 77 | Typically (but not with BMX7), several nodes can announce the same or overlapping HNAs at the same time. 78 | Announced networks do overlap if they are equal or one being a subset of another (eg. 10.1.1.0/24 is a subset and overlapped by 10.1.0.0/16). 79 | Packets with a destination address matching an announced networks will be routed toward any node that originated a corresponding HNA. 80 | Therefore these HNA types may also be called anycast HNA. 81 | 82 | In bmx7, HNAs have an unicast nature (UHNAs) because each network can only be announced once and announced networks MUST NOT overlap (See also Wiki). 83 | This way it can be ensured that the destination of an UHNA routed packet is exactly known. 84 | 85 | In a sense the origination and propagation (by intermediate nodes) of UHNA announcements can be thought of a promise that guarantees: 86 | 1. All packets with a destination address matching an announced UHNA network will be routed exactly to the node (with the global ID) that originated the UHNA and 87 | 2. each node on the forwarding path towards the originator of the UHNA is supporting this promise. 88 | 89 | By default, Bmx7 only announces primary addresses via UHNAs. 90 | The cryptographic address configuration ensures that interface addresses are unique. 91 | 92 | Using UHNAs for the announcements of networks requires a strict coordination to ensure that no network is announced twice. 93 | 94 | Technically, multiple UHNAs, each wrapped into a single message, are aggregated into a UHNA frame and attached to the description of a node. 95 | Only IPv6 UHNAs can be announced. 96 | 97 | The announcement of UHNAs can be configured with the `--unicastHna` or `-u` parameter followed by a network specification in ip/prefixlen notation. 98 | By default all interface addresses are announced via UHNAs. However, this can be disabled by setting the `--dev` subparameter `/announce` or `/a` to 0. 99 | 100 | The following example reconfigures an already running bmx7 daemon to UHNA announce the network fd00:ffff:ffff:ffff::/64 and fd01:ffff:ffff::/48. 101 | By omitting the `--connect / -c` parameter, the same could be configured as startup parameter for bmx7. 102 | 103 | ``` 104 | bmx7 -c u=fd00:ffff:ffff:ffff::/64 u=fd01:ffff:ffff::/48 105 | ``` 106 | 107 | An already active announcement can be removed by preceeding the network with the `-` char: 108 | ``` 109 | bmx7 -c u=-fd00:ffff:ffff:ffff::/64 110 | ``` 111 | 112 | Before bmx7 accepts a dynamically configured UHNA announcement it checks if this UHNA is not overlapping with an already existing UHNA announcement form another node. 113 | If this is the case the configuration will fail. 114 | To check if a chain of dynamic commands would be accepted by a bmx7 daemon without actually applying it, the `--test` command may follow the `--connect` command. 115 | 116 | -------------------------------------------------------------------------------- /doc/Debugging.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | **There three channels for debugging with different intended verbosity:** 4 | 1. system log,which also appears with logread or dmesg. This can be accessed with bmx7 -cd0. 5 | 2. Event logs are more verbose they are used for tracking of events and triggered with code dbgf_track(...). They can be accessed with command bmx7 -cd3. 6 | 3. Most verbose logs coded with dbgf_all(). Can be accessed with command bmx7 -cd4. (But for embedded devices these logs are often compiled out with a NODEBUGALL Macro or so. 7 | 8 | - All system logs also end up as track logs and all-logs. 9 | - Track logs also end up in all logs. 10 | 11 | **There are three different flags for logs:** 12 | 1. DBGT_INFO, 13 | 2. DBGT_WARN, 14 | 3. DBGT_ERR. 15 | 16 | These are just used to unify the severity level with which the log appears. 17 | 18 | ## Developer directives 19 | 20 | BMX7 uses a handful of assertions and debug level directives within it's source 21 | code. 22 | 23 | - A usual scenario would be your changes to pass compilation and then get a 24 | SIG* error on runtime. In this case the core is dumped and an error code of 25 | the range (-500000, -600000) is displayed which can pinpoint you the exact 26 | assert violation that caused it. 27 | Inspect the assertion and then load the core that was dumped along with a 28 | compiled version of bmx7 (that was compiled with the -g option), likewise: 29 | ``` 30 | gdb ./core ./bmx7 31 | ``` 32 | -------------------------------------------------------------------------------- /doc/Plugins.md: -------------------------------------------------------------------------------- 1 | ## Intro 2 | BMX7 offers plugins which are used for the distribution of small files, settings up tunnels or offer stats of the network structure. 3 | 4 | - To enable them run the bmx7 daemon like: 5 | ``` 6 | bmx7 --plugin=bmx7_{wanted-plugin}.so dev={yourDev} 7 | ``` 8 | 9 | - Available Plugins are: 10 | - dnsupdate 11 | - iwinfo 12 | - json 13 | - sms 14 | - table 15 | - topology 16 | - tun 17 | - uci-config 18 | 19 | ## Contents 20 | * [BMX7 Plugins](../src/lib) 21 | * [Config Plugin](#config-plugin) 22 | * [Json Plugin](#json-plugin) 23 | * [SMS Plugin](#sms-plugin) 24 | * [Table plugin](#table-plugin) 25 | 26 | ## Config Plugin 27 | 28 | ### Requirements 29 | 30 | uci libs are needed for the bmx7-config plugin. 31 | To install try (old version): 32 | ``` 33 | wget http://downloads.openwrt.org/sources/uci-0.7.5.tar.gz 34 | tar xzvf uci-0.7.5.tar.gz 35 | cd uci-0.7.5 36 | make clean all install WOPTS="-pedantic -Wall" 37 | sudo make install 38 | ``` 39 | 40 | ### Compile and Install 41 | ``` 42 | make -C lib/bmx7_uci_config/ 43 | sudo make -C lib/bmx7_uci_config/ install 44 | ``` 45 | 46 | ## Json Plugin 47 | 48 | ### Requirements 49 | 50 | json-c for bmx_json plugin (debian package: libjson-c-dev) 51 | 52 | json-c developer libs are needed! 53 | For further reading check: http://json.org/ or https://github.com/jehiah/json-c 54 | 55 | To install manually (only if NOT installed via debian or other package management system): 56 | ``` 57 | wget http://ftp.de.debian.org/debian/pool/main/j/json-c/json-c_0.10.orig.tar.gz 58 | tar xzvf json-c_0.10.orig.tar.gz 59 | cd json-c.. 60 | ./configure ; make ; make install; ldconfig 61 | ``` 62 | 63 | ### Compile and Install 64 | 65 | To compile and install only the bmx7 json plugins: 66 | ``` 67 | make -C lib/bmx7_json/ 68 | sudo make -C lib/bmx7_json/ install 69 | ``` 70 | 71 | ## SMS Plugin 72 | 73 | This plug-in uses routing packets to transmit any information from one node to the 74 | whole network. The good point is that propagation works even if there is no continuous data- 75 | path. Even though the WiFi network is under bad conditions (because the Wireless noise, 76 | distance between nodes, etc...), the data will be propagated. The current implementation, by default, sets a maximum size limit of several KBytes for each file. 77 | 78 | The API of the sms plug-in is very simple. It simply clones the content of one or more files given by one node to all other nodes. All other nodes can do the same. Once started, each node will have two directories: `/var/run/bmx7/sms/rcvdSms` and `/var/run/bmx7/sms/sendSms`. 79 | 80 | Files are cloned from the sendSms folder on the current node to the rcvdSmS folder on all other nodes with the syncSms option using the following steps 81 | 82 | * Place (or link) files you want to send in `/var/run/bmx7/sms/sendSms` 83 | * Use the `syncSms` option in BMX7 to send the file: `bmx7 -c syncSms="filename placed in the sendSms folder"` 84 | 85 | Wireless-mesh distros are using this feature for several things such as positioning Map information or a chat in web interface. 86 | 87 | ## Table plugin 88 | 89 | This plug-in can be used to automatically announce routes from specific routing tables. 90 | For example to dynamically announce (redistribute) routes from another routing protocol. 91 | 92 | ### Usage 93 | 94 | To use the bmx7 table plugin it must be loaded during bmx7 daemon startup with the plugin=bmx7_table.so argument. 95 | Alternatively a plugin section can be defined in the bmx7 config file like this: 96 | ``` 97 | config 'plugin' 98 | option 'plugin' 'bmx7_table.so' 99 | ``` 100 | 101 | Once the plugin is successfully loaded, the new parameters for redistributing routes from specific tables are enabled. 102 | 103 | A full documentation of the table-related parameters is available via the --help and --verboseHelp /r=1 option. 104 | 105 | ### Configuring route redistribution 106 | 107 | Redistribution of routes is configurable with the `--redistTable` parameter. 108 | Similar to the `--tunIn parameter, --redistTable` must be given with an arbitrary name for referencing to a specific redistribution directive and further sub-criterias. 109 | 110 | Mandatary sub-criterias are /table and at least one route of the available types ( /kernel, /boot, /static ) 111 | Typical further but optional sub parameters are: /network, /minPrefixLen, /maxPrefixLen, /aggregatePrefixLen, /bandwidth 112 | The following example automatically and dynamically announces (and removes announcements of) routes as they appear/disappear in routing table 100 and that match the criterias of: 113 | * being a sub network of 192.168.0.0/16 114 | * have a prefix length >= 24 115 | * are configured as type kernel or boot 116 | (manually configured routes via the ip command will appear by default as type boot, 117 | eg: `ip r add 192.168.254.2/31 via 10.0.0.1 table 100` 118 | 119 | If routes matching these criterias exist, then: 120 | * They are announced with a bandwidth of 1Mbit 121 | * Subsequent routes are aggregated down to a minimum prefix length of 24 122 | ``` 123 | bmx7 -c \ 124 | redistTable otherProtocol \ 125 | /network 192.168.0.0/16 \ 126 | /table 100 \ 127 | /aggregatePrefixLen 24 \ 128 | /minPrefixLen 24 \ 129 | /kernel 1 \ 130 | /boot 1 \ 131 | /bandwidth 1000000 132 | ``` 133 | -------------------------------------------------------------------------------- /doc/Tunneling.md: -------------------------------------------------------------------------------- 1 | # Tunnel Announcements # 2 | Tunnel announcements offer an alternative mechanism to propagate routes. 3 | IPv6 and IPv4 networks can be announced. 4 | 5 | ## Content 6 | * [Overview](#overview) 7 | * [Requirements](#requirements) 8 | * [Configuration and Debugging](#configuration-and-debugging) 9 | * [Device Configuration](#device-configuration) 10 | * [Gateway Nodes](#gateway-nodes) 11 | * [Route Redistribution](#route-redistribution) 12 | 13 | ## Overview 14 | 15 | 16 | In contrast to UHNAs, using Tunnel Announcements, the same or overlapping networks can be announced from different nodes. 17 | - Tunnel announcements are an offer from the originating node to other nodes. 18 | - Other nodes can take the offer or not. 19 | - For example, several nodes in a network may offer to share their DSL connection by doing a default-route 20 | (0.0.0.0/0 or ::/0) tunnel announcement. 21 | 22 | Other nodes looking for a route to the internet (a default route) can choose between the multiple offers by establishing a tunnel to one specific of the offering nodes. 23 | 24 | Therefore, an unidirectional (one-way) tunnel is established from the searching to the offering node. 25 | 26 | At the searching node, the remote (outer) tunnel address is configured with an UHNA address (usually the primary address) of the offering node. 27 | 28 | The networks advertised with the tunnel announcements are configured at the client side as routes via (into) the unidirectional tunnel. 29 | 30 | This way, each node can make an individual choice between networks offered via tunnel announcements. 31 | The automatic selection can be specified via a policy description that considers parameters such as advertised bandwidth, path metric, trust in specific GW nodes, hysteresis, ... . 32 | 33 | Since an UHNA address is used as the outer (remote) tunnel address, the client end of the tunnel can be sure that all packets routed into the tunnel will indeed end up at the intended GW node (see Wiki). 34 | 35 | Technically, multiple tunnel announcements, each wrapped into a single tun4/6in6-net message, are aggregated into a tun4/6in6-net frame and attached to the description of a node. 36 | 37 | Tunnel announcements are also used for redistributing routes from other routing protocols (see Wiki) into a bmx7 zone. 38 | 39 | Therefore, each announcements message is decorated with a route-type field indicating the routing protocol that exported the route for being redistributed. 40 | 41 | 42 | ### Requirements 43 | 44 | The following Linux-kernel modules are needed for tunnel-based overlay networking: 45 | * ipv6 46 | * tunnel6 47 | * ip6_tunnel 48 | 49 | ## Configuration and Debugging 50 | In general, a specific tunnel configuration is described from two perspectives: 51 | 52 | * Gateway (GW) nodes or just GWs are offering GW services to networks via the advertizement of tunnel announcements and the provisioning of tunnel-end-points. 53 | 54 | * GW-client nodes (or just GW-clients) that are searching for GWs with tunnel endpoints and routing services to networks. 55 | 56 | A node can (and usually is) operating in both modes (as GW and as GW-client). 57 | But regarding a specific network each node is operating either in GW mode (thus, offering GW-services to that network) or in GW-client mode (thus, searching and using GW-services to that network)! 58 | 59 | A quick and simple tunnel configuration example is given here. 60 | Further details and options are described in the next Sections. 61 | The full set of available options for configuring tunnels is given via the build-in --help and --verboseHelp commands 62 | 63 | * First make your own tunnel addresses known and reachable for other nodes, eg: 64 | `bmx7 -c tunDev=Default /tun4Address=10.254.10.123/32 /tun6Address=2012:1234:5678:123::1/64` 65 | 66 | * Second, configure the automatic establishment of outgoing tunnels to other nodes by searching and selecting any kind of announcement: 67 | `bmx7 -c tunOut=v4Default /network=0.0.0.0/0 tunOut=v6Default /network=::/0` 68 | 69 | * Optionally, check the currently offered tunnel announcements of other GW nodes and the selected tunnel routes by this node with: 70 | `bmx7 -c show=tunnels` 71 | 72 | * Tunnel status information can be accessed with the `--tunnels or --show=tunnels` parameters. 73 | 74 | 75 | ### Device Configuration 76 | 77 | Operation in GW and/or GW-client mode implies the configuration of a bmx7 tunnel device and the IPv4 and/or IPv6 addresses that shall be used for tunnel traffic. 78 | The selection of these addresses should be coordinated with: 79 | * the mesh community because conflicting tunnel address usage will cause problems for the conflicting nodes 80 | * GW administrators because (depending on the GW connection to other networks) only specific addresses may be routable and considered to be originated from the bmx7 cloud. 81 | 82 | The command 83 | ``` 84 | bmx7 -c tunDev=Default /tun4Address=10.254.10.123/32 /tun6Address=2012:1234:5678:123::1/64 85 | ``` 86 | dynamically 87 | * configures a linux ip4/6in6 tunnel device called bmxDefault (check it with command: ip link show). 88 | * assignes the address `10.254.10.123` and `2012:1234:5678:123::1` to the tunnel interface and uses them for outgoing tunnel traffic. 89 | * enables GW-mode for the specified networks: Makes a tunnel announcement so that other nodes can select it for tunneling packets to this node. 90 | 91 | Now other nodes can send tunneled packets to this node via the unidirectional tunnel end point offered by this node. 92 | 93 | But for bidirectional tunnel communication with any another node also a backwards tunnel is needed (an unidirectional tunnel from this node to the other node). 94 | 95 | The automatic selection and establishment of tunnels to other nodes is achieved with the GW-client mode as described in more derail in the next Section. 96 | 97 | ## Gateway-Client Nodes 98 | 99 | The configuration of GW clients can be simple but also, depending on the preferences for a GW-selection policy, very complex. 100 | Through the configuration of the mandatory tunDev and it's addresses (see above), each GW client node is also a GW node to its own (usually small) tunnel address space. 101 | 102 | In the following simple example a GW-client node is searching for any other kind of offered IPv4 and v6 tunnels: 103 | ``` 104 | bmx7 -c tunOut=v4Default /network=0.0.0.0/0 tunOut=v6Default /network=::/0 105 | ``` 106 | 107 | With the above configured tunnel selection policy, tunnels are selected in the following order: 108 | 1. prefix-length of announced tunnels (networks that are more specific than others). 109 | 2. the resulting tunnelMetric (combination of the advertised bandwidth, path metric in the bmx7 cloud, and locally specified preferences like hysteresis or bonus) 110 | 111 | The disadvantage of this simple config is that other nodes can easily redirect your tunnel selections 112 | to specific networks by announcing more precise tunnel networks (larger prefix length). 113 | To prevent this, the selection policy can be split into several and more precise search directives. 114 | 115 | Imagine the following address assignment policy for IPv4 tunnel addresses in a mesh cloud (the general 116 | idea can be straight translated to IPv6). 117 | 118 | * Nodes in the mesh cloud announce their private and local address ranges with a prefix length of 24 and somewhere in the range of 10.254.0.0/16. 119 | 120 | * Announcements of this type should always be preferred, even if any of the following announced types has a better end-to-end metric or more precise announcement. 121 | ``` 122 | bmx7 -c tunOut=v4Nodes /network=10.254.0.0/16 /minPrefixLen=24 /maxPrefixLen=24 /ipmetric=2001 123 | ``` 124 | 125 | * Some BGP GW nodes are connected to other mesh clouds/areas of the same overall community network. These clouds are operating in a different IPv4 range (than 10.254.0.0/16) but always somewhere in the range of 10.0.0.0/8. Route announcements of this type should be preferred over the announcement of a default route. 126 | ``` 127 | bmx7 -c tunOut=v4Clouds /network=10.0.0.0/8 /maxPrefixLen=16 /bgp=1 128 | ``` 129 | 130 | * Some DSL GW nodes are offering to share their DSL line and are announcing a default route (0.0.0.0/0). 131 | 132 | * Further, to mitigate the effects of GW switching between GWs having a similar end-to-end metric a GW switch should only happen if the other GW is at least 30% better. 133 | ``` 134 | bmx7 -c tunOut=v4Default /network=0.0.0.0/0 /maxPrefixLen=0 /hysteresis=30 # refine the above configured v4 tunnel search 135 | ``` 136 | 137 | * In case my node is directly connected to a DSL gateway and gets a automatically (dhcp) configured default route in the main routing table (use: ip route show table main ). then this route 138 | should be preferred and should NOT clash with default tunnel routes configured by bmx7. 139 | * Therefore move all bmx7 tunnel routes to 0.0.0.0/0 into a separate routing table with lower lookup prioriy (check with: ip rule show; ip route show table 150) 140 | ``` 141 | bmx7 -c tunOut=v4Default /network=0.0.0.0/0 /maxPrefixLen=0 /hysteresis=30 /tableRule=50000/150 # again refine the above default search 142 | ``` 143 | 144 | * The default route announcements from two well known GWs (with hostname pepe and paula) should be strictly preferred over unknown GWs. 145 | * So, if available, move them to new table (with lower priority than main and higher priority than used for the backup tunnel rule configured above) 146 | ``` 147 | bmx7 -c tunOut=v4DefaultPepe /network=0.0.0.0/0 /maxPrefixLen=0 /gwName=pepe /hysteresis=30 /tableRule=40000/140 148 | bmx7 -c tunOut=v4DefaultPaula /network=0.0.0.0/0 /maxPrefixLen=0 /gwName=paula /hysteresis=30 /tableRule=40000/140 149 | ``` 150 | 151 | * Finally, GW Paula turned out to be more stable. Therefore I want to prefer GW Paula over Pepe: 152 | ``` 153 | bmx7 -c tunOut=v4DefaultPaula /network=0.0.0.0/0 /maxPrefixLen=0 /gwName=paula /hysteresis=30 /bonus=100 154 | ``` 155 | 156 | ### Gateway Nodes 157 | 158 | The advertisement of a tunnel endpoint to a network can be configured with the --tunIn= and /network= argument and an optional bandwidth specification (given as bits per second) using the /bandwidth or /b sub parameter. 159 | Announcement can be removed by preceeding the name argument with a '-' char. 160 | The following command dynamically configures the advertisement of the following routes: 161 | 162 | * An IPv4 default route 0.0.0.0/0 with a bandwidth of 32 Mbps. 163 | * A more specific route to 10.10.0.0/16 with a bandwidth of 10 Mbps (eg: a local v4 Network). 164 | * An IPv6 route to the [RFC 4291] designated `2000::/3` global unicast address space with a bandwidth of 16 Mbps. 165 | * A more specific route to the `2012:1234::/32` IPv6 space at 10 Mbps (eg: a local v6 Network). 166 | ``` 167 | bmx7 -c tunIn=def4Offer /n=0.0.0.0/0 /b=32000000 tunIn=local4 /n=10.10.0.0/16 /b=10000000 tunIn=def6Offer /n=2000::/3 /b=16000000 tunIn=local6 /n=2012:1234::/32 /b=10000000 168 | ``` 169 | 170 | ### Route Redistribution 171 | 172 | Redistribution of routes is configurable with the `--redistTable` parameter. 173 | Similar to the `--tunIn parameter, --redistTable` must be given with an arbitrary name for referencing to a specific redistribution directive and further sub-criterias. 174 | 175 | Mandatory sub-criterias are /table and at least one route of the available types ( /kernel, /boot, /static ) 176 | Typical further but optional sub parameters are: /network, /minPrefixLen, /maxPrefixLen, /aggregatePrefixLen, /bandwidth 177 | The following example automatically and dynamically announces (and removes announcements of) routes as they appear/disappear in routing table 100 and that match the criterias of: 178 | * being a sub network of 192.168.0.0/16 179 | * have a prefix length >= 24 180 | * are configured as type kernel or boot 181 | (manually configured routes via the ip command will appear by default as type boot, 182 | eg: `ip r add 192.168.254.2/31 via 10.0.0.1 table 100` 183 | 184 | If routes matching these criterias exist, then: 185 | * They are announced with a bandwidth of 1Mbit 186 | * Subsequent routes are aggregated down to a minimum prefix length of 24 187 | ``` 188 | bmx7 -c \ 189 | redistTable otherProtocol \ 190 | /network 192.168.0.0/16 \ 191 | /table 100 \ 192 | /aggregatePrefixLen 24 \ 193 | /minPrefixLen 24 \ 194 | /kernel 1 \ 195 | /boot 1 \ 196 | /bandwidth 1000000 197 | ``` 198 | 199 | -------------------------------------------------------------------------------- /doc/Usage.md: -------------------------------------------------------------------------------- 1 | ## Contents 2 | * [Intro](#intro) 3 | * [Monitoring bmx7](#monitoring-bmx7) 4 | * [Simple Ping Test](#simple-ping-test) 5 | 6 | ## Introduction 7 | 8 | In the most simple configuration, the only required parameter are the interfaces names that should be used for meshing. 9 | The following example starts bmx7 on interface wlan0: 10 | ``` 11 | root@mlc1001:~# bmx7 dev=eth1 12 | ``` 13 | 14 | However, to let this simple command work as expected also check the following basic requirements: 15 | 16 | * `bmx7` must be executed in root context (with super user permissions). If you are not already root, prepend all commands with sudo (eg: `sudo bmx7 dev=eth1` ). 17 | 18 | * No IP address needs to be configured. By default bmx7 assumes IPv6 19 | and autoconfigures a [ULA](https://en.wikipedia.org/wiki/Unique_local_address)-based IPv6 20 | address for each interface based on the MAC address of the 21 | device. The only pre-requisite is that the interfaces must be in the 22 | `up` state, E.G.: `ip link set wlan0 up`. 23 | 24 | If you are using a wireless interface, the interface settings must 25 | have been configured using `iwconfig` or `iw` to communicate with bmx7 26 | daemons running on other nodes. This is a typical configuration for 27 | a wireless mesh setup: ```iwconfig wlan0 mode ad-hoc ap 02:ca:ff:ee:ba:be channel 11 essid my-mesh-network``` 28 | 29 | * Bmx7 (by default) works in daemon mode, thus sends itself to 30 | background and gives back a prompt. To let it run in foreground 31 | specify a debug level with the startup command like: 32 | ``` bmx7 debug=0 dev=eth1 ``` 33 | Of course, you may need to kill a previously 34 | started bmx7 daemon beforehand (`killall bmx7`) 35 | 36 | If everything went fine bmx7 is running now, searches for neighboring 37 | bmx7 daemons via the configured interface (link), and coordinates with 38 | them to learn about existence-of and routes-to all other bmx7 nodes in 39 | the network. 40 | 41 | 42 | ## Monitoring bmx7 43 | 44 | To access debug and status information of a running bmx7 daemon, a 45 | second bmx7 process can be launched in client mode (with the 46 | `--connect` or `-c` parameter) to connect to the main bmx7 daemon and 47 | retrieve the desired information. 48 | 49 | In the following, a few example will be discussed. Continuous debug levels with different verbosity and scope are accessible with the `--debug` or `-d` parameter. 50 | 51 | * Debug level 0 only reports critical events 52 | * Debug level 3 reports relevant changes and 53 | * Debug level 4 reports everything. 54 | * Debug level 12 dump in and outgoing protocol traffic 55 | 56 | For example, `bmx7 -cd3` runs a bmx7 client process at debug level 3, 57 | connected to the main daemon and logs the output to stdout until 58 | terminated with `ctrl-c`. 59 | 60 | Status, network, and statistic information are also accessible via 61 | their own parameters: 62 | 63 | * `parameters` 64 | * `status` 65 | * `interfaces` 66 | * `links` 67 | * `originators` 68 | * `descriptions`, plus optional sub-parameters for filtering 69 | * `tunnels` (only with bmx7_tun.so plugin) 70 | * `traffic=DEV` where DEV:=`all`, `eth1`, etc. 71 | 72 | 73 | ``` 74 | root@mlc1001:~# bmx7 -c show=status 75 | STATUS: 76 | shortId name nodeKey cv revision primaryIp tun6Address tun4Address uptime cpu txQ nbs rts nodes 77 | 01662D16 mlc1001 RSA2048 21 0abee1e fd70:166:2d16:1ff6:253f:d0bc:1558:d89a 2013:0:0:1001::1/64 10.20.1.1/24 0:00:11:43 0.1 4/50 2 9 10/10 78 | ``` 79 | 80 | As can be seen, the status reveals: 81 | * shortId: the short form of the node's [Global ID](wiki#global-id) 82 | * name: the hostname of the node 83 | * nodeKey: the key type and strength of its public RSA key 84 | * cv: compatibility version 85 | * revision: the git revision of the used source code 86 | * primaryIP: its primary cryptographically generated IPv6 address 87 | * uptime: the time since when it is running 88 | * cpu: its current cpu consumption (0.1%) 89 | * nbs: the number of neighbors perceived by this node 90 | * rts: the number of routes to other nodes 91 | * nodes: the total number of known and fully resolved nodes (including itself) 92 | 93 | These desired types can be combined. Also the above given example shows kind of shortcut. 94 | The long argument would be: 95 | `bmx7 connect show=status`. A more informative case using the long form would be: 96 | 97 | ``` 98 | root@mlc1001:~# bmx7 -c parameters show=status show=interfaces show=links show=originators show=tunnels 99 | PARAMETERS: 100 | plugin bmx7_config.so (0) 101 | plugin bmx7_sms.so (0) 102 | plugin bmx7_tun.so (0) 103 | plugin bmx7_topology.so (0) 104 | plugin bmx7_table.so (0) 105 | dev eth1 (0) 106 | dev eth2 (0) 107 | unicastHna 2013:0:0:1001::/64 (0) 108 | tunDev default (0) 109 | /tun4Address 10.20.1.1/24 (0) 110 | /tun6Address 2013:0:0:1001::1/64 (0) 111 | tunOut ip6 (0) 112 | /network 2013::/16 (0) 113 | tunOut ip4 (0) 114 | /network 10.20.0.0/16 (0) 115 | STATUS: 116 | shortId name nodeKey cv revision primaryIp tun6Address tun4Address uptime cpu txQ nbs rts nodes 117 | 01662D16 mlc1001 RSA2048 21 e2bd709 fd70:166:2d16:1ff6:253f:d0bc:1558:d89a 2013:0:0:1001::1/64 10.20.1.1/24 0:00:03:34 0.2 0/50 2 9 10/10 118 | INTERFACES: 119 | dev state linkKey linkKeys type channel rateMax idx localIp rts helloSqn rxBpP txBpP 120 | eth1 UP DH2048M112 RSA896,DH2048M112 ethernet 0 1000M 1 fe80::a2cd:efff:fe10:101/64 9 39457 382/2.6 217/1.3 121 | eth2 UP DH2048M112 RSA896,DH2048M112 ethernet 0 1000M 2 fe80::a2cd:efff:fe10:102/64 0 9120 0/0.0 136/1.3 122 | LINKS: 123 | shortId name linkKey linkKeys nbLocalIp dev rts rq tq rxRate txRate wTxRate mcs sgi chw wSnr 124 | 2ECE1A4E mlc1000 DH2048M112 RSA896,DH2048M112 fe80::a2cd:efff:fe10:1 eth1 1 100 100 1000M 1000M -1 0 0 20 0 125 | AAD9C0F5 mlc1002 DH2048M112 RSA896,DH2048M112 fe80::a2cd:efff:fe10:201 eth1 8 100 100 1000M 1000M -1 0 0 20 0 126 | ORIGINATORS: 127 | shortId name as S s T t descSqn lastDesc descSize cv revision primaryIp dev nbShortId nbName metric hops ogmSqn lastRef 128 | 2ECE1A4E mlc1000 nA A A A A 612 212 733+784 21 e2bd709 fd70:2ece:1a4e:fa8e:fb9d:3b70:33e3:da00 eth1 2ECE1A4E mlc1000 999M 1 36 0 129 | 01662D16 mlc1001 nQ A A A A 612 213 733+784 21 e2bd709 fd70:166:2d16:1ff6:253f:d0bc:1558:d89a --- --- --- 257G 0 36 0 130 | AAD9C0F5 mlc1002 nA A A A A 612 212 733+784 21 e2bd709 fd70:aad9:c0f5:8c20:a082:a462:a859:210d eth1 AAD9C0F5 mlc1002 999M 1 36 0 131 | DD57B855 mlc1003 pA A A A A 612 203 733+784 21 e2bd709 fd70:dd57:b855:3cdf:b057:10cc:2a93:c19 eth1 AAD9C0F5 mlc1002 706M 2 36 1 132 | 369C6293 mlc1004 pA A A A A 612 200 733+784 21 e2bd709 fd70:369c:6293:4199:c156:3bb8:2c6a:e3aa eth1 AAD9C0F5 mlc1002 576M 3 36 1 133 | 0BE5272C mlc1005 pA A A A A 612 200 733+784 21 e2bd709 fd70:be5:272c:703e:822a:e0c5:5d6c:587d eth1 AAD9C0F5 mlc1002 495M 4 36 1 134 | DDC8E9EF mlc1006 pA A A A A 612 193 733+784 21 e2bd709 fd70:ddc8:e9ef:4ff0:385e:b034:6fd0:b5f eth1 AAD9C0F5 mlc1002 443M 5 36 0 135 | 6F59035D mlc1007 pA A A A A 612 188 733+784 21 e2bd709 fd70:6f59:35d:ae9b:1d55:3066:b3f9:74c7 eth1 AAD9C0F5 mlc1002 403M 6 36 0 136 | BF335A96 mlc1008 pA A A A A 612 178 733+784 21 e2bd709 fd70:bf33:5a96:889d:eedd:767b:6ca9:42fb eth1 AAD9C0F5 mlc1002 373M 7 36 0 137 | 1191C909 mlc1009 pA A A A A 612 184 733+784 21 e2bd709 fd70:1191:c909:1e4e:4c9c:4d4a:33eb:b09b eth1 AAD9C0F5 mlc1002 349M 8 35 6 138 | ``` 139 | 140 | Only if relevant information exists for a requested type is available 141 | is will be shown. In this example no tunnels are configured locally 142 | nor are any tunnels offered by other nodes, so no tunnel information 143 | is shown. 144 | 145 | The `loop` argument can be prepended to the connect argument to 146 | continuously show the requested information. Many of the long 147 | arguments are available via a short notation, like `l` for `loop`, `c` 148 | for `connect`, `s` for `show`, `d` for `debug`. And there is another 149 | shortcut summarizing my current favorite information types via debug 150 | level 8 The following commands do the same as above: `bmx7 -lc status 151 | interfaces links originators tunnels` or simply `bmx7 -lcd8`. 152 | 153 | Description of selected section columns: 154 | 155 | PARAMETERS section: 156 | 157 | This section shows all configured parameters. 158 | The value in braces indicates the default value for the given parameter or 0 if no default value exists. 159 | 160 | INTERFACES section: 161 | 162 | * dev: Interface name 163 | * state and type: Whether the interface is UP or DOWN and its assumed link-layer type. 164 | * rateMax: assumed maximum transmit rates for this interface. 165 | * llocalIp: IPv6 link-local address (used as source address for all outgoing protocol data). 166 | * rts: nuber of routes to other nodes via this interface 167 | * rxBpP: received protocol data in Bytes per Packet per second via this interface 168 | * txBpP: transmitted protocol data in Bytes per Packet per second via this interface 169 | 170 | LINKS section: 171 | 172 | * shortId and name of link neighbor 173 | * linkKey and linkKeys show currently active and supported signature schemes for link verification 174 | * nbLocalIp: Neighbors IPv6 link-local address 175 | * dev: Interface via which this link is detected 176 | * rts: Nuber of active routes to other nodes via this link 177 | * rq: Measured receive rate in percent for the link. 178 | * tq: Measured transmit rate in percent for the link. 179 | * rxRate: Calculated receive rate in bps for the link. 180 | * txRate: Calculated transmit rate in bps for the link. 181 | * ...: More wireless channel statistics (if available) 182 | 183 | 184 | ORIGINATORS section: 185 | 186 | * shortId and name of node (originator) 187 | * lastDesc: Seconds since the last description update was received 188 | * primaryIp: The primary IP of that node. 189 | * viaDev: Outgoing interface of the best route towards this node. 190 | * metric: Calculated end to end path metric to this node 191 | * lastRef: Seconds since this node was referenced by any neighboring node 192 | 193 | 194 | Quick summary of provided info: 195 | 196 | * Node mlc1001 uses two wired interface (eth1 and eth2) which is up and actively used for meshing. 197 | * Node mlc1001 got aware of 2 neighbors and 10 nodes (originators) including itself. 198 | * The link qualities (rx and tx rate) to its neighbors are perfect (100%) 199 | * Routes to nodes mlc1000 and mlc1002 are via interface eth1 and directly to the neighbor's link-local address with a metric of 999M (nearly maximum tx/rx rate of the configured interface) 200 | * Route to node mlc1003 is setup via interface eth1 and via the link-local address of neighbor mlc1002 (at least two hops to the destination node). 201 | 202 | The following links of the total network topology can be guessed from this information (further links may exist): 203 | ``` 204 | mlc1000 --- mlc1001 --- mlc1002 --- mlc1003 --- ... --- mlc1009 205 | ``` 206 | 207 | ## Simple Ping Test 208 | 209 | This could be verified using traceroute6 towards the primary IP of the other nodes. 210 | 211 | To mlc1000's primary IP fd66:66:66:0:a2cd:efff:fe10:1 shows one hop: 212 | 213 | ``` 214 | root@mlc1001:~# traceroute6 -n -q 1 fd66:66:66:0:a2cd:efff:fe10:1 215 | traceroute to fd66:66:66:0:a2cd:efff:fe10:1 (fd66:66:66:0:a2cd:efff:fe10:1), 30 hops max, 80 byte packets 216 | 1 fd66:66:66:0:a2cd:efff:fe10:1 0.324 ms 217 | ``` 218 | 219 | To mlc1002's primary IP fd66:66:66:0:a2cd:efff:fe10:201 shows one hop: 220 | 221 | ``` 222 | root@mlc1001:~# traceroute6 -n -q 1 fd66:66:66:0:a2cd:efff:fe10:201 223 | traceroute to fd66:66:66:0:a2cd:efff:fe10:201 (fd66:66:66:0:a2cd:efff:fe10:201), 30 hops max, 80 byte packets 224 | 1 fd66:66:66:0:a2cd:efff:fe10:201 0.302 ms 225 | ``` 226 | 227 | To mlc1003's primary IP fd66:66:66:0:a2cd:efff:fe10:301 shows two hops: 228 | 229 | ``` 230 | root@mlc1001:~# traceroute6 -n -q 1 fd66:66:66:0:a2cd:efff:fe10:301 231 | traceroute to fd66:66:66:0:a2cd:efff:fe10:301 (fd66:66:66:0:a2cd:efff:fe10:301), 30 hops max, 80 byte packets 232 | 1 fd66:66:66:0:a2cd:efff:fe10:201 0.313 ms 233 | 2 fd66:66:66:0:a2cd:efff:fe10:301 0.429 ms 234 | `` 235 | -------------------------------------------------------------------------------- /doc/images/bmx7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmx-routing/bmx7/9020896f89006bc5d3487222eefc7ddea9e8b2bd/doc/images/bmx7.png -------------------------------------------------------------------------------- /doc/images/routing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bmx-routing/bmx7/9020896f89006bc5d3487222eefc7ddea9e8b2bd/doc/images/routing.png -------------------------------------------------------------------------------- /src/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | include $(LOCAL_PATH)/Common.mk 5 | 6 | LOCAL_SRC_FILES := $(SRC_C) 7 | 8 | # -pedantic yields a lot of warnings from the NDK includes 9 | LOCAL_CFLAGS := $(filter-out -pedantic,$(CFLAGS)) 10 | 11 | # Separate, since changing it on its own will break the Android app 12 | LOCAL_MODULE := bmx6 13 | 14 | LOCAL_FORCE_STATIC_EXECUTABLE := true 15 | 16 | include $(BUILD_EXECUTABLE) 17 | -------------------------------------------------------------------------------- /src/Application.mk: -------------------------------------------------------------------------------- 1 | # Older platforms don't have fdprintf and vfdprintf 2 | APP_PLATFORM := android-8 3 | 4 | # GCC 4.8/4.9 build arm binaries that crashed due to memory alignment issues. 5 | # Clang build binaries that ran fine. 6 | NDK_TOOLCHAIN_VERSION := clang 7 | -------------------------------------------------------------------------------- /src/Common.mk: -------------------------------------------------------------------------------- 1 | GIT_REV ?= $(shell [ -r .git ] && git --no-pager log -n 1 --oneline | cut -d " " -f 1 || echo 0) 2 | 3 | # //TODO: Fix -Wno-address-of-packed-member related reference problems and disabled related compile flag 4 | CFLAGS += -pedantic -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wno-address-of-packed-member -Os -g3 -std=gnu99 -DGIT_REV=\"$(GIT_REV)\" 5 | # CFLAGS += -DHAVE_CONFIG_H 6 | # CFLAGS += -DCRYPTLIB=MBEDTLS_2_8_0 # -DCRYPTLIB=MBEDTLS_3_6_0 7 | 8 | # optional defines: 9 | # CFLAGS += -static 10 | # CFLAGS += -pg # "-pg" with openWrt causes "gcrt1.o: No such file"! Needs ld -o myprog /lib/gcrt0.o myprog.o utils.o -lc_p, grep: http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html 11 | 12 | # paranoid defines (helps bug hunting during development): 13 | # CFLAGS += -DEXTREME_PARANOIA -DEXIT_ON_ERROR -DPROFILING 14 | 15 | # CFLAGS += -DNO_KEY_GEN # use openssl instead, like: 16 | # openssl genrsa -out /etc/bmx7/rsa.pem 1024 17 | # openssl rsa -in /etc/bmx7/rsa.pem -inform PEM -out /etc/bmx7/rsa.der -outform DER 18 | 19 | # Some test cases: 20 | # CFLAGS += -DTEST_LINK_ID_COLLISION_DETECTION 21 | # CFLAGS += -DTEST_DEBUG # (testing syntax of __VA_ARGS__ dbg...() macros) 22 | # CFLAGS += -DTEST_DEBUG_MALLOC # allocates a never freed byte which should be reported at bmx7 termination 23 | # CFLAGS += -DAVL_5XLINKED -DAVL_DEBUG -DAVL_TEST 24 | CFLAGS += -DAVL_5XLINKED 25 | 26 | # optional defines (you may disable these features if you dont need them) 27 | # CFLAGS += -DNO_DEBUG_TRACK 28 | # CFLAGS += -DNO_DEBUG_SYS 29 | # CFLAGS += -DLESS_OPTIONS 30 | # CFLAGS += -DNO_DYN_PLUGIN 31 | 32 | # CFLAGS += -DDEBUG_ALL 33 | # CFLAGS += -DTRAFFIC_DUMP 34 | # CFLAGS += -DDEBUG_DUMP 35 | CFLAGS += -DDEBUG_MALLOC 36 | # CFLAGS += -DMEMORY_USAGE 37 | 38 | # experimental or advanced defines (please dont touch): 39 | # CFLAGS += -DNO_ASSERTIONS # (disable syntax error checking and error-code creation!) 40 | # CFLAGS += -DEXTREME_PARANOIA # (check difficult syntax errors) 41 | # CFLAGS += -DEXIT_ON_ERROR # (exit and return code due to unusual behavior) 42 | # CFLAGS += -DTEST_DEBUG 43 | # CFLAGS += -DWITH_DEVEL # (includes debug, yet unused, and buggy stuff) 44 | # CFLAGS += -DPROFILING # (no static functions -> better profiling and cores) 45 | CFLAGS += -DCORE_LIMIT=20000 # equals ulimit -c 20000 46 | 47 | # EXTRA_CFLAGS += -fsanitize=undefined 48 | # EXTRA_LDFLAGS += -fsanitize=undefined 49 | 50 | # add as much features and test cases as possible: 51 | #EXTRA_CFLAGS += -DMOST 52 | 53 | #for profiling: 54 | #EXTRA_CFLAGS="-DPROFILING -pg" 55 | 56 | #for very poor embedded stuff (reducing binary size and cpu footprint): 57 | #EXTRA_CFLAGS="-DNO_DEBUG_TRACK -DNO_ASSERTIONS" 58 | 59 | #for small embedded stuff the defaults are just fine. 60 | 61 | #for normal machines (adding features and facilitating debugging): 62 | #EXTRA_CFLAGS="-DDEBUG_ALL -DTRAFFIC_DUMP -DDEBUG_DUMP -DEBUG_MALLOC -DMEMORY_USAGE" 63 | 64 | CFLAGS += $(shell echo "$(EXTRA_CFLAGS)" | grep -q "DMOST" && echo "-pg -DCORE_LIMIT=20000 -DEXTREME_PARANOIA -DPROFILING -DDEBUG_ALL -DTRAFFIC_DUMP -DDEBUG_DUMP -DDEBUG_MALLOC -DMEMORY_USAGE " ) 65 | 66 | LDFLAGS += -g3 67 | 68 | LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DNO_DYN_PLUGIN" || echo "-Wl,-export-dynamic -ldl" ) 69 | LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DPROFILING" && echo "-pg -lc" ) 70 | LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DBMX7_LIB_IWINFO" && echo "-liwinfo" || echo "-liw" ) 71 | 72 | LDFLAGS += -lz -lm 73 | LDFLAGS += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "POLARSSL" && echo "-lpolarssl" || echo "-lmbedcrypto" ) 74 | 75 | SBINDIR = $(INSTALL_PREFIX)/usr/sbin 76 | 77 | SRC_C = bmx.c key.c node.c crypt.c sec.c content.c msg.c z.c iid.c desc.c metrics.c ogm.c link.c iptools.c tools.c plugin.c list.c allocate.c avl.c hna.c control.c schedule.c ip.c prof.c 78 | SRC_H = bmx.h key.h node.h crypt.h sec.h content.h msg.h z.h iid.h desc.h metrics.h ogm.h link.h iptools.h tools.h plugin.h list.h allocate.h avl.h hna.h control.h schedule.h ip.h prof.h 79 | 80 | SRC_C += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DTRAFFIC_DUMP" && echo dump.c ) 81 | SRC_H += $(shell echo "$(CFLAGS) $(EXTRA_CFLAGS)" | grep -q "DTRAFFIC_DUMP" && echo dump.h ) 82 | 83 | OBJS = $(SRC_C:.c=.o) 84 | 85 | PACKAGE_NAME := bmx7 86 | BINARY_NAME := bmx7 87 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010-2016 BMX protocol contributors 2 | # 3 | # This program is free software; you can redistribute it and/or 4 | # modify it under the terms of version 2 of the GNU General Public 5 | # License as published by the Free Software Foundation. 6 | # 7 | # This program is distributed in the hope that it will be useful, but 8 | # WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | # General Public License for more details. 11 | # 12 | # You should have received a copy of the GNU General Public License 13 | # along with this program; if not, write to the Free Software 14 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | # 02110-1301, USA 16 | 17 | include Common.mk 18 | 19 | #debug: $(CFLAGS) 20 | 21 | all: 22 | $(MAKE) $(BINARY_NAME) 23 | # further make targets: help, libs, build_all, strip[_libs|_all], install[_libs|_all], clean[_libs|_all] 24 | 25 | libs: all 26 | $(MAKE) -C lib all CORE_CFLAGS='$(CFLAGS)' 27 | 28 | 29 | $(BINARY_NAME): $(OBJS) Makefile Common.mk 30 | $(CC) $(OBJS) -o $@ $(LDFLAGS) $(EXTRA_LDFLAGS) 31 | 32 | %.o: %.c %.h Makefile Common.mk $(SRC_H) 33 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 34 | 35 | strip: all 36 | strip $(BINARY_NAME) 37 | 38 | strip_libs: all libs 39 | $(MAKE) -C lib strip 40 | 41 | install: all 42 | mkdir -p $(SBINDIR) 43 | install -m 0755 $(BINARY_NAME) $(SBINDIR) 44 | 45 | install_libs: all 46 | $(MAKE) -C lib install CORE_CFLAGS='$(CFLAGS)' 47 | 48 | 49 | clean: 50 | rm -f $(BINARY_NAME) *.o posix/*.o linux/*.o 51 | 52 | clean_libs: 53 | $(MAKE) -C lib clean 54 | 55 | 56 | clean_all: clean clean_libs 57 | build_all: all libs 58 | strip_all: strip strip_libs 59 | install_all: install install_libs 60 | 61 | 62 | help: 63 | # see also http://bmx6.net/projects/bmx6/wiki 64 | # 65 | # further make targets: 66 | # help show this help 67 | # all compile bmx7 core only 68 | # libs compile bmx7 plugins 69 | # build_all compile bmx7 and plugins 70 | # strip / strip_libs / strip_all strip bmx7 / plugins / all 71 | # install / install_libs / install_all install bmx7 / plugins / all 72 | # clean / clean_libs / clean_all clean bmx7 / libs / all 73 | # 74 | # minimum compile requirements are zlib and polarssl libraries: 75 | # 76 | # for polarssl on debian do: 77 | # apt-get install libpolarssl-dev 78 | # 79 | # for zlib on debian do: 80 | # apt-get install zlib1g-dev 81 | # 82 | # 83 | 84 | -------------------------------------------------------------------------------- /src/allocate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006 B.A.T.M.A.N. contributors: 3 | * Thomas Lopatic, Corinna 'Elektra' Aichele, Axel Neumann, Marek Lindner 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of version 2 of the GNU General Public 6 | * License as published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | * General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16 | * 02110-1301, USA 17 | * 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "list.h" 27 | #include "control.h" 28 | #include "bmx.h" 29 | #include "allocate.h" 30 | 31 | uint32_t debugMalloc_bytes = 0; 32 | uint32_t debugMalloc_objects = 0; 33 | 34 | typedef struct { 35 | long size, resident, share, text, lib, data, dt; 36 | } statm_t; 37 | 38 | uint64_t getProcMemory(void) 39 | { 40 | static statm_t s; 41 | FILE *f = fopen("/proc/self/statm", "r"); 42 | if (!f) 43 | return 0; 44 | 45 | if (fscanf(f, "%ld %ld %ld %ld %ld %ld %ld", &s.size, &s.resident, &s.share, &s.text, &s.lib, &s.data, &s.dt) != 7) { 46 | fclose(f); 47 | return 0; 48 | } 49 | 50 | fclose(f); 51 | 52 | return(s.size * getpagesize()); 53 | } 54 | 55 | 56 | #ifdef DEBUG_MALLOC 57 | 58 | #define MAGIC_NUMBER_HEADER 0xB2B2B2B2 59 | #define MAGIC_NUMBER_TRAILOR 0xB2 60 | 61 | 62 | struct chunkHeader *chunkList = NULL; 63 | 64 | struct chunkHeader { 65 | struct chunkHeader *next; 66 | uint32_t length; 67 | int32_t tag; 68 | uint32_t magicNumberHeader; 69 | }; 70 | 71 | typedef unsigned char MAGIC_TRAILER_T; 72 | 73 | 74 | #ifdef MEMORY_USAGE 75 | 76 | struct memoryUsage *memoryList = NULL; 77 | 78 | struct memoryUsage { 79 | struct memoryUsage *next; 80 | uint32_t length; 81 | uint32_t counter; 82 | int32_t tag; 83 | }; 84 | 85 | void addMemory(uint32_t length, int32_t tag) 86 | { 87 | 88 | struct memoryUsage *walker; 89 | 90 | for (walker = memoryList; walker != NULL; walker = walker->next) { 91 | 92 | if (walker->tag == tag) { 93 | 94 | walker->counter++; 95 | break; 96 | } 97 | } 98 | 99 | if (walker == NULL) { 100 | 101 | walker = malloc(sizeof(struct memoryUsage)); 102 | 103 | walker->length = length; 104 | walker->tag = tag; 105 | walker->counter = 1; 106 | 107 | walker->next = memoryList; 108 | memoryList = walker; 109 | } 110 | 111 | } 112 | 113 | void removeMemory(int32_t tag, int32_t freetag) 114 | { 115 | 116 | struct memoryUsage *walker; 117 | 118 | for (walker = memoryList; walker != NULL; walker = walker->next) { 119 | 120 | if (walker->tag == tag) { 121 | 122 | if (walker->counter == 0) { 123 | 124 | dbg_sys(DBGT_ERR, "Freeing more memory than was allocated: malloc tag = %d, free tag = %d", 125 | tag, freetag); 126 | cleanup_all(-500069); 127 | 128 | } 129 | 130 | walker->counter--; 131 | break; 132 | 133 | } 134 | 135 | } 136 | 137 | if (walker == NULL) { 138 | 139 | dbg_sys(DBGT_ERR, "Freeing memory that was never allocated: malloc tag = %d, free tag = %d", 140 | tag, freetag); 141 | cleanup_all(-500070); 142 | } 143 | } 144 | 145 | void debugMemory(struct ctrl_node *cn) 146 | { 147 | 148 | struct memoryUsage *memoryWalker; 149 | 150 | dbg_printf(cn, "\nMemory usage information:\n"); 151 | 152 | for (memoryWalker = memoryList; memoryWalker != NULL; memoryWalker = memoryWalker->next) { 153 | 154 | if (memoryWalker->counter != 0) 155 | dbg_printf(cn, " tag: %4i, num malloc: %4i, bytes per malloc: %4i, total: %6i\n", 156 | memoryWalker->tag, memoryWalker->counter, memoryWalker->length, 157 | memoryWalker->counter * memoryWalker->length); 158 | 159 | } 160 | dbg_printf(cn, "\n"); 161 | 162 | } 163 | 164 | #endif //#ifdef MEMORY_USAGE 165 | 166 | void checkIntegrity(void) 167 | { 168 | struct chunkHeader *walker; 169 | MAGIC_TRAILER_T *chunkTrailer; 170 | unsigned char *memory; 171 | 172 | for (walker = chunkList; walker != NULL; walker = walker->next) { 173 | if (walker->magicNumberHeader != MAGIC_NUMBER_HEADER) { 174 | dbgf_sys(DBGT_ERR, "invalid magic number in header: %08x, malloc tag = %d", 175 | walker->magicNumberHeader, walker->tag); 176 | cleanup_all(-500073); 177 | } 178 | 179 | memory = (unsigned char *) walker; 180 | 181 | chunkTrailer = (MAGIC_TRAILER_T*) (memory + sizeof(struct chunkHeader) +walker->length); 182 | 183 | if (*chunkTrailer != MAGIC_NUMBER_TRAILOR) { 184 | dbgf_sys(DBGT_ERR, "invalid magic number in trailer: %08x, malloc tag = %d", 185 | *chunkTrailer, walker->tag); 186 | cleanup_all(-500075); 187 | } 188 | } 189 | 190 | } 191 | 192 | void checkLeak(void) 193 | { 194 | struct chunkHeader *walker; 195 | 196 | if (chunkList != NULL) { 197 | 198 | openlog("bmx7", LOG_PID, LOG_DAEMON); 199 | 200 | for (walker = chunkList; walker != NULL; walker = walker->next) { 201 | syslog(LOG_ERR, "Memory leak detected, malloc tag = %d\n", walker->tag); 202 | 203 | fprintf(stderr, "Memory leak detected, malloc tag = %d \n", walker->tag); 204 | 205 | } 206 | 207 | closelog(); 208 | } 209 | 210 | } 211 | 212 | void *_debugMalloc(size_t length, int32_t tag, uint8_t reset) 213 | { 214 | 215 | unsigned char *memory; 216 | struct chunkHeader *chunkHeader; 217 | MAGIC_TRAILER_T *chunkTrailer; 218 | unsigned char *chunk; 219 | 220 | debugMalloc_bytes += (length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T)); 221 | debugMalloc_objects += 1; 222 | 223 | if (!length) 224 | return NULL; 225 | 226 | if (reset) { 227 | memory = malloc(length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T)); 228 | memset(memory, 0, length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T)); 229 | } else { 230 | memory = malloc(length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T)); 231 | } 232 | 233 | if (memory == NULL) { 234 | dbg_sys(DBGT_ERR, "Cannot allocate %u bytes, malloc tag = %d", 235 | (unsigned int) (length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T)), tag); 236 | cleanup_all(-500076); 237 | } 238 | 239 | chunkHeader = (struct chunkHeader *) memory; 240 | chunk = memory + sizeof(struct chunkHeader); 241 | chunkTrailer = (MAGIC_TRAILER_T*) (memory + sizeof(struct chunkHeader) +length); 242 | 243 | chunkHeader->length = length; 244 | chunkHeader->tag = tag; 245 | chunkHeader->magicNumberHeader = MAGIC_NUMBER_HEADER; 246 | 247 | *chunkTrailer = MAGIC_NUMBER_TRAILOR; 248 | 249 | chunkHeader->next = chunkList; 250 | chunkList = chunkHeader; 251 | 252 | #ifdef MEMORY_USAGE 253 | 254 | addMemory(length, tag); 255 | 256 | #endif //#ifdef MEMORY_USAGE 257 | 258 | return chunk; 259 | } 260 | 261 | void *_debugRealloc(void *memoryParameter, size_t length, int32_t tag) 262 | { 263 | 264 | unsigned char *result = _debugMalloc(length, tag, 0); 265 | uint32_t copyLength = 0; 266 | 267 | if (memoryParameter) { /* if memoryParameter==NULL, realloc() should work like malloc() !! */ 268 | 269 | struct chunkHeader *chunkHeader = 270 | (struct chunkHeader *) (((unsigned char *) memoryParameter) - sizeof(struct chunkHeader)); 271 | 272 | MAGIC_TRAILER_T * chunkTrailer = 273 | (MAGIC_TRAILER_T *) (((unsigned char *) memoryParameter) + chunkHeader->length); 274 | 275 | if (chunkHeader->magicNumberHeader != MAGIC_NUMBER_HEADER) { 276 | dbgf_sys(DBGT_ERR, "invalid magic number in header: %08x, malloc tag = %d", 277 | chunkHeader->magicNumberHeader, chunkHeader->tag); 278 | cleanup_all(-500078); 279 | } 280 | 281 | if (*chunkTrailer != MAGIC_NUMBER_TRAILOR) { 282 | dbgf_sys(DBGT_ERR, "invalid magic number in trailer: %08x, malloc tag = %d", 283 | *chunkTrailer, chunkHeader->tag); 284 | cleanup_all(-500079); 285 | } 286 | 287 | copyLength = (length < chunkHeader->length) ? length : chunkHeader->length; 288 | 289 | if (copyLength) 290 | memcpy(result, memoryParameter, copyLength); 291 | 292 | debugFree(memoryParameter, -300280); 293 | } 294 | 295 | return result; 296 | } 297 | 298 | void _debugFree(void *memoryParameter, int tag) 299 | { 300 | MAGIC_TRAILER_T *chunkTrailer; 301 | struct chunkHeader *walker; 302 | struct chunkHeader *previous; 303 | struct chunkHeader *chunkHeader = 304 | (struct chunkHeader *) (((unsigned char *) memoryParameter) - sizeof(struct chunkHeader)); 305 | 306 | if (chunkHeader->magicNumberHeader != MAGIC_NUMBER_HEADER) { 307 | dbgf_sys(DBGT_ERR, 308 | "invalid magic number in header: %08x, malloc tag = %d, free tag = %d, malloc size = %d", 309 | chunkHeader->magicNumberHeader, chunkHeader->tag, tag, chunkHeader->length); 310 | cleanup_all(-500080); 311 | } 312 | 313 | previous = NULL; 314 | 315 | for (walker = chunkList; walker != NULL; walker = walker->next) { 316 | if (walker == chunkHeader) 317 | break; 318 | 319 | previous = walker; 320 | } 321 | 322 | if (walker == NULL) { 323 | dbg_sys(DBGT_ERR, "Double free detected, malloc tag = %d, free tag = %d malloc size = %d", 324 | chunkHeader->tag, tag, chunkHeader->length); 325 | cleanup_all(-500081); 326 | } 327 | 328 | if (previous == NULL) 329 | chunkList = walker->next; 330 | 331 | else 332 | previous->next = walker->next; 333 | 334 | 335 | chunkTrailer = (MAGIC_TRAILER_T *) (((unsigned char *) memoryParameter) + chunkHeader->length); 336 | 337 | if (*chunkTrailer != MAGIC_NUMBER_TRAILOR) { 338 | dbgf_sys(DBGT_ERR, "invalid magic number in trailer: %08x, malloc tag = %d, free tag = %d, malloc size = %d", 339 | *chunkTrailer, chunkHeader->tag, tag, chunkHeader->length); 340 | cleanup_all(-500082); 341 | } 342 | 343 | debugMalloc_bytes -= (chunkHeader->length + sizeof(struct chunkHeader) + sizeof(MAGIC_TRAILER_T)); 344 | debugMalloc_objects -= 1; 345 | 346 | #ifdef MEMORY_USAGE 347 | 348 | removeMemory(chunkHeader->tag, tag); 349 | 350 | #endif //#ifdef MEMORY_USAGE 351 | 352 | if (!terminating) 353 | free(chunkHeader); 354 | 355 | } 356 | 357 | void _debugFreeReset(void **mem, size_t resetSize, int tag) 358 | { 359 | if (mem) { 360 | if (resetSize) 361 | memset(*mem, 0, resetSize); 362 | 363 | debugFree(*mem, tag); 364 | 365 | *mem = NULL; 366 | } 367 | } 368 | 369 | #else 370 | 371 | void * _malloc(size_t length) 372 | { 373 | debugMalloc_objects += 1; 374 | return malloc(length); 375 | } 376 | 377 | void * _calloc(size_t length) 378 | { 379 | debugMalloc_objects += 1; 380 | void *mem = malloc(length); 381 | memset(mem, 0, length); 382 | return mem; 383 | } 384 | 385 | void * _realloc(void *mem, size_t length) 386 | { 387 | return realloc(mem, length); 388 | } 389 | 390 | void _free(void *mem) 391 | { 392 | debugMalloc_objects -= 1; 393 | if (!terminating) 394 | free(mem); 395 | } 396 | 397 | void _freeReset(void **mem, size_t resetSize) 398 | { 399 | 400 | if (mem) { 401 | debugMalloc_objects -= 1; 402 | 403 | if (resetSize) 404 | memset(*mem, 0, resetSize); 405 | 406 | if (!terminating) 407 | free(*mem); 408 | 409 | *mem = NULL; 410 | } 411 | } 412 | 413 | #endif 414 | -------------------------------------------------------------------------------- /src/allocate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006 B.A.T.M.A.N. contributors: 3 | * Thomas Lopatic, Corinna 'Elektra' Aichele, Axel Neumann, Marek Lindner 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of version 2 of the GNU General Public 6 | * License as published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | * General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16 | * 02110-1301, USA 17 | * 18 | */ 19 | 20 | 21 | #ifndef _ALLOCATE_H 22 | #define _ALLOCATE_H 1 23 | 24 | #include 25 | 26 | extern uint32_t debugMalloc_bytes; 27 | extern uint32_t debugMalloc_objects; 28 | 29 | uint64_t getProcMemory(void); 30 | 31 | #ifdef DEBUG_MALLOC 32 | 33 | // currently used memory tags: -300000, -300001 .. -300853 34 | #define debugMalloc( length,tag ) _debugMalloc( (length), (tag), 0 ) 35 | #define debugMallocReset( length,tag ) _debugMalloc( (length), (tag), 1 ) 36 | #define debugRealloc( mem,length,tag ) _debugRealloc( (mem), (length), (tag) ) 37 | 38 | #define debugFree( mem,tag ) _debugFree( (mem), (tag) ) 39 | #define debugFreeReset( mempp, resetSize, tag ) _debugFreeReset( ((void**)(mempp)), (resetSize), (tag) ) 40 | 41 | void *_debugMalloc(size_t length, int32_t tag, uint8_t reset); 42 | void *_debugRealloc(void *memory, size_t length, int32_t tag); 43 | void _debugFree(void *memoryParameter, int32_t tag); 44 | void _debugFreeReset(void **memoryParameter, size_t resetSize, int32_t tag); 45 | 46 | void checkIntegrity(void); 47 | void checkLeak(void); 48 | void debugMemory(struct ctrl_node *cn); 49 | 50 | #else 51 | 52 | #define debugMalloc( length,tag ) _malloc( (length) ) 53 | #define debugMallocReset( length,tag ) _calloc( (length) ) 54 | #define debugRealloc( mem,length,tag ) _realloc( (mem), (length) ) 55 | #define debugFree( mem,tag ) _free( (mem) ) 56 | #define debugFreeReset( mempp, resetSize, tag ) _freeReset( ((void**)(mempp)), (resetSize) ) 57 | 58 | #define checkIntegrity() 59 | #define checkLeak() 60 | #define debugMemory( c ) 61 | 62 | void * _malloc(size_t length); 63 | void * _calloc(size_t length); 64 | void * _realloc(void *mem, size_t length); 65 | void _free(void *mem); 66 | void _freeReset(void **mem, size_t resetLength); 67 | 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/avl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | /* 19 | * avl code inspired by: 20 | * http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_avl.aspx 21 | * where Julienne Walker said (web page from 28. 2. 2010 12:55): 22 | * ...Once again, all of the code in this tutorial is in the public domain. 23 | * You can do whatever you want with it, but I assume no responsibility 24 | * for any damages from improper use. ;-) 25 | */ 26 | 27 | #ifndef _AVL_H 28 | #define _AVL_H 29 | 30 | #include 31 | 32 | 33 | #define AVL_MAX_HEIGHT 128 34 | 35 | struct avl_node { 36 | void *item; 37 | int balance; 38 | struct avl_node * up; 39 | struct avl_node * down[2]; 40 | #ifdef AVL_5XLINKED 41 | struct avl_node * left; // it less-equal node 42 | struct avl_node * right; // it greater node 43 | #endif 44 | }; 45 | 46 | // obtain key pointer based on avl_node pointer 47 | #define AVL_NODE_KEY( a_tree, a_node ) ( (void*) ( ((char*)(a_node)->item)+((a_tree)->key_offset) ) ) 48 | 49 | // obtain key pointer based on item pointer 50 | #define AVL_ITEM_KEY( a_tree, a_item ) ( (void*) ( ((char*)(a_item))+((a_tree)->key_offset) ) ) 51 | 52 | struct avl_tree { 53 | struct avl_node *root; 54 | #ifdef AVL_5XLINKED 55 | struct avl_node *first; 56 | struct avl_node *last; 57 | #endif 58 | uint16_t key_size; 59 | uint16_t key_offset; 60 | uint32_t items; 61 | }; 62 | 63 | #ifdef AVL_5XLINKED 64 | 65 | #define AVL_INIT_TREE(tree, element_type, key_field) do { \ 66 | tree.root = NULL; \ 67 | tree.first = NULL; \ 68 | tree.last = NULL; \ 69 | tree.key_size = sizeof( (((element_type *) 0)->key_field) ); \ 70 | tree.key_offset = ((unsigned long) (&((element_type *) 0)->key_field)); \ 71 | tree.items = 0; \ 72 | } while (0) 73 | 74 | #define AVL_TREE(tree, element_type, key_field) struct avl_tree (tree) = { \ 75 | NULL, NULL, NULL, \ 76 | (sizeof( (((element_type *) 0)->key_field) )), \ 77 | ((unsigned long)(&(((element_type *)0)->key_field))), \ 78 | 0 } 79 | #else 80 | #define AVL_INIT_TREE(tree, element_type, key_field) do { \ 81 | tree.root = NULL; \ 82 | tree.key_size = sizeof( (((element_type *) 0)->key_field) ); \ 83 | tree.key_offset = ((unsigned long) (&((element_type *) 0)->key_field)); \ 84 | tree.items = 0; \ 85 | } while (0) 86 | 87 | #define AVL_TREE(tree, element_type, key_field) struct avl_tree (tree) = { \ 88 | NULL, \ 89 | (sizeof( (((element_type *) 0)->key_field) )), \ 90 | ((unsigned long)(&(((element_type *)0)->key_field))), \ 91 | 0 } 92 | #endif 93 | 94 | #define avl_height(p) ((p) == NULL ? -1 : (p)->balance) 95 | #define avl_max(a,b) ((a) > (b) ? (a) : (b)) 96 | 97 | 98 | struct avl_node *avl_find(struct avl_tree *tree, void *key); 99 | void *avl_find_item(struct avl_tree *tree, void *key); 100 | void *avl_next_item(struct avl_tree *tree, void *key); 101 | void *avl_closest_item(struct avl_tree *tree, void *key); 102 | void *avl_first_item(struct avl_tree *tree); 103 | void *avl_iterate_item(struct avl_tree *tree, struct avl_node **it); 104 | void *_avl_find_item_by_field(struct avl_tree *tree, void *value, unsigned long offset, uint32_t size); 105 | #define avl_find_item_by_field(tree,val,s,field) _avl_find_item_by_field( tree, val, (unsigned long)((&(((struct s*)0)->field))), sizeof(((struct s*)0)->field) ) 106 | void avl_insert(struct avl_tree *tree, void *node, int32_t tag); 107 | void *avl_remove(struct avl_tree *tree, void *key, int32_t tag); 108 | void *avl_remove_first_item(struct avl_tree *tree, int32_t tag); 109 | void init_avl(void); 110 | 111 | #ifdef AVL_DEBUG 112 | 113 | struct avl_iterator { 114 | struct avl_node * up[AVL_MAX_HEIGHT]; 115 | int upd[AVL_MAX_HEIGHT]; 116 | int top; 117 | }; 118 | 119 | struct avl_node *avl_iter(struct avl_tree *tree, struct avl_iterator *it); 120 | void avl_debug(struct avl_tree *tree); 121 | void avl_test(int m); 122 | #endif 123 | 124 | 125 | #endif 126 | -------------------------------------------------------------------------------- /src/content.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | //TODO: set REQ_TO to 1 (in a non-packet-loss testenvironment this may be set to 1000 for testing) 24 | #define DEF_TX_CONTENT_REQ_TO ((DEF_TX_MIN_INTERVAL*3)/2) 25 | #define DEF_TX_CONTENT_ADV_TO 200 26 | 27 | #define MAX_DESC_TYPE_CONTENT_OCCURANCE 10 28 | #define ARG_CONTENTS "contents" 29 | 30 | #define DEF_UNSOLICITED_CONTENT_ADVS 1 31 | #define MIN_UNSOLICITED_CONTENT_ADVS 0 32 | #define MAX_UNSOLICITED_CONTENT_ADVS 1 33 | #define ARG_UNSOLICITED_CONTENT_ADVS "unsolicitedContentAdvs" 34 | 35 | extern struct avl_tree content_tree; 36 | 37 | 38 | 39 | #define DSC_MSG_CHASH_FORMAT { \ 40 | {FIELD_TYPE_STRING_BINARY, -1, 160, 1, FIELD_RELEVANCE_LOW, "chash"}, \ 41 | FIELD_FORMAT_END } 42 | 43 | struct dsc_msg_chash { 44 | CRYPTSHA_T chash; // hash over frame data (without frame-header, but including hdr_content_adv and all body data) as transmitted via content_adv 45 | } __attribute__((packed)); 46 | 47 | struct dsc_hdr_chash { 48 | CRYPTSHA_T expanded_chash; // hash over zero-frame_hdr_content_adv and frame body data with all resolved, re-assembled, uncompressed. 49 | // So for a dsc_hdr/msg_chash frame with a single uncompressed and non-nested chash this would equal the chash of dsc_msg_chash which MUST be omitted. 50 | // Otherwise it provides a checksum over the final data. 51 | 52 | union { 53 | 54 | struct { 55 | #if __BYTE_ORDER == __LITTLE_ENDIAN 56 | unsigned int gzip : 1; // only contents are compressed, all resolved and re-assembled contents are compressed (NOT the hashes) 57 | unsigned int maxNesting : 2; 58 | unsigned int expanded_type : 5; 59 | unsigned int expanded_length : 24; 60 | #elif __BYTE_ORDER == __BIG_ENDIAN 61 | unsigned int expanded_length : 24; 62 | unsigned int expanded_type : 5; 63 | unsigned int maxNesting : 2; 64 | unsigned int gzip : 1; 65 | #else 66 | #error "Please fix " 67 | #endif 68 | } __attribute((packed)) i; 69 | uint32_t u32; 70 | } u; 71 | 72 | struct dsc_msg_chash msg[]; 73 | 74 | } __attribute__((packed)); 75 | 76 | struct frame_msg_content_adv { 77 | CRYPTSHA_T chash; // hash over frame data (without frame-header, but including hdr_content_adv and all body data) as transmitted via content_adv 78 | } __attribute__((packed)); 79 | 80 | struct frame_hdr_content_adv { 81 | #if __BYTE_ORDER == __LITTLE_ENDIAN 82 | unsigned int gzip : 1; // only contents are compressed, all resolved and re-assembled contents are compressed (NOT the hashes) 83 | unsigned int maxNesting : 2; 84 | unsigned int reserved : 5; 85 | #elif __BYTE_ORDER == __BIG_ENDIAN 86 | unsigned int reserved : 5; 87 | unsigned int maxNesting : 2; 88 | unsigned int gzip : 1; 89 | #else 90 | #error "Please fix " 91 | #endif 92 | uint8_t content[]; //hashes if nested, otherwise raw content data 93 | } __attribute__((packed)); 94 | 95 | 96 | 97 | // for FRAME_TYPE_REF_REQ: 98 | 99 | struct msg_content_req { 100 | CRYPTSHA_T chash; 101 | } __attribute__((packed)); 102 | 103 | //TODO: Use this destination header!!! 104 | 105 | struct hdr_content_req { // 20 bytes 106 | GLOBAL_ID_T dest_kHash; 107 | struct msg_content_req msg[]; 108 | } __attribute__((packed)); 109 | 110 | struct desc_content { 111 | DHASH_T dHash; 112 | 113 | IDM_T cntr; 114 | struct key_node *kn; 115 | struct orig_node *on; 116 | uint8_t *desc_frame; 117 | uint16_t desc_frame_len; 118 | int32_t ref_content_len; 119 | DESC_SQN_T descSqn; 120 | union content_sizes claimedVirtDescSizes; 121 | union content_sizes countedVirtDescSizes; 122 | TIME_T referred_by_others_timestamp; 123 | 124 | struct avl_tree contentRefs_tree; 125 | uint32_t unresolvedContentCounter; 126 | uint8_t max_nesting; 127 | 128 | uint16_t ogmSqnRange; 129 | OGM_SQN_T ogmSqnMaxSend; 130 | OGM_SQN_T ogmSqnMaxRcvd; 131 | ChainLink_T chainLinkMaxRcvd; 132 | ChainInputs_T chainCache; 133 | CRYPTSHA_T chainOgmConstInputHash; 134 | ChainLink_T *chainAnchor; 135 | 136 | struct desc_tlv_body final[BMX_DSC_TLV_ARRSZ]; 137 | }; 138 | 139 | 140 | int8_t descContent_assemble(struct desc_content *dc, IDM_T init_not_finalize); 141 | struct desc_content* descContent_create(uint8_t *dsc, uint32_t dlen, struct key_node *kn); 142 | void descContent_destroy(struct desc_content *dc); 143 | void content_resolve(struct key_node *kn, struct neigh_node *viaNeigh); 144 | struct content_node * content_find(CRYPTSHA_T *chash); 145 | void *contents_data(struct desc_content *contents, uint8_t type); 146 | uint32_t contents_dlen(struct desc_content *contents, uint8_t type); 147 | struct content_node * content_add_hash(CRYPTSHA_T *chash); 148 | struct content_node * content_add_body(uint8_t *body, uint32_t body_len, uint8_t compressed, uint8_t nested, uint8_t force); 149 | int32_t create_chash_tlv(struct tlv_hdr *tlv, uint8_t *f_data, uint32_t f_len, uint8_t f_type, uint8_t fzip, uint8_t level, union content_sizes *virtDescSizes); 150 | void content_purge_unused(struct content_node *onlyCn); 151 | 152 | void init_content(void); 153 | -------------------------------------------------------------------------------- /src/crypt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2024 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | /* 19 | * Alternative cryptographic libraries are: 20 | * libtomcrypt, gcrypt, cyassl 21 | */ 22 | #define MBEDTLS_MIN 2000 23 | #define MBEDTLS_2_4_0 2240 24 | #define MBEDTLS_2_6_0 2260 25 | #define MBEDTLS_2_7_0 2270 26 | #define MBEDTLS_2_8_0 2280 27 | #define MBEDTLS_3_0_0 2300 28 | #define MBEDTLS_3_6_0 2360 29 | #define MBEDTLS_MAX 2999 30 | 31 | #include "mbedtls/version.h" 32 | #ifndef MBEDTLS_VERSION_NUMBER 33 | #define CRYPTLIB MBEDTLS_2_8_0 34 | #elif (MBEDTLS_VERSION_NUMBER >= 0x01000000 && MBEDTLS_VERSION_NUMBER < 0x03000000) 35 | #define CRYPTLIB MBEDTLS_2_8_0 36 | #elif (MBEDTLS_VERSION_NUMBER >= 0x03000000) 37 | #define CRYPTLIB MBEDTLS_3_6_0 38 | #endif 39 | 40 | #define CRYPT_DER_BUF_SZ 16000 41 | 42 | #define CRYPT_KEY_N_MOD 128 43 | #define CRYPT_KEY_E_VAL 65537 44 | 45 | #define CRYPT_RSA512_TYPE 1 46 | #define CRYPT_RSA512_LEN 64 47 | #define CRYPT_RSA512_NAME "RSA512" 48 | #define CRYPT_RSA768_TYPE 2 49 | #define CRYPT_RSA768_LEN (768/8) //96 50 | #define CRYPT_RSA768_NAME "RSA768" 51 | #define CRYPT_RSA896_TYPE 3 52 | #define CRYPT_RSA896_LEN (896/8) //112 53 | #define CRYPT_RSA896_NAME "RSA896" 54 | #define CRYPT_RSA1024_TYPE 4 55 | #define CRYPT_RSA1024_LEN (1024/8) //128 56 | #define CRYPT_RSA1024_NAME "RSA1024" 57 | #define CRYPT_RSA1536_TYPE 5 58 | #define CRYPT_RSA1536_LEN (1536/8) //192 59 | #define CRYPT_RSA1536_NAME "RSA1536" 60 | #define CRYPT_RSA2048_TYPE 6 61 | #define CRYPT_RSA2048_LEN (2048/8) //256 62 | #define CRYPT_RSA2048_NAME "RSA2048" 63 | #define CRYPT_RSA3072_TYPE 7 64 | #define CRYPT_RSA3072_LEN (3072/8) //384 65 | #define CRYPT_RSA3072_NAME "RSA3072" 66 | #define CRYPT_RSA4096_TYPE 8 67 | #define CRYPT_RSA4096_LEN (4096/8) //512 68 | #define CRYPT_RSA4096_NAME "RSA4096" 69 | 70 | #define CRYPT_RSA_MIN_TYPE CRYPT_RSA1024_TYPE 71 | #define CRYPT_RSA_MAX_TYPE 8 72 | #define CRYPT_RSA_MAX_LEN 512 73 | 74 | #define CRYPT_DHM1024_TYPE 16 //DHM parameter defined in DHM_RFC2409_MODP_1024_P /_G 75 | #define CRYPT_DHM1024_LEN (1024/8) //128 76 | #define CRYPT_DHM1024_NAME "DH1024M112" 77 | #define CRYPT_DHM2048_TYPE 17 //DHM parameter defined in DHM_RFC3526_MODP_2048_P /_G 78 | #define CRYPT_DHM2048_LEN (2048/8) //256 79 | #define CRYPT_DHM2048_NAME "DH2048M112" 80 | #define CRYPT_DHM3072_TYPE 18 //DHM parameter defined in DHM_RFC3526_MODP_3072_P /_G 81 | #define CRYPT_DHM3072_LEN (3072/8) 82 | #define CRYPT_DHM3072_NAME "DH3072M112" 83 | 84 | #define CRYPT_DHM_MIN_TYPE CRYPT_DHM2048_TYPE 85 | #define CRYPT_DHM_MAX_TYPE CRYPT_DHM3072_TYPE 86 | #define CRYPT_DHM_MAX_LEN CRYPT_DHM3072_LEN 87 | 88 | #define CRYPT_SHA_LEN (224/8)//28 89 | 90 | typedef struct CRYPTSHA_T { 91 | 92 | union { 93 | uint8_t u8[CRYPT_SHA_LEN]; 94 | uint32_t u32[CRYPT_SHA_LEN / sizeof(uint32_t)]; 95 | } h; 96 | } CRYPTSHA_T; 97 | 98 | extern const CRYPTSHA_T ZERO_CYRYPSHA; 99 | 100 | #define CRYPT_SHA112_BITSIZE 112 101 | // 2^112=5.2e33! 102 | // As of April 2016 the total cummulative number of bitcoin double-sha256 hashes is < 1e26 < 2^89 (source http://bitcoin.sipa.be/ ). 103 | // Work for 2^89 double-sha256 == work for 2^90 single-sha256 (and single-sha224) 104 | // Assuming a doubling of hash power per year I assume that 112 bits remains unfeasible for 112-90=22 more years! 105 | // Note that HashChainAnchors and DhmKeys are renewed with description updates (e.g. every OGM_SQN_RANGE ogm intervals ~ every hour) 106 | 107 | typedef struct CRYPTSHA112_T { 108 | uint8_t u8[CRYPT_SHA112_BITSIZE / 8]; 109 | } CRYPTSHA112_T; 110 | 111 | typedef struct CRYPTRSA_T { 112 | TIME_SEC_T endOfLife; 113 | uint8_t rawKeyType; 114 | uint16_t rawKeyLen; 115 | // uint8_t __nativeBackendKey; 116 | // uint8_t *__rawKey; 117 | void *backendKey; 118 | } CRYPTRSA_T; 119 | 120 | extern const CRYPTRSA_T CYRYPTRSA_ZERO; 121 | 122 | typedef struct CRYPTDHM_T { 123 | TIME_SEC_T endOfLife; 124 | uint16_t rawGXLen; 125 | uint8_t rawGXType; 126 | void *backendKey; 127 | } CRYPTDHM_T; 128 | 129 | uint8_t cryptDhmKeyTypeByLen(int len); 130 | uint16_t cryptDhmKeyLenByType(int type); 131 | char *cryptDhmKeyTypeAsString(int type); 132 | 133 | void cryptDhmKeyFree(CRYPTDHM_T **cryptKey); 134 | CRYPTDHM_T *cryptDhmKeyMake(uint8_t dhmSignType, uint8_t attempt); 135 | CRYPTSHA_T *cryptDhmSecretForNeigh(CRYPTDHM_T *myDhm, uint8_t *neighRawKey, uint16_t neighRawKeyLen); 136 | void cryptDhmPubKeyGetRaw(CRYPTDHM_T* key, uint8_t* buff, uint16_t buffLen); 137 | 138 | #ifndef NO_KEY_GEN 139 | int cryptRsaKeyMakeDer(int32_t keyType, char *path); 140 | CRYPTRSA_T *cryptRsaKeyMake(uint8_t keyType); 141 | #endif 142 | 143 | CRYPTRSA_T *cryptRsaKeyFromDer(char *tmp_path); 144 | CRYPTRSA_T *cryptRsaPubKeyFromRaw(uint8_t *rawKey, uint16_t rawKeyLen); 145 | int cryptRsaPubKeyGetRaw(CRYPTRSA_T *key, uint8_t *buff, uint16_t buffLen); 146 | int cryptRsaPubKeyCheck(CRYPTRSA_T *pubKey); 147 | 148 | void cryptRsaKeyFree(CRYPTRSA_T **key); 149 | 150 | int cryptRsaEncrypt(uint8_t *in, size_t inLen, uint8_t *out, size_t *outLen, CRYPTRSA_T *pubKey); 151 | int cryptRsaDecrypt(uint8_t *in, size_t inLen, uint8_t *out, size_t *outLen); 152 | int cryptRsaSign(CRYPTSHA_T *inSha, uint8_t *out, size_t outLen, CRYPTRSA_T *cryptKey); 153 | int cryptRsaVerify(uint8_t *sign, size_t signLen, CRYPTSHA_T *sha, CRYPTRSA_T *pubKey); 154 | uint8_t cryptRsaKeyTypeByLen(int len); 155 | uint16_t cryptRsaKeyLenByType(int type); 156 | char *cryptRsaKeyTypeAsString(int type); 157 | 158 | void cryptRand(void *out, uint32_t outLen); 159 | 160 | void cryptShaAtomic(void *in, int32_t len, CRYPTSHA_T *sha); 161 | void cryptShaNew(void *in, int32_t len); 162 | void cryptShaUpdate(void *in, int32_t len); 163 | void cryptShaFinal(CRYPTSHA_T *sha); 164 | 165 | char *cryptShaAsString(CRYPTSHA_T *sha); 166 | char *cryptShaAsShortStr(CRYPTSHA_T *sha); 167 | 168 | int cryptShasEqual(CRYPTSHA_T *shaA, CRYPTSHA_T *shaB); 169 | 170 | void init_crypt(void); 171 | void cleanup_crypt(void); 172 | -------------------------------------------------------------------------------- /src/desc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #define ARG_DESC_ROOT_SIZE "descRootSizeOut" 23 | extern int32_t desc_root_size_out; 24 | #define HLP_DESC_ROOT_SIZE "set maximum size for own description and references" 25 | #define MIN_DESC_ROOT_SIZE (MIN_UDPD_SIZE - sizeof(struct packet_header) - (2*sizeof(struct tlv_hdr))) 26 | #define MAX_DESC_ROOT_SIZE (MAX_UDPD_SIZE - sizeof(struct packet_header) - (2*sizeof(struct tlv_hdr))) 27 | #define DEF_DESC_ROOT_SIZE MAX_DESC_ROOT_SIZE 28 | #define REF_CONTENT_BODY_SIZE_OUT (desc_root_size_out - sizeof(struct frame_hdr_content_adv)) 29 | #define REF_CONTENT_BODY_SIZE_MAX (MAX_DESC_ROOT_SIZE - sizeof(struct frame_hdr_content_adv)) 30 | 31 | extern int32_t vrt_frame_max_nesting; 32 | 33 | 34 | #define ARG_VRT_FRAME_DATA_SIZE_OUT "descVirtFrameSizeOut" 35 | #define HLP_VRT_FRAME_DATA_SIZE_OUT "set maximum virtual size for own description frames" 36 | #define ARG_VRT_FRAME_DATA_SIZE_IN "descVirtFrameSizeIn" 37 | #define HLP_VRT_FRAME_DATA_SIZE_IN "set maximum virtual size for other description frames" 38 | #define MIN_VRT_FRAME_DATA_SIZE (MIN_DESC_ROOT_SIZE) 39 | // this should be nearly the max possible with a reference depth of 2: 40 | #define MAX_VRT_FRAME_DATA_SIZE (32*((REF_CONTENT_BODY_SIZE_MAX / sizeof(CRYPTSHA_T)) * REF_CONTENT_BODY_SIZE_MAX)) 41 | #define DEF_VRT_FRAME_DATA_SIZE ( 2*((REF_CONTENT_BODY_SIZE_MAX / sizeof(CRYPTSHA_T)) * REF_CONTENT_BODY_SIZE_MAX)) 42 | extern int32_t vrt_frame_data_size_in; 43 | extern int32_t vrt_frame_data_size_out; 44 | 45 | 46 | 47 | #define ARG_DESC_VBODIES_SIZE_OUT "descVirtSizeOut" 48 | #define HLP_DESC_VBODIES_SIZE_OUT "set maximum virtual size for own description" 49 | #define ARG_DESC_VBODIES_SIZE_IN "descVirtSizeIn" 50 | #define HLP_DESC_VBODIES_SIZE_IN "set maximum virtual size for other node descriptions" 51 | #define MIN_DESC_VBODIES_SIZE (MIN_DESC_ROOT_SIZE) 52 | #define MAX_DESC_VBODIES_SIZE MAX_VRT_FRAME_DATA_SIZE 53 | #define DEF_DESC_VBODIES_SIZE DEF_VRT_FRAME_DATA_SIZE 54 | 55 | #define MIN_DESC_CONTENTS 0 56 | #define MAX_DESC_CONTENTS 512 57 | #define DEF_DESC_CONTENTS 32 58 | 59 | extern int32_t desc_vbodies_size_in; 60 | extern int32_t desc_vbodies_size_out; 61 | 62 | #define DEF_DESC_CHECKING 0 63 | #define MIN_DESC_CHECKING 0 64 | #define TYP_DESC_CHECKING_SIZES 1 65 | #define MAX_DESC_CHECKING 10 66 | #define ARG_DESC_CHECKING "descChecks" 67 | #define HLP_DESC_CHECKING "extended descriptions checking (allowing future additional consistency checks" 68 | 69 | extern int32_t extended_desc_checking; 70 | 71 | 72 | #define MIN_DESC0_REFERRED_TO 10000 73 | #define MAX_DESC0_REFERRED_TO 100000 74 | #define DEF_DESC0_REFERRED_TO 10000 75 | 76 | #define DEF_UNSOLICITED_DESC_ADVS 1 77 | #define MIN_UNSOLICITED_DESC_ADVS 0 78 | #define MAX_UNSOLICITED_DESC_ADVS 1 79 | #define ARG_UNSOLICITED_DESC_ADVS "unsolicitedDescAdvs" 80 | 81 | #define ARG_DSQN_PATH "descSqnPath" 82 | #define DEF_DSQN_PATH "/etc/bmx7/descSqn" 83 | 84 | 85 | #define ARG_DESCRIPTIONS "descriptions" 86 | #define HLP_DESCRIPTIONS "show node descriptions\n" 87 | 88 | #define ARG_DESCRIPTION_NAME "name" 89 | 90 | #define ARG_DESCRIPTION_TYPE "type" 91 | #define DEF_DESCRIPTION_TYPE FRAME_TYPE_PROCESS_ALL 92 | #define MIN_DESCRIPTION_TYPE 0 93 | #define MAX_DESCRIPTION_TYPE FRAME_TYPE_PROCESS_ALL 94 | #define HLP_DESCRIPTION_TYPE "show description extension(s) of given type (0..253=type 254=none 255=all) \n" 95 | 96 | #define MIN_REF_MAINTAIN_INTERVAL 1 97 | #define MAX_REF_MAINTAIN_INTERVAL 1000000 98 | #define DEF_REF_MAINTAIN_INTERVAL 5000 99 | #define ARG_REF_MAINTAIN_INTERVAL "maintainanceInterval" 100 | extern int32_t maintainanceInterval; 101 | 102 | #define MIN_DHASH_RSLV_ITERS 1 103 | #define MAX_DHASH_RSLV_ITERS 20 104 | #define DEF_DHASH_RSLV_ITERS 4 105 | #define ARG_DHASH_RSLV_ITERS "resolveIterations" 106 | extern int32_t resolveIterations; 107 | 108 | #define MIN_DHASH_RSLV_INTERVAL 100 109 | #define MAX_DHASH_RSLV_INTERVAL 10000 110 | #define DEF_DHASH_RSLV_INTERVAL 200 111 | #define ARG_DHASH_RSLV_INTERVAL "resolveInterval" 112 | extern int32_t resolveInterval; 113 | 114 | 115 | #define MIN_DHASH_RETRY_ITERS 0 116 | #define MAX_DHASH_RETRY_ITERS 256 117 | #define DEF_DHASH_RETRY_ITERS 4 118 | #define ARG_DHASH_RETRY_ITERS "descRetryIterations" 119 | 120 | #define MIN_DHASH_RETRY_INTERVAL 100 121 | #define MAX_DHASH_RETRY_INTERVAL 100000 122 | #define DEF_DHASH_RETRY_INTERVAL 10000 123 | #define ARG_DHASH_RETRY_INTERVAL "descRetryInterval" 124 | 125 | #define DEF_DESCRIBE_INFOS 1 126 | #define MIN_DESCRIBE_INFOS 0 127 | #define MAX_DESCRIBE_INFOS 1 128 | #define ARG_DESCRIBE_INFOS "describeNodeInfos" 129 | 130 | struct msg_iid_adv { 131 | IID_T transmitterIID4x; 132 | DESC_SQN_T descSqn; 133 | ChainLink_T chainOgm; 134 | CRYPTSHA_T nodeId; 135 | } __attribute__((packed)); 136 | 137 | struct msg_iid_request { 138 | IID_T receiverIID4x; 139 | } __attribute__((packed)); 140 | 141 | struct hdr_iid_request { 142 | GLOBAL_ID_T dest_nodeId; 143 | struct msg_iid_request msg[]; 144 | } __attribute__((packed)); 145 | 146 | struct schedule_dsc_req { 147 | IID_T iid; 148 | DESC_SQN_T descSqn; 149 | }; 150 | 151 | struct msg_description_request { 152 | CRYPTSHA_T kHash; 153 | } __attribute__((packed)); 154 | 155 | struct hdr_description_request { 156 | DHASH_T dest_kHash; 157 | struct msg_description_request msg[]; 158 | } __attribute__((packed)); 159 | 160 | 161 | #define DESCRIPTION_MSG_INFO_FORMAT { \ 162 | {FIELD_TYPE_UINT, -1, 8, 0, FIELD_RELEVANCE_HIGH, "type"}, \ 163 | {FIELD_TYPE_UINT, -1, 8, 0, FIELD_RELEVANCE_HIGH, "infoOffset"}, \ 164 | {FIELD_TYPE_STRING_BINARY, -1, 32, 0, FIELD_RELEVANCE_HIGH, "codeRevision"}, \ 165 | {FIELD_TYPE_STRING_BINARY, -1, 32, 0, FIELD_RELEVANCE_LOW, "reservedA"}, \ 166 | {FIELD_TYPE_STRING_BINARY, -1, 32, 0, FIELD_RELEVANCE_LOW, "reservedB"}, \ 167 | {FIELD_TYPE_STRING_BINARY, -1, 32, 0, FIELD_RELEVANCE_LOW, "reservedC"}, \ 168 | {FIELD_TYPE_UINT, -1, 8, 0, FIELD_RELEVANCE_HIGH, "nameLen"}, \ 169 | {FIELD_TYPE_UINT, -1, 8, 0, FIELD_RELEVANCE_HIGH, "mailLen"}, \ 170 | {FIELD_TYPE_STRING_BINARY, -1, 0, 0, FIELD_RELEVANCE_HIGH, "variableInfoFields" }, \ 171 | FIELD_FORMAT_END } 172 | 173 | struct description_msg_info { 174 | uint8_t type; 175 | uint8_t infoOffset; 176 | uint32_t codeRevision; 177 | uint32_t reservedA; 178 | uint32_t reservedB; 179 | uint32_t reservedC; 180 | uint8_t nameLen; 181 | uint8_t mailLen; 182 | char info[]; 183 | } __attribute__((packed)); 184 | 185 | 186 | 187 | void process_description_tlvs_del(struct orig_node *on, struct desc_content *dcOld, uint8_t ft_start, uint8_t ft_end); 188 | IDM_T process_description_tlvs(struct packet_buff *pb, struct orig_node *on, struct desc_content *dcOld, struct desc_content *dcOp, uint8_t op, uint8_t filter); 189 | void update_my_description(void); 190 | 191 | void update_orig_dhash(struct desc_content *dc); 192 | 193 | CRYPTSHA_T *nodeIdFromDescAdv(uint8_t *desc_adv); 194 | char *nodeIdAsStringFromDescAdv(uint8_t *desc_adv); 195 | IDM_T desc_frame_changed(struct desc_content *dcA, struct desc_content *dcB, uint8_t type); 196 | 197 | int32_t opt_update_description(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn); 198 | 199 | void init_desc(void); 200 | -------------------------------------------------------------------------------- /src/dump.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | 20 | #define DUMP_ERROR_STR "DUMP_ERROR" 21 | #define DUMP_MAX_STR_SIZE (MAX_DBG_STR_SIZE - strlen(DUMP_ERROR_STR)) 22 | #define DUMP_MAX_MSG_SIZE 200 23 | 24 | 25 | #define DUMP_DIRECTION_OUT 0 26 | #define DUMP_DIRECTION_IN 1 27 | #define DUMP_DIRECTION_ARRSZ 2 28 | 29 | #define DEF_DUMP_PERIOD 1000 30 | #define MIN_DUMP_PERIOD 100 31 | #define MAX_DUMP_PERIOD 1000000 32 | #define ARG_DUMP_PERIOD "trafficCapturePeriod" 33 | 34 | #define ARG_DUMP "traffic" 35 | #define ARG_DUMP_ALL "all" 36 | #define ARG_DUMP_DEV "devs" 37 | #define ARG_DUMP_SUMMARY "summary" 38 | 39 | 40 | #define DUMP_TYPE_UDP_PAYLOAD 0 41 | #define DUMP_TYPE_PACKET_HEADER 1 42 | #define DUMP_TYPE_FRAME_HEADER 2 43 | #define DUMP_TYPE_ARRSZ 3 44 | 45 | struct dump_data { 46 | uint32_t tmp_frame[DUMP_DIRECTION_ARRSZ][FRAME_TYPE_ARRSZ]; 47 | uint32_t pre_frame[DUMP_DIRECTION_ARRSZ][FRAME_TYPE_ARRSZ]; 48 | uint32_t avg_frame[DUMP_DIRECTION_ARRSZ][FRAME_TYPE_ARRSZ]; 49 | 50 | uint32_t tmp_all[DUMP_DIRECTION_ARRSZ][DUMP_TYPE_ARRSZ]; 51 | uint32_t pre_all[DUMP_DIRECTION_ARRSZ][DUMP_TYPE_ARRSZ]; 52 | uint32_t avg_all[DUMP_DIRECTION_ARRSZ][DUMP_TYPE_ARRSZ]; 53 | }; 54 | -------------------------------------------------------------------------------- /src/hna.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | #define ARG_UHNA "unicastHna" 20 | 21 | 22 | 23 | #define HNA6_PREFIXLEN_MIN 32 24 | #define HNA4_PREFIXLEN_MIN 8 25 | 26 | //#define ARG_UHNA_NETWORK "network" 27 | // 28 | //#define MIN_UHNA_PREFIXLEN 1 29 | //#define MAX_UHNA_PREFIXLEN 32 30 | //#define ARG_UHNA_PREFIXLEN "prefixlen" 31 | 32 | #define MIN_IP_METRIC 0 33 | #define MAX_IP_METRIC U32_MAX 34 | #define DEF_IP_METRIC 1024 35 | #define ARG_IP_METRIC "ipMetric" 36 | 37 | 38 | #define TLV_OP_CUSTOM_HNA_MIN (TLV_OP_CUSTOM_MIN + 0) 39 | #define TLV_OP_CUSTOM_TUN6_GET_SHA (TLV_OP_CUSTOM_MIN + 0) 40 | #define TLV_OP_CUSTOM_HNA_ROUTE_ADD (TLV_OP_CUSTOM_MIN + 1) 41 | #define TLV_OP_CUSTOM_HNA_ROUTE_DEL (TLV_OP_CUSTOM_MIN + 2) 42 | #define TLV_OP_CUSTOM_HNA_MAX (TLV_OP_CUSTOM_MIN + 2) 43 | 44 | struct hna_node { 45 | struct net_key key; 46 | struct orig_node *on; 47 | uint8_t flags; 48 | }; 49 | 50 | struct dsc_msg_hna6 { 51 | uint8_t prefixlen; 52 | uint8_t flags; 53 | IP6_T ip6; 54 | } __attribute__((packed)); 55 | 56 | #define DESCRIPTION_MSG_HNA6_FORMAT { \ 57 | {FIELD_TYPE_UINT, -1, 8, 0, FIELD_RELEVANCE_HIGH, "prefixLen"}, \ 58 | {FIELD_TYPE_UINT, -1, 8, 0, FIELD_RELEVANCE_LOW, "flags"}, \ 59 | {FIELD_TYPE_IPX6, -1, 128, 0, FIELD_RELEVANCE_HIGH, "address" }, \ 60 | FIELD_FORMAT_END } 61 | 62 | 63 | 64 | 65 | struct hna_node * find_overlapping_hna(IPX_T *ipX, uint8_t prefixlen, struct orig_node *except); 66 | 67 | struct plugin *hna_get_plugin(void); 68 | uint32_t create_tlv_hna(uint8_t* data, uint32_t max_size, uint32_t pos, struct net_key *net, uint8_t flags); 69 | 70 | 71 | 72 | //finally some tunnel stuff that is needed by other modules: 73 | 74 | extern struct avl_tree tun_in_tree; 75 | extern IFNAME_T tun_name_prefix; 76 | 77 | #define DEF_TUN_NAME_PREFIX "X7" 78 | 79 | #define ARG_TUNS "tunnels" 80 | #define DESC_MSG_HNA_FLAG_NO_ROUTE 0x01 81 | 82 | struct tun_in_node { 83 | IFNAME_T nameKey; // key for tunnel_in_tree 84 | uint8_t name_auto; 85 | uint8_t remote_manual; 86 | 87 | // the advertised part (by description_msg_tun6_adv): 88 | IP6_T remote; 89 | struct net_key tunAddr46[2]; 90 | 91 | 92 | // the advertised part (by description_msg_src6in6_adv): 93 | struct net_key ingressPrefix46[2]; 94 | 95 | uint8_t srcType46[2]; 96 | uint8_t srcPrefixMin46[2]; 97 | uint8_t advProto; 98 | 99 | //the status: 100 | int16_t tun6Id; 101 | int32_t upIfIdx; 102 | 103 | struct avl_tree tun_dev_tree; 104 | }; 105 | 106 | extern void (*set_tunXin6_net_adv_list) (uint8_t, void**); 107 | -------------------------------------------------------------------------------- /src/iid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #define _GNU_SOURCE 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "list.h" 34 | #include "control.h" 35 | #include "bmx.h" 36 | #include "crypt.h" 37 | #include "avl.h" 38 | #include "node.h" 39 | #include "key.h" 40 | #include "sec.h" 41 | #include "metrics.h" 42 | #include "ogm.h" 43 | #include "msg.h" 44 | #include "ip.h" 45 | #include "hna.h" 46 | #include "schedule.h" 47 | #include "tools.h" 48 | #include "iptools.h" 49 | #include "plugin.h" 50 | #include "allocate.h" 51 | #include "z.h" 52 | 53 | #define CODE_CATEGORY_NAME "iid" 54 | 55 | 56 | 57 | /*********************************************************** 58 | IID Infrastructure 59 | ************************************************************/ 60 | 61 | 62 | struct iid_repos my_iid_repos = {0, 0, 0, 0, {NULL}}; 63 | 64 | void iid_extend_repos(struct iid_repos *rep) 65 | { 66 | assertion(-500217, (rep != &my_iid_repos || rep->tot_used == rep->arr_size)); 67 | 68 | if (rep->arr_size + IID_REPOS_SIZE_BLOCK >= IID_REPOS_SIZE_WARN) { 69 | 70 | dbgf_sys(DBGT_WARN, "%d", rep->arr_size); 71 | 72 | assertion(-502538, (rep->arr_size + IID_REPOS_SIZE_BLOCK <= IID_REPOS_SIZE_MAX)); 73 | } 74 | 75 | if (rep->arr_size) { 76 | 77 | rep->arr.u8 = debugRealloc(rep->arr.u8, (rep->arr_size + IID_REPOS_SIZE_BLOCK) * sizeof(struct iid_ref), -300035); 78 | 79 | } else { 80 | 81 | rep->arr.u8 = debugMalloc(IID_REPOS_SIZE_BLOCK * sizeof(struct iid_ref), -300085); 82 | rep->tot_used = IID_RSVD_MAX + 1; 83 | rep->min_free = IID_RSVD_MAX + 1; 84 | rep->max_free = IID_RSVD_MAX + 1; 85 | } 86 | 87 | memset(&(rep->arr.u8[rep->arr_size * sizeof(struct iid_ref)]), 0, IID_REPOS_SIZE_BLOCK * sizeof(struct iid_ref)); 88 | 89 | rep->arr_size += IID_REPOS_SIZE_BLOCK; 90 | } 91 | 92 | void iid_purge_repos(struct iid_repos *rep) 93 | { 94 | if (rep->arr.u8) 95 | debugFree(rep->arr.u8, -300135); 96 | 97 | memset(rep, 0, sizeof( struct iid_repos)); 98 | 99 | } 100 | 101 | void iid_free(struct iid_repos *rep, IID_T iid) 102 | { 103 | rep = rep ? rep : &my_iid_repos; 104 | 105 | assertion(-500330, (iid > IID_RSVD_MAX)); 106 | assertion(-500228, (iid < rep->arr_size && iid < rep->max_free && rep->tot_used > IID_RSVD_MAX)); 107 | 108 | struct iid_ref *ref = &rep->arr.r[iid]; 109 | assertion(-500229, (ref->referred_timestamp)); 110 | 111 | if (rep == &my_iid_repos) 112 | ((MIID_T*) (ref->iidn))->__myIID4x = 0; 113 | else 114 | ((NIID_T*) (ref->iidn))->__neighIID4x = 0; 115 | 116 | ref->iidn = NULL; 117 | ref->referred_timestamp = 0; 118 | 119 | rep->min_free = XMIN(rep->min_free, iid); 120 | 121 | if (rep->max_free == iid + 1) { 122 | 123 | IID_T i; 124 | 125 | for (i = iid; i > IID_MIN_USED_FOR_SELF; i--) { 126 | 127 | if (rep->arr.r[i - 1].referred_timestamp) 128 | break; 129 | } 130 | 131 | rep->max_free = i; 132 | } 133 | 134 | rep->tot_used--; 135 | 136 | dbgf_all(DBGT_INFO, "mine=%d, iid=%d tot_used=%d, min_free=%d max_free=%d", 137 | (rep == &my_iid_repos), iid, rep->tot_used, rep->min_free, rep->max_free); 138 | 139 | if (rep->tot_used > 0 && rep->tot_used <= IID_MIN_USED_FOR_SELF) { 140 | 141 | assertion(-500362, (rep->tot_used == IID_MIN_USED_FOR_SELF && rep->max_free == IID_MIN_USED_FOR_SELF && rep->min_free == IID_MIN_USED_FOR_SELF)); 142 | 143 | iid_purge_repos(rep); 144 | } 145 | 146 | } 147 | 148 | IID_T iid_get_myIID4x_by_node(MIID_T* miidn) 149 | { 150 | assertion(-502539, (miidn)); 151 | IID_T iid = miidn->__myIID4x; 152 | 153 | assertion(-502540, (iid)); 154 | assertion(-502541, (my_iid_repos.max_free > iid)); 155 | assertion(-502542, (my_iid_repos.arr.r[iid].iidn == miidn)); 156 | 157 | my_iid_repos.arr.r[iid].referred_timestamp = bmx_time; 158 | 159 | return iid; 160 | } 161 | 162 | MIID_T* iid_get_node_by_myIID4x(IID_T myIID4x) 163 | { 164 | if (my_iid_repos.max_free <= myIID4x) 165 | return NULL; 166 | 167 | MIID_T *ref = my_iid_repos.arr.r[myIID4x].iidn; 168 | 169 | if (ref) { 170 | assertion(-502543, (ref->__myIID4x == myIID4x)); 171 | my_iid_repos.arr.r[myIID4x].referred_timestamp = bmx_time; 172 | } 173 | 174 | return ref; 175 | } 176 | 177 | IID_T iid_get_neighIID4x_timeout_by_node(NIID_T *niidn) 178 | { 179 | assertion(-502544, (niidn)); 180 | assertion(-502545, (niidn && niidn->__neighIID4x)); 181 | assertion(-502546, (niidn->nn)); 182 | assertion(-502547, (niidn->nn->neighIID4x_repos.max_free > niidn->__neighIID4x)); 183 | assertion(-502548, (niidn->nn->neighIID4x_repos.arr.r[niidn->__neighIID4x].iidn == niidn)); 184 | 185 | TIME_T to = ((TIME_T) ((bmx_time - niidn->nn->neighIID4x_repos.arr.r[niidn->__neighIID4x].referred_timestamp))); 186 | 187 | if (to < NB_IID_TIMEOUT) 188 | return(NB_IID_TIMEOUT - to); 189 | else 190 | return 0; 191 | } 192 | 193 | IID_T iid_get_neighIID4x_by_node(NIID_T *niidn) 194 | { 195 | return niidn ? niidn->__neighIID4x : IID_RSVD_MAX; 196 | } 197 | 198 | NIID_T* iid_get_node_by_neighIID4x(struct iid_repos *rep, IID_T neighIID4x, IDM_T update) 199 | { 200 | struct iid_ref *ref = NULL; 201 | 202 | 203 | if (!rep || rep->max_free <= neighIID4x || !(ref = &(rep->arr.r[neighIID4x])) || !ref->iidn) { 204 | 205 | return NULL; 206 | 207 | } else { 208 | 209 | assertion(-502549, (((NIID_T*) (ref->iidn))->__neighIID4x == neighIID4x)); 210 | if (update) 211 | ref->referred_timestamp = bmx_time; 212 | return((NIID_T*) (ref->iidn)); 213 | } 214 | 215 | return NULL; 216 | } 217 | 218 | STATIC_FUNC 219 | void _iid_set(struct iid_repos *rep, IID_T IIDpos, NIID_T *nbn, MIID_T *myn) 220 | { 221 | assertion(-500530, (rep)); 222 | assertion(-500535, (IIDpos >= IID_MIN_USED_FOR_SELF)); 223 | assertion(-502550, (XOR(nbn, myn))); // eihter the one ore the other !! 224 | assertion(-500531, IMPLIES(myn, rep == &my_iid_repos)); 225 | 226 | rep->tot_used++; 227 | rep->max_free = XMAX(rep->max_free, IIDpos + 1); 228 | 229 | IID_T min = rep->min_free; 230 | 231 | if (min == IIDpos) { 232 | for (min++; min < rep->arr_size; min++) { 233 | 234 | if (!(rep->arr.r[min].referred_timestamp)) 235 | break; 236 | } 237 | } 238 | 239 | assertion(-500244, (min <= rep->max_free)); 240 | 241 | rep->min_free = min; 242 | 243 | assertion(-502551, (!rep->arr.r[IIDpos].iidn)); 244 | assertion(-502552, (!rep->arr.r[IIDpos].referred_timestamp)); 245 | 246 | if (nbn) { 247 | assertion(-502553, (!nbn->__neighIID4x)); 248 | rep->arr.r[IIDpos].iidn = nbn; 249 | nbn->__neighIID4x = IIDpos; 250 | } else { 251 | assertion(-502554, (!myn->__myIID4x)); 252 | rep->arr.r[IIDpos].iidn = myn; 253 | myn->__myIID4x = IIDpos; 254 | } 255 | 256 | rep->arr.r[IIDpos].referred_timestamp = bmx_time; 257 | 258 | 259 | } 260 | 261 | IID_T iid_new_myIID4x(MIID_T *on) 262 | { 263 | IID_T mid; 264 | 265 | assertion(-500216, (my_iid_repos.tot_used <= my_iid_repos.arr_size)); 266 | 267 | while (my_iid_repos.arr_size <= my_iid_repos.tot_used) 268 | iid_extend_repos(&my_iid_repos); 269 | 270 | mid = my_iid_repos.min_free; 271 | 272 | _iid_set(&my_iid_repos, mid, 0, on); 273 | 274 | return mid; 275 | 276 | } 277 | 278 | void iid_set_neighIID4x(struct iid_repos *rep, IID_T neighIID4x, NIID_T *niidn) 279 | { 280 | assertion(-500326, (neighIID4x > IID_RSVD_MAX)); 281 | assertion(-500327, (niidn)); 282 | assertion(-500384, (rep && rep != &my_iid_repos)); 283 | 284 | 285 | if (rep->max_free > neighIID4x) { 286 | 287 | struct iid_ref *ref = &(rep->arr.r[neighIID4x]); 288 | 289 | if (ref->iidn) { 290 | ref->iidn = niidn; 291 | ref->referred_timestamp = bmx_time; 292 | return; 293 | } 294 | } 295 | 296 | while (rep->arr_size <= neighIID4x) { 297 | 298 | if ( 299 | rep->arr_size > IID_REPOS_SIZE_BLOCK && 300 | rep->arr_size > my_iid_repos.arr_size && 301 | rep->tot_used < rep->arr_size / 2) { 302 | 303 | dbgf_track(DBGT_WARN, "IID_REPOS USAGE WARNING neighIID4x=%d arr_size=%d used=%d", 304 | neighIID4x, rep->arr_size, rep->tot_used); 305 | } 306 | 307 | iid_extend_repos(rep); 308 | } 309 | 310 | assertion(-500243, (rep->arr_size > neighIID4x && 311 | (rep->max_free <= neighIID4x || rep->arr.r[neighIID4x].iidn == NULL))); 312 | 313 | _iid_set(rep, neighIID4x, niidn, NULL); 314 | } 315 | -------------------------------------------------------------------------------- /src/iid.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * from iid.h: 4 | */ 5 | typedef uint16_t IID_T; 6 | #define IID_BIT_SIZE (14) 7 | #define IID_MASK ((1< 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | 34 | #include "list.h" 35 | #include "control.h" 36 | #include "bmx.h" 37 | #include "tools.h" 38 | #include "allocate.h" 39 | #include "iptools.h" 40 | 41 | 42 | const IP6_T IP6_LOOPBACK_ADDR = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }; 43 | 44 | IDM_T str2netw(char* args, IPX_T *ipX, struct ctrl_node *cn, uint8_t *maskp, uint8_t *familyp, uint8_t is_addr) 45 | { 46 | 47 | const char delimiter = '/'; 48 | char *slashptr = NULL; 49 | uint8_t family; 50 | 51 | char switch_arg[IP6NET_STR_LEN] = { 0 }; 52 | 53 | if (wordlen(args) < 1 || wordlen(args) >= IP6NET_STR_LEN) 54 | return FAILURE; 55 | 56 | wordCopy(switch_arg, args); 57 | switch_arg[wordlen(args)] = '\0'; 58 | 59 | if (maskp) { 60 | 61 | if ((slashptr = strchr(switch_arg, delimiter))) { 62 | char *end = NULL; 63 | 64 | *slashptr = '\0'; 65 | 66 | errno = 0; 67 | int mask = strtol(slashptr + 1, &end, 10); 68 | 69 | if ((errno == ERANGE) || mask > 128 || mask < 0) { 70 | 71 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "invalid argument %s %s", 72 | args, strerror(errno)); 73 | 74 | return FAILURE; 75 | 76 | } else if (end == slashptr + 1 || wordlen(end)) { 77 | 78 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "invalid argument trailer %s", end); 79 | return FAILURE; 80 | } 81 | 82 | *maskp = mask; 83 | 84 | } else { 85 | 86 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "invalid argument %s! Fix you parameters!", switch_arg); 87 | return FAILURE; 88 | } 89 | } 90 | 91 | errno = 0; 92 | 93 | struct in_addr in4; 94 | struct in6_addr in6; 95 | 96 | if ((inet_pton(AF_INET, switch_arg, &in4) == 1) && (!maskp || *maskp <= 32)) { 97 | 98 | *ipX = ip4ToX(in4.s_addr); 99 | family = AF_INET; 100 | 101 | } else if ((inet_pton(AF_INET6, switch_arg, &in6) == 1) && (!maskp || *maskp <= 128)) { 102 | 103 | *ipX = in6; 104 | family = AF_INET6; 105 | 106 | } else { 107 | 108 | dbgf_all(DBGT_WARN, "invalid argument: %s: %s", args, strerror(errno)); 109 | return FAILURE; 110 | 111 | } 112 | 113 | if (is_addr) { 114 | IPX_T netw = *ipX; 115 | if ((ip_netmask_validate(&netw, (maskp ? *maskp : (family == AF_INET ? 32 : 128)), family, YES) == FAILURE) || 116 | (maskp && *maskp != (family == AF_INET ? 32 : 128) && !memcmp(&netw, ipX, sizeof(netw)))) { 117 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "Address required! NOT network!"); 118 | return FAILURE; 119 | } 120 | 121 | } else { 122 | if (ip_netmask_validate(ipX, (maskp ? *maskp : (family == AF_INET ? 32 : 128)), family, NO) == FAILURE) { 123 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "Network required! NOT address!"); 124 | return FAILURE; 125 | } 126 | } 127 | 128 | if (familyp && (*familyp == AF_INET || *familyp == AF_INET6) && *familyp != family) { 129 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "%s required!", family2Str(*familyp)); 130 | } 131 | 132 | if (familyp) 133 | *familyp = family; 134 | 135 | return SUCCESS; 136 | 137 | } 138 | 139 | char *family2Str(uint8_t family) 140 | { 141 | static char b[B64_SIZE]; 142 | 143 | switch (family) { 144 | case AF_INET: 145 | return "IPv4"; 146 | case AF_INET6: 147 | return "IPv6"; 148 | default: 149 | sprintf(b, "%d ???", family); 150 | return b; 151 | } 152 | } 153 | 154 | void ipXToStr(int family, const IPX_T *addr, char *str) 155 | { 156 | assertion(-500583, (str)); 157 | uint32_t *a; 158 | 159 | if (!addr && (family == AF_INET6 || family == AF_INET)) { 160 | 161 | strcpy(str, "---"); 162 | return; 163 | 164 | } else if (family == AF_INET) { 165 | 166 | a = (uint32_t *)&(addr->s6_addr32[3]); 167 | 168 | } else if (family == AF_INET6) { 169 | 170 | a = (uint32_t *)&(addr->s6_addr32[0]); 171 | 172 | } else { 173 | strcpy(str, "ERROR"); 174 | return; 175 | } 176 | 177 | inet_ntop(family, a, str, family == AF_INET ? INET_ADDRSTRLEN : INET6_ADDRSTRLEN); 178 | return; 179 | } 180 | 181 | void ip6ToStr(const IPX_T *addr, char *str) 182 | { 183 | ipXToStr(AF_INET6, addr, str); 184 | } 185 | 186 | IPX_T ip4ToX(IP4_T ip4) 187 | { 188 | IPX_T ip = ZERO_IP; 189 | ip.s6_addr32[3] = ip4; 190 | return ip; 191 | } 192 | 193 | char *ipXAsStr(int family, const IPX_T *addr) 194 | { 195 | static uint8_t c = 0; 196 | static char str[IP2S_ARRAY_LEN][INET6_ADDRSTRLEN]; 197 | 198 | c = (c + 1) % IP2S_ARRAY_LEN; 199 | 200 | ipXToStr(family, addr, str[c]); 201 | 202 | return str[c]; 203 | } 204 | 205 | char *ip4AsStr(IP4_T addr) 206 | { 207 | 208 | static uint8_t c = 0; 209 | static char str[IP2S_ARRAY_LEN][INET_ADDRSTRLEN]; 210 | 211 | c = (c + 1) % IP2S_ARRAY_LEN; 212 | 213 | inet_ntop(AF_INET, &addr, str[c], INET_ADDRSTRLEN); 214 | 215 | return str[c]; 216 | } 217 | 218 | char *netAsStr(const struct net_key *net) 219 | { 220 | static uint8_t c = 0; 221 | static char str[IP2S_ARRAY_LEN][IPXNET_STR_LEN]; 222 | 223 | c = (c + 1) % IP2S_ARRAY_LEN; 224 | 225 | if (net) { 226 | ipXToStr(net->af, &net->ip, str[c]); 227 | sprintf(&((str[c]) [ strlen(str[c])]), "/%d", net->mask); 228 | } else { 229 | sprintf(str[c], "---"); 230 | } 231 | 232 | return str[c]; 233 | } 234 | 235 | struct net_key * setNet(struct net_key *netp, uint8_t family, uint8_t prefixlen, IPX_T *ip) 236 | { 237 | static struct net_key net; 238 | netp = netp ? netp : &net; 239 | *netp = ZERO_NET_KEY; 240 | netp->af = family; 241 | netp->mask = prefixlen; 242 | netp->ip = ip ? *ip : ZERO_IP; 243 | return netp; 244 | } 245 | 246 | char* macAsStr(const MAC_T* mac) 247 | { 248 | return strToLower(memAsHexStringSep(mac, MAC_ADDR_LEN, 1, ":")); 249 | } 250 | 251 | IDM_T is_mac_equal(const MAC_T *a, const MAC_T *b) 252 | { 253 | return(a->u16[2] == b->u16[2] && 254 | a->u16[1] == b->u16[1] && 255 | a->u16[0] == b->u16[0]); 256 | 257 | } 258 | 259 | IDM_T is_ip_equal(const IPX_T *a, const IPX_T *b) 260 | { 261 | return(a->s6_addr32[3] == b->s6_addr32[3] && 262 | a->s6_addr32[2] == b->s6_addr32[2] && 263 | a->s6_addr32[1] == b->s6_addr32[1] && 264 | a->s6_addr32[0] == b->s6_addr32[0]); 265 | 266 | } 267 | 268 | IDM_T is_ip_net_equal(const IPX_T *netA, const IPX_T *netB, const uint8_t plen, const uint8_t family) 269 | { 270 | 271 | IPX_T aprefix = *netA; 272 | IPX_T bprefix = *netB; 273 | 274 | ip_netmask_validate(&aprefix, plen, family, YES /*force*/); 275 | ip_netmask_validate(&bprefix, plen, family, YES /*force*/); 276 | 277 | return is_ip_equal(&aprefix, &bprefix); 278 | } 279 | 280 | IDM_T is_ip_set(const IPX_T *ip) 281 | { 282 | return(ip && !is_ip_equal(ip, &ZERO_IP)); 283 | } 284 | 285 | IDM_T is_ip_valid(const IPX_T *ip, const uint8_t family) 286 | { 287 | if (!is_ip_set(ip)) 288 | return NO; 289 | 290 | if (family != (is_zero((void*) ip, sizeof( IPX_T) - sizeof(IP4_T)) ? AF_INET : AF_INET6)) 291 | return NO; 292 | 293 | if (family == AF_INET6) { 294 | 295 | if (!is_ip_equal(ip, &IP6_LOOPBACK_ADDR)) 296 | return YES; 297 | 298 | 299 | } else if (family == AF_INET) { 300 | 301 | if (ipXto4(*ip) != INADDR_LOOPBACK && ipXto4(*ip) != INADDR_NONE) 302 | return YES; 303 | } 304 | 305 | return NO; 306 | } 307 | 308 | IDM_T ip_netmask_validate(IPX_T *ipX, uint8_t mask, uint8_t family, uint8_t force) 309 | { 310 | uint8_t nmask = mask; 311 | int i; 312 | IP4_T ip32 = 0, m32 = 0; 313 | 314 | if (nmask > (family == AF_INET ? 32 : 128)) 315 | goto validate_netmask_error; 316 | 317 | if (family == AF_INET) 318 | nmask += (IP6_MAX_PREFIXLEN - IP4_MAX_PREFIXLEN); 319 | 320 | for (i = 3; i >= 0 && i >= (nmask / 32); i--) { 321 | 322 | if (!(ip32 = ipX->s6_addr32[i])) 323 | continue; 324 | 325 | if (force) { 326 | 327 | if (nmask <= (i * 32)) 328 | ipX->s6_addr32[i] = 0; 329 | else 330 | ipX->s6_addr32[i] = (ip32 & (m32 = htonl(0xFFFFFFFF << (32 - (nmask - (i * 32)))))); 331 | 332 | } else { 333 | 334 | if (nmask <= (i * 32)) 335 | goto validate_netmask_error; 336 | 337 | else if (ip32 != (ip32 & (m32 = htonl(0xFFFFFFFF << (32 - (nmask - (i * 32))))))) 338 | goto validate_netmask_error; 339 | } 340 | } 341 | 342 | 343 | return SUCCESS; 344 | validate_netmask_error: 345 | 346 | dbgf_sys(DBGT_ERR, "inconsistent network prefix %s/%d (force=%d nmask=%d, ip32=%s m32=%s)", 347 | ipXAsStr(family, ipX), mask, force, nmask, ip4AsStr(ip32), ip4AsStr(m32)); 348 | 349 | return FAILURE; 350 | 351 | } 352 | 353 | /* recurse down layer-2 interfaces until we hit a layer-1 interface using Linux' sysfs */ 354 | int interface_get_lowest(char *hwifname, const char *ifname) 355 | { 356 | glob_t globbuf = { .gl_offs = 1 }; 357 | char *lowentry = NULL; 358 | char *fnamebuf = debugMalloc(1 + strlen(VIRTIF_PREFIX) + IF_NAMESIZE + strlen(LOWERGLOB_SUFFIX), -300840); 359 | char path[PATH_MAX]; 360 | 361 | sprintf(fnamebuf, "%s%s%s", VIRTIF_PREFIX, ifname, LOWERGLOB_SUFFIX); 362 | glob(fnamebuf, GLOB_NOSORT | GLOB_NOESCAPE, NULL, &globbuf); 363 | 364 | if (globbuf.gl_pathc == 1) { 365 | lowentry = debugMalloc(1 + strlen(globbuf.gl_pathv[0]), -300841); 366 | strncpy(lowentry, globbuf.gl_pathv[0], 1 + strlen(globbuf.gl_pathv[0])); 367 | } 368 | 369 | globfree(&globbuf); 370 | debugFree(fnamebuf, -300842); 371 | 372 | if (lowentry) { 373 | ssize_t len; 374 | /* lower interface found, recurse down */ 375 | 376 | len = readlink(lowentry, path, PATH_MAX - 1); 377 | debugFree(lowentry, -300846); 378 | 379 | if (len != -1 && strncmp(path, "../", 3) == 0) { 380 | path[len] = '\0'; 381 | return interface_get_lowest(hwifname, strrchr(path, '/') + 1); 382 | } 383 | 384 | } else { 385 | /* no lower interface found, check if physical interface exists */ 386 | sprintf(path, "%s%s", NETIF_PREFIX, ifname); 387 | 388 | if (access(path, F_OK) == 0) { 389 | strncpy(hwifname, ifname, IF_NAMESIZE - 1); 390 | dbgf_track(DBGT_INFO, "got %s", hwifname); 391 | return SUCCESS; 392 | } 393 | } 394 | 395 | return FAILURE; 396 | } 397 | -------------------------------------------------------------------------------- /src/iptools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #define IP2S_ARRAY_LEN 10 19 | 20 | #define IP6NET_STR_LEN (INET6_ADDRSTRLEN+4) // eg ::1/128 21 | #define IPXNET_STR_LEN IP6NET_STR_LEN 22 | #define B64_SIZE 64 23 | 24 | #define IP4_MAX_PREFIXLEN 32 25 | #define IP6_MAX_PREFIXLEN 128 26 | 27 | #define NETIF_PREFIX "/sys/class/net/" 28 | #define VIRTIF_PREFIX "/sys/devices/virtual/net/" 29 | #define LOWERGLOB_SUFFIX "/lower_*" 30 | 31 | 32 | extern const IP6_T IP6_LOOPBACK_ADDR; 33 | 34 | 35 | IDM_T str2netw(char* args, IPX_T *ipX, struct ctrl_node *cn, uint8_t *maskp, uint8_t *familyp, uint8_t is_addr); 36 | 37 | char *family2Str(uint8_t family); 38 | 39 | 40 | char *ipXAsStr(int family, const IPX_T *addr); 41 | char *ip4AsStr(IP4_T addr); 42 | void ipXToStr(int family, const IPX_T *addr, char *str); 43 | void ip6ToStr(const IPX_T *addr, char *str); 44 | char *netAsStr(const struct net_key *net); 45 | 46 | 47 | #define ipXto4( ipx ) ((ipx).s6_addr32[3]) 48 | IPX_T ip4ToX(IP4_T ip4); 49 | 50 | char* macAsStr(const MAC_T* mac); 51 | 52 | #define ip6AsStr( addr_ptr ) ipXAsStr( AF_INET6, addr_ptr) 53 | 54 | struct net_key * setNet(struct net_key *netp, uint8_t family, uint8_t prefixlen, IPX_T *ip); 55 | 56 | 57 | IDM_T is_mac_equal(const MAC_T *a, const MAC_T *b); 58 | 59 | IDM_T is_ip_equal(const IPX_T *a, const IPX_T *b); 60 | IDM_T is_ip_set(const IPX_T *ip); 61 | 62 | IDM_T is_ip_valid(const IPX_T *ip, const uint8_t family); 63 | 64 | IDM_T ip_netmask_validate(IPX_T *ipX, uint8_t mask, uint8_t family, uint8_t force); 65 | 66 | IDM_T is_ip_net_equal(const IPX_T *netA, const IPX_T *netB, const uint8_t plen, const uint8_t family); 67 | 68 | int interface_get_lowest(char *hwifname, const char *ifname); 69 | -------------------------------------------------------------------------------- /src/key.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | 20 | 21 | 22 | 23 | extern int32_t tracked_timeout; 24 | extern int32_t neigh_qualifying_to; 25 | 26 | 27 | #define MIN_ID_PURGE_TO 0 28 | #define MAX_ID_PURGE_TO 864000000 /*10 days*/ 29 | #define DEF_ID_PURGE_TO 20000 30 | #define ARG_ID_PURGE_TO "idTimeout" 31 | 32 | #define ARG_SET_CREDITS "setCredits" 33 | #define ARG_SET_CREDITS_MAX "maxNodes" 34 | #define HLP_SET_CREDITS "parametrize given state section" 35 | #define MIN_SET_CREDITS_MAX 1 36 | #define MAX_SET_CREDITS_MAX 100000 37 | #define HLP_SET_CREDITS_MAX "set maximum number of nodes of state section" 38 | #define ARG_SET_CREDITS_PREF "preference" 39 | #define MIN_SET_CREDITS_PREF 0 40 | #define MAX_SET_CREDITS_PREF 9999 41 | #define HLP_SET_CREDITS_PREF "set preference for nodes of given state section" 42 | 43 | 44 | // Key Weight: 45 | #define KCNull (-1) 46 | 47 | enum KColumns { 48 | KCListed, 49 | KCTracked, 50 | KCCertified, 51 | KCPromoted, 52 | KCNeighbor, 53 | KCSize, 54 | }; 55 | 56 | // Key Credits: 57 | 58 | enum KRows { 59 | KRQualifying, 60 | KRFriend, 61 | KRRecommended, 62 | KRAlien, 63 | KRSize, 64 | }; 65 | 66 | int16_t kPref_neighbor_metric(struct key_node *kn); 67 | 68 | extern struct KeyState keyMatrix[KCSize][KRSize]; 69 | extern uint32_t key_tree_deletions_chk, key_tree_deletions_cntr; 70 | 71 | void keyNode_schedLowerWeight(struct key_node *kn, int8_t weight); 72 | 73 | struct key_node *keyNode_updCredits(GLOBAL_ID_T *kHash, struct key_node *kn, struct key_credits *kc); 74 | 75 | #define keyNode_delCredits( a, b, c, d ) keyNode_delCredits_(__func__, (a), (b), (c), (d) ) 76 | void keyNode_delCredits_(const char *f, GLOBAL_ID_T *kHash, struct key_node *kn, struct key_credits *kc, IDM_T reAssessState); 77 | #define KEYNODES_BLOCKING_ID 10 78 | 79 | #define keyNodes_block_and_sync( id, force ) keyNodes_block_and_sync_( __func__, (id), (force) ) 80 | uint32_t keyNodes_block_and_sync_(const char *f, uint32_t id, IDM_T force); 81 | void keyNode_fixTimeouts(void); 82 | struct key_node *keyNode_get(GLOBAL_ID_T *kHask); 83 | void keyNodes_cleanup(int8_t keyStateColumn, struct key_node *except); 84 | void init_key(void); 85 | -------------------------------------------------------------------------------- /src/lib/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += 3 | LDFLAGS += 4 | 5 | PLUGINS = $(shell find -maxdepth 1 -type d | grep -e '^./bmx7_' | sort) 6 | 7 | %: 8 | for d in $(PLUGINS); do $(MAKE) CORE_CFLAGS='$(CORE_CFLAGS)' -C $$d $@ || echo compiling $$d failed; echo;echo; done 9 | echo 2 flags: $(CFLAGS) 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/lib/bmx7_evil/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += $(CORE_CFLAGS) -fpic -I../../ 3 | LDFLAGS += -shared 4 | 5 | PLUGIN_NAME = bmx7_evil 6 | 7 | SRC_C = evil.c 8 | SRC_H = evil.h 9 | OBJS= $(SRC_C:.c=.o) 10 | 11 | PLUGIN_FULLNAME = $(PLUGIN_NAME).so 12 | PLUGIN_SHORTNAME = $(PLUGIN_NAME).so 13 | 14 | LIBDIR = /usr/lib 15 | THISDIR = $(shell pwd ) 16 | 17 | all: $(PLUGIN_FULLNAME) Makefile 18 | 19 | 20 | $(PLUGIN_FULLNAME): $(OBJS) Makefile 21 | $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME) 22 | ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME) 23 | 24 | %.o: %.c %.h Makefile 25 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 26 | 27 | 28 | clean: 29 | rm -f *.o *.so 30 | 31 | 32 | install: all 33 | mkdir -p $(LIBDIR) 34 | install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR) 35 | 36 | 37 | strip: all 38 | strip $(PLUGIN_FULLNAME) 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/lib/bmx7_evil/evil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #define DEF_ATTACKED_NODES_DIR "/etc/bmx7/attackedNodes" 19 | #define ARG_ATTACKED_NODES_DIR "attackedNodesDir" 20 | 21 | #define DEF_EVIL_TUN_NAME "bmxZero" 22 | #define DEF_EVIL_IP_TABLE 59 23 | #define DEF_EVIL_IP_RULE 59 24 | #define DEF_EVIL_IP_METRIC 1024 25 | 26 | #define ARG_EVIL_ROUTE_DROPPING "evilRouteDropping" 27 | #define DEF_EVIL_ROUTE_DROPPING 0 28 | #define MIN_EVIL_ROUTE_DROPPING 0 29 | #define MAX_EVIL_ROUTE_DROPPING 1 30 | 31 | #define ARG_EVIL_PRIMARY_IPS "evilPrimaryIps" 32 | #define DEF_EVIL_PRIMARY_IPS 0 33 | #define MIN_EVIL_PRIMARY_IPS 0 34 | #define MAX_EVIL_PRIMARY_IPS 1 35 | 36 | #define ARG_EVIL_DESC_DROPPING "evilDescDropping" 37 | #define DEF_EVIL_DESC_DROPPING 0 38 | #define MIN_EVIL_DESC_DROPPING 0 39 | #define MAX_EVIL_DESC_DROPPING 1 40 | 41 | #define ARG_EVIL_DESC_SQNS "evilDescSqns" 42 | #define DEF_EVIL_DESC_SQNS 0 43 | #define MIN_EVIL_DESC_SQNS 0 44 | #define MAX_EVIL_DESC_SQNS 1 45 | 46 | #define ARG_EVIL_DHASH_DROPPING "evilDhashDropping" 47 | #define DEF_EVIL_DHASH_DROPPING 0 48 | #define MIN_EVIL_DHASH_DROPPING 0 49 | #define MAX_EVIL_DHASH_DROPPING 1 50 | 51 | #define ARG_EVIL_OGM_DROPPING "evilOgmDropping" 52 | #define DEF_EVIL_OGM_DROPPING 0 53 | #define MIN_EVIL_OGM_DROPPING 0 54 | #define MAX_EVIL_OGM_DROPPING 1 55 | 56 | #define ARG_EVIL_OGM_METRICS "evilOgmMetrics" 57 | #define DEF_EVIL_OGM_METRICS 0 58 | #define MIN_EVIL_OGM_METRICS 0 59 | #define MAX_EVIL_OGM_METRICS 1 60 | 61 | #define ARG_EVIL_OGM_HASH "evilOgmHash" 62 | #define DEF_EVIL_OGM_HASH 0 63 | #define MIN_EVIL_OGM_HASH 0 64 | #define MAX_EVIL_OGM_HASH 10 65 | -------------------------------------------------------------------------------- /src/lib/bmx7_http_info/HOWTO: -------------------------------------------------------------------------------- 1 | very short HOWTO for the bmx_http_info.so plugin 2 | 3 | just load launch bmxd with new startup args e.g.: 4 | bmxd plugin=bmx_http_info.so http_info_port=8099 eth0 5 | 6 | then point you browser to 7 | http://localhost:8099/originators or /hnas or /status or /interfaces or /version or /services or... 8 | 9 | alternatively, when using the bmx_uci_config.so plugin, 10 | something like the following should go into /etc/config/bmx: 11 | 12 | config 'bmx' 'general' 13 | option 'http_info_port' '8099' #necessary to enable the plugin 14 | # option 'http_info_global_access' '1' #only necessary to allow access from non-127.0.0.1 host 15 | 16 | 17 | config 'plugin' 18 | option 'plugin' 'bmx_uci_config.so' 19 | 20 | config 'plugin' 21 | option 'plugin' 'bmx_http_info.so' 22 | -------------------------------------------------------------------------------- /src/lib/bmx7_http_info/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += $(CORE_CFLAGS) -fpic -I../../ 3 | LDFLAGS += -shared 4 | #-Wl,-soname,bmxd_config 5 | 6 | PLUGIN_NAME = bmx7_http_info 7 | 8 | SRC_C = http_info.c 9 | SRC_H = http_info.h 10 | OBJS= $(SRC_C:.c=.o) 11 | 12 | PLUGIN_FULLNAME = $(PLUGIN_NAME).so 13 | PLUGIN_SHORTNAME = $(PLUGIN_NAME).so 14 | 15 | LIBDIR = /usr/lib 16 | THISDIR = $(shell pwd ) 17 | 18 | all: $(PLUGIN_FULLNAME) Makefile 19 | 20 | 21 | $(PLUGIN_FULLNAME): $(OBJS) Makefile 22 | $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME) 23 | ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME) 24 | 25 | %.o: %.c %.h Makefile 26 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 27 | 28 | 29 | clean: 30 | rm -f *.o *.so 31 | 32 | 33 | install: all 34 | mkdir -p $(LIBDIR) 35 | install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR) 36 | 37 | 38 | strip: all 39 | strip $(PLUGIN_FULLNAME) 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/lib/bmx7_http_info/http_info.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006 BATMAN contributors: 3 | * Axel Neumann 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of version 2 of the GNU General Public 6 | * License as published by the Free Software Foundation. 7 | * 8 | * This program is distributed in the hope that it will be useful, but 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | * General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public License 14 | * along with this program; if not, write to the Free Software 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 16 | * 02110-1301, USA 17 | * 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | 32 | 33 | #include "list.h" 34 | #include "control.h" 35 | #include "bmx.h" 36 | #include "crypt.h" 37 | #include "avl.h" 38 | #include "node.h" 39 | #include "plugin.h" 40 | #include "schedule.h" 41 | #include "tools.h" 42 | #include "iptools.h" 43 | #include "ip.h" 44 | 45 | #define CODE_CATEGORY_NAME "http_info" 46 | 47 | #define MAX_TCP_REQ_LEN MAX_UNIX_MSG_SIZE 48 | #define HTTP_PREAMBLE "GET /" 49 | #define HTTP_PREAMBLE_LEN strlen(HTTP_PREAMBLE) 50 | 51 | #define HTTP_INFO_PORT "http_info_port" 52 | static int32_t http_info_port; 53 | 54 | #define HTTP_INFO_GLOB_ACCESS "http_info_global_access" 55 | static int32_t http_access; 56 | 57 | #define HTTP_INFO_LISTEN_QUEUE 5 58 | 59 | 60 | static int http_info_tcp_sock_in = 0; 61 | 62 | static void http_info_rcv_tcp_data(struct ctrl_node *cn) 63 | { 64 | 65 | char tcp_req_data[MAX_TCP_REQ_LEN + 1]; 66 | int tcp_req_len; 67 | 68 | memset(&tcp_req_data, 0, MAX_TCP_REQ_LEN + 1); 69 | 70 | errno = 0; 71 | tcp_req_len = read(cn->fd, &tcp_req_data, MAX_TCP_REQ_LEN); 72 | 73 | if (tcp_req_len > 5 && 74 | !memcmp(HTTP_PREAMBLE, tcp_req_data, HTTP_PREAMBLE_LEN) && 75 | tcp_req_len <= MAX_TCP_REQ_LEN) { 76 | 77 | tcp_req_data[tcp_req_len] = 0; 78 | 79 | struct opt_type *opt; 80 | char *request = &(tcp_req_data[HTTP_PREAMBLE_LEN]); 81 | 82 | dbg_printf(cn, "Content-type: text/plain\n\n"); 83 | dbg_printf(cn, "\n"); 84 | 85 | 86 | if (wordlen(request) <= MAX_ARG_SIZE && 87 | (opt = get_option(0, 0, request)) && 88 | opt->auth_t == A_USR && 89 | opt->opt_t == A_PS0 && 90 | opt->dyn_t != A_INI && 91 | opt->cfg_t == A_ARG) { 92 | 93 | dbgf(DBGL_CHANGES, DBGT_INFO, "rcvd %d bytes long HTTP request via fd %d: %s", 94 | tcp_req_len, cn->fd, opt->name); 95 | 96 | check_apply_parent_option(ADD, OPT_APPLY, 0, opt, 0, cn); 97 | 98 | } else { 99 | 100 | /* 101 | dbg_cn( cn, DBGL_ALL, DBGT_INFO, "rcvd illegal %d bytes long HTTP request via fd %d:\n%s\n", 102 | tcp_req_len, cn->fd, tcp_req_data); 103 | */ 104 | check_apply_parent_option(ADD, OPT_APPLY, 0, get_option(0, 0, ARG_STATUS), 0, cn); 105 | 106 | dbg_printf(cn, "\nillegal HTTP request! Valid requests are:\n\n"); 107 | 108 | struct list_node *list_pos; 109 | 110 | list_for_each(list_pos, &opt_list) 111 | { 112 | 113 | struct opt_type *opt = (struct opt_type *) list_entry(list_pos, struct opt_data, list); 114 | 115 | if (opt->auth_t == A_USR && 116 | opt->opt_t == A_PS0 && 117 | opt->dyn_t != A_INI && 118 | opt->cfg_t == A_ARG) { 119 | dbg_printf(cn, "/%s\n\n", opt->name); 120 | 121 | } 122 | } 123 | 124 | } 125 | 126 | } else { 127 | 128 | dbgf(DBGL_SYS, DBGT_ERR, "illegal request via cn->fd %d: %s", cn->fd, strerror(errno)); 129 | } 130 | 131 | close_ctrl_node(CTRL_CLOSE_STRAIGHT, cn); 132 | 133 | } 134 | 135 | static void http_info_rcv_tcp_connect(int32_t fd_in) 136 | { 137 | 138 | int tmp_tcp_sock; 139 | 140 | struct sockaddr_in addr; 141 | socklen_t addrlen = sizeof(struct sockaddr_in); 142 | 143 | if (!fd_in) 144 | return; 145 | 146 | assertion(-500155, (fd_in == http_info_tcp_sock_in)); 147 | 148 | if (fd_in != http_info_tcp_sock_in) { 149 | dbgf(DBGL_SYS, DBGT_ERR, "rcvd invalid fd %d - should be %d", fd_in, http_info_tcp_sock_in); 150 | set_fd_hook(fd_in, http_info_rcv_tcp_connect, YES /*unregister*/); 151 | close(fd_in); 152 | } 153 | 154 | errno = 0; 155 | if ((tmp_tcp_sock = accept(http_info_tcp_sock_in, (struct sockaddr *) &addr, &addrlen)) < 0) { 156 | dbgf(DBGL_SYS, DBGT_ERR, "accept failed: %s", strerror(errno)); 157 | return; 158 | } 159 | 160 | 161 | if (!http_access && addr.sin_addr.s_addr != 0x100007f /*127.0.0.1*/) { 162 | 163 | dbg_mute(35, DBGL_SYS, DBGT_WARN, "rcvd illegal info request from %12s %x", 164 | ip4AsStr(addr.sin_addr.s_addr), addr.sin_addr.s_addr); 165 | close(tmp_tcp_sock); 166 | return; 167 | } 168 | 169 | /* 170 | int32_t sock_opts; 171 | sock_opts = fcntl( tmp_tcp_sock, F_GETFL, 0 ); 172 | fcntl( tmp_tcp_sock, F_SETFL, sock_opts | O_NONBLOCK ); 173 | */ 174 | 175 | dbgf(DBGL_CHANGES, DBGT_INFO, "rcvd connect via fd %d from %s", tmp_tcp_sock, ip4AsStr(addr.sin_addr.s_addr)); 176 | 177 | struct ctrl_node *cn = create_ctrl_node(tmp_tcp_sock, http_info_rcv_tcp_data, NO /*admin rights*/); 178 | close_ctrl_node(CTRL_CLOSE_DELAY, cn); 179 | change_selects(); 180 | } 181 | 182 | static int32_t opt_http_port(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn) 183 | { 184 | 185 | 186 | if (cmd == OPT_APPLY) { 187 | 188 | if (http_info_tcp_sock_in) { 189 | 190 | set_fd_hook(http_info_tcp_sock_in, http_info_rcv_tcp_connect, YES /*unregister*/); 191 | close(http_info_tcp_sock_in); 192 | http_info_tcp_sock_in = 0; 193 | } 194 | 195 | 196 | if (http_info_port > 0) { 197 | 198 | int32_t tmp_tcp_sock_in; 199 | struct sockaddr_in http_info_addr; 200 | 201 | errno = 0; 202 | if ((tmp_tcp_sock_in = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 203 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "requesting socket failed: %s", strerror(errno)); 204 | return SUCCESS; 205 | } 206 | 207 | int sock_opts = 1; 208 | if (setsockopt(tmp_tcp_sock_in, SOL_SOCKET, SO_REUSEADDR, &sock_opts, sizeof(sock_opts)) < 0) { 209 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "can't set SO_REUSEADDR option: %s\n", strerror(errno)); 210 | close(tmp_tcp_sock_in); 211 | return SUCCESS; 212 | } 213 | 214 | memset(&http_info_addr, 0, sizeof(http_info_addr)); 215 | http_info_addr.sin_family = AF_INET; 216 | http_info_addr.sin_addr.s_addr = htonl(INADDR_ANY); 217 | http_info_addr.sin_port = htons(http_info_port); 218 | 219 | errno = 0; 220 | if (bind(tmp_tcp_sock_in, (struct sockaddr *) &http_info_addr, sizeof(http_info_addr)) < 0) { 221 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "binding socket failed: %s", strerror(errno)); 222 | close(tmp_tcp_sock_in); 223 | return SUCCESS; 224 | } 225 | 226 | errno = 0; 227 | if (listen(tmp_tcp_sock_in, HTTP_INFO_LISTEN_QUEUE) < 0) { 228 | dbgf_cn(cn, DBGL_SYS, DBGT_ERR, "listening on socket failed: %s", strerror(errno)); 229 | close(tmp_tcp_sock_in); 230 | return SUCCESS; 231 | } 232 | 233 | http_info_tcp_sock_in = tmp_tcp_sock_in; 234 | 235 | set_fd_hook(http_info_tcp_sock_in, http_info_rcv_tcp_connect, NO /*unregister*/); 236 | 237 | 238 | } 239 | 240 | 241 | } else if (cmd == OPT_UNREGISTER) { 242 | 243 | if (http_info_tcp_sock_in) { 244 | 245 | set_fd_hook(http_info_tcp_sock_in, http_info_rcv_tcp_connect, YES /*unregister*/); 246 | close(http_info_tcp_sock_in); 247 | http_info_tcp_sock_in = 0; 248 | } 249 | 250 | } 251 | 252 | return SUCCESS; 253 | } 254 | 255 | 256 | static struct opt_type http_info_options[]= { 257 | // ord parent long_name shrt Attributes *ival min max default *func,*syntax,*help 258 | 259 | {ODI,0,HTTP_INFO_PORT, 0,9,2, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &http_info_port,0, 64000, 0,0, opt_http_port, 260 | ARG_PORT_FORM, "set tcp port for http_info plugin" }, 261 | 262 | {ODI,0,HTTP_INFO_GLOB_ACCESS, 0,9,2, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &http_access, 0, 1, 0,0, 0, 263 | ARG_VALUE_FORM, "disable/enable global accessibility of http_info plugin via configured tcp port" } 264 | 265 | }; 266 | static void http_info_cleanup(void) 267 | { 268 | 269 | // remove_options_array( http_info_options ); 270 | 271 | } 272 | 273 | static int32_t http_info_init(void) 274 | { 275 | 276 | register_options_array(http_info_options, sizeof( http_info_options), CODE_CATEGORY_NAME); 277 | 278 | return SUCCESS; 279 | 280 | } 281 | 282 | struct plugin* get_plugin(void) 283 | { 284 | 285 | static struct plugin http_info_plugin; 286 | 287 | memset(&http_info_plugin, 0, sizeof( struct plugin)); 288 | 289 | 290 | http_info_plugin.plugin_name = "bmx7_http_info_plugin"; 291 | http_info_plugin.plugin_size = sizeof( struct plugin); 292 | http_info_plugin.cb_init = http_info_init; 293 | http_info_plugin.cb_cleanup = http_info_cleanup; 294 | 295 | return &http_info_plugin; 296 | 297 | } 298 | -------------------------------------------------------------------------------- /src/lib/bmx7_http_info/http_info.h: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/lib/bmx7_iwinfo/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += $(CORE_CFLAGS) -fpic -I../../ 3 | LDFLAGS += -shared 4 | #-Wl,-soname,bmxd_config 5 | 6 | PLUGIN_NAME = bmx7_iwinfo 7 | 8 | SRC_C = bmx7_iwinfo.c 9 | SRC_H = bmx7_iwinfo.h 10 | OBJS= $(SRC_C:.c=.o) 11 | 12 | PLUGIN_FULLNAME = $(PLUGIN_NAME).so 13 | PLUGIN_SHORTNAME = $(PLUGIN_NAME).so 14 | 15 | LIBDIR = /usr/lib 16 | THISDIR = $(shell pwd ) 17 | 18 | all: $(PLUGIN_FULLNAME) Makefile 19 | 20 | 21 | $(PLUGIN_FULLNAME): $(OBJS) Makefile 22 | $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) -liwinfo $(OBJS) -o $(PLUGIN_FULLNAME) 23 | ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME) 24 | 25 | %.o: %.c %.h Makefile 26 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DHAVE_IWINFO_THR -c $< -o $@ || $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 27 | 28 | 29 | clean: 30 | rm -f *.o *.so 31 | 32 | 33 | install: all 34 | mkdir -p $(LIBDIR) 35 | install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR) 36 | 37 | 38 | strip: all 39 | strip $(PLUGIN_FULLNAME) 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/lib/bmx7_iwinfo/bmx7_iwinfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | #define ARG_LINK_PROBE_IVAL "linkProbeInterval" 20 | #define HLP_LINK_PROBE_IVAL "set interval in ms for unicast link probing to improve link-capacity estimation" 21 | #define DEF_LINK_PROBE_IVAL 3000 22 | #define MIN_LINK_PROBE_IVAL 0 23 | #define MAX_LINK_PROBE_IVAL 10000000 24 | 25 | #define ARG_LINK_PROBE_PACKETSZ "linkProbeSize" 26 | #define HLP_LINK_PROBE_PACKETSZ "set byte size of packets for unicast link probing to improve link-capacity estimation" 27 | #define DEF_LINK_PROBE_PACKETSZ 100 28 | #define MIN_LINK_PROBE_PACKETSZ 0 29 | #define MAX_LINK_PROBE_PACKETSZ PKT_MSGS_SIZE_MAX 30 | 31 | 32 | 33 | 34 | #define ARG_LINK_BURST_IVAL "linkBurstInterval" 35 | #define HLP_LINK_BURST_IVAL "set interval in ms for unicast link probing bursts to improve link-capacity estimation" 36 | #define DEF_LINK_BURST_IVAL 0 37 | #define MIN_LINK_BURST_IVAL 0 38 | #define MAX_LINK_BURST_IVAL 10000000 39 | 40 | #define ARG_LINK_BURST_THRESHOLD "linkBurstThreshold" 41 | #define HLP_LINK_BURST_THRESHOLD "set number of packets for discarding current linkBurstInterval" 42 | #define DEF_LINK_BURST_THRESHOLD 100 43 | #define MIN_LINK_BURST_THRESHOLD 0 44 | #define MAX_LINK_BURST_THRESHOLD 1000000 45 | 46 | #define ARG_LINK_BURST_PACKETSZ "linkBurstSize" 47 | #define HLP_LINK_BURST_PACKETSZ "set byte size of packets for unicast link probing bursts to improve link-capacity estimation" 48 | #define DEF_LINK_BURST_PACKETSZ PKT_MSGS_SIZE_MAX 49 | #define MIN_LINK_BURST_PACKETSZ 0 50 | #define MAX_LINK_BURST_PACKETSZ PKT_MSGS_SIZE_MAX 51 | 52 | 53 | #define ARG_LINK_BURST_DURATION "linkBurstDuration" 54 | #define HLP_LINK_BURST_DURATION "set duration in ms for unicast link probing bursts to improve link-capacity estimation" 55 | #define DEF_LINK_BURST_DURATION 150 56 | #define MIN_LINK_BURST_DURATION 0 57 | #define MAX_LINK_BURST_DURATION 1000 58 | 59 | #define ARG_LINK_BURST_BYTES "linkBurstBytes" 60 | #define HLP_LINK_BURST_BYTES "maximum total amount of data per link probe burst to improve link-capacity estimation" 61 | #define DEF_LINK_BURST_BYTES 1000000 62 | #define MIN_LINK_BURST_BYTES 0 63 | #define MAX_LINK_BURST_BYTES 1000000 64 | 65 | #define ARG_LINK_RATE_AVG_WEIGHT "linkAvgWeight" 66 | #define HLP_LINK_RATE_AVG_WEIGHT "inverse weight (1/x) for averaging out old link-rate probes" 67 | #define DEF_LINK_RATE_AVG_WEIGHT 10 68 | #define MIN_LINK_RATE_AVG_WEIGHT 1 69 | #define MAX_LINK_RATE_AVG_WEIGHT 100 70 | 71 | struct tp_test_key { 72 | uint32_t packetSize; 73 | uint32_t totalSend; 74 | TIME_T duration; 75 | TIME_T endTime; 76 | }; 77 | -------------------------------------------------------------------------------- /src/lib/bmx7_json/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += $(CORE_CFLAGS) -fpic -I../../ 3 | LDFLAGS += 4 | #-Wl,-soname,bmxd_config 5 | 6 | PLUGIN_NAME = bmx7_json 7 | 8 | SRC_C = json.c 9 | SRC_H = json.h 10 | OBJS= $(SRC_C:.c=.o) 11 | 12 | PLUGIN_FULLNAME = $(PLUGIN_NAME).so 13 | PLUGIN_SHORTNAME = $(PLUGIN_NAME).so 14 | 15 | LIBDIR = /usr/lib 16 | THISDIR = $(shell pwd ) 17 | 18 | all: $(PLUGIN_FULLNAME) Makefile 19 | 20 | 21 | $(PLUGIN_FULLNAME): $(OBJS) Makefile 22 | $(CC) -shared $(OBJS) $(LDFLAGS) -ljson-c $(EXTRA_LDFLAGS) -o $(PLUGIN_FULLNAME) || $(CC) -shared $(OBJS) $(LDFLAGS) -ljson $(EXTRA_LDFLAGS) -o $(PLUGIN_FULLNAME) 23 | ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME) 24 | 25 | %.o: %.c %.h Makefile 26 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 27 | 28 | 29 | clean: 30 | rm -f *.o *.so 31 | 32 | 33 | install: all 34 | mkdir -p $(LIBDIR) 35 | install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR) 36 | 37 | 38 | strip: all 39 | strip $(PLUGIN_FULLNAME) 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/lib/bmx7_json/json.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | #define DEF_JSON_SUBDIR "json" 20 | 21 | #define JSON_OPTIONS_FILE "options" 22 | #define JSON_PARAMETERS_FILE "parameters" 23 | #define DEF_JSON_DESC_SUBDIR "descriptions" 24 | #define DEF_JSON_ORIG_SUBDIR "originators" 25 | #define DEF_JSON_NETJSON_SUBDIR "netjson" 26 | 27 | #define ARG_JSON_STATUS "jshow" 28 | #define ARG_TOPOLOGY "topology" 29 | 30 | 31 | 32 | #define ARG_JSON_SUBDIR "jsonSubdir" 33 | 34 | 35 | #define ARG_JSON_UPDATE "jsonUpdateInterval" 36 | #define DEF_JSON_UPDATE 60000 37 | #define MIN_JSON_UPDATE 0 38 | #define MAX_JSON_UPDATE REGISTER_TASK_TIMEOUT_MAX 39 | -------------------------------------------------------------------------------- /src/lib/bmx7_sms/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += $(CORE_CFLAGS) -fpic -I../../ 3 | LDFLAGS += -shared 4 | #-Wl,-soname,bmxd_config 5 | 6 | PLUGIN_NAME = bmx7_sms 7 | 8 | SRC_C = sms.c 9 | SRC_H = sms.h 10 | OBJS= $(SRC_C:.c=.o) 11 | 12 | PLUGIN_FULLNAME = $(PLUGIN_NAME).so 13 | PLUGIN_SHORTNAME = $(PLUGIN_NAME).so 14 | 15 | LIBDIR = /usr/lib 16 | THISDIR = $(shell pwd ) 17 | 18 | all: $(PLUGIN_FULLNAME) Makefile 19 | 20 | 21 | $(PLUGIN_FULLNAME): $(OBJS) Makefile 22 | $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME) 23 | ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME) 24 | 25 | %.o: %.c %.h Makefile 26 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 27 | 28 | 29 | clean: 30 | rm -f *.o *.so 31 | 32 | 33 | install: all 34 | mkdir -p $(LIBDIR) 35 | install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR) 36 | 37 | 38 | strip: all 39 | strip $(PLUGIN_FULLNAME) 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/lib/bmx7_sms/sms.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | #define DEF_SMS_SUBDIR "sms" 20 | #define DEF_SMS_RX_SUBDIR "rcvdSms" 21 | #define DEF_SMS_TX_SUBDIR "sendSms" 22 | 23 | #define ARG_SMS "syncSms" 24 | 25 | #define MAX_SMS_NAME_LEN 16 26 | #define MAX_SMS_DATA_LEN 300 27 | #define MAX_SMS_DATA_LEN_REF MAX_VRT_FRAME_DATA_SIZE 28 | 29 | #define SMS_POLLING_INTERVAL 5000 30 | 31 | #define ARG_SMS_FZIP "zipSms" 32 | #define DEF_SMS_FZIP TYP_FZIP_DO 33 | 34 | #define ARG_SMS_FREF "refSms" 35 | #define DEF_SMS_FREF TYP_FREF_DO2 36 | 37 | struct sms_node { 38 | char name[MAX_SMS_NAME_LEN]; 39 | uint16_t stale; 40 | uint32_t dataLen; 41 | char data[]; 42 | }; 43 | 44 | struct description_msg_sms { 45 | char name[MAX_SMS_NAME_LEN]; 46 | uint32_t dataLen; 47 | char data[]; 48 | } __attribute__((packed)); 49 | 50 | #define DESCRIPTION_MSG_SMS_FORMAT { \ 51 | {FIELD_TYPE_STRING_CHAR, -1, (8*MAX_SMS_NAME_LEN), 1, FIELD_RELEVANCE_HIGH, "name"}, \ 52 | {FIELD_TYPE_STRING_SIZE, -1, 32, 0, FIELD_RELEVANCE_LOW, "len"}, \ 53 | {FIELD_TYPE_STRING_BINARY, -1, 0, 1, FIELD_RELEVANCE_LOW, "data" }, \ 54 | FIELD_FORMAT_END } 55 | -------------------------------------------------------------------------------- /src/lib/bmx7_table/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += $(CORE_CFLAGS) -fpic -I../../ 3 | LDFLAGS += -shared 4 | #-Wl,-soname,bmxd_config 5 | 6 | PLUGIN_NAME = bmx7_table 7 | 8 | SRC_C = table.c ../../redist.c 9 | SRC_H = table.h ../../redist.h ../../tun.h 10 | OBJS= $(SRC_C:.c=.o) 11 | 12 | PLUGIN_FULLNAME = $(PLUGIN_NAME).so 13 | PLUGIN_SHORTNAME = $(PLUGIN_NAME).so 14 | 15 | LIBDIR = /usr/lib 16 | THISDIR = $(shell pwd ) 17 | 18 | all: $(PLUGIN_FULLNAME) Makefile 19 | 20 | 21 | $(PLUGIN_FULLNAME): $(OBJS) Makefile 22 | $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME) 23 | ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME) 24 | 25 | %.o: %.c %.h Makefile $(SRC_H) 26 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 27 | 28 | 29 | clean: 30 | rm -f *.o *.so 31 | 32 | 33 | install: all 34 | mkdir -p $(LIBDIR) 35 | install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR) 36 | 37 | 38 | strip: all 39 | strip $(PLUGIN_FULLNAME) 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/lib/bmx7_table/table.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2013 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #define ARG_REDIST_DELAY "redistTableOutDelay" 19 | #define HLP_REDIST_DELAY "delay announcement of changed table routes in ms to aggregate shortly following changes" 20 | #define MIN_REDIST_DELAY 100 21 | #define MAX_REDIST_DELAY 3600000 22 | #define DEF_REDIST_DELAY 2000 23 | 24 | #define ARG_FILTER_DELAY "redistTableInDelay" 25 | #define DEF_FILTER_DELAY 1000 26 | #define HLP_FILTER_DELAY "delay processing of changed table routes in ms to filter shortly following changes" 27 | 28 | 29 | #define ARG_REDIST "redistTable" 30 | #define HLP_REDIST "arbitrary but unique name for redistributed table network(s) depending on sub criterias" 31 | -------------------------------------------------------------------------------- /src/lib/bmx7_topology/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += $(CORE_CFLAGS) -fpic -I../../ 3 | LDFLAGS += -shared 4 | #-Wl,-soname,bmxd_config 5 | 6 | PLUGIN_NAME = bmx7_topology 7 | 8 | SRC_C = topology.c 9 | SRC_H = topology.h 10 | OBJS= $(SRC_C:.c=.o) 11 | 12 | PLUGIN_FULLNAME = $(PLUGIN_NAME).so 13 | PLUGIN_SHORTNAME = $(PLUGIN_NAME).so 14 | 15 | LIBDIR = /usr/lib 16 | THISDIR = $(shell pwd ) 17 | 18 | all: $(PLUGIN_FULLNAME) Makefile 19 | 20 | 21 | $(PLUGIN_FULLNAME): $(OBJS) Makefile 22 | $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME) 23 | ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME) 24 | 25 | %.o: %.c %.h Makefile 26 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 27 | 28 | 29 | clean: 30 | rm -f *.o *.so 31 | 32 | 33 | install: all 34 | mkdir -p $(LIBDIR) 35 | install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR) 36 | 37 | 38 | strip: all 39 | strip $(PLUGIN_FULLNAME) 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/lib/bmx7_topology/topology.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | #define ARG_TOPOLOGY "topology" 20 | #define ARG_TOPOLOGY_HYSTERESIS "topologyUpdateHysteresis" 21 | #define MIN_TOPOLOGY_HYSTERESIS 1 22 | #define MAX_TOPOLOGY_HYSTERESIS 10000 23 | #define DEF_TOPOLOGY_HYSTERESIS 33 24 | 25 | #define ARG_TOPOLOGY_PERIOD "topologyUpdatePeriod" 26 | #define MIN_TOPOLOGY_PERIOD 0 27 | #define MAX_TOPOLOGY_PERIOD 360000 28 | #define DEF_TOPOLOGY_PERIOD 3600 29 | 30 | #define TLV_OP_CUSTOM_TOPOLOGY (TLV_OP_CUSTOM_MIN + 1) 31 | 32 | struct description_msg_topology { 33 | GLOBAL_ID_T nbId; 34 | DESC_SQN_T nbDescSqn; 35 | DEVIDX_T nbIdx; 36 | DEVIDX_T idx; 37 | 38 | FMETRIC_U8_T txBw; 39 | FMETRIC_U8_T rxBw; 40 | LQ_T tq; 41 | LQ_T rq; 42 | int8_t signal; 43 | int8_t noise; 44 | uint8_t channel; 45 | uint8_t reserved1; 46 | uint16_t reserved2; 47 | 48 | } __attribute__((packed)); 49 | 50 | struct description_hdr_topology { 51 | uint8_t type; 52 | uint8_t reserved; 53 | struct description_msg_topology msg[]; 54 | } __attribute__((packed)); 55 | 56 | 57 | #define DESCRIPTION_MSG_TOPOLOGY_FORMAT { \ 58 | {FIELD_TYPE_GLOBAL_ID, -1, (8*sizeof(GLOBAL_ID_T)), 0, FIELD_RELEVANCE_HIGH, "nbId"}, \ 59 | {FIELD_TYPE_UINT, -1, (8*sizeof(DESC_SQN_T)), 0, FIELD_RELEVANCE_HIGH, "nbDescSqn"}, \ 60 | {FIELD_TYPE_UINT, -1, (8*sizeof(DEVIDX_T)), 0, FIELD_RELEVANCE_HIGH, "nbIdx"}, \ 61 | {FIELD_TYPE_UINT, -1, (8*sizeof(DEVIDX_T)), 0, FIELD_RELEVANCE_HIGH, "myIdx"}, \ 62 | {FIELD_TYPE_UINT, -1, (8*sizeof(FMETRIC_U8_T)),0, FIELD_RELEVANCE_HIGH, "txBw"}, \ 63 | {FIELD_TYPE_UINT, -1, (8*sizeof(FMETRIC_U8_T)),0, FIELD_RELEVANCE_HIGH, "rxBw"}, \ 64 | {FIELD_TYPE_UINT, -1, (8*sizeof(uint8_t)), 0, FIELD_RELEVANCE_HIGH, "tq"}, \ 65 | {FIELD_TYPE_UINT, -1, (8*sizeof(uint8_t)), 0, FIELD_RELEVANCE_HIGH, "rq"}, \ 66 | {FIELD_TYPE_INT, -1, (8*sizeof(int8_t)), 0, FIELD_RELEVANCE_HIGH, "signal"}, \ 67 | {FIELD_TYPE_INT, -1, (8*sizeof(int8_t)), 0, FIELD_RELEVANCE_HIGH, "noise"}, \ 68 | {FIELD_TYPE_UINT, -1, (8*sizeof(uint8_t)), 0, FIELD_RELEVANCE_HIGH, "channel"}, \ 69 | {FIELD_TYPE_UINT, -1, (8*sizeof(uint8_t)), 0, FIELD_RELEVANCE_HIGH, "reserved1"}, \ 70 | {FIELD_TYPE_UINT, -1, (8*sizeof(uint16_t)), 0, FIELD_RELEVANCE_HIGH, "reserved2"}, \ 71 | FIELD_FORMAT_END } 72 | 73 | struct local_topology_key { 74 | GLOBAL_ID_T nbId; 75 | DEVIDX_T nbIdx; 76 | DEVIDX_T myIdx; 77 | } __attribute__((packed)); 78 | 79 | struct local_topology_node { 80 | struct local_topology_key k; 81 | uint8_t sqn; 82 | UMETRIC_T txBw; 83 | UMETRIC_T rxBw; 84 | LQ_T tq; 85 | LQ_T rq; 86 | int8_t signal; 87 | int8_t noise; 88 | uint8_t channel; 89 | uint8_t updated; 90 | }; 91 | 92 | struct topology_status { 93 | GLOBAL_ID_T *id; 94 | char* name; 95 | IPX_T *primaryIp; 96 | DEVIDX_T idx; 97 | 98 | GLOBAL_ID_T *neighId; 99 | DESC_SQN_T neighDescSqnDiff; 100 | char* neighName; 101 | IPX_T *neighIp; 102 | DEVIDX_T neighIdx; 103 | 104 | uint32_t lastDesc; 105 | int8_t signal; 106 | int8_t noise; 107 | int8_t snr; 108 | uint8_t channel; 109 | uint8_t rq; 110 | uint8_t tq; 111 | UMETRIC_T rxRate; 112 | UMETRIC_T txRate; 113 | }; 114 | -------------------------------------------------------------------------------- /src/lib/bmx7_tun/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += $(CORE_CFLAGS) -fpic -I../../ 3 | LDFLAGS += -shared 4 | #-Wl,-soname,bmxd_config 5 | 6 | PLUGIN_NAME = bmx7_tun 7 | 8 | SRC_C = tun.c 9 | SRC_H = ../../redist.h ../../tun.h 10 | OBJS= $(SRC_C:.c=.o) 11 | 12 | PLUGIN_FULLNAME = $(PLUGIN_NAME).so 13 | PLUGIN_SHORTNAME = $(PLUGIN_NAME).so 14 | 15 | LIBDIR = /usr/lib 16 | THISDIR = $(shell pwd ) 17 | 18 | all: $(PLUGIN_FULLNAME) Makefile 19 | 20 | 21 | $(PLUGIN_FULLNAME): $(OBJS) Makefile 22 | $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME) 23 | ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME) 24 | 25 | %.o: %.c Makefile $(SRC_H) 26 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 27 | 28 | 29 | clean: 30 | rm -f *.o *.so 31 | 32 | 33 | install: all 34 | mkdir -p $(LIBDIR) 35 | install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR) 36 | 37 | 38 | strip: all 39 | strip $(PLUGIN_FULLNAME) 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/lib/bmx7_uci_config/HOWTO.md: -------------------------------------------------------------------------------- 1 | ## BMX7_config plugin for OpenWRT universal configuraton interface (UCI) 2 | 3 | - Plugin for dynamic interaction with uci 4 | 5 | - To compile first install uci (old version): 6 | wget http://downloads.openwrt.org/sources/uci-0.7.5.tar.gz 7 | sometimes theres an error: edit cli.c # change line 465 to: char *argv[MAX_ARGS+2]; 8 | tar xzvf uci-0.7.5.tar.gz; cd uci-0.7.5; make; sudo make install 9 | 10 | - Alternatively check: http://www.wakoond.hu/2013/06/using-uci-on-ubuntu.html 11 | 12 | - Default configuration backend is: /etc/config/bmx7 13 | 14 | - see lib/bmx7_config/etc_config for a simple (bmx) 15 | and an advanced (bmx-advanced) example 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/lib/bmx7_uci_config/Makefile: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS += $(CORE_CFLAGS) -fpic -I../../ -I/usr/local/include/uci/ 3 | LDFLAGS += -luci 4 | 5 | PLUGIN_NAME = bmx7_config 6 | 7 | SRC_C = uci_config.c 8 | SRC_H = uci_config.h 9 | OBJS= $(SRC_C:.c=.o) 10 | 11 | PLUGIN_FULLNAME = $(PLUGIN_NAME).so 12 | PLUGIN_SHORTNAME = $(PLUGIN_NAME).so 13 | 14 | LIBDIR = /usr/lib 15 | THISDIR = $(shell pwd ) 16 | 17 | all: $(PLUGIN_FULLNAME) Makefile 18 | 19 | 20 | $(PLUGIN_FULLNAME): $(OBJS) Makefile 21 | $(CC) -shared $(OBJS) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $(PLUGIN_FULLNAME) 22 | ln -f -s $(THISDIR)/$(PLUGIN_FULLNAME) $(THISDIR)/../$(PLUGIN_FULLNAME) 23 | 24 | %.o: %.c %.h Makefile 25 | $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ 26 | 27 | 28 | clean: 29 | rm -f *.o *.so 30 | 31 | 32 | install: all 33 | mkdir -p $(LIBDIR) 34 | install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR) 35 | 36 | 37 | strip: all 38 | strip $(PLUGIN_FULLNAME) 39 | -------------------------------------------------------------------------------- /src/lib/bmx7_uci_config/etc_config/bmx7-advanced: -------------------------------------------------------------------------------- 1 | # bmx_uci_config plugin depends on the UCI (universial configuration interface) 2 | # from http://downloads.openwrt.org/sources/uci-0.7.3.tar.gz 3 | # to compile first install uci: 4 | # wget http://downloads.openwrt.org/sources/uci-0.7.3.tar.gz 5 | # tar xzvf uci-0.7.3.tar.gz; cd uci-0.7.3; make; sudo make install 6 | # 7 | # 8 | # the default location for this config file is /etc/config/bmx 9 | # from where it would be loaded automatically during initialization of bmxd. 10 | # Use bmxd -f /etc/config/another-bmx-config to load an alternative config file. 11 | # and bmxd -f 0 to disable all config-file functionality. 12 | # 13 | # You may also start bmxd as you always did (e.g. bmxd --neta -o 1000 ath0:bmx) 14 | # and then use bmxd -c show-config and bmxd -c show-config > /etc/config/bmx 15 | # to generate the config file you need. Afterwards a simple $ bmxd should do it. 16 | # 17 | # With uci comes a bunch of new configuration possibilities: 18 | # The bmxd can be configured on-the-fly from bmxd or uci. 19 | # To configure from bmxd simply type: bmxd -c ogm_interval=500 or: bmxd -co500 20 | # To configure from uci: uci set bmx.general.ogm_interval=500 21 | # followed by: kill -HUP $(cat /var/run/pid) or: bmxd -c reload-config 22 | # To permanently store the changes: uci commit bmx 23 | # And to revert them: uci revert bmx 24 | # For more possibilities check out openWrt, UCI, and bmxd -X 25 | 26 | 27 | # the following example substitutes the now deprecated --neta option 28 | # 29 | config 'bmx7' 'general' 30 | # option 'runtime_dir' '/var/run/bmx7' 31 | option 'base_port' '6240' 32 | 33 | 34 | # bmxd always tries to load bmx7_config.so from /usr/lib/ 35 | # Therefore, there is no obligation to request this explicitly. 36 | # An alternative library-path can be set with the environment variable BMX7_LIB_PATH 37 | # E.g. BMX7_LIB_PATH=/usr/src/bmx7/lib will check the given directory for plugins 38 | config 'plugin' 39 | option 'plugin' 'bmx7_config.so' 40 | 41 | 42 | # other plugin must be requested explicitly: 43 | # config 'plugin' 44 | # option 'plugin' 'bmx7_howto_plugin.so' 45 | 46 | 47 | # it is allways a good idea to use an alias on your loopback interface 48 | # as the primary interface because the loopback interface is probably 49 | # the most stable you have on your system and then you are always 50 | # reachable under your primary IP. E.g.: 51 | # ifconfig lo:bmx 6.6.1.1 netmask 255.255.0.0 52 | config 'dev' 53 | option 'dev' 'lo:bmx' 54 | 55 | 56 | # Of course, a real interface is necessary 57 | # to link up with the rest of the world. 58 | # However, all non-primary interfaces may be added and removed on the fly. 59 | config 'dev' 60 | option 'dev' 'ath0:bmx' 61 | 62 | 63 | # In openWrt interfaces are usually configured in /etc/config/network 64 | # to avoid redundancy it is also possible to resolve values from there. E.g.: 65 | # 66 | #config 'dev' 67 | # option 'dev' 'ref:network.lan0_bmx.ifname' 68 | 69 | 70 | 71 | 72 | 73 | # unicast host-network announcements (HNAs) may look like this: 74 | # config 'unicast_hna' 75 | # option 'unicast_hna' '106.1.2.4/32' 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/lib/bmx7_uci_config/etc_config/bmx7-simple: -------------------------------------------------------------------------------- 1 | # this config file should be stored in /etc/config/bmx7 2 | # for more options check the bmx-advanced configuration example and bmx7 -X 3 | # 4 | # bmx_uci_config plugin depends on the UCI (universial configuration interface) 5 | # from http://downloads.openwrt.org/sources/uci-0.7.3.tar.gz 6 | # to compile first install uci: 7 | # wget http://downloads.openwrt.org/sources/uci-0.7.3.tar.gz 8 | # tar xzvf uci-0.7.3.tar.gz; cd uci-0.7.3; make; sudo make install 9 | # 10 | 11 | config 'bmx7' 'general' 12 | 13 | config 'dev' 14 | option 'dev' 'ath0' 15 | -------------------------------------------------------------------------------- /src/lib/bmx7_uci_config/uci_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #define DEF_CONF_NAME "bmx7" 19 | #define DEF_CONF_FILE UCI_CONFDIR"/"DEF_CONF_NAME 20 | #define DEF_SECT_NAME "general" 21 | #define DEF_SECT_TYPE "bmx7" 22 | 23 | #define ARG_CONFIG_FILE "configFile" 24 | #define ARG_SAVE_CONFIG "configSave" 25 | #define ARG_SHOW_CONFIG "configShow" 26 | #define ARG_RELOAD_CONFIG "configReload" 27 | 28 | #define ARG_SYNC_CONFIG "configSync" 29 | #define DEF_SYNC_CONFIG 1 30 | #define HLP_SYNC_CONFIG "Automatically sync bmx (init and dynamically-applied) parameters with reversible uci data base" 31 | 32 | 33 | #define ARG_NO_CONFIG_FILE "0" 34 | -------------------------------------------------------------------------------- /src/link.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | #define DEF_LINK_METRIC_FLAGS (0x0) 20 | #define ARG_LINK_METRIC_FLAGS "linkMetricFlags" 21 | 22 | #define ARG_LINKS "links" 23 | 24 | #define MIN_LINK_PURGE_TO MAX_TX_MIN_INTERVAL 25 | #define MAX_LINK_PURGE_TO 864000000 /*10 days*/ 26 | #define DEF_LINK_PURGE_TO 20000 27 | #define ARG_LINK_PURGE_TO "linkTimeout" 28 | extern int32_t link_purge_to; 29 | 30 | #define MIN_TIMEAWARE_LQ_MIN 1 31 | #define MAX_TIMEAWARE_LQ_MIN LQ_MAX 32 | #define DEF_TIMEAWARE_LQ_MIN (LQ_MAX / 10) 33 | #define ARG_TIMEAWARE_LQ_MIN "minLinkQuality" 34 | 35 | #define MAX_LINK_KEYS_SIZE 30 36 | 37 | struct dsc_msg_llip { 38 | IP6_T ip6; 39 | } __attribute__((packed)); 40 | 41 | #define DESCRIPTION_MSG_LLIP_FORMAT { \ 42 | {FIELD_TYPE_IPX6, -1, 128, 1, FIELD_RELEVANCE_HIGH, "address" }, \ 43 | FIELD_FORMAT_END } 44 | 45 | struct msg_hello_adv { // 2 bytes 46 | HELLO_SQN_T hello_sqn; 47 | } __attribute__((packed)); 48 | 49 | struct msg_hello_reply_dhash { 50 | DHASH_T dest_dhash; 51 | LQ_T rxLq; 52 | DEVIDX_T receiverDevIdx; 53 | } __attribute__((packed)); 54 | 55 | 56 | 57 | //IDM_T updateNeighDevId(struct neigh_node *nn, struct desc_content *contents); 58 | IDM_T min_lq_probe(LinkNode *link); 59 | LinkNode *getLinkNode(struct dev_node *dev, IPX_T *llip, DEVIDX_T idx, struct neigh_node *verifiedNeigh); 60 | uint16_t purge_linkDevs(LinkDevNode *onlyLinkDev, struct dev_node *onlyDev, LinkNode *onlyLink, IDM_T onlyExpired, IDM_T purgeLocal); 61 | char * getLinkKeysAsString(struct orig_node *on); 62 | 63 | struct plugin *link_get_plugin(void); 64 | -------------------------------------------------------------------------------- /src/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or 3 | * modify it under the terms of version 2 of the GNU General Public 4 | * License as published by the Free Software Foundation. 5 | * 6 | * This program is distributed in the hope that it will be useful, but 7 | * WITHOUT ANY WARRANTY; without even the implied warranty of 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | * General Public License for more details. 10 | * 11 | * You should have received a copy of the GNU General Public License 12 | * along with this program; if not, write to the Free Software 13 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 14 | * 02110-1301, USA 15 | */ 16 | 17 | /* 18 | * This list implementation is originally based on the 19 | * double-linked list implementaton from the linux-kernel 20 | * which can be found in include/linux/list.h 21 | * 22 | * The following has been changed/added to better fit my needs: 23 | * - items counter 24 | * - plist handler (list-node structure with void* item pointer 25 | * - single-linked list instead of double-linked list to save overhead 26 | * - some functions for straight item access! 27 | * - ... 28 | */ 29 | #include 30 | 31 | #include "list.h" 32 | #include "control.h" 33 | #include "bmx.h" 34 | #include "tools.h" 35 | #include "allocate.h" 36 | 37 | /** 38 | * list_iterate - return pointer to next node maintained in the list or NULL 39 | * @head: list head of maintained nodes 40 | * @node: a node maintained in the list or NULL 41 | */ 42 | void * list_iterate(struct bmx_list_head *head, void *node) 43 | { 44 | struct list_node *ln = (node ? 45 | ((struct list_node*) (((char*) node) + head->list_node_offset)) : 46 | ((struct list_node*) head)); 47 | 48 | assertion(-501044, (IMPLIES((!node && head->last == ln), !head->items))); 49 | 50 | if (ln->next == ((struct list_node*) head)) 51 | return NULL; 52 | 53 | return(((char*) ln->next) - head->list_node_offset); 54 | } 55 | 56 | void *list_find_next(struct bmx_list_head *head, void* key, void *node) 57 | { 58 | while ((node = list_iterate(head, node))) { 59 | 60 | if (memcmp(((char*) node) + head->key_node_offset, key, head->key_length) == 0) 61 | return node; 62 | } 63 | return NULL; 64 | } 65 | 66 | /** 67 | * list_add_head - add a new entry at the beginning of a list 68 | * @head: list head to add it after 69 | * @new: new entry to be added 70 | */ 71 | void list_add_head(struct bmx_list_head *head, struct list_node *new) 72 | { 73 | 74 | new->next = head->next; 75 | head->next = new; 76 | 77 | if (head->last == (struct list_node *) head) 78 | head->last = new; 79 | 80 | head->items++; 81 | 82 | } 83 | 84 | /** 85 | * bmx_list_add_tail - add a new entry 86 | * @head: list head to add it before 87 | * @new: new entry to be added 88 | */ 89 | 90 | void bmx_list_add_tail(struct bmx_list_head *head, struct list_node *new) 91 | { 92 | new->next = (struct list_node *) head; 93 | head->last->next = new; 94 | 95 | head->last = new; 96 | head->items++; 97 | } 98 | 99 | void list_add_after(struct bmx_list_head *head, struct list_node *ln, struct list_node *new) 100 | { 101 | new->next = ln->next; 102 | ln->next = new; 103 | 104 | if (head->last == ln) 105 | head->last = new; 106 | 107 | head->items++; 108 | } 109 | 110 | /** 111 | * list_del_next - deletes next entry from list. 112 | * @entry: the element to delete from the list. 113 | * Note: list_empty on entry does not return true after this, the entry is in an undefined state. 114 | */ 115 | void list_del_next(struct bmx_list_head *head, struct list_node *ln) 116 | { 117 | assertion(-502641, (ln->next != (struct list_node*) head)); 118 | 119 | struct list_node *rem = ln->next; 120 | 121 | if (head->last == rem) 122 | head->last = ln; 123 | 124 | ln->next = rem->next; 125 | 126 | head->items--; 127 | } 128 | 129 | void *list_del_head(struct bmx_list_head *head) 130 | { 131 | if (LIST_EMPTY(head)) 132 | return NULL; 133 | 134 | struct list_node* entry = head->next; 135 | 136 | list_del_next(head, (struct list_node*) head); 137 | 138 | return(((char*) entry) - head->list_node_offset); 139 | } 140 | 141 | 142 | 143 | /** 144 | * plist_get_next - return pointer to next node maintained in the list or NULL 145 | * @head: list head of maintained nodes 146 | * @@pnode: MBZ at beginning! pointing to current plist_node in list 147 | */ 148 | 149 | /* UNTESTED 150 | void * plist_iterate(struct bmx_list_head *head, struct plist_node **pln) 151 | { 152 | 153 | if (head->last == (struct list_node*) 154 | (*pln = *pln ? (struct plist_node*) ((*pln)->list.next) : (struct plist_node*) (head->next))) 155 | return NULL; 156 | 157 | return (*pln)->item; 158 | 159 | } 160 | */ 161 | 162 | 163 | static struct plist_node *plist_node_create(void *item) 164 | { 165 | assertion(-500266, (item)); 166 | struct plist_node *plh = debugMalloc(sizeof( struct plist_node), -300113); 167 | 168 | plh->item = item; 169 | return plh; 170 | } 171 | 172 | void plist_add_head(struct bmx_list_head *head, void *item) 173 | { 174 | list_add_head(head, &((plist_node_create(item))->list)); 175 | } 176 | 177 | void plist_add_tail(struct bmx_list_head *head, void *item) 178 | { 179 | bmx_list_add_tail(head, &((plist_node_create(item))->list)); 180 | } 181 | 182 | void * plist_del_head(struct bmx_list_head *head) 183 | { 184 | struct plist_node *pln = list_del_head(head); 185 | 186 | if (!pln) 187 | return NULL; 188 | 189 | void *item = pln->item; 190 | 191 | debugFree(pln, -300114); 192 | 193 | return item; 194 | } 195 | -------------------------------------------------------------------------------- /src/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or 3 | * modify it under the terms of version 2 of the GNU General Public 4 | * License as published by the Free Software Foundation. 5 | * 6 | * This program is distributed in the hope that it will be useful, but 7 | * WITHOUT ANY WARRANTY; without even the implied warranty of 8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | * General Public License for more details. 10 | * 11 | * You should have received a copy of the GNU General Public License 12 | * along with this program; if not, write to the Free Software 13 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 14 | * 02110-1301, USA 15 | */ 16 | 17 | /* 18 | * This list implementation is originally based on the 19 | * double-linked list implementaton from the linux-kernel 20 | * which can be found in include/linux/list.h 21 | * 22 | * The following has been changed to better fit my needs and intuition: 23 | * - items counter 24 | * - plist handler (list-node structure with void* item pointer 25 | * - single-linked list instead of double-linked list to save overhead 26 | * - some functions for straight item access! 27 | */ 28 | 29 | 30 | #ifndef _LIST_H 31 | #define _LIST_H_ 32 | 33 | #include 34 | 35 | struct list_node { 36 | struct list_node *next; 37 | }; 38 | 39 | struct bmx_list_head { 40 | struct list_node *next; 41 | struct list_node *last; 42 | uint16_t items; 43 | uint16_t list_node_offset; 44 | uint16_t key_node_offset; 45 | uint16_t key_length; 46 | }; 47 | 48 | struct plist_node { 49 | struct list_node list; 50 | void *item; 51 | }; 52 | 53 | 54 | 55 | #define LIST_SIMPEL(ptr, element_type, list_field, key_field ) struct bmx_list_head ptr = { \ 56 | .next = (struct list_node *)&ptr, \ 57 | .last = (struct list_node *)&ptr, \ 58 | .items = 0, \ 59 | .list_node_offset = ((unsigned long)(&((element_type *)0)->list_field)), \ 60 | .key_node_offset = ((unsigned long)(&((element_type *)0)->key_field)), \ 61 | .key_length = sizeof(((element_type *)0)->key_field) } 62 | 63 | #define LIST_INIT_HEAD(ptr, element_type, list_field, key_field) do { \ 64 | ptr.next = (struct list_node *)&ptr; \ 65 | ptr.last = (struct list_node *)&ptr; \ 66 | ptr.items = 0; \ 67 | ptr.list_node_offset = ((unsigned long)(&((element_type *)0)->list_field)); \ 68 | ptr.key_node_offset = ((unsigned long)(&((element_type *)0)->key_field)); \ 69 | ptr.key_length = sizeof(((element_type *)0)->key_field); \ 70 | } while (0) 71 | 72 | #define LIST_EMPTY(lst) ((lst)->next == (struct list_node *)(lst)) 73 | 74 | 75 | #define list_get_first(head) ((void*)((LIST_EMPTY(head)) ? NULL : (((char*) (head)->next) - (head)->list_node_offset) )) 76 | #define list_get_last(head) ((void*)((LIST_EMPTY(head)) ? NULL : (((char*) (head)->last) - (head)->list_node_offset) )) 77 | 78 | void *list_iterate(struct bmx_list_head *head, void *node); 79 | void *list_find_next(struct bmx_list_head *head, void* key, void *node); 80 | 81 | void list_add_head(struct bmx_list_head *head, struct list_node * new); 82 | void bmx_list_add_tail(struct bmx_list_head *head, struct list_node * new); 83 | void list_add_after(struct bmx_list_head *head, struct list_node *pos, struct list_node * new); 84 | void list_del_next(struct bmx_list_head *head, struct list_node *pos); 85 | void *list_del_head(struct bmx_list_head *head); 86 | 87 | 88 | #define plist_get_first(head) (LIST_EMPTY(head) ? NULL : \ 89 | ((struct plist_node*)(((char*) (head)->next) - (head)->list_node_offset))->item ) 90 | 91 | #define plist_get_last(head) (LIST_EMPTY(head) ? NULL : \ 92 | ((struct plist_node*)(((char*) (head)->prev) - (head)->list_node_offset))-item ) 93 | 94 | void * plist_iterate(struct bmx_list_head *head, struct plist_node **pln); 95 | 96 | void plist_add_head(struct bmx_list_head *head, void *item); 97 | void plist_add_tail(struct bmx_list_head *head, void *item); 98 | void *plist_del_head(struct bmx_list_head *head); 99 | 100 | 101 | 102 | /** 103 | * list_entry - get the struct for this entry 104 | * @ptr: the &struct bmx_list_head pointer. 105 | * @type: the type of the struct this is embedded in. 106 | * @member: the name of the list_struct within the struct. 107 | */ 108 | #define list_entry(ptr, type, member) ( (type *)( (char *)(ptr) - (unsigned long)(&((type *)0)->member) ) ) 109 | 110 | /** 111 | * list_for_each - iterate over a list 112 | * @pos: the &struct bmx_list_head to use as a loop counter. 113 | * @head: the head for your list. 114 | */ 115 | #define list_for_each(pos, head) \ 116 | for (pos = (head)->next; pos != (struct list_node *)(head); pos = pos->next) 117 | 118 | #define list_for_each_item(pos, head, item, type, member) \ 119 | for (pos = (head)->next; \ 120 | pos != (struct list_node *)(head) && \ 121 | (item = ((type *)( (char *)(pos) - (unsigned long)(&((type *)0)->member) ) )); \ 122 | pos = pos->next) 123 | 124 | /** 125 | * list_for_each_safe - iterate over a list safe against removal of list entry 126 | * @pos: the &struct bmx_list_head to use as a loop counter. 127 | * @n: another &struct bmx_list_head to use as temporary storage 128 | * @head: the head for your list. 129 | */ 130 | #define list_for_each_safe(pos, n, head) \ 131 | for (pos = (head)->next, n = pos->next; pos != (struct list_node *)(head); \ 132 | pos = n, n = pos->next) 133 | 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /src/ogm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | 20 | 21 | 22 | 23 | extern uint32_t ogms_pending; 24 | 25 | #define ARG_OGM_IFACTOR "ogmIntervalFactor" 26 | #define DEF_OGM_IFACTOR 110 27 | #define MIN_OGM_IFACTOR 100 28 | #define MAX_OGM_IFACTOR 1000 29 | 30 | 31 | #define ARG_OGM_INTERVAL "ogmInterval" 32 | #define DEF_OGM_INTERVAL 6000 33 | #define MIN_OGM_INTERVAL 200 34 | #define MAX_OGM_INTERVAL 60000 // 60000 = 1 minutes 35 | extern int32_t my_ogmInterval; 36 | 37 | #define MIN_OGM_AGGREG_HISTORY 2 38 | #define MAX_OGM_AGGREG_HISTORY AGGREG_SQN_CACHE_RANGE 39 | #define DEF_OGM_AGGREG_HISTORY 20 40 | #define ARG_OGM_AGGREG_HISTORY "ogmAggregHistory" 41 | 42 | extern AGGREG_SQN_T ogm_aggreg_sqn_max; 43 | extern AGGREG_SQN_T ogm_aggreg_sqn_max_window_size; 44 | extern AGGREG_SQN_T ogm_aggreg_sqn_send; 45 | 46 | 47 | #define FRM_SIGN_VERS_SIZE_MAX_XXX (FRM_SIGN_VERS_SIZE_MIN + XMAX(cryptRsaKeyLenByType(MAX_LINK_RSA_TX_TYPE), (MAX_MAX_DHM_NEIGHS*sizeof(struct frame_msg_dhMac112)))) 48 | 49 | //note that precalculated ogm-aggregations MUST fit into remaining space of DHM signed frames with many neighbors: 50 | #define SIGNED_FRAMES_SIZE_PREF_XXX (PKT_FRAMES_SIZE_PREF - FRM_SIGN_VERS_SIZE_MAX_XXX) 51 | 52 | #define OGMS_DHASH_MSGS_LEN_PER_AGGREG_PREF (SIGNED_FRAMES_SIZE_PREF_XXX - (sizeof(struct tlv_hdr) + sizeof (struct hdr_ogm_adv))) 53 | 54 | //#define OGMS_DHASH_PER_AGGREG_PREF_REMOVE (OGMS_DHASH_MSGS_LEN_PER_AGGREG_PREF / sizeof(struct msg_ogm_adv)) 55 | 56 | 57 | 58 | #define OGM_IID_RSVD_JUMP (OGM_IIDOFFST_MASK) // 63 //255 // resulting from ((2^transmitterIIDoffset_bit_range)-1) 59 | 60 | struct msg_ogm_aggreg_sqn_adv { 61 | AGGREG_SQN_T max; 62 | uint16_t size; 63 | } __attribute__((packed)); 64 | 65 | struct msg_ogm_aggreg_req { 66 | AGGREG_SQN_T sqn; 67 | } __attribute__((packed)); 68 | 69 | struct hdr_ogm_aggreg_req { 70 | GLOBAL_ID_T dest_nodeId; 71 | struct msg_ogm_aggreg_req msg[]; 72 | } __attribute__((packed)); 73 | 74 | /* 75 | * short long 76 | * sqnHashLink 112 112 77 | * shortDhash 15 16 78 | * sqn 13 13 79 | * flags 1 8 80 | * metric 11 11 81 | * --------------------- 82 | * 152 160 83 | * */ 84 | 85 | union msg_ogm_adv_metric { 86 | 87 | struct { 88 | #if __BYTE_ORDER == __LITTLE_ENDIAN 89 | unsigned int metric_mantissa : OGM_MANTISSA_BIT_SIZE; // 6 90 | unsigned int metric_exp : OGM_EXPONENT_BIT_SIZE; // 5 91 | unsigned int hopCount : OGM_HOP_COUNT_BITSIZE; //6 92 | unsigned int transmitterIID4x : IID_BIT_SIZE; // 14 93 | unsigned int more : 1; 94 | #elif __BYTE_ORDER == __BIG_ENDIAN 95 | unsigned int more : 1; 96 | unsigned int transmitterIID4x : IID_BIT_SIZE; 97 | unsigned int hopCount : OGM_HOP_COUNT_BITSIZE; 98 | unsigned int metric_exp : OGM_EXPONENT_BIT_SIZE; // 5 99 | unsigned int metric_mantissa : OGM_MANTISSA_BIT_SIZE; // 6 100 | #else 101 | #error "Please fix " 102 | #endif 103 | } __attribute__((packed)) f; 104 | uint32_t u32; 105 | }; 106 | 107 | struct msg_ogm_adv { 108 | ChainLink_T chainOgm; 109 | 110 | union msg_ogm_adv_metric u; 111 | struct msg_ogm_adv_metric_t0 mt0[]; 112 | 113 | } __attribute__((packed)); 114 | 115 | struct hdr_ogm_adv { 116 | AGGREG_SQN_T aggregation_sqn; 117 | // struct msg_ogm_adv msg[]; 118 | } __attribute__((packed)); 119 | 120 | struct OgmAggreg_node { 121 | struct avl_tree tree; 122 | int16_t msgsLen; 123 | }; 124 | 125 | 126 | struct OgmAggreg_node *getOgmAggregNode(AGGREG_SQN_T aggSqn); 127 | 128 | 129 | void remove_ogm(struct orig_node *on); 130 | void process_ogm_metric(void *voidRef); 131 | 132 | int32_t init_ogm(void); 133 | -------------------------------------------------------------------------------- /src/plugin.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "list.h" 24 | #include "control.h" 25 | #include "bmx.h" 26 | #include "crypt.h" 27 | #include "avl.h" 28 | #include "node.h" 29 | #include "ip.h" 30 | #include "plugin.h" 31 | #include "schedule.h" 32 | #include "tools.h" 33 | #include "allocate.h" 34 | 35 | #define CODE_CATEGORY_NAME "plugin" 36 | 37 | static LIST_SIMPEL(plugin_list, struct plugin_node, list, list); 38 | 39 | static LIST_SIMPEL(cb_route_change_list, struct cb_route_change_node, list, list); 40 | static LIST_SIMPEL(cb_packet_list, struct cb_packet_node, list, list); 41 | LIST_SIMPEL(cb_fd_list, struct cb_fd_node, list, list); 42 | 43 | 44 | 45 | int32_t plugin_data_registries[PLUGIN_DATA_SIZE]; 46 | 47 | void cb_plugin_hooks(int32_t cb_id, void* data) 48 | { 49 | struct list_node *list_pos; 50 | struct plugin_node *pn, *prev_pn = NULL; 51 | 52 | list_for_each(list_pos, &plugin_list) 53 | { 54 | pn = list_entry(list_pos, struct plugin_node, list); 55 | 56 | if (prev_pn && prev_pn->plugin && prev_pn->plugin->cb_plugin_handler[cb_id]) 57 | (*(prev_pn->plugin->cb_plugin_handler[cb_id])) (cb_id, data); 58 | 59 | prev_pn = pn; 60 | } 61 | 62 | if (prev_pn && prev_pn->plugin && prev_pn->plugin->cb_plugin_handler[cb_id]) 63 | ((*(prev_pn->plugin->cb_plugin_handler[cb_id])) (cb_id, data)); 64 | 65 | } 66 | 67 | STATIC_FUNC 68 | void _set_thread_hook(int32_t cb_type, void (*cb_handler) (void), int8_t del, struct list_node *cb_list) 69 | { 70 | struct list_node *list_pos, *tmp_pos, *prev_pos = cb_list; 71 | struct cb_node *cbn; 72 | 73 | if (!cb_type || !cb_handler) { 74 | cleanup_all(-500143); 75 | } 76 | 77 | list_for_each_safe(list_pos, tmp_pos, (struct bmx_list_head*) cb_list) 78 | { 79 | cbn = list_entry(list_pos, struct cb_node, list); 80 | 81 | if (cb_type == cbn->cb_type && cb_handler == cbn->cb_handler) { 82 | 83 | if (del) { 84 | 85 | list_del_next(((struct bmx_list_head*) cb_list), prev_pos); 86 | debugFree(cbn, -300069); 87 | return; 88 | 89 | } else { 90 | cleanup_all(-500144); 91 | //dbgf_sys(DBGT_ERR, "cb_hook for cb_type %d and cb_handler already registered", cb_type ); 92 | } 93 | 94 | } else { 95 | 96 | prev_pos = &cbn->list; 97 | } 98 | } 99 | 100 | assertion(-501289, (!del)); 101 | 102 | cbn = debugMallocReset(sizeof( struct cb_node), -300027); 103 | 104 | cbn->cb_type = cb_type; 105 | cbn->cb_handler = cb_handler; 106 | bmx_list_add_tail(((struct bmx_list_head*) cb_list), &cbn->list); 107 | 108 | } 109 | 110 | void set_route_change_hooks(void (*cb_route_change_handler) (uint8_t del, struct orig_node *dest), uint8_t del) 111 | { 112 | _set_thread_hook(1, (void (*) (void)) cb_route_change_handler, del, (struct list_node*) & cb_route_change_list); 113 | } 114 | 115 | 116 | // notify interested plugins of a changed route... 117 | // THIS MAY CRASH when one plugin unregisteres two packet_hooks while being called with cb_packet_handler() 118 | 119 | void cb_route_change_hooks(uint8_t del, struct orig_node *dest) 120 | { 121 | struct list_node *list_pos; 122 | struct cb_route_change_node *con, *prev_con = NULL; 123 | struct neigh_node *local_router = dest->neighPath.link->k.linkDev->key.local; 124 | 125 | totalOrigRoutes += (del ? -1 : +1); 126 | 127 | local_router->orig_routes += (del ? -1 : +1); 128 | dest->neighPath.link->orig_routes += (del ? -1 : +1); 129 | dest->neighPath.link->k.myDev->totalOrigRoutes += (del ? -1 : +1); 130 | 131 | assertion(-501320, (local_router->orig_routes >= 0 && local_router->orig_routes < (int) orig_tree.items)); 132 | 133 | list_for_each(list_pos, &cb_route_change_list) 134 | { 135 | con = list_entry(list_pos, struct cb_route_change_node, list); 136 | 137 | if (prev_con) 138 | (*(prev_con->cb_route_change_handler)) (del, dest); 139 | 140 | prev_con = con; 141 | 142 | } 143 | 144 | if (prev_con) 145 | (*(prev_con->cb_route_change_handler)) (del, dest); 146 | 147 | } 148 | 149 | void set_packet_hook(void (*cb_packet_handler) (struct packet_buff *), int8_t del) 150 | { 151 | _set_thread_hook(1, (void (*) (void)) cb_packet_handler, del, (struct list_node*) &cb_packet_list); 152 | } 153 | 154 | void cb_packet_hooks(struct packet_buff *pb) 155 | { 156 | struct list_node *list_pos; 157 | struct cb_packet_node *cpn, *prev_cpn = NULL; 158 | 159 | list_for_each(list_pos, &cb_packet_list) 160 | { 161 | cpn = list_entry(list_pos, struct cb_packet_node, list); 162 | 163 | if (prev_cpn) { 164 | 165 | (*(prev_cpn->cb_packet_handler)) (pb); 166 | 167 | } 168 | 169 | prev_cpn = cpn; 170 | 171 | } 172 | 173 | if (prev_cpn) 174 | (*(prev_cpn->cb_packet_handler)) (pb); 175 | 176 | } 177 | 178 | void set_fd_hook(int32_t fd, void (*cb_fd_handler) (int32_t fd), int8_t del) 179 | { 180 | 181 | _set_thread_hook(fd, (void (*) (void)) cb_fd_handler, del, (struct list_node*) & cb_fd_list); 182 | 183 | change_selects(); 184 | } 185 | 186 | int32_t get_plugin_data_registry(uint8_t data_type) 187 | { 188 | static int is_plugin_data_initialized = NO; 189 | 190 | if (!is_plugin_data_initialized) { 191 | memset(plugin_data_registries, 0, sizeof( plugin_data_registries)); 192 | is_plugin_data_initialized = YES; 193 | } 194 | 195 | assertion(-501366, (initializing && data_type < PLUGIN_DATA_SIZE)); 196 | 197 | // do NOT return the incremented value! 198 | plugin_data_registries[data_type]++; 199 | return((plugin_data_registries[data_type]) - 1); 200 | } 201 | 202 | void **get_plugin_data(void *data, uint8_t data_type, int32_t registry) 203 | { 204 | assertion(-501284, (data_type < PLUGIN_DATA_SIZE)); 205 | assertion(-501285, (registry < plugin_data_registries[data_type])); 206 | 207 | if (data_type == PLUGIN_DATA_ORIG) 208 | return &(((struct orig_node*) data)->plugin_data[registry]); 209 | 210 | if (data_type == PLUGIN_DATA_DEV) 211 | return &(((struct dev_node*) data)->plugin_data[registry]); 212 | 213 | return NULL; 214 | } 215 | 216 | STATIC_FUNC 217 | int is_plugin_active(void *plugin) 218 | { 219 | 220 | struct list_node *list_pos; 221 | 222 | list_for_each(list_pos, &plugin_list) 223 | { 224 | 225 | if (((struct plugin_node *) (list_entry(list_pos, struct plugin_node, list)))->plugin == plugin) 226 | return YES; 227 | 228 | } 229 | 230 | return NO; 231 | } 232 | 233 | int activate_plugin(struct plugin *p, void *dlhandle, const char *dl_name) 234 | { 235 | 236 | if (p == NULL) 237 | return SUCCESS; 238 | 239 | if (is_plugin_active(p)) 240 | return FAILURE; 241 | 242 | 243 | if (p->plugin_size != sizeof( struct plugin)) { 244 | 245 | dbgf_sys(DBGT_ERR, 246 | "plugin with unexpected size %d != %zu, revision=%s", 247 | p->plugin_size, sizeof( struct plugin), GIT_REV); 248 | 249 | return FAILURE; 250 | } 251 | 252 | 253 | if (p->cb_init == NULL || ((*(p->cb_init)) ()) == FAILURE) { 254 | 255 | dbg_sys(DBGT_ERR, "could not init plugin"); 256 | return FAILURE; 257 | } 258 | 259 | struct plugin_node *pn = debugMallocReset(sizeof( struct plugin_node), -300028); 260 | 261 | pn->plugin = p; 262 | pn->dlhandle = dlhandle; 263 | 264 | bmx_list_add_tail(&plugin_list, &pn->list); 265 | 266 | dbgf_all(DBGT_INFO, "%s SUCCESS", pn->plugin->plugin_name); 267 | 268 | if (dl_name) { 269 | pn->dlname = debugMalloc(strlen(dl_name) + 1, -300029); 270 | strcpy(pn->dlname, dl_name); 271 | } 272 | 273 | return SUCCESS; 274 | } 275 | 276 | STATIC_FUNC 277 | void deactivate_plugin(void *p) 278 | { 279 | 280 | if (!is_plugin_active(p)) { 281 | cleanup_all(-500190); 282 | } 283 | 284 | struct list_node *list_pos, *tmp_pos, *prev_pos = (struct list_node*) &plugin_list; 285 | 286 | list_for_each_safe(list_pos, tmp_pos, &plugin_list) 287 | { 288 | 289 | struct plugin_node *pn = list_entry(list_pos, struct plugin_node, list); 290 | 291 | if (pn->plugin == p) { 292 | 293 | list_del_next(&plugin_list, prev_pos); 294 | 295 | dbg_track(DBGT_INFO, "deactivating plugin %s", pn->plugin->plugin_name); 296 | 297 | if (pn->plugin->cb_cleanup) 298 | (*(pn->plugin->cb_cleanup)) (); 299 | 300 | 301 | if (pn->dlname) 302 | debugFree(pn->dlname, -300070); 303 | 304 | debugFree(pn, -300071); 305 | 306 | } else { 307 | 308 | prev_pos = &pn->list; 309 | 310 | } 311 | 312 | } 313 | 314 | } 315 | 316 | #ifndef NO_DYN_PLUGIN 317 | 318 | STATIC_FUNC 319 | int8_t activate_dyn_plugin(const char* name) 320 | { 321 | 322 | struct plugin * (*get_plugin) (void) = NULL; 323 | 324 | void *dlhandle; 325 | struct plugin *pv1; 326 | char dl_path[1000]; 327 | 328 | char *My_libs = getenv(BMX_ENV_LIB_PATH); 329 | 330 | if (!name) 331 | return FAILURE; 332 | 333 | // dl_open sigfaults on some systems without reason. 334 | // removing the dl files from BMX_DEF_LIB_PATH is a way to prevent calling dl_open. 335 | // Therefore we restrict dl search to BMX_DEF_LIB_PATH and BMX_ENV_LIB_PATH and ensure that dl_open 336 | // is only called if a file with the requested dl name could be found. 337 | 338 | if (My_libs) 339 | sprintf(dl_path, "%s/%s", My_libs, name); 340 | else 341 | sprintf(dl_path, "%s/%s", BMX_DEF_LIB_PATH, name); 342 | 343 | 344 | dbgf_all(DBGT_INFO, "trying to load dl %s", dl_path); 345 | 346 | int dl_tried = 0; 347 | 348 | if (check_file(dl_path, YES/*regular*/, YES/*read*/, NO/*writeble*/, YES/*executable*/) == SUCCESS && 349 | (dl_tried = 1) && (dlhandle = dlopen(dl_path, RTLD_NOW))) { 350 | 351 | dbgf_all(DBGT_INFO, "succesfully loaded dynamic library %s", dl_path); 352 | 353 | } else { 354 | 355 | dbg(dl_tried ? DBGL_SYS : DBGL_CHANGES, dl_tried ? DBGT_ERR : DBGT_WARN, 356 | "failed loading dl %s %s (maybe incompatible binary/lib versions?)", 357 | dl_path, dl_tried ? dlerror() : ""); 358 | 359 | return FAILURE; 360 | 361 | } 362 | 363 | dbgf_all(DBGT_INFO, "survived dlopen()!"); 364 | 365 | 366 | typedef struct plugin * (*sdl_init_function_type) (void); 367 | 368 | union { 369 | sdl_init_function_type func; 370 | void * obj; 371 | } alias; 372 | 373 | alias.obj = dlsym(dlhandle, "get_plugin"); 374 | 375 | if (!(get_plugin = alias.func)) { 376 | dbgf_sys(DBGT_ERR, "dlsym( %s ) failed: %s", name, dlerror()); 377 | return FAILURE; 378 | } 379 | 380 | 381 | if (!(pv1 = get_plugin())) { 382 | 383 | dbgf_sys(DBGT_ERR, "get_plugin( %s ) failed", name); 384 | return FAILURE; 385 | 386 | } 387 | 388 | if (is_plugin_active(pv1)) 389 | return SUCCESS; 390 | 391 | 392 | if (activate_plugin(pv1, dlhandle, name) == FAILURE) { 393 | 394 | dbgf_sys(DBGT_ERR, "activate_plugin( %s ) failed", dl_path); 395 | return FAILURE; 396 | 397 | } 398 | 399 | dbg_track(DBGT_INFO, "loading and activating %s dl %s succeeded", My_libs ? "customized" : "default", dl_path); 400 | 401 | return SUCCESS; 402 | } 403 | 404 | STATIC_FUNC 405 | int32_t opt_plugin(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn) 406 | { 407 | 408 | dbgf_all(DBGT_INFO, "%s %d", opt_cmd2str[cmd], _save); 409 | 410 | char tmp_name[MAX_PATH_SIZE] = ""; 411 | 412 | 413 | if (cmd == OPT_CHECK) { 414 | 415 | dbgf_all(DBGT_INFO, "about to load dl %s", patch->val); 416 | 417 | if (wordlen(patch->val) + 1 >= MAX_PATH_SIZE || patch->val[0] == '/') 418 | return FAILURE; 419 | 420 | wordCopy(tmp_name, patch->val); 421 | 422 | if (get_opt_parent_val(opt, tmp_name)) 423 | return SUCCESS; 424 | 425 | if (activate_dyn_plugin(tmp_name) == FAILURE) 426 | return FAILURE; 427 | 428 | } 429 | 430 | return SUCCESS; 431 | } 432 | 433 | static struct opt_type plugin_options[]= 434 | { 435 | // ord parent long_name shrt Attributes *ival min max default *func,*syntax,*help 436 | 437 | //order> config-file order to be loaded by config file, order < ARG_CONNECT oder to appera first in help text 438 | {ODI,0,ARG_PLUGIN, 0, 2,2,A_PM1N,A_ADM,A_INI,A_CFA,A_ANY, 0, 0, 0, 0,0, opt_plugin, 439 | ARG_FILE_FORM, "load plugin. "ARG_FILE_FORM" must be in LD_LIBRARY_PATH or " BMX_ENV_LIB_PATH 440 | "\n path (e.g. --plugin bmx7_howto_plugin.so )\n"} 441 | }; 442 | #endif 443 | 444 | IDM_T init_plugin(void) 445 | { 446 | 447 | 448 | // set_snd_ext_hook( 0, NULL, YES ); //ensure correct initialization of extension hooks 449 | // reg_plugin_data( PLUGIN_DATA_SIZE );// ensure correct initialization of plugin_data 450 | ; 451 | #ifndef NO_DYN_PLUGIN 452 | // first try loading config plugin, if succesfull, continue loading optinal plugins depending on config 453 | activate_dyn_plugin(BMX_LIB_CONFIG); 454 | 455 | register_options_array(plugin_options, sizeof( plugin_options), CODE_CATEGORY_NAME); 456 | #endif 457 | 458 | return SUCCESS; 459 | } 460 | 461 | void cleanup_plugin(void) 462 | { 463 | 464 | while (!LIST_EMPTY(&plugin_list)) 465 | deactivate_plugin(((struct plugin_node*) (list_entry((&plugin_list)->next, struct plugin_node, list)))->plugin); 466 | 467 | } 468 | -------------------------------------------------------------------------------- /src/plugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #define BMX_LIB_CONFIG "bmx7_config.so" 19 | 20 | #define ARG_PLUGIN "plugin" 21 | 22 | 23 | //for config and rareley used hooks: 24 | 25 | enum { 26 | PLUGIN_CB_STATUS, 27 | PLUGIN_CB_CONF, 28 | PLUGIN_CB_BMX_DEV_EVENT, 29 | PLUGIN_CB_SYS_DEV_EVENT, 30 | PLUGIN_CB_LINKS_EVENT, 31 | PLUGIN_CB_DESCRIPTION_CREATED, 32 | PLUGIN_CB_DESCRIPTION_DESTROY, 33 | PLUGIN_CB_TERM, 34 | PLUGIN_CB_SIZE 35 | }; 36 | 37 | void cb_plugin_hooks(int32_t cb_id, void* data); 38 | 39 | 40 | 41 | 42 | //for registering data hooks (attaching plugin data to bmx data structures) 43 | 44 | enum { 45 | PLUGIN_DATA_ORIG, 46 | PLUGIN_DATA_DEV, 47 | PLUGIN_DATA_SIZE 48 | }; 49 | 50 | 51 | extern int32_t plugin_data_registries[PLUGIN_DATA_SIZE]; 52 | 53 | 54 | int32_t get_plugin_data_registry(uint8_t data_type); 55 | 56 | void **get_plugin_data(void *data, uint8_t data_type, int32_t registry); 57 | 58 | 59 | 60 | 61 | 62 | 63 | // for registering thread hooks (often and fast-to-be-done hooks) 64 | 65 | struct cb_node { 66 | struct list_node list; 67 | int32_t cb_type; 68 | void (*cb_handler) (void); 69 | }; 70 | 71 | struct cb_fd_node { 72 | struct list_node list; 73 | int32_t fd; 74 | void (*cb_fd_handler) (int32_t fd); 75 | }; 76 | 77 | extern struct bmx_list_head cb_fd_list; 78 | // cb_fd_handler is called when fd received data 79 | // called function may remove itself 80 | void set_fd_hook(int32_t fd, void (*cb_fd_handler) (int32_t fd), int8_t del); 81 | 82 | struct cb_route_change_node { 83 | struct list_node list; 84 | int32_t cb_type; 85 | void (*cb_route_change_handler) (uint8_t del, struct orig_node * dest); 86 | }; 87 | 88 | void set_route_change_hooks(void (*cb_route_change_handler) (uint8_t del, struct orig_node *dest), uint8_t del); 89 | void cb_route_change_hooks(uint8_t del, struct orig_node *dest); 90 | 91 | struct cb_packet_node { 92 | struct list_node list; 93 | int32_t packet_type; 94 | void (*cb_packet_handler) (struct packet_buff *); 95 | }; 96 | 97 | 98 | void set_packet_hook(void (*cb_packet_handler) (struct packet_buff *), int8_t del); 99 | void cb_packet_hooks(struct packet_buff *pb); 100 | 101 | 102 | 103 | 104 | 105 | // for initializing: 106 | 107 | struct plugin { 108 | uint32_t plugin_size; 109 | char *plugin_name; 110 | int32_t(*cb_init) (void); 111 | void (*cb_cleanup) (void); 112 | //some more advanced (rarely called) callbacks hooks 113 | void (*cb_plugin_handler[PLUGIN_CB_SIZE]) (int32_t, void*); 114 | 115 | }; 116 | 117 | struct plugin_node { 118 | struct list_node list; 119 | struct plugin *plugin; 120 | void *dlhandle; 121 | char *dlname; 122 | }; 123 | 124 | 125 | int activate_plugin(struct plugin *p, void *dlhandle, const char *dl_name); 126 | 127 | IDM_T init_plugin(void); 128 | void cleanup_plugin(void); 129 | -------------------------------------------------------------------------------- /src/prof.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | #include "list.h" 30 | #include "control.h" 31 | #include "bmx.h" 32 | #include "crypt.h" 33 | #include "avl.h" 34 | #include "node.h" 35 | #include "allocate.h" 36 | #include "tools.h" 37 | #include "prof.h" 38 | #include "schedule.h" 39 | 40 | #define CODE_CATEGORY_NAME "profiling" 41 | 42 | static AVL_TREE(prof_tree, struct prof_ctx, k); 43 | 44 | void prof_init(struct prof_ctx *sp) 45 | { 46 | assertion(-502112, (!sp->initialized)); 47 | assertion(-502113, (sp && sp->k.func && sp->name && strlen(sp->name) < 100)); 48 | assertion(-502114, (!(sp->k.orig && sp->k.neigh))); 49 | assertion(-502115, (!avl_find_item(&prof_tree, &sp->k))); 50 | 51 | if (sp->parent_func) { 52 | struct prof_ctx_key pk = { .func = sp->parent_func }; 53 | struct prof_ctx *pp = avl_find_item(&prof_tree, &pk); 54 | 55 | assertion(-502116, (pp)); 56 | 57 | avl_insert(&pp->childs_tree, sp, -300644); 58 | sp->parent = pp; 59 | } 60 | 61 | AVL_INIT_TREE(sp->childs_tree, struct prof_ctx, k); 62 | 63 | avl_insert(&prof_tree, sp, -300645); 64 | sp->initialized = 1; 65 | 66 | } 67 | 68 | void prof_free(struct prof_ctx *p) 69 | { 70 | assertion(-502117, (p)); 71 | assertion(-502118, (p->initialized)); 72 | assertion(-502119, (!(p->childs_tree.items))); 73 | assertion(-502120, (avl_find_item(&prof_tree, &p->k))); 74 | // assertion(-502121, !((*p)->timeBefore)); 75 | 76 | p->initialized = 0; 77 | 78 | avl_remove(&prof_tree, &p->k, -300646); 79 | 80 | if (p->parent) 81 | avl_remove(&(p->parent->childs_tree), &p->k, -300647); 82 | 83 | } 84 | 85 | static uint8_t prof_check_disabled = 0; 86 | 87 | STATIC_FUNC 88 | int prof_check(struct prof_ctx *p, int childs) 89 | { 90 | if (prof_check_disabled || 91 | !p || (p->active_prof && !!p->active_childs == childs && prof_check(p->parent, 1) == SUCCESS)) 92 | return SUCCESS; 93 | 94 | dbgf_sys(DBGT_ERR, "func=%d name=%s parent_func=%d neigh=%p orig=%p parent_active_childs=%d childs=%d", 95 | !!p->k.func, p->name, !!p->parent_func, (void*) p->k.neigh, (void*) p->k.orig, p->active_childs, childs); 96 | 97 | return FAILURE; 98 | } 99 | 100 | void prof_start_(struct prof_ctx *p) 101 | { 102 | assertion_dbg(-502122, (!p->active_prof && !p->clockBeforePStart && !p->active_childs), 103 | "func=%s %d %ju %d", p->name, p->active_prof, (uintmax_t) p->clockBeforePStart, p->active_childs); 104 | 105 | if (!p->initialized) 106 | prof_init(p); 107 | 108 | p->clockBeforePStart = (TIME_T) clock(); 109 | p->active_prof = 1; 110 | 111 | if (p->parent) 112 | p->parent->active_childs++; 113 | 114 | ASSERTION(-502125, (prof_check(p, 0) == SUCCESS)); 115 | } 116 | 117 | void prof_stop_(struct prof_ctx *p) 118 | { 119 | TIME_T clockAfter = clock(); 120 | TIME_T clockPeriod = (clockAfter - p->clockBeforePStart); 121 | 122 | assertion_dbg(-502126, (p->active_prof && !p->active_childs), 123 | "func=%s %d %d %ju %d %d", p->name, p->active_prof, p->active_childs, (uintmax_t) p->clockBeforePStart, clockAfter, clockPeriod); 124 | 125 | ASSERTION(-502127, (prof_check(p, 0) == SUCCESS)); 126 | 127 | // IDM_T TODO_Fix_this_for_critical_system_time_drifts; 128 | // assertion(-502128, (clockPeriod < ((~((TIME_T)0))>>1)) ); //this wraps around some time.. 129 | 130 | if (clockPeriod < ((~((TIME_T) 0)) >> 1)) 131 | p->clockRunningPeriod += clockPeriod; 132 | 133 | p->clockBeforePStart = 0; 134 | p->active_prof = 0; 135 | 136 | if (p->parent) 137 | p->parent->active_childs--; 138 | } 139 | 140 | static uint64_t durationPrevPeriod = 0; 141 | static uint64_t timeAfterPrevPeriod = 0; 142 | 143 | STATIC_FUNC 144 | void prof_update_all(void *unused) 145 | { 146 | 147 | struct avl_node *an = NULL; 148 | struct prof_ctx *pn; 149 | 150 | struct timeval tvAfterRunningPeriod; 151 | upd_time(&tvAfterRunningPeriod); 152 | uint64_t timeAfterRunningPeriod = (((uint64_t) tvAfterRunningPeriod.tv_sec) * 1000000) + tvAfterRunningPeriod.tv_usec; 153 | 154 | durationPrevPeriod = (timeAfterRunningPeriod - timeAfterPrevPeriod); 155 | 156 | assertion(-502129, (durationPrevPeriod > 0)); 157 | assertion(-502130, (durationPrevPeriod < 10 * 1000000)); 158 | 159 | prof_check_disabled = YES; 160 | 161 | while ((pn = avl_iterate_item(&prof_tree, &an))) { 162 | 163 | uint8_t active = pn->active_prof; 164 | 165 | dbgf_all(DBGT_INFO, "updating %s active=%d", pn->name, active); 166 | 167 | if (active) 168 | prof_stop_(pn); 169 | 170 | pn->clockPrevPeriod = pn->clockRunningPeriod; 171 | pn->clockPrevTotal += pn->clockRunningPeriod; 172 | 173 | pn->clockRunningPeriod = 0; 174 | 175 | if (active) 176 | prof_start_(pn); 177 | } 178 | 179 | prof_check_disabled = NO; 180 | 181 | timeAfterPrevPeriod = timeAfterRunningPeriod; 182 | 183 | task_register(5000, prof_update_all, NULL, -300648); 184 | } 185 | 186 | struct prof_status { 187 | GLOBAL_ID_T *neighId; 188 | GLOBAL_ID_T *origId; 189 | const char* parent; 190 | const char* name; 191 | // uint32_t total; 192 | char sysCurrCpu[10]; 193 | char relCurrCpu[10]; 194 | char sysAvgCpu[10]; 195 | char relAvgCpu[10]; 196 | 197 | }; 198 | 199 | static const struct field_format prof_status_format[] = { 200 | FIELD_FORMAT_INIT(FIELD_TYPE_POINTER_SHORT_ID, prof_status, neighId, 1, FIELD_RELEVANCE_HIGH), 201 | FIELD_FORMAT_INIT(FIELD_TYPE_POINTER_GLOBAL_ID, prof_status, origId, 1, FIELD_RELEVANCE_HIGH), 202 | FIELD_FORMAT_INIT(FIELD_TYPE_POINTER_CHAR, prof_status, parent, 1, FIELD_RELEVANCE_HIGH), 203 | FIELD_FORMAT_INIT(FIELD_TYPE_POINTER_CHAR, prof_status, name, 1, FIELD_RELEVANCE_HIGH), 204 | // FIELD_FORMAT_INIT(FIELD_TYPE_UINT, prof_status, total, 1, FIELD_RELEVANCE_HIGH), 205 | FIELD_FORMAT_INIT(FIELD_TYPE_STRING_CHAR, prof_status, sysCurrCpu, 1, FIELD_RELEVANCE_HIGH), 206 | FIELD_FORMAT_INIT(FIELD_TYPE_STRING_CHAR, prof_status, relCurrCpu, 1, FIELD_RELEVANCE_HIGH), 207 | FIELD_FORMAT_INIT(FIELD_TYPE_STRING_CHAR, prof_status, sysAvgCpu, 1, FIELD_RELEVANCE_HIGH), 208 | FIELD_FORMAT_INIT(FIELD_TYPE_STRING_CHAR, prof_status, relAvgCpu, 1, FIELD_RELEVANCE_HIGH), 209 | FIELD_FORMAT_END 210 | }; 211 | 212 | STATIC_FUNC 213 | struct prof_status *prof_status_iterate(struct prof_ctx *pn, struct prof_status *status) 214 | { 215 | dbgf_all(DBGT_INFO, "dbg pn=%s status=%p", pn->name, (void*) status); 216 | 217 | status->neighId = pn->k.neigh ? &pn->k.neigh->k.nodeId : NULL; 218 | status->origId = pn->k.orig ? &pn->k.orig->k.nodeId : NULL; 219 | status->parent = pn->parent ? pn->parent->name : NULL; 220 | status->name = pn->name; 221 | sprintf(status->sysCurrCpu, DBG_NIL); 222 | sprintf(status->relCurrCpu, DBG_NIL); 223 | sprintf(status->sysAvgCpu, DBG_NIL); 224 | sprintf(status->relAvgCpu, DBG_NIL); 225 | 226 | if (!durationPrevPeriod || !timeAfterPrevPeriod) 227 | goto prof_status_iterate_childs; 228 | 229 | uint32_t loadPrevPeriod = (((uint64_t) pn->clockPrevPeriod)* 230 | ((((uint64_t) 100)*1000 * 1000000) / ((uint64_t) CLOCKS_PER_SEC))) / 231 | durationPrevPeriod; 232 | 233 | snprintf(status->sysCurrCpu, sizeof(status->sysCurrCpu), "%8.4f", ((float) loadPrevPeriod) / 1000); 234 | 235 | uint32_t loadPrevTotal = (((uint64_t) pn->clockPrevTotal)* 236 | ((((uint64_t) 100)*1000 * 1000000) / ((uint64_t) CLOCKS_PER_SEC))) / 237 | timeAfterPrevPeriod; 238 | 239 | snprintf(status->sysAvgCpu, sizeof(status->sysAvgCpu), "%8.4f", ((float) loadPrevTotal) / 1000); 240 | 241 | if (!pn->parent) 242 | goto prof_status_iterate_childs; 243 | 244 | uint32_t loadParentPrevPeriod = (((uint64_t) pn->parent->clockPrevPeriod)* 245 | ((((uint64_t) 100)*1000 * 1000000) / ((uint64_t) CLOCKS_PER_SEC))) / 246 | durationPrevPeriod; 247 | 248 | if (loadParentPrevPeriod) 249 | snprintf(status->relCurrCpu, sizeof(status->relCurrCpu), "%8.4f", ((((float) loadPrevPeriod)*100) / ((float) loadParentPrevPeriod))); 250 | else if (!loadParentPrevPeriod && loadPrevPeriod) 251 | sprintf(status->relCurrCpu, "ERR"); 252 | 253 | uint32_t loadParentPrevTotal = (((uint64_t) pn->parent->clockPrevTotal)* 254 | ((((uint64_t) 100)*1000 * 1000000) / ((uint64_t) CLOCKS_PER_SEC))) / 255 | timeAfterPrevPeriod; 256 | 257 | if (loadParentPrevTotal) 258 | snprintf(status->relAvgCpu, sizeof(status->relAvgCpu), "%8.4f", ((((float) loadPrevTotal)*100) / ((float) loadParentPrevTotal))); 259 | else if (!loadParentPrevTotal && loadPrevTotal) 260 | sprintf(status->relAvgCpu, "ERR"); 261 | 262 | 263 | prof_status_iterate_childs: 264 | { 265 | 266 | status = &(status[1]); 267 | 268 | struct avl_node *an = NULL; 269 | struct prof_ctx *cn; 270 | while ((cn = avl_iterate_item(&pn->childs_tree, &an))) { 271 | status = prof_status_iterate(cn, status); 272 | } } 273 | return status; 274 | } 275 | 276 | STATIC_FUNC 277 | int32_t prof_status_creator(struct status_handl *handl, void *data) 278 | { 279 | struct avl_node *it = NULL; 280 | struct prof_ctx *pn; 281 | uint32_t status_size = (prof_tree.items) * sizeof(struct prof_status); 282 | struct prof_status *status = ((struct prof_status*) (handl->data = debugRealloc(handl->data, status_size, -300366))); 283 | memset(status, 0, status_size); 284 | 285 | while ((pn = avl_iterate_item(&prof_tree, &it))) { 286 | 287 | if (!pn->parent) { 288 | status = prof_status_iterate(pn, status); 289 | } 290 | } 291 | 292 | return status_size; 293 | } 294 | 295 | 296 | static struct opt_type prof_options[] ={ 297 | // ord parent long_name shrt Attributes *ival min max default *func,*syntax,*help 298 | {ODI,0,ARG_CPU_PROFILING, 0, 9,1,A_PS0N,A_USR,A_DYN,A_ARG,A_ANY, 0, 0, 0, 0,0, opt_status, 299 | 0, "show cpu usage of relevant functions\n"} 300 | }; 301 | 302 | void init_prof(void) 303 | { 304 | register_status_handl(sizeof(struct prof_status), 1, prof_status_format, ARG_CPU_PROFILING, prof_status_creator); 305 | register_options_array(prof_options, sizeof( prof_options), CODE_CATEGORY_NAME); 306 | 307 | task_register(5000, prof_update_all, NULL, -300649); 308 | 309 | } 310 | 311 | void cleanup_prof(void) 312 | { 313 | 314 | struct avl_node *it = NULL; 315 | struct prof_ctx *pn; 316 | 317 | for (it = NULL; (pn = avl_iterate_item(&prof_tree, &it));) { 318 | pn->parent = NULL; 319 | while ((avl_remove_first_item(&(pn->childs_tree), -300650))); 320 | } 321 | 322 | while ((avl_remove_first_item(&prof_tree, -300651))); 323 | } 324 | -------------------------------------------------------------------------------- /src/prof.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | #define ARG_CPU_PROFILING "cpu" 18 | 19 | struct prof_ctx_key { 20 | struct neigh_node *neigh; 21 | struct orig_node *orig; 22 | void (* func) (void); 23 | } __attribute__((packed)); 24 | 25 | struct prof_ctx { 26 | // must be initialized: 27 | struct prof_ctx_key k; 28 | const char *name; 29 | void (* parent_func) (void); 30 | // updated by first prof_start() -> prof_init(): 31 | struct prof_ctx *parent; 32 | struct avl_tree childs_tree; 33 | int8_t initialized; 34 | 35 | int8_t active_childs; 36 | int8_t active_prof; 37 | 38 | clock_t clockBeforePStart; 39 | 40 | // updated by prof_stop(): 41 | clock_t clockRunningPeriod; 42 | clock_t clockPrevPeriod; 43 | uint64_t clockPrevTotal; 44 | }; 45 | 46 | //void prof_init( struct prof_ctx *sp); 47 | 48 | void prof_free(struct prof_ctx *p); 49 | 50 | void prof_start_(struct prof_ctx *p); 51 | void prof_stop_(struct prof_ctx *p); 52 | 53 | #define prof_start( thisFunc, parentFunc ) \ 54 | extern int main(int argc, char *argv[]); \ 55 | static struct prof_ctx prof_ctx_ = {.k = { .func = (void(*)(void))thisFunc}, .name = __func__, .parent_func = (void (*) (void))parentFunc}; \ 56 | prof_start_(&prof_ctx_) 57 | 58 | #define prof_stop() prof_stop_( &prof_ctx_ ) 59 | 60 | 61 | 62 | 63 | void init_prof(void); 64 | void cleanup_prof(void); 65 | -------------------------------------------------------------------------------- /src/redist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | 20 | /* 21 | #define ARG_EXPORT "export" 22 | 23 | #define ARG_EXPORT_UHNA "unicastHna" 24 | #define DEF_EXPORT_UHNA 0 25 | 26 | #define ARG_EXPORT_RTYPE_BMX "bmx7" 27 | #define DEF_EXPORT_RTYPE_BMX 1 28 | 29 | #define ARG_EXPORT_ONLY "exportOnly" 30 | #define DEF_EXPORT_ONLY 0 31 | #define MIN_EXPORT_ONLY 0 32 | #define MAX_EXPORT_ONLY 1 33 | */ 34 | 35 | 36 | 37 | #define ARG_REDIST_NET "network" 38 | #define HLP_REDIST_NET "network permit filter (optional)" 39 | 40 | #define ARG_REDIST_BW "bandwidth" 41 | #define HLP_REDIST_BW "bandwidth to network as bits/sec default: 1000 range: [36 ... 128849018880]" 42 | 43 | #define ARG_REDIST_METRIC "metric" 44 | #define DEF_REDIST_METRIC 0 45 | #define MIN_REDIST_METRIC 0 46 | #define MAX_REDIST_METRIC INT32_MAX 47 | 48 | #define ARG_REDIST_DISTANCE "distance" 49 | #define DEF_REDIST_DISTANCE 0 50 | #define MIN_REDIST_DISTANCE 0 51 | #define MAX_REDIST_DISTANCE UINT8_MAX 52 | 53 | #define MIN_REDIST_PREFIX 0 54 | #define MAX_REDIST_PREFIX 129 55 | #define TYP_REDIST_PREFIX_NET 129 //assumes prefix from ARG_TUN_OUT_NET 56 | 57 | #define ARG_REDIST_PREFIX_MIN "minPrefixLen" 58 | #define HLP_REDIST_PREFIX_MIN "minumum prefix len (129 = network prefix len)" 59 | #define DEF_REDIST_PREFIX_MIN TYP_REDIST_PREFIX_NET 60 | 61 | #define ARG_REDIST_PREFIX_MAX "maxPrefixLen" 62 | #define HLP_REDIST_PREFIX_MAX "maximum prefix len (129 = network prefix len)" 63 | #define DEF_REDIST_PREFIX_MAX 128 64 | 65 | #define ARG_REDIST_TABLE "table" 66 | #define DEF_REDIST_TABLE 0 67 | #define MIN_REDIST_TABLE 0 68 | #define MAX_REDIST_TABLE MAX_IP_TABLE 69 | #define HLP_REDIST_TABLE "table to be searched for to-be redistributed routes (mandatory)" 70 | 71 | #define ARG_REDIST_AGGREGATE "aggregatePrefixLen" 72 | #define HLP_REDIST_AGGREGATE "minimum prefix len to aggregate redistributions" 73 | #define MIN_REDIST_AGGREGATE 0 74 | #define MAX_REDIST_AGGREGATE 128 75 | #define DEF_REDIST_AGGREGATE 0 76 | 77 | //#define MIN_REDIST_RTYPE_ENABLED 0 78 | //#define MAX_REDIST_RTYPE_ENABLED 1 79 | //#define DEF_REDIST_RTYPE_ENABLED 0 80 | 81 | 82 | #define ARG_REDIST_HYSTERESIS "hysteresis" 83 | #define DEF_REDIST_HYSTERESIS 20 84 | #define MIN_REDIST_HYSTERESIS 0 85 | #define MAX_REDIST_HYSTERESIS XMIN(100000, (UMETRIC_MULTIPLY_MAX - 100)) 86 | 87 | #define NETWORK_NAME_LEN 32 88 | 89 | struct redist_out_key { 90 | IFNAME_T tunInDev; 91 | uint8_t proto_type; 92 | FMETRIC_U8_T bandwidth; 93 | struct net_key net; 94 | uint8_t must_be_one; // to find_next route_type and bandwidth if net is zero 95 | } __attribute__((packed)); 96 | 97 | struct redist_out_node { 98 | struct redist_out_key k; 99 | uint8_t minAggregatePrefixLen; 100 | uint8_t old; 101 | uint8_t new; 102 | }; 103 | 104 | struct redist_in_key { 105 | struct net_key net; 106 | IPX_T via; 107 | uint32_t table; 108 | uint32_t ifindex; 109 | uint8_t proto_type; 110 | } __attribute__((packed)); 111 | 112 | struct redist_in_node { 113 | struct redist_in_key k; 114 | 115 | int16_t cnt; 116 | uint8_t flags; 117 | uint8_t message; 118 | uint8_t old; 119 | uint8_t distance; 120 | uint32_t metric; 121 | TIME_T stamp; 122 | struct redistr_opt_node *roptn; 123 | }; 124 | 125 | struct redistr_opt_node { 126 | char nameKey[NETWORK_NAME_LEN]; 127 | struct net_key net; 128 | uint32_t hysteresis; 129 | uint32_t table; 130 | uint16_t searchProto; 131 | uint16_t advProto; 132 | uint8_t netPrefixMin; 133 | uint8_t netPrefixMax; 134 | uint8_t minAggregatePrefixLen; 135 | FMETRIC_U8_T bandwidth; 136 | char *tunInDev; 137 | }; 138 | 139 | void redist_dbg(int8_t dbgl, int8_t dbgt, const char *func, struct redist_in_node *zrn, char* misc1, char* misc2); 140 | void update_tunXin6_net_adv_list(struct avl_tree *redist_out_tree, struct tunXin6_net_adv_node **tunXin6_net_adv_list); 141 | IDM_T redistribute_routes(struct avl_tree *redist_out_tree, struct avl_tree *zroute_tree, struct avl_tree *redist_opt_tree); 142 | 143 | int32_t opt_redist(uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn, struct avl_tree *redist_opt_tree, uint8_t *changed); 144 | struct redistr_opt_node *matching_redist_opt(struct redist_in_node *rin, struct avl_tree *redist_opt_tree); 145 | -------------------------------------------------------------------------------- /src/schedule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | #define REGISTER_TASK_TIMEOUT_MAX ((~((TIME_T)0))>>2) //100000 20 | 21 | struct task_node { 22 | struct list_node list; 23 | TIME_T expire; 24 | void (* task) (void *fpara); // pointer to the function to be executed 25 | void *data; //NULL or pointer to data to be given to function. Data will be freed after functio is called. 26 | }; 27 | 28 | 29 | void upd_time(struct timeval *precise_tv); 30 | 31 | void init_schedule(void); 32 | void change_selects(void); 33 | void cleanup_schedule(void); 34 | void task_register(TIME_T timeout, void (* task) (void *), void *data, int32_t tag); 35 | IDM_T task_remove(void (* task) (void *), void *data); 36 | TIME_T task_next(void); 37 | void wait4Event(TIME_T timeout); 38 | 39 | IDM_T doNowOrLater(TIME_T *nextScheduled, TIME_T interval, IDM_T now); 40 | -------------------------------------------------------------------------------- /src/tools.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #define XOR( a, b ) ( !(a) != !(b) ) 19 | #define IMPLIES( a, b ) ( !(a) || (b) ) 20 | 21 | // LOG2(val=0)=0, LOG2(val=1)=0, LOG2(val=2)=1, LOG2(val=3)=1, LOG2(val=4)=2, ... 22 | #define LOG2(result, val, VAL_TYPE) \ 23 | do { \ 24 | VAL_TYPE val_tmp = val; \ 25 | uint8_t j = ((8 * sizeof (VAL_TYPE) ) >> 1 ); \ 26 | result = 0; \ 27 | for (; val_tmp > 0x01; j >>= 1) { \ 28 | if (val_tmp >> j) { \ 29 | result += j; \ 30 | val_tmp >>= j; \ 31 | } \ 32 | } \ 33 | } while(0) 34 | 35 | static inline uint64_t ntoh64(uint64_t x) 36 | { 37 | #if __BYTE_ORDER == __LITTLE_ENDIAN 38 | return(((uint64_t) ntohl(x & (uint64_t) 0xFFFFFFFFULL)) << 32) | ((uint64_t) ntohl((x & (uint64_t) 0xFFFFFFFF00000000ULL) >> 32)); 39 | #else 40 | return x; 41 | #endif 42 | } 43 | 44 | #define hton64 ntoh64 45 | 46 | char *strToLower(char *s); 47 | char* rmStrKeyValue(char* str, char* key); 48 | IDM_T hexStrToMem(char *s, uint8_t *m, uint16_t mLen, uint8_t strict); 49 | char* memAsHexString(const void* mem, uint32_t len); 50 | char* memAsHexStringSep(const void* mem, uint32_t len, uint16_t seperationLen, char *seperator); 51 | char* memAsCharString(const char* mem, uint32_t len); 52 | 53 | IDM_T check_string(char*s, char *okChars, char replaceChar); 54 | IDM_T validate_char_string(const char* data, uint32_t len); 55 | IDM_T validate_name_string(char* name, uint32_t field_len, char* exceptions); 56 | 57 | int32_t max_i32(int32_t a, int32_t b); 58 | int32_t min_i32(int32_t a, int32_t b); 59 | 60 | float fast_inverse_sqrt(float x); 61 | 62 | uint32_t rand_num(const uint32_t limit); 63 | 64 | void byte_clear(uint8_t *array, uint32_t array_size, uint32_t begin, uint32_t end); 65 | uint8_t bits_count(uint32_t v); 66 | uint8_t bit_get(const uint8_t *array, const uint32_t array_bit_size, uint32_t bit); 67 | 68 | void bit_set(uint8_t *array, uint32_t array_bit_size, uint32_t bit, IDM_T value); 69 | 70 | uint32_t bits_get(uint8_t *array, uint32_t array_bit_size, uint32_t beg_bit, uint32_t end_bit, uint32_t range_mask); 71 | 72 | void bits_clear(uint8_t *array, uint32_t array_bit_size, uint32_t beg_bit, uint32_t end_bit, uint32_t range_mask); 73 | 74 | char* bits_print(uint8_t *array, uint32_t array_bit_size, uint32_t beg_bit, uint32_t end_bit, uint32_t range_mask); 75 | 76 | void bit_xor(void *out, void *a, void *b, uint32_t size); 77 | 78 | uint8_t is_zero(void *data, int len); 79 | 80 | int8_t wordsEqual(char *a, char *b); 81 | void wordCopy(char *out, char *in); 82 | uint32_t wordlen(char *s); 83 | int32_t check_file(char *path, uint8_t regular, uint8_t read, uint8_t write, uint8_t exec); 84 | int32_t check_dir(char *path, uint8_t create, uint8_t write, uint8_t onlyBasePath); 85 | int32_t rm_dir_content(char* dir_name, char* prefix); 86 | 87 | uint8_t *find_array_data(uint8_t *arr, uint32_t arrLen, uint8_t *element, uint32_t elemLen); 88 | 89 | void init_tools(void); 90 | -------------------------------------------------------------------------------- /src/z.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "list.h" 26 | #include "control.h" 27 | #include "bmx.h" 28 | #include "allocate.h" 29 | #include "z.h" 30 | 31 | 32 | //inspired by: http://www.zlib.net/zpipe.c 33 | 34 | //compress 35 | 36 | /* 37 | * on success and if available and when finished stores uncompressed data to: 38 | * *dst + dlen (which is reallocated) and 39 | * darr and returns compressed data size. 40 | * Therefore, src and *dst can point to same memory area ! 41 | * on failure leaves dst untouched and returnes -1 42 | */ 43 | int32_t z_compress(uint8_t *src, int32_t slen, uint8_t **dst, uint32_t dpos, uint8_t *darr, int32_t darr_max_size) 44 | { 45 | 46 | z_stream strm = { .zalloc = Z_NULL, .zfree = Z_NULL, .opaque = Z_NULL }; 47 | int32_t tlen = 0; 48 | uint8_t *tmp = NULL; 49 | int z_ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION); 50 | 51 | if (z_ret != Z_OK) 52 | return FAILURE; 53 | 54 | strm.avail_in = slen; 55 | strm.next_in = src; 56 | 57 | do { 58 | tmp = debugRealloc(tmp, tlen + Z_CHUNK_SIZE, -300573); 59 | 60 | strm.avail_out = Z_CHUNK_SIZE; 61 | strm.next_out = tmp + tlen; 62 | 63 | if ((z_ret = deflate(&strm, Z_FINISH)) != Z_OK && z_ret != Z_STREAM_END) { //== Z_STREAM_ERROR) { 64 | dbgf_sys(DBGT_ERR, "slen=%d tlen=%d z_ret=%d error: %s ???", slen, tlen, z_ret, strerror(errno)); 65 | tlen = FAILURE; 66 | break; 67 | } else { 68 | tlen += (Z_CHUNK_SIZE - strm.avail_out); 69 | } 70 | 71 | } while (strm.avail_out == 0); 72 | 73 | if (tmp && tlen > 0 && tlen < slen) { 74 | if (dst) { 75 | *dst = debugRealloc(*dst, dpos + tlen, -300574); 76 | memcpy(*dst + dpos, tmp, tlen); 77 | } 78 | if (darr && darr_max_size >= tlen) 79 | memcpy(darr, tmp, tlen); 80 | 81 | } else if (tmp && tlen >= slen) { 82 | tlen = 0; 83 | 84 | } else { 85 | tlen = FAILURE; 86 | } 87 | 88 | (void) deflateEnd(&strm); 89 | 90 | if (tmp) 91 | debugFree(tmp, -300575); 92 | 93 | dbgf(tlen >= 0 ? DBGL_CHANGES : DBGL_SYS, tlen >= 0 ? DBGT_INFO : DBGT_ERR, "slen=%d tlen=%d", slen, tlen); 94 | 95 | return tlen; 96 | } 97 | 98 | 99 | 100 | //decompress: 101 | 102 | /* 103 | * on success and when finished, returns new decompressed size and adds to (*dstA) + dpos 104 | * Therefore src and *dstA can point to same memory area. 105 | * on failure returns -1 and (*dstA) is untouched 106 | * if dstA == NULL then dstA is untouched 107 | */ 108 | int32_t z_decompress(uint8_t *src, uint32_t slen, uint8_t *dstB, uint32_t dstBlen) 109 | { 110 | 111 | int32_t tlen = 0; 112 | int z_ret; 113 | 114 | z_stream strm = { .zalloc = Z_NULL, .zfree = Z_NULL, .opaque = Z_NULL, .avail_in = 0, .next_in = Z_NULL }; 115 | 116 | if ((z_ret = inflateInit(&strm)) != Z_OK) 117 | return FAILURE; 118 | 119 | strm.avail_in = slen; 120 | strm.next_in = (Bytef*) src; 121 | 122 | strm.avail_out = dstBlen; 123 | strm.next_out = dstB; 124 | 125 | if ((((z_ret = inflate(&strm, Z_NO_FLUSH)) != Z_OK) && z_ret != Z_STREAM_END && strm.avail_out == 0)) { 126 | // if (err==Z_STREAM_ERROR || err==Z_NEED_DICT || err==Z_DATA_ERROR || err==Z_MEM_ERROR) { 127 | dbgf_sys(DBGT_ERR, "slen=%d tlen=%d avaoi_out=%d z_ret=%d error: %s ???", slen, tlen, strm.avail_out, z_ret, strerror(errno)); 128 | tlen = FAILURE; 129 | 130 | } else { 131 | 132 | tlen += (dstBlen - strm.avail_out); 133 | } 134 | 135 | // clean up and return: 136 | (void) inflateEnd(&strm); 137 | 138 | 139 | dbgf(tlen > 0 ? DBGL_CHANGES : DBGL_SYS, tlen > 0 ? DBGT_INFO : DBGT_ERR, "slen=%d tlen=%d", slen, tlen); 140 | 141 | return tlen; 142 | } 143 | -------------------------------------------------------------------------------- /src/z.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 Axel Neumann 3 | * This program is free software; you can redistribute it and/or 4 | * modify it under the terms of version 2 of the GNU General Public 5 | * License as published by the Free Software Foundation. 6 | * 7 | * This program is distributed in the hope that it will be useful, but 8 | * WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | * General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 15 | * 02110-1301, USA 16 | */ 17 | 18 | #define Z_CHUNK_SIZE (2*16384) 19 | 20 | 21 | int32_t z_compress(uint8_t *src, int32_t slen, uint8_t **dst, uint32_t dpos, uint8_t *darr, int32_t darr_max_size); 22 | int32_t z_decompress(uint8_t *src, uint32_t slen, uint8_t *dstB, uint32_t dstBlen); 23 | --------------------------------------------------------------------------------