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]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
29 #include <sys/sysmacros.h>
30 #include <sys/types.h>
31 #include <sys/errno.h>
33 #include <sys/socket.h>
35 #include <netinet/in_systm.h>
36 #include <netinet/in.h>
37 #include <netinet/ip.h>
38 #include <netinet/if_ether.h>
46 static const struct porttable pt_udp
[] = {
47 { IPPORT_ECHO
, "ECHO" },
48 { IPPORT_DISCARD
, "DISCARD" },
49 { IPPORT_DAYTIME
, "DAYTIME" },
50 { IPPORT_CHARGEN
, "CHARGEN" },
51 { IPPORT_TIMESERVER
, "TIME" },
52 { IPPORT_NAMESERVER
, "NAME" },
53 { IPPORT_DOMAIN
, "DNS" },
54 { IPPORT_MDNS
, "MDNS" },
55 { IPPORT_BOOTPS
, "BOOTPS" },
56 { IPPORT_BOOTPC
, "BOOTPC" },
57 { IPPORT_TFTP
, "TFTP" },
58 { IPPORT_FINGER
, "FINGER" },
59 /* { 111, "PORTMAP" }, Just Sun RPC */
60 { IPPORT_NTP
, "NTP" },
61 { IPPORT_NETBIOS_NS
, "NBNS" },
62 { IPPORT_NETBIOS_DGM
, "NBDG" },
63 { IPPORT_LDAP
, "LDAP" },
64 { IPPORT_SLP
, "SLP" },
65 /* Mobile IP defines a set of new control messages sent over UDP port 434 */
66 { IPPORT_MIP
, "Mobile IP" },
67 { IPPORT_BIFFUDP
, "BIFF" },
68 { IPPORT_WHOSERVER
, "WHO" },
69 { IPPORT_SYSLOG
, "SYSLOG" },
70 { IPPORT_TALK
, "TALK" },
71 { IPPORT_ROUTESERVER
, "RIP" },
72 { IPPORT_RIPNG
, "RIPng" },
73 { IPPORT_DHCPV6C
, "DHCPv6C" },
74 { IPPORT_DHCPV6S
, "DHCPv6S" },
78 { IPPORT_SOCKS
, "SOCKS" },
82 static struct porttable pt_tcp
[] = {
84 { IPPORT_ECHO
, "ECHO" },
85 { IPPORT_DISCARD
, "DISCARD" },
86 { IPPORT_SYSTAT
, "SYSTAT" },
87 { IPPORT_DAYTIME
, "DAYTIME" },
88 { IPPORT_NETSTAT
, "NETSTAT" },
89 { IPPORT_CHARGEN
, "CHARGEN" },
91 { IPPORT_FTP
, "FTP" },
92 { IPPORT_TELNET
, "TELNET" },
93 { IPPORT_SMTP
, "SMTP" },
94 { IPPORT_TIMESERVER
, "TIME" },
96 { IPPORT_NAMESERVER
, "NAMESERVER" },
97 { IPPORT_WHOIS
, "NICNAME" },
98 { IPPORT_DOMAIN
, "DNS" },
100 { IPPORT_RJE
, "RJE" },
101 { IPPORT_FINGER
, "FINGER" },
102 { IPPORT_HTTP
, "HTTP" },
103 { IPPORT_TTYLINK
, "LINK" },
104 { IPPORT_SUPDUP
, "SUPDUP" },
111 /* { 111, "PORTMAP" }, Just Sun RPC */
113 { 117, "UUCP-PATH" },
115 { IPPORT_NTP
, "NTP" },
116 { IPPORT_NETBIOS_SSN
, "NBT" },
119 { IPPORT_LDAP
, "LDAP" },
120 { IPPORT_SLP
, "SLP" },
123 { IPPORT_EXECSERVER
, "EXEC" },
124 { IPPORT_LOGINSERVER
, "RLOGIN" },
125 { IPPORT_CMDSERVER
, "RSHELL" },
126 { IPPORT_PRINTER
, "PRINTER" },
130 { IPPORT_SOCKS
, "SOCKS" },
131 { 1524, "INGRESLOCK" },
135 { IPPORT_HTTP_ALT
, "HTTP (proxy)" },
141 getportname(int proto
, in_port_t port
)
143 const struct porttable
*p
, *pt
;
146 case IPPROTO_SCTP
: /* fallthru */
147 case IPPROTO_TCP
: pt
= pt_tcp
; break;
148 case IPPROTO_UDP
: pt
= pt_udp
; break;
149 default: return (NULL
);
152 for (p
= pt
; p
->pt_num
; p
++) {
153 if (port
== p
->pt_num
)
154 return (p
->pt_short
);
160 reservedport(int proto
, int port
)
162 const struct porttable
*p
, *pt
;
165 case IPPROTO_TCP
: pt
= pt_tcp
; break;
166 case IPPROTO_UDP
: pt
= pt_udp
; break;
169 for (p
= pt
; p
->pt_num
; p
++) {
170 if (port
== p
->pt_num
)
177 * Need to be able to register an
178 * interpreter for transient ports.
179 * See TFTP interpreter.
182 static struct ttable
{
184 int (*t_proc
)(int, char *, int);
185 } transients
[MAXTRANS
];
188 add_transient(int port
, int (*proc
)(int, char *, int))
190 static struct ttable
*next
= transients
;
195 if (++next
>= &transients
[MAXTRANS
])
201 static struct ttable
*
202 is_transient(int port
)
206 for (p
= transients
; p
->t_port
&& p
< &transients
[MAXTRANS
]; p
++) {
207 if (port
== p
->t_port
)
215 del_transient(int port
)
219 for (p
= transients
; p
->t_port
&& p
< &transients
[MAXTRANS
]; p
++) {
220 if (port
== p
->t_port
)
226 interpret_syslog(int flags
, char dir
, int port
, const char *syslogstr
,
229 static const char *pris
[] = {
230 "emerg", "alert", "crit", "error", "warn", "notice", "info", "debug"
232 static const char *facs
[] = {
233 "kern", "user", "mail", "daemon", "auth", "syslog", "lpr", "news",
234 "uucp", NULL
, NULL
, NULL
, NULL
, "audit", NULL
, "cron", "local0",
235 "local1", "local2", "local3", "local4", "local5", "local6", "local7"
241 boolean_t bogus
= B_TRUE
;
244 char unknown
[4]; /* for unrecognized ones */
245 const char *facilstr
= "BAD";
246 const char *pristr
= "FMT";
247 const char *data
= syslogstr
;
250 * Is there enough data to interpret (left bracket + at least 3 chars
251 * which could be digits, right bracket, or space)?
253 if (datalen
>= 4 && data
!= NULL
) {
255 const int FACS_LEN
= sizeof (facs
) / sizeof (facs
[0]);
262 (void) strlcpy(buffer
, data
, sizeof (buffer
));
263 composit
= strtoul(buffer
, &end
, 0);
264 data
+= end
- buffer
;
267 datalen
-= end
- buffer
+ 1;
269 pri
= composit
& 0x7;
270 facil
= (composit
& 0xF8) >> 3;
272 if ((facil
>= FACS_LEN
) ||
273 (facs
[facil
] == NULL
)) {
274 snprintf(unknown
, sizeof (unknown
),
278 facilstr
= facs
[facil
];
281 priostrlen
= dlen
- datalen
;
291 (void) snprintf(get_sum_line(), MAXLINE
,
292 "SYSLOG %c port=%d %s.%s: %s",
293 dir
, port
, facilstr
, pristr
,
294 show_string(syslogstr
, dlen
, 20));
298 if (flags
& F_DTAIL
) {
299 static char syslog
[] = "SYSLOG: ";
300 show_header(syslog
, syslog
, dlen
);
302 (void) snprintf(get_detail_line(0, 0), MAXLINE
,
303 "%s%sPriority: %.*s%s(%s.%s)", prot_nest_prefix
, syslog
,
304 priostrlen
, syslogstr
, bogus
? "" : " ",
306 (void) snprintf(get_line(0, 0), get_line_remain(),
308 show_string(syslogstr
, dlen
, 60));
313 int src_port
, dst_port
, curr_proto
;
316 interpret_reserved(int flags
, int proto
, in_port_t src
, in_port_t dst
,
317 char *data
, int dlen
)
320 int dir
, port
, which
;
321 char pbuff
[16], hbuff
[32];
322 struct ttable
*ttabp
;
328 pn
= getportname(proto
, src
);
334 pn
= getportname(proto
, dst
);
336 ttabp
= is_transient(src
);
338 (ttabp
->t_proc
)(flags
, data
, dlen
);
341 ttabp
= is_transient(dst
);
343 (ttabp
->t_proc
)(flags
, data
, dlen
);
354 if ((dst
== IPPORT_DOMAIN
|| src
== IPPORT_DOMAIN
||
355 dst
== IPPORT_MDNS
|| src
== IPPORT_MDNS
) &&
356 proto
!= IPPROTO_TCP
) {
357 interpret_dns(flags
, proto
, (uchar_t
*)data
, dlen
, which
);
361 if (dst
== IPPORT_SYSLOG
&& proto
!= IPPROTO_TCP
) {
363 * TCP port 514 is rshell. UDP port 514 is syslog.
365 interpret_syslog(flags
, dir
, port
, (const char *)data
, dlen
);
373 (void) interpret_dhcp(flags
, (struct dhcp
*)data
,
378 (void) interpret_dhcpv6(flags
, (uint8_t *)data
, dlen
);
381 (void) interpret_tftp(flags
, (struct tftphdr
*)data
,
385 case IPPORT_HTTP_ALT
:
386 (void) interpret_http(flags
, data
, dlen
);
389 (void) interpret_ntp(flags
, (struct ntpdata
*)data
,
392 case IPPORT_NETBIOS_NS
:
393 interpret_netbios_ns(flags
, (uchar_t
*)data
, dlen
);
395 case IPPORT_NETBIOS_DGM
:
396 interpret_netbios_datagram(flags
, (uchar_t
*)data
,
399 case IPPORT_NETBIOS_SSN
:
402 * SMB on port 445 is a subset of NetBIOS SMB
403 * on port 139. The same interpreter can be used
406 interpret_netbios_ses(flags
, (uchar_t
*)data
, dlen
);
409 interpret_ldap(flags
, data
, dlen
, src
, dst
);
412 interpret_slp(flags
, data
, dlen
);
415 interpret_mip_cntrlmsg(flags
, (uchar_t
*)data
, dlen
);
417 case IPPORT_ROUTESERVER
:
418 (void) interpret_rip(flags
, (struct rip
*)data
, dlen
);
421 (void) interpret_rip6(flags
, (struct rip6
*)data
,
426 (void) interpret_socks_call(flags
, data
, dlen
);
428 (void) interpret_socks_reply(flags
, data
,
435 (void) snprintf(get_sum_line(), MAXLINE
,
438 show_string(data
, dlen
, 20));
441 if (flags
& F_DTAIL
) {
442 (void) snprintf(pbuff
, sizeof (pbuff
), "%s: ", pn
);
443 (void) snprintf(hbuff
, sizeof (hbuff
), "%s: ", pn
);
444 show_header(pbuff
, hbuff
, dlen
);
446 (void) snprintf(get_line(0, 0), get_line_remain(),
448 show_string(data
, dlen
, 60));