Print this page
dccp: options and features
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c
+++ new/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 #include <stdio.h>
27 27 #include <stdlib.h>
28 28 #include <strings.h>
29 29 #include <sys/sysmacros.h>
30 30 #include <sys/types.h>
31 31 #include <sys/errno.h>
32 32 #include <setjmp.h>
33 33 #include <sys/socket.h>
34 34 #include <net/if.h>
35 35 #include <netinet/in_systm.h>
36 36 #include <netinet/in.h>
37 37 #include <netinet/ip.h>
38 38 #include <netinet/if_ether.h>
39 39 #include "snoop.h"
40 40
41 41 struct porttable {
42 42 int pt_num;
43 43 char *pt_short;
44 44 };
45 45
46 46 static const struct porttable pt_udp[] = {
47 47 { IPPORT_ECHO, "ECHO" },
48 48 { IPPORT_DISCARD, "DISCARD" },
49 49 { IPPORT_DAYTIME, "DAYTIME" },
50 50 { IPPORT_CHARGEN, "CHARGEN" },
51 51 { IPPORT_TIMESERVER, "TIME" },
52 52 { IPPORT_NAMESERVER, "NAME" },
53 53 { IPPORT_DOMAIN, "DNS" },
54 54 { IPPORT_MDNS, "MDNS" },
55 55 { IPPORT_BOOTPS, "BOOTPS" },
56 56 { IPPORT_BOOTPC, "BOOTPC" },
57 57 { IPPORT_TFTP, "TFTP" },
58 58 { IPPORT_FINGER, "FINGER" },
59 59 /* { 111, "PORTMAP" }, Just Sun RPC */
60 60 { IPPORT_NTP, "NTP" },
61 61 { IPPORT_NETBIOS_NS, "NBNS" },
62 62 { IPPORT_NETBIOS_DGM, "NBDG" },
63 63 { IPPORT_LDAP, "LDAP" },
64 64 { IPPORT_SLP, "SLP" },
65 65 /* Mobile IP defines a set of new control messages sent over UDP port 434 */
66 66 { IPPORT_MIP, "Mobile IP" },
67 67 { IPPORT_BIFFUDP, "BIFF" },
68 68 { IPPORT_WHOSERVER, "WHO" },
69 69 { IPPORT_SYSLOG, "SYSLOG" },
70 70 { IPPORT_TALK, "TALK" },
71 71 { IPPORT_ROUTESERVER, "RIP" },
72 72 { IPPORT_RIPNG, "RIPng" },
73 73 { IPPORT_DHCPV6C, "DHCPv6C" },
74 74 { IPPORT_DHCPV6S, "DHCPv6S" },
75 75 { 550, "NEW-RWHO" },
76 76 { 560, "RMONITOR" },
77 77 { 561, "MONITOR" },
78 78 { IPPORT_SOCKS, "SOCKS" },
79 79 { 0, NULL }
80 80 };
81 81
82 82 static struct porttable pt_tcp[] = {
83 83 { 1, "TCPMUX" },
84 84 { IPPORT_ECHO, "ECHO" },
85 85 { IPPORT_DISCARD, "DISCARD" },
86 86 { IPPORT_SYSTAT, "SYSTAT" },
87 87 { IPPORT_DAYTIME, "DAYTIME" },
88 88 { IPPORT_NETSTAT, "NETSTAT" },
89 89 { IPPORT_CHARGEN, "CHARGEN" },
90 90 { 20, "FTP-DATA" },
91 91 { IPPORT_FTP, "FTP" },
92 92 { IPPORT_TELNET, "TELNET" },
93 93 { IPPORT_SMTP, "SMTP" },
94 94 { IPPORT_TIMESERVER, "TIME" },
95 95 { 39, "RLP" },
96 96 { IPPORT_NAMESERVER, "NAMESERVER" },
97 97 { IPPORT_WHOIS, "NICNAME" },
98 98 { IPPORT_DOMAIN, "DNS" },
99 99 { 70, "GOPHER" },
100 100 { IPPORT_RJE, "RJE" },
101 101 { IPPORT_FINGER, "FINGER" },
102 102 { IPPORT_HTTP, "HTTP" },
103 103 { IPPORT_TTYLINK, "LINK" },
104 104 { IPPORT_SUPDUP, "SUPDUP" },
105 105 { 101, "HOSTNAME" },
106 106 { 102, "ISO-TSAP" },
107 107 { 103, "X400" },
108 108 { 104, "X400-SND" },
109 109 { 105, "CSNET-NS" },
110 110 { 109, "POP-2" },
111 111 /* { 111, "PORTMAP" }, Just Sun RPC */
112 112 { 113, "AUTH" },
113 113 { 117, "UUCP-PATH" },
114 114 { 119, "NNTP" },
115 115 { IPPORT_NTP, "NTP" },
116 116 { IPPORT_NETBIOS_SSN, "NBT" },
117 117 { 143, "IMAP" },
118 118 { 144, "NeWS" },
119 119 { IPPORT_LDAP, "LDAP" },
120 120 { IPPORT_SLP, "SLP" },
121 121 { 443, "HTTPS" },
122 122 { 445, "SMB" },
123 123 { IPPORT_EXECSERVER, "EXEC" },
124 124 { IPPORT_LOGINSERVER, "RLOGIN" },
125 125 { IPPORT_CMDSERVER, "RSHELL" },
126 126 { IPPORT_PRINTER, "PRINTER" },
127 127 { 530, "COURIER" },
128 128 { 540, "UUCP" },
129 129 { 600, "PCSERVER" },
130 130 { IPPORT_SOCKS, "SOCKS" },
131 131 { 1524, "INGRESLOCK" },
132 132 { 2904, "M2UA" },
133 133 { 2905, "M3UA" },
134 134 { 6000, "XWIN" },
135 135 { IPPORT_HTTP_ALT, "HTTP (proxy)" },
↓ open down ↓ |
135 lines elided |
↑ open up ↑ |
136 136 { 9900, "IUA" },
137 137 { 0, NULL },
138 138 };
139 139
140 140 char *
141 141 getportname(int proto, in_port_t port)
142 142 {
143 143 const struct porttable *p, *pt;
144 144
145 145 switch (proto) {
146 - case IPPROTO_SCTP: /* fallthru */
146 + case IPPROTO_DCCP: /* fallthru */
147 + case IPPROTO_SCTP:
147 148 case IPPROTO_TCP: pt = pt_tcp; break;
148 149 case IPPROTO_UDP: pt = pt_udp; break;
149 150 default: return (NULL);
150 151 }
151 152
152 153 for (p = pt; p->pt_num; p++) {
153 154 if (port == p->pt_num)
154 155 return (p->pt_short);
155 156 }
156 157 return (NULL);
157 158 }
158 159
159 160 int
160 161 reservedport(int proto, int port)
161 162 {
162 163 const struct porttable *p, *pt;
163 164
164 165 switch (proto) {
165 166 case IPPROTO_TCP: pt = pt_tcp; break;
166 167 case IPPROTO_UDP: pt = pt_udp; break;
167 168 default: return (NULL);
168 169 }
169 170 for (p = pt; p->pt_num; p++) {
170 171 if (port == p->pt_num)
171 172 return (1);
172 173 }
173 174 return (0);
174 175 }
175 176
176 177 /*
177 178 * Need to be able to register an
178 179 * interpreter for transient ports.
179 180 * See TFTP interpreter.
180 181 */
181 182 #define MAXTRANS 64
182 183 static struct ttable {
183 184 int t_port;
184 185 int (*t_proc)(int, char *, int);
185 186 } transients [MAXTRANS];
186 187
187 188 int
188 189 add_transient(int port, int (*proc)(int, char *, int))
189 190 {
190 191 static struct ttable *next = transients;
191 192
192 193 next->t_port = port;
193 194 next->t_proc = proc;
194 195
195 196 if (++next >= &transients[MAXTRANS])
196 197 next = transients;
197 198
198 199 return (1);
199 200 }
200 201
201 202 static struct ttable *
202 203 is_transient(int port)
203 204 {
204 205 struct ttable *p;
205 206
206 207 for (p = transients; p->t_port && p < &transients[MAXTRANS]; p++) {
207 208 if (port == p->t_port)
208 209 return (p);
209 210 }
210 211
211 212 return (NULL);
212 213 }
213 214
214 215 void
215 216 del_transient(int port)
216 217 {
217 218 struct ttable *p;
218 219
219 220 for (p = transients; p->t_port && p < &transients[MAXTRANS]; p++) {
220 221 if (port == p->t_port)
221 222 p->t_port = -1;
222 223 }
223 224 }
224 225
225 226 static void
226 227 interpret_syslog(int flags, char dir, int port, const char *syslogstr,
227 228 int dlen)
228 229 {
229 230 static const char *pris[] = {
230 231 "emerg", "alert", "crit", "error", "warn", "notice", "info", "debug"
231 232 };
232 233 static const char *facs[] = {
233 234 "kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news",
234 235 "uucp", NULL, NULL, NULL, NULL, "audit", NULL, "cron", "local0",
235 236 "local1", "local2", "local3", "local4", "local5", "local6", "local7"
236 237 };
237 238
238 239 int composit;
239 240 int pri = -1;
240 241 int facil = -1;
241 242 boolean_t bogus = B_TRUE;
242 243 int priostrlen = 0;
243 244 int datalen = dlen;
244 245 char unknown[4]; /* for unrecognized ones */
245 246 const char *facilstr = "BAD";
246 247 const char *pristr = "FMT";
247 248 const char *data = syslogstr;
248 249
249 250 /*
250 251 * Is there enough data to interpret (left bracket + at least 3 chars
251 252 * which could be digits, right bracket, or space)?
252 253 */
253 254 if (datalen >= 4 && data != NULL) {
254 255 if (*data == '<') {
255 256 const int FACS_LEN = sizeof (facs) / sizeof (facs[0]);
256 257 char buffer[4];
257 258 char *end;
258 259
259 260 data++;
260 261 datalen--;
261 262
262 263 (void) strlcpy(buffer, data, sizeof (buffer));
263 264 composit = strtoul(buffer, &end, 0);
264 265 data += end - buffer;
265 266 if (*data == '>') {
266 267 data++;
267 268 datalen -= end - buffer + 1;
268 269
269 270 pri = composit & 0x7;
270 271 facil = (composit & 0xF8) >> 3;
271 272
272 273 if ((facil >= FACS_LEN) ||
273 274 (facs[facil] == NULL)) {
274 275 snprintf(unknown, sizeof (unknown),
275 276 "%d", facil);
276 277 facilstr = unknown;
277 278 } else {
278 279 facilstr = facs[facil];
279 280 }
280 281 pristr = pris[pri];
281 282 priostrlen = dlen - datalen;
282 283 bogus = B_FALSE;
283 284 } else {
284 285 data = syslogstr;
285 286 datalen = dlen;
286 287 }
287 288 }
288 289 }
289 290
290 291 if (flags & F_SUM) {
291 292 (void) snprintf(get_sum_line(), MAXLINE,
292 293 "SYSLOG %c port=%d %s.%s: %s",
293 294 dir, port, facilstr, pristr,
294 295 show_string(syslogstr, dlen, 20));
295 296
296 297 }
297 298
298 299 if (flags & F_DTAIL) {
299 300 static char syslog[] = "SYSLOG: ";
300 301 show_header(syslog, syslog, dlen);
301 302 show_space();
302 303 (void) snprintf(get_detail_line(0, 0), MAXLINE,
303 304 "%s%sPriority: %.*s%s(%s.%s)", prot_nest_prefix, syslog,
304 305 priostrlen, syslogstr, bogus ? "" : " ",
305 306 facilstr, pristr);
306 307 (void) snprintf(get_line(0, 0), get_line_remain(),
307 308 "\"%s\"",
308 309 show_string(syslogstr, dlen, 60));
309 310 show_trailer();
310 311 }
311 312 }
312 313
313 314 int src_port, dst_port, curr_proto;
314 315
315 316 int
316 317 interpret_reserved(int flags, int proto, in_port_t src, in_port_t dst,
317 318 char *data, int dlen)
318 319 {
319 320 const char *pn;
320 321 int dir, port, which;
321 322 char pbuff[16], hbuff[32];
322 323 struct ttable *ttabp;
323 324
324 325 src_port = src;
325 326 dst_port = dst;
326 327 curr_proto = proto;
327 328
328 329 pn = getportname(proto, src);
329 330 if (pn != NULL) {
330 331 dir = 'R';
331 332 port = dst;
332 333 which = src;
333 334 } else {
334 335 pn = getportname(proto, dst);
335 336 if (pn == NULL) {
336 337 ttabp = is_transient(src);
337 338 if (ttabp) {
338 339 (ttabp->t_proc)(flags, data, dlen);
339 340 return (1);
340 341 }
341 342 ttabp = is_transient(dst);
342 343 if (ttabp) {
343 344 (ttabp->t_proc)(flags, data, dlen);
344 345 return (1);
345 346 }
346 347 return (0);
347 348 }
348 349
349 350 dir = 'C';
350 351 port = src;
351 352 which = dst;
352 353 }
353 354
354 355 if ((dst == IPPORT_DOMAIN || src == IPPORT_DOMAIN ||
355 356 dst == IPPORT_MDNS || src == IPPORT_MDNS) &&
356 357 proto != IPPROTO_TCP) {
357 358 interpret_dns(flags, proto, (uchar_t *)data, dlen, which);
358 359 return (1);
359 360 }
360 361
361 362 if (dst == IPPORT_SYSLOG && proto != IPPROTO_TCP) {
362 363 /*
363 364 * TCP port 514 is rshell. UDP port 514 is syslog.
364 365 */
365 366 interpret_syslog(flags, dir, port, (const char *)data, dlen);
366 367 return (1);
367 368 }
368 369
369 370 if (dlen > 0) {
370 371 switch (which) {
371 372 case IPPORT_BOOTPS:
372 373 case IPPORT_BOOTPC:
373 374 (void) interpret_dhcp(flags, (struct dhcp *)data,
374 375 dlen);
375 376 return (1);
376 377 case IPPORT_DHCPV6S:
377 378 case IPPORT_DHCPV6C:
378 379 (void) interpret_dhcpv6(flags, (uint8_t *)data, dlen);
379 380 return (1);
380 381 case IPPORT_TFTP:
381 382 (void) interpret_tftp(flags, (struct tftphdr *)data,
382 383 dlen);
383 384 return (1);
384 385 case IPPORT_HTTP:
385 386 case IPPORT_HTTP_ALT:
386 387 (void) interpret_http(flags, data, dlen);
387 388 return (1);
388 389 case IPPORT_NTP:
389 390 (void) interpret_ntp(flags, (struct ntpdata *)data,
390 391 dlen);
391 392 return (1);
392 393 case IPPORT_NETBIOS_NS:
393 394 interpret_netbios_ns(flags, (uchar_t *)data, dlen);
394 395 return (1);
395 396 case IPPORT_NETBIOS_DGM:
396 397 interpret_netbios_datagram(flags, (uchar_t *)data,
397 398 dlen);
398 399 return (1);
399 400 case IPPORT_NETBIOS_SSN:
400 401 case 445:
401 402 /*
402 403 * SMB on port 445 is a subset of NetBIOS SMB
403 404 * on port 139. The same interpreter can be used
404 405 * for both.
405 406 */
406 407 interpret_netbios_ses(flags, (uchar_t *)data, dlen);
407 408 return (1);
408 409 case IPPORT_LDAP:
409 410 interpret_ldap(flags, data, dlen, src, dst);
410 411 return (1);
411 412 case IPPORT_SLP:
412 413 interpret_slp(flags, data, dlen);
413 414 return (1);
414 415 case IPPORT_MIP:
415 416 interpret_mip_cntrlmsg(flags, (uchar_t *)data, dlen);
416 417 return (1);
417 418 case IPPORT_ROUTESERVER:
418 419 (void) interpret_rip(flags, (struct rip *)data, dlen);
419 420 return (1);
420 421 case IPPORT_RIPNG:
421 422 (void) interpret_rip6(flags, (struct rip6 *)data,
422 423 dlen);
423 424 return (1);
424 425 case IPPORT_SOCKS:
425 426 if (dir == 'C')
426 427 (void) interpret_socks_call(flags, data, dlen);
427 428 else
428 429 (void) interpret_socks_reply(flags, data,
429 430 dlen);
430 431 return (1);
431 432 }
432 433 }
433 434
434 435 if (flags & F_SUM) {
435 436 (void) snprintf(get_sum_line(), MAXLINE,
436 437 "%s %c port=%d %s",
437 438 pn, dir, port,
438 439 show_string(data, dlen, 20));
439 440 }
440 441
441 442 if (flags & F_DTAIL) {
442 443 (void) snprintf(pbuff, sizeof (pbuff), "%s: ", pn);
443 444 (void) snprintf(hbuff, sizeof (hbuff), "%s: ", pn);
444 445 show_header(pbuff, hbuff, dlen);
445 446 show_space();
446 447 (void) snprintf(get_line(0, 0), get_line_remain(),
447 448 "\"%s\"",
448 449 show_string(data, dlen, 60));
449 450 show_trailer();
450 451 }
451 452 return (1);
452 453 }
↓ open down ↓ |
296 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX