IPv6
From BroWiki
Contents |
Building Bro for IPv6 compatibility
Bro can be optionally configured using --enable-brov6 for compatibility with IPv6. When doing so, some internal data structures change to accommodate the larger addresses. (These changes are made conditional on IPv6 support rather than permanently because the larger addresses take up considerably more memory.) In addition, BROv6 is #define'd to be used in conditional code.
When configured for IPv6, if fed purely IPv4 traffic Bro's functionality should be unchanged.
Use of addr_type and subnet_type
The typedef addr_type serves as a general means for indirectly manipulating addresses (e.g., as parameters to function calls or values returned by functions) inside Bro. It is either uint32 (when Bro is only configured for IPv4) or uint32* (BROv6). The companion typedef, const_addr_type, is the const version of the type. Often your code will simply need to use this type rather than directly using uint32 to gain BROv6 compatibility, if you are not poking through addresses directly.
Similarly, the struct subnet_type lets you refer to subnet's in a general way, where the .net field holds the prefix bits of the subnet (either 32 packed into a single uint32, or 128 packed into uint32[4]). The .width field gives the length of the prefix (0..32 or 0..128).
Poking through addresses directly
If you need to directly manipulate addresses, you do so by using
- uint32 my_addr[NUM_ADDR_WORDS];
where NUM_ADDR_WORDS will either be 1 or 4.
IPv4 addresses embedded within an IPv6-compatible array of uint32's are placed in the last word (my_addr[3]) rather than the first. All other words are 0.
Functions to manipulate addresses
The following functions are available to manipulate addresses in a manner independent of whether BROv6 is configured:
- dotted_addr
- Takes either a uint32 address or a const uint32[] address and returns a string (in static storage) giving it's dotted quad representation (first form) or its generalized IPv6 representation (second form).
- dotted_net, dotted_net6
- The same for class A/B/C network prefixes, but are deprecated
- dotted_to_addr
- Takes a string and returns it as a uint32 address.
- dotted_to-addr6
- The same but returns a uint32* address (which has been new'd and should be deleted'd when you're done with it).
- is_v4_addr
- Returns true if the given 4-word address corresponds to an embedded IPv4 address, false otherwise. Note that this function only exists for BROv6, so must only be called in code that is #ifdef'd accordingly
- to_v4_addr
- Given an address of general type addr_type, returns a uint32 corresponding to the embedded IPv4 address (or simply the address itself, if not BROv6). Note that it is an internal error to call this function on a non-IPv4 address; you must first check for that case using is_v4_addr.
- mask_addr
- Takes either a uint32 or a const uint32* and a number of top bits to keep and returns the corresponding modified address. The second form returns a pointer to a static region.
- copy_addr
- Takes a const uint32* (so either the address of an addr_type for non-BROv6, or an addr_type itself for BROv6) and a target uint32* to which it copies the former. Only 1 word is copied for non-BROv6; 4 words for BROv6.
- addr_eq
- Returns true if two const uint32*'s denote the same address. For non-BROv6, this just means that the word they directly point to is the same. For BROv6, it means that the 4 words they point to are the same.
- subnet_eq
- Same, but for const subnet_type*'s.
Testing
To test whether your changes are IPv6-compatible, you should
- ./configure --enable-brov6
- make
- Most problems manifest already at this stage.
- make test
- Bro should pass the test suite in the same manner as when built without --enable-brov6
For a simple IPv6 trace to try, see devel-traces/http6.trace .
