ngctl revision 222179
153913Sarchie# $FreeBSD: head/share/examples/netgraph/ngctl 222179 2011-05-22 14:23:48Z uqs $ 253913Sarchie 353913Sarchie# 453913Sarchie# This is an example that shows how to send ASCII formatted control 553913Sarchie# messages to a node using ngctl(8). 653913Sarchie# 753913Sarchie# What we will do here create a divert(4) tap. This simply dumps 853913Sarchie# out all packets diverted by some ipfw(8) divert rule to the console. 953913Sarchie# 1053913Sarchie# Lines that begin with ``$'' (shell prompt) or ``+'' (ngctl prompt) 1153913Sarchie# indicate user input 1253913Sarchie# 1353913Sarchie 1453913Sarchie# First, start up ngctl in interactive mode: 1553913Sarchie 1653913Sarchie $ ngctl 1753913Sarchie Available commands: 1853913Sarchie connect Connects hook <peerhook> of the node at <relpath> to <hook> 1953913Sarchie debug Get/set debugging verbosity level 2053913Sarchie help Show command summary or get more help on a specific command 2153913Sarchie list Show information about all nodes 2253913Sarchie mkpeer Create and connect a new node to the node at "path" 2353913Sarchie msg Send a netgraph control message to the node at "path" 2453913Sarchie name Assign name <name> to the node at <path> 2553913Sarchie read Read and execute commands from a file 2653913Sarchie rmhook Disconnect hook "hook" of the node at "path" 2753913Sarchie show Show information about the node at <path> 2853913Sarchie shutdown Shutdown the node at <path> 2953913Sarchie status Get human readable status information from the node at <path> 3053913Sarchie types Show information about all installed node types 3153913Sarchie quit Exit program 3253913Sarchie + 3353913Sarchie 34120612Sjulian# Now let's create a ng_ksocket(4) node, in the family PF_INET, 3553913Sarchie# of type SOCK_RAW, and protocol IPPROTO_DIVERT: 3653913Sarchie 3753913Sarchie + mkpeer ksocket foo inet/raw/divert 3853913Sarchie 3953913Sarchie# Note that ``foo'' is the hook name on the socket node, which can be 4053913Sarchie# anything. The ``inet/raw/divert'' is the hook name on the ksocket 4153913Sarchie# node, which tells it what kind of socket to create. 4253913Sarchie 4353913Sarchie# Lets give our ksocket node a global name. How about ``fred'': 4453913Sarchie 4553913Sarchie + name foo fred 4653913Sarchie 4753913Sarchie# Note that we used ngctl's ``name'' command to do this. However, 4853913Sarchie# the following manually constructed netgraph message would have 49222179Suqs# accomplished the exact same thing: 5053913Sarchie 5153913Sarchie + msg foo name { name="fred" } 5253913Sarchie 5353913Sarchie# Here we are using the ASCII <-> binary control message conversion 5453913Sarchie# routines. ngctl does this for us automatically when we use the 5553913Sarchie# ``msg'' command. 5653913Sarchie 5753913Sarchie# Now lets bind the socket associated with the ksocket node to a port 5853913Sarchie# supplied by the system. We do this by sending the ksocket node a 5953913Sarchie# ``bind'' control message. Again, ngctl does the conversion of the 6053913Sarchie# control message from ASCII to binary behind the scenes. 6153913Sarchie 6253913Sarchie + msg fred: bind inet/192.168.1.1 6353913Sarchie 6453913Sarchie# The ksocket accepts arbitrary sockaddr structures, but also has 6553913Sarchie# special support for the PF_LOCAL and PF_INET protocol families. 6653913Sarchie# That is why we can specify the struct sockaddr argument to the 6753913Sarchie# ``bind'' command as ``inet/192.168.1.1'' (since we didn't specify 6853913Sarchie# a port number, it's assumed to be zero). We could have also 6953913Sarchie# relied on the generic sockaddr syntax and instead said this: 7053913Sarchie 7153913Sarchie + msg fred: bind { family=2 len=16 data=[ 2=192 168 1 1 ] } 7253913Sarchie 7353913Sarchie# This is what you would have to do for protocol families other 7453913Sarchie# that PF_INET and PF_LOCAL, at least until special handling for 7553913Sarchie# new ones is added. 7653913Sarchie 7753913Sarchie# The reason for the ``2=192'' is to skip the two byte IP port number, 7853913Sarchie# which causes it to be set to zero, the default value for integral 7953913Sarchie# types when parsing. Now since we didn't ask for a specific port 8053913Sarchie# number, we need to do a ``getname'' to see what port number we got: 8153913Sarchie 8253913Sarchie + msg fred: getname 8353913Sarchie Rec'd response "getname" (5) from "fred:": 8453913Sarchie Args: inet/192.168.1.1:1029 8553913Sarchie 8653913Sarchie# As soon as we sent the message, we got back a response. Here 8753913Sarchie# ngctl is telling us that it received a control message with the 88222179Suqs# NGF_RESP (response) flag set, the response was to a prior ``getname'' 8953913Sarchie# control message, that the originator was the node addressable 9053913Sarchie# as ``fred:''. The message arguments field is then displayed to 9153913Sarchie# us in its ASCII form. In this case, what we get back is a struct 9253913Sarchie# sockaddr, and there we see that our port number is 1029. 9353913Sarchie 9453913Sarchie# So now let's add the ipfw divert rule for whatever packets we 9553913Sarchie# want to see. How about anything from 192.168.1.129. 9653913Sarchie 9753913Sarchie + ^Z 9853913Sarchie Suspended 9953913Sarchie $ ipfw add 100 divert 1029 ip from 192.168.1.129 to any 10053913Sarchie 00100 divert 1029 ip from 192.168.1.129 to any 10153913Sarchie $ fg 10253913Sarchie 10353913Sarchie# Now watch what happens when we try to ping from that machine: 10453913Sarchie 10553913Sarchie + 10653913Sarchie Rec'd data packet on hook "foo": 10753913Sarchie 0000: 45 00 00 3c 57 00 00 00 20 01 bf ee c0 a8 01 81 E..<W... ....... 10853913Sarchie 0010: c0 a8 01 01 08 00 49 5c 03 00 01 00 61 62 63 64 ......I\....abcd 10953913Sarchie 0020: 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 efghijklmnopqrst 11053913Sarchie 0030: 75 76 77 61 62 63 64 65 66 67 68 69 uvwabcdefghi 11153913Sarchie + 11253913Sarchie Rec'd data packet on hook "foo": 11353913Sarchie 0000: 45 00 00 3c 58 00 00 00 20 01 be ee c0 a8 01 81 E..<X... ....... 11453913Sarchie 0010: c0 a8 01 01 08 00 48 5c 03 00 02 00 61 62 63 64 ......H\....abcd 11553913Sarchie 0020: 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 efghijklmnopqrst 11653913Sarchie 0030: 75 76 77 61 62 63 64 65 66 67 68 69 uvwabcdefghi 11753913Sarchie + 11853913Sarchie Rec'd data packet on hook "foo": 11953913Sarchie 0000: 45 00 00 3c 59 00 00 00 20 01 bd ee c0 a8 01 81 E..<Y... ....... 12053913Sarchie 0010: c0 a8 01 01 08 00 47 5c 03 00 03 00 61 62 63 64 ......G\....abcd 12153913Sarchie 0020: 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 efghijklmnopqrst 12253913Sarchie 0030: 75 76 77 61 62 63 64 65 66 67 68 69 uvwabcdefghi 12353913Sarchie + 12453913Sarchie 12553913Sarchie# So we're seeing the output from the ksocket socket appear on the ``foo'' 12653913Sarchie# hook of ngctl's socket node. Since the packets are getting diverted, 12753913Sarchie# the 192.168.1.129 machine doesn't see any response from us. 12853913Sarchie 12953913Sarchie# Of course, any type of socket can be used, even TCP: 13053913Sarchie 13153913Sarchie + mkpeer ksocket bar inet/stream/tcp 13253913Sarchie + msg bar connect inet/192.168.1.33:13 13353913Sarchie ngctl: send msg: Operation now in progress 13453913Sarchie + 13553913Sarchie Rec'd data packet on hook "foo": 13653913Sarchie 0000: 4d 6f 6e 20 4e 6f 76 20 32 39 20 31 37 3a 34 38 Mon Nov 29 17:48 13753913Sarchie 0010: 3a 33 37 20 31 39 39 39 0d 0a :37 1999.. 13853913Sarchie + 13953913Sarchie 14053913Sarchie# Or, UNIX domain: 14153913Sarchie 14253913Sarchie + mkpeer ksocket bar local/stream/0 14353913Sarchie + msg bar bind local/"/tmp/bar.socket" 14453913Sarchie + 14553913Sarchie 14653913Sarchie# Here's an example of a more complicated ASCII control message argument. 14753913Sarchie# If you look in /sys/netgraph/ng_message.h, you will see that a node 14853913Sarchie# responds to a NGM_LISTHOOKS with a struct hooklist, which contains 14953913Sarchie# an array of struct linkinfo: 15053913Sarchie# 15153913Sarchie# /* Structure used for NGM_LISTHOOKS */ 15253913Sarchie# struct linkinfo { 153122758Sharti# char ourhook[NG_HOOKSIZ]; /* hook name */ 154122758Sharti# char peerhook[NG_HOOKSIZ]; /* peer hook */ 15553913Sarchie# struct nodeinfo nodeinfo; 15653913Sarchie# }; 15753913Sarchie# 15853913Sarchie# struct hooklist { 15953913Sarchie# struct nodeinfo nodeinfo; /* node information */ 16053913Sarchie# struct linkinfo link[0]; /* info about each hook */ 16153913Sarchie# }; 16253913Sarchie# 16353913Sarchie# By sending a node the ``listhooks'' command using ngctl, we can see 16453913Sarchie# this structure in ASCII form (lines wrapped for readability): 16553913Sarchie 16653913Sarchie + msg bar bind local/"/tmp/bar.socket" 16753913Sarchie + msg bar listhooks 16853913Sarchie Rec'd response "listhooks" (7) from "bar": 16953913Sarchie Args: { nodeinfo={ type="ksocket" id=9 hooks=1 } 17053913Sarchie linkinfo=[ { ourhook="local/stream/0" peerhook="bar" 17153913Sarchie nodeinfo={ name="ngctl1327" type="socket" id=8 hooks=1 } } ] } 17253913Sarchie 17353913Sarchie 174