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