1.\" Copyright (c) 2006 Vadim Goncharov <vadimnuclight@tpu.ru> 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.Dd June 10, 2006 26.Dt NG_TAG 4 27.Os 28.Sh NAME 29.Nm ng_tag 30.Nd "mbuf tags manipulating netgraph node type" 31.Sh SYNOPSIS 32.In netgraph/ng_tag.h 33.Sh DESCRIPTION 34The 35.Nm tag 36node type allows mbuf packet tags (see 37.Xr mbuf_tags 9 ) 38to be examined, stripped or applied to data travelling through a 39Netgraph network. 40Mbuf tags are used in many parts of the 41.Fx 42kernel network subsystem, 43including the storage of VLAN tags as described in 44.Xr vlan 4 , 45Mandatory Access Control (MAC) labels as described in 46.Xr mac 9 , 47IPsec policy information as described in 48.Xr ipsec 4 , 49and packet filter tags used by 50.Xr pf 4 . 51One should also consider useful setting or checking 52.Xr ipfw 8 53tags, which are implemented as mbuf tags, too. 54.Pp 55Each node allows an arbitrary number of connections to arbitrarily 56named hooks. 57With each hook is associated a tag which will be searched in the list 58of all tags attached to a packet incoming to this hook, a destination hook 59for matching packets, a destination hook for non-matching packets, 60a tag which will be appended to data leaving node through this hook, 61and various statistics counters. 62.Pp 63The list of incoming packet's tags is traversed to find a tag with 64specified 65.Va type 66and 67.Va cookie 68values. 69Upon match, if specified 70.Va tag_len 71is non-zero, 72.Va tag_data 73of tag is checked to be identical to that specified in the hook structure. 74Packets with matched tags are forwarded to 75.Dq match 76destination hook, or forwarded to 77.Dq non-match 78hook otherwise. 79Either or both destination hooks can be an empty string, or may 80not exist, in which case the packet is dropped. 81.Pp 82Tag list of packets leaving the node is extended with a new tag 83specified in outgoing hook structure (it is possible to avoid appending 84a new tag to pass packet completely unchanged by specifying zero 85.Va type 86and 87.Va cookie 88values in the structure of the corresponding outgoing hook). 89Additionally, 90a tag can be stripped from incoming packet after match if 91.Va strip 92flag is set. 93This can be used for simple tag removal or tag replacement, if combined 94with tag addition on outgoing matching hook. 95Note that new tag is appended unconditionally, without checking if 96such a tag is already present in the list (it is up to user to check 97if this is a concern). 98.Pp 99New hooks are initially configured to drop all incoming packets 100(as all hook names are empty strings; zero values can be specified 101to forward all packets to non-matching hook), 102and to forward all outgoing packets without any tag appending. 103.Pp 104Data payload of packets passing through the node is completely 105unchanged, all operations can affect tag list only. 106.Sh HOOKS 107This node type supports any number of hooks having arbitrary names. 108In order to allow internal optimizations, user should never try to 109configure a hook with a structure pointing to hooks which do not exist yet. 110The safe way is to create all hooks first, then begin to configure them. 111.Sh CONTROL MESSAGES 112This node type supports the generic control messages, plus the following: 113.Bl -tag -width foo 114.It Dv NGM_TAG_SET_HOOKIN Pq Ic sethookin 115This command sets tag values which will be searched in the tag list of 116incoming packets on a hook. 117The following structure must be supplied as an argument: 118.Bd -literal -offset 4n 119struct ng_tag_hookin { 120 char thisHook[NG_HOOKSIZ]; /* name of hook */ 121 char ifMatch[NG_HOOKSIZ]; /* match dest hook */ 122 char ifNotMatch[NG_HOOKSIZ]; /* !match dest hook */ 123 uint8_t strip; /* strip tag if found */ 124 uint32_t tag_cookie; /* ABI/Module ID */ 125 uint16_t tag_id; /* tag ID */ 126 uint16_t tag_len; /* length of data */ 127 uint8_t tag_data[0]; /* tag data */ 128}; 129.Ed 130.Pp 131The hook to be updated is specified in 132.Va thisHook . 133Data bytes of tag corresponding to specified 134.Va tag_id 135(type) and 136.Va tag_cookie 137are placed in the 138.Va tag_data 139array; there must be 140.Va tag_len 141of them. 142Matching and non-matching incoming packets are delivered out the hooks named 143.Va ifMatch 144and 145.Va ifNotMatch , 146respectively. 147If 148.Va strip 149flag is non-zero, then found tag is deleted from list of packet tags. 150.It Dv NGM_TAG_GET_HOOKIN Pq Ic gethookin 151This command takes an ASCII string argument, the hook name, and returns the 152corresponding 153.Vt "struct ng_tag_hookin" 154as shown above. 155.It Dv NGM_TAG_SET_HOOKOUT Pq Ic sethookout 156This command sets tags values which will be applied to outgoing 157packets. 158The following structure must be supplied as an argument: 159.Bd -literal -offset 4n 160struct ng_tag_hookout { 161 char thisHook[NG_HOOKSIZ]; /* name of hook */ 162 uint32_t tag_cookie; /* ABI/Module ID */ 163 uint16_t tag_id; /* tag ID */ 164 uint16_t tag_len; /* length of data */ 165 uint8_t tag_data[0]; /* tag data */ 166}; 167.Ed 168.Pp 169The hook to be updated is specified in 170.Va thisHook . 171Other variables mean basically the same as in 172.Vt "struct ng_tag_hookin" 173shown above, except used for setting values in a new tag. 174.It Dv NGM_TAG_GET_HOOKOUT Pq Ic gethookout 175This command takes an ASCII string argument, the hook name, and returns the 176corresponding 177.Vt "struct ng_tag_hookout" 178as shown above. 179.It Dv NGM_TAG_GET_STATS Pq Ic getstats 180This command takes an ASCII string argument, the hook name, and returns the 181statistics associated with the hook as a 182.Vt "struct ng_tag_hookstat" . 183.It Dv NGM_TAG_CLR_STATS Pq Ic clrstats 184This command takes an ASCII string argument, the hook name, and clears the 185statistics associated with the hook. 186.It Dv NGM_TAG_GETCLR_STATS Pq Ic getclrstats 187This command is identical to 188.Dv NGM_TAG_GET_STATS , 189except that the statistics are also atomically cleared. 190.El 191.Pp 192.Em Note : 193statistics counters as well as three statistics messages above work 194only if code was compiled with the 195.Dv NG_TAG_DEBUG 196option. 197The reason for this is that statistics is rarely used in practice, 198but still consumes CPU cycles for every packet. 199Moreover, it is even not accurate on SMP systems due to lack of 200synchronization between threads, as this is very expensive. 201.Sh SHUTDOWN 202This node shuts down upon receipt of a 203.Dv NGM_SHUTDOWN 204control message, or when all hooks have been disconnected. 205.Sh EXAMPLES 206It is possible to do a simple L7 filtering by using 207.Xr ipfw 8 208tags in conjunction with 209.Xr ng_bpf 4 210traffic analyzer. 211Example below explains how to filter DirectConnect P2P network data traffic, 212which cannot be done by usual means as it uses random ports. 213It is known that such data connection always contains a TCP packet with 2146-byte payload string "$Send|". 215So ipfw's 216.Cm netgraph 217action will be used to divert all TCP packets to an 218.Xr ng_bpf 4 219node which will check for the specified string and return non-matching 220packets to 221.Xr ipfw 8 . 222Matching packets are passed to 223.Nm 224node, which will set a tag and pass them back to 225.Xr ng_bpf 4 226node on a hook programmed to accept all packets and pass them back to 227.Xr ipfw 8 . 228A script provided in 229.Xr ng_bpf 4 230manual page will be used for programming node. 231Note that packets diverted from 232.Xr ipfw 8 233to Netgraph have no link-level header, so offsets in 234.Xr tcpdump 1 235expressions must be altered accordingly. 236Thus, there will be expression 237.Dq Li "ether[40:2]=0x244c && ether[42:4]=0x6f636b20" 238on incoming hook and empty expression to match all packets from 239.Nm . 240.Pp 241So, this is 242.Xr ngctl 8 243script for nodes creating and naming for easier access: 244.Bd -literal -offset 4n 245/usr/sbin/ngctl -f- <<-SEQ 246 mkpeer ipfw: bpf 41 ipfw 247 name ipfw:41 dcbpf 248 mkpeer dcbpf: tag matched th1 249 name dcbpf:matched ngdc 250SEQ 251.Ed 252.Pp 253Now 254.Dq Li ngdc 255node (which is of type 256.Nm ) 257must be programmed to echo all packets received on the 258.Dq Li th1 259hook back, with the 260.Xr ipfw 8 261tag 412 attached. 262.Dv MTAG_IPFW 263value for 264.Va tag_cookie 265was taken from file 266.In netinet/ip_fw.h 267and value for 268.Va tag_id 269is tag number (412), with zero tag length: 270.Bd -literal -offset 4n 271ngctl msg ngdc: sethookin { thisHook=\e"th1\e" ifNotMatch=\e"th1\e" } 272ngctl msg ngdc: sethookout { thisHook=\e"th1\e" \e 273 tag_cookie=1148380143 \e 274 tag_id=412 } 275.Ed 276.Pp 277Do not forget to program 278.Xr ng_bpf 4 279.Dq Li ipfw 280hook with the above expression (see 281.Xr ng_bpf 4 282for script doing this) and 283.Dq Li matched 284hook with an empty expression: 285.Bd -literal -offset 4n 286ngctl msg dcbpf: setprogram { thisHook=\e"matched\e" ifMatch=\e"ipfw\e" \e 287 bpf_prog_len=1 bpf_prog=[ { code=6 k=8192 } ] } 288.Ed 289.Pp 290After finishing with 291.Xr netgraph 4 292nodes, 293.Xr ipfw 8 294rules must be added to enable packet flow: 295.Bd -literal -offset 4n 296ipfw add 100 netgraph 41 tcp from any to any iplen 46 297ipfw add 110 reset tcp from any to any tagged 412 298.Ed 299.Pp 300Note: one should ensure that packets are returned to ipfw after processing 301inside 302.Xr netgraph 4 , 303by setting appropriate 304.Xr sysctl 8 305variable: 306.Bd -literal -offset 4n 307sysctl net.inet.ip.fw.one_pass=0 308.Ed 309.Sh SEE ALSO 310.Xr netgraph 4 , 311.Xr ng_bpf 4 , 312.Xr ng_ipfw 4 , 313.Xr ipfw 8 , 314.Xr ngctl 8 , 315.Xr mbuf_tags 9 316.Sh HISTORY 317The 318.Nm 319node type was implemented in 320.Fx 6.2 . 321.Sh AUTHORS 322.An Vadim Goncharov Aq Mt vadimnuclight@tpu.ru 323.Sh BUGS 324For manipulating any tags with data payload (that is, all tags with non-zero 325.Va tag_len ) 326one should care about non-portable machine-dependent representation of 327tags on the low level as byte stream. 328Perhaps this should be done by another program rather than manually. 329