dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / cmd-inet / usr.sbin / snoop / snoop_rip.c
blob38d83976c34ffc8160b08c0967297ca795a43bc1
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <stdio.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <fcntl.h>
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
36 #define RIPVERSION RIPv2
37 #include <protocols/routed.h>
38 #include "snoop.h"
40 static const char *show_cmd(int);
41 static int get_numtokens(unsigned int);
43 int
44 interpret_rip(int flags, struct rip *rip, int fraglen)
46 const struct netinfo *nip;
47 const struct entryinfo *ep;
48 const struct netauth *nap;
49 const struct rip_emetric *rep;
50 const uint32_t *tokp;
51 int len, count;
52 const char *cmdstr, *auth;
53 struct in_addr dst;
54 uint32_t mval;
55 const struct sockaddr_in *sin;
56 /* Room for IP destination + "/" + IP mask */
57 char addrstr[15+1+15+1];
58 /* Room for "RIPv" + uint8_t as %d */
59 char ripvers[4+3+1];
61 /* RIP header is 4 octets long */
62 if ((len = fraglen - 4) < 0)
63 return (0);
65 if (flags & F_SUM) {
66 switch (rip->rip_cmd) {
67 case RIPCMD_REQUEST: cmdstr = "C"; break;
68 case RIPCMD_RESPONSE: cmdstr = "R"; break;
69 case RIPCMD_TRACEON: cmdstr = "Traceon"; break;
70 case RIPCMD_TRACEOFF: cmdstr = "Traceoff"; break;
71 case RIPCMD_POLL: cmdstr = "Poll"; break;
72 case RIPCMD_POLLENTRY: cmdstr = "Poll entry"; break;
73 default: cmdstr = "?"; break;
76 if (rip->rip_vers == RIPv1)
77 (void) strlcpy(ripvers, "RIP", sizeof (ripvers));
78 else
79 (void) snprintf(ripvers, sizeof (ripvers), "RIPv%d",
80 rip->rip_vers);
82 switch (rip->rip_cmd) {
83 case RIPCMD_REQUEST:
84 case RIPCMD_RESPONSE:
85 case RIPCMD_POLL:
86 nip = rip->rip_nets;
87 auth = "";
88 if (len >= sizeof (*nip) &&
89 nip->n_family == RIP_AF_AUTH) {
90 nap = (struct netauth *)nip;
91 len -= sizeof (*nip);
92 if (nap->a_type == RIP_AUTH_MD5 &&
93 len >= ntohs(nap->au.a_md5.md5_auth_len))
94 len -= ntohs(nap->au.a_md5.
95 md5_auth_len);
96 auth = " +Auth";
98 count = len / sizeof (*nip);
99 len %= sizeof (*nip);
100 (void) snprintf(get_sum_line(), MAXLINE,
101 "%s %s (%d destinations%s%s)", ripvers, cmdstr,
102 count, (len != 0 ? "?" : ""), auth);
103 break;
105 case RIPCMD_TRACEON:
106 case RIPCMD_TRACEOFF:
107 (void) snprintf(get_sum_line(), MAXLINE,
108 "%s %s File=\"%.*s\"", ripvers, cmdstr, len,
109 rip->rip_tracefile);
110 len = 0;
111 break;
113 default:
114 (void) snprintf(get_sum_line(), MAXLINE,
115 "%s %d (%s)", ripvers, rip->rip_cmd, cmdstr);
116 len = 0;
117 break;
121 if (flags & F_DTAIL) {
123 len = fraglen - 4;
124 show_header("RIP: ", "Routing Information Protocol", fraglen);
125 show_space();
126 (void) snprintf(get_line(0, 0), get_line_remain(),
127 "Opcode = %d (%s)", rip->rip_cmd,
128 show_cmd(rip->rip_cmd));
129 (void) snprintf(get_line(0, 0), get_line_remain(),
130 "Version = %d", rip->rip_vers);
132 switch (rip->rip_cmd) {
133 case RIPCMD_REQUEST:
134 case RIPCMD_RESPONSE:
135 case RIPCMD_POLL:
136 show_space();
137 (void) snprintf(get_line(0, 0), get_line_remain(),
138 "Destination Next Hop "
139 "Tag Metric");
140 for (nip = rip->rip_nets; len >= sizeof (*nip); nip++,
141 len -= sizeof (*nip)) {
142 if (nip->n_family == RIP_AF_AUTH) {
143 nap = (const struct netauth *)nip;
144 if (nap->a_type == RIP_AUTH_NONE) {
145 (void) snprintf(get_line
146 ((char *)nip - dlc_header,
147 sizeof (*nip)),
148 get_line_remain(),
149 " *** Auth None");
150 } else if (nap->a_type == RIP_AUTH_PW) {
151 (void) snprintf(get_line
152 ((char *)nip - dlc_header,
153 sizeof (*nip)),
154 get_line_remain(),
155 " *** Auth PW \"%.*s\"",
156 RIP_AUTH_PW_LEN,
157 nap->au.au_pw);
158 } else if (nap->a_type ==
159 RIP_AUTH_MD5) {
160 (void) snprintf(get_line(0, 0),
161 get_line_remain(),
162 " *** Auth MD5 pkt len %d, "
163 "keyid %d, sequence %08lX, "
164 "authlen %d",
165 ntohs(nap->au.a_md5.
166 md5_pkt_len),
167 nap->au.a_md5.md5_keyid,
168 (long)ntohl(nap->au.a_md5.
169 md5_seqno),
170 ntohs(nap->au.a_md5.
171 md5_auth_len));
172 if (len - sizeof (*nip) >=
173 ntohs(nap->au.a_md5.
174 md5_auth_len))
175 len -= ntohs(nap->au.
176 a_md5.md5_auth_len);
177 else
178 len = sizeof (*nip);
179 } else {
180 (void) snprintf(get_line
181 ((char *)nip - dlc_header,
182 sizeof (*nip)),
183 get_line_remain(),
184 " *** Auth Type %d?",
185 ntohs(nap->a_type));
187 continue;
189 if (nip->n_family == RIP_AF_UNSPEC &&
190 rip->rip_cmd == RIPCMD_REQUEST) {
191 (void) snprintf(get_line(0, 0),
192 get_line_remain(),
193 " *** All routes");
194 continue;
196 if (nip->n_family != RIP_AF_INET) {
197 (void) snprintf(get_line(0, 0),
198 get_line_remain(),
199 " *** Address Family %d?",
200 ntohs(nip->n_family));
201 continue;
203 if (nip->n_dst == htonl(RIP_DEFAULT)) {
204 (void) strcpy(addrstr, "default");
205 } else {
206 dst.s_addr = nip->n_dst;
207 (void) strlcpy(addrstr, inet_ntoa(dst),
208 sizeof (addrstr));
210 if (nip->n_dst != htonl(RIP_DEFAULT) &&
211 rip->rip_vers >= RIPv2) {
212 count = strlen(addrstr);
213 mval = ntohl(nip->n_mask);
214 /* LINTED */
215 if (mval == INADDR_ANY) {
216 /* No mask */;
217 } else if ((mval + (mval & -mval)) ==
218 0) {
219 (void) snprintf(addrstr + count,
220 sizeof (addrstr) - count,
221 "/%d", 33 - ffs(mval));
222 } else {
223 dst.s_addr = nip->n_mask;
224 (void) snprintf(addrstr + count,
225 sizeof (addrstr) - count,
226 "/%s", inet_ntoa(dst));
229 dst.s_addr = nip->n_nhop;
230 mval = ntohl(nip->n_metric);
231 (void) snprintf(get_line(0, 0),
232 get_line_remain(),
233 "%-31s %-15s %-6d %d%s",
234 addrstr,
235 dst.s_addr == htonl(INADDR_ANY) ?
236 "--" : addrtoname(AF_INET, &dst),
237 ntohs(nip->n_tag),
238 mval,
239 (mval == HOPCNT_INFINITY ?
240 " (not reachable)" : ""));
242 break;
244 case RIPCMD_POLLENTRY:
245 if (len < sizeof (*ep))
246 break;
247 len -= sizeof (*ep);
248 ep = (const struct entryinfo *)rip->rip_nets;
249 /* LINTED */
250 sin = (const struct sockaddr_in *)&ep->rtu_dst;
251 (void) snprintf(get_line(0, 0), get_line_remain(),
252 "Destination = %s %s",
253 inet_ntoa(sin->sin_addr),
254 addrtoname(AF_INET, (void *)&sin->sin_addr));
255 /* LINTED */
256 sin = (const struct sockaddr_in *)&ep->rtu_router;
257 (void) snprintf(get_line(0, 0), get_line_remain(),
258 "Router = %s %s",
259 inet_ntoa(sin->sin_addr),
260 addrtoname(AF_INET, (void *)&sin->sin_addr));
261 (void) snprintf(get_line(0, 0), get_line_remain(),
262 "Flags = %4x", (unsigned)ep->rtu_flags);
263 (void) snprintf(get_line(0, 0), get_line_remain(),
264 "State = %d", ep->rtu_state);
265 (void) snprintf(get_line(0, 0), get_line_remain(),
266 "Timer = %d", ep->rtu_timer);
267 (void) snprintf(get_line(0, 0), get_line_remain(),
268 "Metric = %d", ep->rtu_metric);
269 (void) snprintf(get_line(0, 0), get_line_remain(),
270 "Int flags = %8x", ep->int_flags);
271 (void) snprintf(get_line(0, 0), get_line_remain(),
272 "Int name = \"%.*s\"", sizeof (ep->int_name),
273 ep->int_name);
274 break;
276 case RIPCMD_TRACEON:
277 case RIPCMD_TRACEOFF:
278 (void) snprintf(get_line(0, 0), get_line_remain(),
279 "Trace file = %.*s", len, rip->rip_tracefile);
280 len = 0;
281 break;
285 return (fraglen - len);
288 static const char *
289 show_cmd(int c)
291 switch (c) {
292 case RIPCMD_REQUEST:
293 return ("route request");
294 case RIPCMD_RESPONSE:
295 return ("route response");
296 case RIPCMD_TRACEON:
297 return ("route trace on");
298 case RIPCMD_TRACEOFF:
299 return ("route trace off");
300 case RIPCMD_POLL:
301 return ("route poll");
302 case RIPCMD_POLLENTRY:
303 return ("route poll entry");
305 return ("?");
308 static int
309 get_numtokens(unsigned int mask)
311 int num = 0;
313 while (mask != 0) {
314 num++;
315 mask &= mask - 1;
317 return (num);