Merge from vendor branch FILE:
[dragonfly.git] / share / examples / netgraph / ngctl
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.2 2003/06/17 04:36:57 dillon 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_HOOKLEN + 1];        /* hook name */
155 #             char            peerhook[NG_HOOKLEN + 1];       /* 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