nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1996 |
||
3 | * The Regents of the University of California. All rights reserved. |
||
4 | * |
||
5 | * Redistribution and use in source and binary forms, with or without |
||
6 | * modification, are permitted provided that: (1) source code distributions |
||
7 | * retain the above copyright notice and this paragraph in its entirety, (2) |
||
8 | * distributions including binary code include the above copyright notice and |
||
9 | * this paragraph in its entirety in the documentation or other materials |
||
10 | * provided with the distribution, and (3) all advertising materials mentioning |
||
11 | * features or use of this software display the following acknowledgement: |
||
12 | * ``This product includes software developed by the University of California, |
||
13 | * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of |
||
14 | * the University nor the names of its contributors may be used to endorse |
||
15 | * or promote products derived from this software without specific prior |
||
16 | * written permission. |
||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED |
||
18 | * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
||
20 | */ |
||
21 | |||
22 | #define NETDISSECT_REWORKED |
||
23 | #ifdef HAVE_CONFIG_H |
||
24 | #include "config.h" |
||
25 | #endif |
||
26 | |||
27 | #include <tcpdump-stdinc.h> |
||
28 | |||
29 | #include <stdio.h> |
||
30 | |||
31 | #include "interface.h" |
||
32 | #include "addrtoname.h" |
||
33 | #include "extract.h" /* must come after interface.h */ |
||
34 | |||
35 | #include "af.h" |
||
36 | |||
37 | static const char tstr[] = "[|rip]"; |
||
38 | |||
39 | struct rip { |
||
40 | uint8_t rip_cmd; /* request/response */ |
||
41 | uint8_t rip_vers; /* protocol version # */ |
||
42 | uint8_t unused[2]; /* unused */ |
||
43 | }; |
||
44 | |||
45 | #define RIPCMD_REQUEST 1 /* want info */ |
||
46 | #define RIPCMD_RESPONSE 2 /* responding to request */ |
||
47 | #define RIPCMD_TRACEON 3 /* turn tracing on */ |
||
48 | #define RIPCMD_TRACEOFF 4 /* turn it off */ |
||
49 | #define RIPCMD_POLL 5 /* want info from everybody */ |
||
50 | #define RIPCMD_POLLENTRY 6 /* poll for entry */ |
||
51 | |||
52 | static const struct tok rip_cmd_values[] = { |
||
53 | { RIPCMD_REQUEST, "Request" }, |
||
54 | { RIPCMD_RESPONSE, "Response" }, |
||
55 | { RIPCMD_TRACEON, "Trace on" }, |
||
56 | { RIPCMD_TRACEOFF, "Trace off" }, |
||
57 | { RIPCMD_POLL, "Poll" }, |
||
58 | { RIPCMD_POLLENTRY, "Poll Entry" }, |
||
59 | { 0, NULL} |
||
60 | }; |
||
61 | |||
62 | #define RIP_AUTHLEN 16 |
||
63 | #define RIP_ROUTELEN 20 |
||
64 | |||
65 | /* |
||
66 | * rfc 1723 |
||
67 | * |
||
68 | * 0 1 2 3 3 |
||
69 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
||
70 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
||
71 | * | Command (1) | Version (1) | unused | |
||
72 | * +---------------+---------------+-------------------------------+ |
||
73 | * | Address Family Identifier (2) | Route Tag (2) | |
||
74 | * +-------------------------------+-------------------------------+ |
||
75 | * | IP Address (4) | |
||
76 | * +---------------------------------------------------------------+ |
||
77 | * | Subnet Mask (4) | |
||
78 | * +---------------------------------------------------------------+ |
||
79 | * | Next Hop (4) | |
||
80 | * +---------------------------------------------------------------+ |
||
81 | * | Metric (4) | |
||
82 | * +---------------------------------------------------------------+ |
||
83 | * |
||
84 | */ |
||
85 | |||
86 | struct rip_netinfo { |
||
87 | uint16_t rip_family; |
||
88 | uint16_t rip_tag; |
||
89 | uint32_t rip_dest; |
||
90 | uint32_t rip_dest_mask; |
||
91 | uint32_t rip_router; |
||
92 | uint32_t rip_metric; /* cost of route */ |
||
93 | }; |
||
94 | |||
95 | static void |
||
96 | rip_entry_print_v1(netdissect_options *ndo, |
||
97 | register const struct rip_netinfo *ni) |
||
98 | { |
||
99 | register u_short family; |
||
100 | |||
101 | /* RFC 1058 */ |
||
102 | family = EXTRACT_16BITS(&ni->rip_family); |
||
103 | if (family != BSD_AFNUM_INET && family != 0) { |
||
104 | ND_PRINT((ndo, "\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family))); |
||
105 | print_unknown_data(ndo, (uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); |
||
106 | return; |
||
107 | } |
||
108 | if (EXTRACT_16BITS(&ni->rip_tag) || |
||
109 | EXTRACT_32BITS(&ni->rip_dest_mask) || |
||
110 | EXTRACT_32BITS(&ni->rip_router)) { |
||
111 | /* MBZ fields not zero */ |
||
112 | print_unknown_data(ndo, (uint8_t *)&ni->rip_family, "\n\t ", RIP_ROUTELEN); |
||
113 | return; |
||
114 | } |
||
115 | if (family == 0) { |
||
116 | ND_PRINT((ndo, "\n\t AFI 0, %s, metric: %u", |
||
117 | ipaddr_string(ndo, &ni->rip_dest), |
||
118 | EXTRACT_32BITS(&ni->rip_metric))); |
||
119 | return; |
||
120 | } /* BSD_AFNUM_INET */ |
||
121 | ND_PRINT((ndo, "\n\t %s, metric: %u", |
||
122 | ipaddr_string(ndo, &ni->rip_dest), |
||
123 | EXTRACT_32BITS(&ni->rip_metric))); |
||
124 | } |
||
125 | |||
126 | static unsigned |
||
127 | rip_entry_print_v2(netdissect_options *ndo, |
||
128 | register const struct rip_netinfo *ni, const unsigned remaining) |
||
129 | { |
||
130 | register u_short family; |
||
131 | |||
132 | family = EXTRACT_16BITS(&ni->rip_family); |
||
133 | if (family == 0xFFFF) { /* variable-sized authentication structures */ |
||
134 | uint16_t auth_type = EXTRACT_16BITS(&ni->rip_tag); |
||
135 | if (auth_type == 2) { |
||
136 | register u_char *p = (u_char *)&ni->rip_dest; |
||
137 | u_int i = 0; |
||
138 | ND_PRINT((ndo, "\n\t Simple Text Authentication data: ")); |
||
139 | for (; i < RIP_AUTHLEN; p++, i++) |
||
140 | ND_PRINT((ndo, "%c", ND_ISPRINT(*p) ? *p : '.')); |
||
141 | } else if (auth_type == 3) { |
||
142 | ND_PRINT((ndo, "\n\t Auth header:")); |
||
143 | ND_PRINT((ndo, " Packet Len %u,", EXTRACT_16BITS((uint8_t *)ni + 4))); |
||
144 | ND_PRINT((ndo, " Key-ID %u,", *((uint8_t *)ni + 6))); |
||
145 | ND_PRINT((ndo, " Auth Data Len %u,", *((uint8_t *)ni + 7))); |
||
146 | ND_PRINT((ndo, " SeqNo %u,", EXTRACT_32BITS(&ni->rip_dest_mask))); |
||
147 | ND_PRINT((ndo, " MBZ %u,", EXTRACT_32BITS(&ni->rip_router))); |
||
148 | ND_PRINT((ndo, " MBZ %u", EXTRACT_32BITS(&ni->rip_metric))); |
||
149 | } else if (auth_type == 1) { |
||
150 | ND_PRINT((ndo, "\n\t Auth trailer:")); |
||
151 | print_unknown_data(ndo, (uint8_t *)&ni->rip_dest, "\n\t ", remaining); |
||
152 | return remaining; /* AT spans till the packet end */ |
||
153 | } else { |
||
154 | ND_PRINT((ndo, "\n\t Unknown (%u) Authentication data:", |
||
155 | EXTRACT_16BITS(&ni->rip_tag))); |
||
156 | print_unknown_data(ndo, (uint8_t *)&ni->rip_dest, "\n\t ", remaining); |
||
157 | } |
||
158 | } else if (family != BSD_AFNUM_INET && family != 0) { |
||
159 | ND_PRINT((ndo, "\n\t AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family))); |
||
160 | print_unknown_data(ndo, (uint8_t *)&ni->rip_tag, "\n\t ", RIP_ROUTELEN-2); |
||
161 | } else { /* BSD_AFNUM_INET or AFI 0 */ |
||
162 | ND_PRINT((ndo, "\n\t AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ", |
||
163 | tok2str(bsd_af_values, "%u", family), |
||
164 | ipaddr_string(ndo, &ni->rip_dest), |
||
165 | mask2plen(EXTRACT_32BITS(&ni->rip_dest_mask)), |
||
166 | EXTRACT_16BITS(&ni->rip_tag), |
||
167 | EXTRACT_32BITS(&ni->rip_metric))); |
||
168 | if (EXTRACT_32BITS(&ni->rip_router)) |
||
169 | ND_PRINT((ndo, "%s", ipaddr_string(ndo, &ni->rip_router))); |
||
170 | else |
||
171 | ND_PRINT((ndo, "self")); |
||
172 | } |
||
173 | return sizeof (*ni); |
||
174 | } |
||
175 | |||
176 | void |
||
177 | rip_print(netdissect_options *ndo, |
||
178 | const u_char *dat, u_int length) |
||
179 | { |
||
180 | register const struct rip *rp; |
||
181 | register const struct rip_netinfo *ni; |
||
182 | register u_int i, j; |
||
183 | |||
184 | if (ndo->ndo_snapend < dat) { |
||
185 | ND_PRINT((ndo, " %s", tstr)); |
||
186 | return; |
||
187 | } |
||
188 | i = ndo->ndo_snapend - dat; |
||
189 | if (i > length) |
||
190 | i = length; |
||
191 | if (i < sizeof(*rp)) { |
||
192 | ND_PRINT((ndo, " %s", tstr)); |
||
193 | return; |
||
194 | } |
||
195 | i -= sizeof(*rp); |
||
196 | |||
197 | rp = (struct rip *)dat; |
||
198 | |||
199 | ND_PRINT((ndo, "%sRIPv%u", |
||
200 | (ndo->ndo_vflag >= 1) ? "\n\t" : "", |
||
201 | rp->rip_vers)); |
||
202 | |||
203 | switch (rp->rip_vers) { |
||
204 | case 0: |
||
205 | /* |
||
206 | * RFC 1058. |
||
207 | * |
||
208 | * XXX - RFC 1058 says |
||
209 | * |
||
210 | * 0 Datagrams whose version number is zero are to be ignored. |
||
211 | * These are from a previous version of the protocol, whose |
||
212 | * packet format was machine-specific. |
||
213 | * |
||
214 | * so perhaps we should just dump the packet, in hex. |
||
215 | */ |
||
216 | print_unknown_data(ndo, (uint8_t *)&rp->rip_cmd, "\n\t", length); |
||
217 | break; |
||
218 | default: |
||
219 | /* dump version and lets see if we know the commands name*/ |
||
220 | ND_PRINT((ndo, ", %s, length: %u", |
||
221 | tok2str(rip_cmd_values, |
||
222 | "unknown command (%u)", |
||
223 | rp->rip_cmd), |
||
224 | length)); |
||
225 | |||
226 | if (ndo->ndo_vflag < 1) |
||
227 | return; |
||
228 | |||
229 | switch (rp->rip_cmd) { |
||
230 | case RIPCMD_REQUEST: |
||
231 | case RIPCMD_RESPONSE: |
||
232 | j = length / sizeof(*ni); |
||
233 | ND_PRINT((ndo, ", routes: %u%s", j, rp->rip_vers == 2 ? " or less" : "")); |
||
234 | ni = (struct rip_netinfo *)(rp + 1); |
||
235 | for (; i >= sizeof(*ni); ++ni) { |
||
236 | if (rp->rip_vers == 1) |
||
237 | { |
||
238 | rip_entry_print_v1(ndo, ni); |
||
239 | i -= sizeof(*ni); |
||
240 | } |
||
241 | else if (rp->rip_vers == 2) |
||
242 | i -= rip_entry_print_v2(ndo, ni, i); |
||
243 | else |
||
244 | break; |
||
245 | } |
||
246 | if (i) |
||
247 | ND_PRINT((ndo, "%s", tstr)); |
||
248 | break; |
||
249 | |||
250 | case RIPCMD_TRACEOFF: |
||
251 | case RIPCMD_POLL: |
||
252 | case RIPCMD_POLLENTRY: |
||
253 | break; |
||
254 | |||
255 | case RIPCMD_TRACEON: |
||
256 | /* fall through */ |
||
257 | default: |
||
258 | if (ndo->ndo_vflag <= 1) { |
||
259 | if(!print_unknown_data(ndo, (uint8_t *)rp, "\n\t", length)) |
||
260 | return; |
||
261 | } |
||
262 | break; |
||
263 | } |
||
264 | /* do we want to see an additionally hexdump ? */ |
||
265 | if (ndo->ndo_vflag> 1) { |
||
266 | if(!print_unknown_data(ndo, (uint8_t *)rp, "\n\t", length)) |
||
267 | return; |
||
268 | } |
||
269 | } |
||
270 | } |
||
271 | |||
272 |