IPv6

From BroWiki

Jump to: navigation, search

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 .

Personal tools