1f8307e12SArchie Cobbs 2f8307e12SArchie Cobbs# 3f8307e12SArchie Cobbs# This is an example that shows how to send ASCII formatted control 4f8307e12SArchie Cobbs# messages to a node using ngctl(8). 5f8307e12SArchie Cobbs# 6f8307e12SArchie Cobbs# What we will do here create a divert(4) tap. This simply dumps 7f8307e12SArchie Cobbs# out all packets diverted by some ipfw(8) divert rule to the console. 8f8307e12SArchie Cobbs# 9f8307e12SArchie Cobbs# Lines that begin with ``$'' (shell prompt) or ``+'' (ngctl prompt) 10f8307e12SArchie Cobbs# indicate user input 11f8307e12SArchie Cobbs# 12f8307e12SArchie Cobbs 13f8307e12SArchie Cobbs# First, start up ngctl in interactive mode: 14f8307e12SArchie Cobbs 15f8307e12SArchie Cobbs $ ngctl 16f8307e12SArchie Cobbs Available commands: 17f8307e12SArchie Cobbs connect Connects hook <peerhook> of the node at <relpath> to <hook> 18f8307e12SArchie Cobbs debug Get/set debugging verbosity level 19f8307e12SArchie Cobbs help Show command summary or get more help on a specific command 20f8307e12SArchie Cobbs list Show information about all nodes 21f8307e12SArchie Cobbs mkpeer Create and connect a new node to the node at "path" 22f8307e12SArchie Cobbs msg Send a netgraph control message to the node at "path" 23f8307e12SArchie Cobbs name Assign name <name> to the node at <path> 24f8307e12SArchie Cobbs read Read and execute commands from a file 25f8307e12SArchie Cobbs rmhook Disconnect hook "hook" of the node at "path" 26f8307e12SArchie Cobbs show Show information about the node at <path> 27f8307e12SArchie Cobbs shutdown Shutdown the node at <path> 28f8307e12SArchie Cobbs status Get human readable status information from the node at <path> 29f8307e12SArchie Cobbs types Show information about all installed node types 30f8307e12SArchie Cobbs quit Exit program 31f8307e12SArchie Cobbs + 32f8307e12SArchie Cobbs 33*8624f434SGleb Smirnoff# Now let's create a ng_ksocket(4) node, in the family PF_DIVERT, 34*8624f434SGleb Smirnoff# of type SOCK_RAW: 35f8307e12SArchie Cobbs 36*8624f434SGleb Smirnoff + mkpeer ksocket foo divert/raw/0 37f8307e12SArchie Cobbs 38f8307e12SArchie Cobbs# Note that ``foo'' is the hook name on the socket node, which can be 39f8307e12SArchie Cobbs# anything. The ``inet/raw/divert'' is the hook name on the ksocket 40f8307e12SArchie Cobbs# node, which tells it what kind of socket to create. 41f8307e12SArchie Cobbs 42f8307e12SArchie Cobbs# Lets give our ksocket node a global name. How about ``fred'': 43f8307e12SArchie Cobbs 44f8307e12SArchie Cobbs + name foo fred 45f8307e12SArchie Cobbs 46f8307e12SArchie Cobbs# Note that we used ngctl's ``name'' command to do this. However, 47f8307e12SArchie Cobbs# the following manually constructed netgraph message would have 485665fe6bSUlrich Spörlein# accomplished the exact same thing: 49f8307e12SArchie Cobbs 50f8307e12SArchie Cobbs + msg foo name { name="fred" } 51f8307e12SArchie Cobbs 52f8307e12SArchie Cobbs# Here we are using the ASCII <-> binary control message conversion 53f8307e12SArchie Cobbs# routines. ngctl does this for us automatically when we use the 54f8307e12SArchie Cobbs# ``msg'' command. 55f8307e12SArchie Cobbs 56f8307e12SArchie Cobbs# Now lets bind the socket associated with the ksocket node to a port 57f8307e12SArchie Cobbs# supplied by the system. We do this by sending the ksocket node a 58f8307e12SArchie Cobbs# ``bind'' control message. Again, ngctl does the conversion of the 59f8307e12SArchie Cobbs# control message from ASCII to binary behind the scenes. 60f8307e12SArchie Cobbs 61f8307e12SArchie Cobbs + msg fred: bind inet/192.168.1.1 62f8307e12SArchie Cobbs 63f8307e12SArchie Cobbs# The ksocket accepts arbitrary sockaddr structures, but also has 64f8307e12SArchie Cobbs# special support for the PF_LOCAL and PF_INET protocol families. 65f8307e12SArchie Cobbs# That is why we can specify the struct sockaddr argument to the 66f8307e12SArchie Cobbs# ``bind'' command as ``inet/192.168.1.1'' (since we didn't specify 67f8307e12SArchie Cobbs# a port number, it's assumed to be zero). We could have also 68f8307e12SArchie Cobbs# relied on the generic sockaddr syntax and instead said this: 69f8307e12SArchie Cobbs 70f8307e12SArchie Cobbs + msg fred: bind { family=2 len=16 data=[ 2=192 168 1 1 ] } 71f8307e12SArchie Cobbs 72f8307e12SArchie Cobbs# This is what you would have to do for protocol families other 73f8307e12SArchie Cobbs# that PF_INET and PF_LOCAL, at least until special handling for 74f8307e12SArchie Cobbs# new ones is added. 75f8307e12SArchie Cobbs 76f8307e12SArchie Cobbs# The reason for the ``2=192'' is to skip the two byte IP port number, 77f8307e12SArchie Cobbs# which causes it to be set to zero, the default value for integral 78f8307e12SArchie Cobbs# types when parsing. Now since we didn't ask for a specific port 79f8307e12SArchie Cobbs# number, we need to do a ``getname'' to see what port number we got: 80f8307e12SArchie Cobbs 81f8307e12SArchie Cobbs + msg fred: getname 82f8307e12SArchie Cobbs Rec'd response "getname" (5) from "fred:": 83f8307e12SArchie Cobbs Args: inet/192.168.1.1:1029 84f8307e12SArchie Cobbs 85f8307e12SArchie Cobbs# As soon as we sent the message, we got back a response. Here 86f8307e12SArchie Cobbs# ngctl is telling us that it received a control message with the 875665fe6bSUlrich Spörlein# NGF_RESP (response) flag set, the response was to a prior ``getname'' 88f8307e12SArchie Cobbs# control message, that the originator was the node addressable 89f8307e12SArchie Cobbs# as ``fred:''. The message arguments field is then displayed to 90f8307e12SArchie Cobbs# us in its ASCII form. In this case, what we get back is a struct 91f8307e12SArchie Cobbs# sockaddr, and there we see that our port number is 1029. 92f8307e12SArchie Cobbs 93f8307e12SArchie Cobbs# So now let's add the ipfw divert rule for whatever packets we 94f8307e12SArchie Cobbs# want to see. How about anything from 192.168.1.129. 95f8307e12SArchie Cobbs 96f8307e12SArchie Cobbs + ^Z 97f8307e12SArchie Cobbs Suspended 98f8307e12SArchie Cobbs $ ipfw add 100 divert 1029 ip from 192.168.1.129 to any 99f8307e12SArchie Cobbs 00100 divert 1029 ip from 192.168.1.129 to any 100f8307e12SArchie Cobbs $ fg 101f8307e12SArchie Cobbs 102f8307e12SArchie Cobbs# Now watch what happens when we try to ping from that machine: 103f8307e12SArchie Cobbs 104f8307e12SArchie Cobbs + 105f8307e12SArchie Cobbs Rec'd data packet on hook "foo": 106f8307e12SArchie Cobbs 0000: 45 00 00 3c 57 00 00 00 20 01 bf ee c0 a8 01 81 E..<W... ....... 107f8307e12SArchie Cobbs 0010: c0 a8 01 01 08 00 49 5c 03 00 01 00 61 62 63 64 ......I\....abcd 108f8307e12SArchie Cobbs 0020: 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 efghijklmnopqrst 109f8307e12SArchie Cobbs 0030: 75 76 77 61 62 63 64 65 66 67 68 69 uvwabcdefghi 110f8307e12SArchie Cobbs + 111f8307e12SArchie Cobbs Rec'd data packet on hook "foo": 112f8307e12SArchie Cobbs 0000: 45 00 00 3c 58 00 00 00 20 01 be ee c0 a8 01 81 E..<X... ....... 113f8307e12SArchie Cobbs 0010: c0 a8 01 01 08 00 48 5c 03 00 02 00 61 62 63 64 ......H\....abcd 114f8307e12SArchie Cobbs 0020: 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 efghijklmnopqrst 115f8307e12SArchie Cobbs 0030: 75 76 77 61 62 63 64 65 66 67 68 69 uvwabcdefghi 116f8307e12SArchie Cobbs + 117f8307e12SArchie Cobbs Rec'd data packet on hook "foo": 118f8307e12SArchie Cobbs 0000: 45 00 00 3c 59 00 00 00 20 01 bd ee c0 a8 01 81 E..<Y... ....... 119f8307e12SArchie Cobbs 0010: c0 a8 01 01 08 00 47 5c 03 00 03 00 61 62 63 64 ......G\....abcd 120f8307e12SArchie Cobbs 0020: 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 efghijklmnopqrst 121f8307e12SArchie Cobbs 0030: 75 76 77 61 62 63 64 65 66 67 68 69 uvwabcdefghi 122f8307e12SArchie Cobbs + 123f8307e12SArchie Cobbs 124f8307e12SArchie Cobbs# So we're seeing the output from the ksocket socket appear on the ``foo'' 125f8307e12SArchie Cobbs# hook of ngctl's socket node. Since the packets are getting diverted, 126f8307e12SArchie Cobbs# the 192.168.1.129 machine doesn't see any response from us. 127f8307e12SArchie Cobbs 128f8307e12SArchie Cobbs# Of course, any type of socket can be used, even TCP: 129f8307e12SArchie Cobbs 130f8307e12SArchie Cobbs + mkpeer ksocket bar inet/stream/tcp 131f8307e12SArchie Cobbs + msg bar connect inet/192.168.1.33:13 132f8307e12SArchie Cobbs ngctl: send msg: Operation now in progress 133f8307e12SArchie Cobbs + 134f8307e12SArchie Cobbs Rec'd data packet on hook "foo": 135f8307e12SArchie Cobbs 0000: 4d 6f 6e 20 4e 6f 76 20 32 39 20 31 37 3a 34 38 Mon Nov 29 17:48 136f8307e12SArchie Cobbs 0010: 3a 33 37 20 31 39 39 39 0d 0a :37 1999.. 137f8307e12SArchie Cobbs + 138f8307e12SArchie Cobbs 139f8307e12SArchie Cobbs# Or, UNIX domain: 140f8307e12SArchie Cobbs 141f8307e12SArchie Cobbs + mkpeer ksocket bar local/stream/0 142f8307e12SArchie Cobbs + msg bar bind local/"/tmp/bar.socket" 143f8307e12SArchie Cobbs + 144f8307e12SArchie Cobbs 145f8307e12SArchie Cobbs# Here's an example of a more complicated ASCII control message argument. 146f8307e12SArchie Cobbs# If you look in /sys/netgraph/ng_message.h, you will see that a node 147f8307e12SArchie Cobbs# responds to a NGM_LISTHOOKS with a struct hooklist, which contains 148f8307e12SArchie Cobbs# an array of struct linkinfo: 149f8307e12SArchie Cobbs# 150f8307e12SArchie Cobbs# /* Structure used for NGM_LISTHOOKS */ 151f8307e12SArchie Cobbs# struct linkinfo { 15289624a34SHartmut Brandt# char ourhook[NG_HOOKSIZ]; /* hook name */ 15389624a34SHartmut Brandt# char peerhook[NG_HOOKSIZ]; /* peer hook */ 154f8307e12SArchie Cobbs# struct nodeinfo nodeinfo; 155f8307e12SArchie Cobbs# }; 156f8307e12SArchie Cobbs# 157f8307e12SArchie Cobbs# struct hooklist { 158f8307e12SArchie Cobbs# struct nodeinfo nodeinfo; /* node information */ 159f8307e12SArchie Cobbs# struct linkinfo link[0]; /* info about each hook */ 160f8307e12SArchie Cobbs# }; 161f8307e12SArchie Cobbs# 162f8307e12SArchie Cobbs# By sending a node the ``listhooks'' command using ngctl, we can see 163f8307e12SArchie Cobbs# this structure in ASCII form (lines wrapped for readability): 164f8307e12SArchie Cobbs 165f8307e12SArchie Cobbs + msg bar bind local/"/tmp/bar.socket" 166f8307e12SArchie Cobbs + msg bar listhooks 167f8307e12SArchie Cobbs Rec'd response "listhooks" (7) from "bar": 168f8307e12SArchie Cobbs Args: { nodeinfo={ type="ksocket" id=9 hooks=1 } 169f8307e12SArchie Cobbs linkinfo=[ { ourhook="local/stream/0" peerhook="bar" 170f8307e12SArchie Cobbs nodeinfo={ name="ngctl1327" type="socket" id=8 hooks=1 } } ] } 171f8307e12SArchie Cobbs 172f8307e12SArchie Cobbs 173