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