Home | History | Annotate | Download | only in snoop
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 #include <stdio.h>
     30 #include <ctype.h>
     31 #include <string.h>
     32 #include <fcntl.h>
     33 #include <string.h>
     34 #include <sys/types.h>
     35 #include <sys/time.h>
     36 
     37 #include <sys/socket.h>
     38 #include <sys/sockio.h>
     39 #include <net/if.h>
     40 #include <netinet/in_systm.h>
     41 #include <netinet/in.h>
     42 #include <netinet/ip.h>
     43 #include <netinet/if_ether.h>
     44 #include <netinet/udp.h>
     45 #include "snoop.h"
     46 
     47 extern char *dlc_header;
     48 
     49 int
     50 interpret_udp(int flags, struct udphdr *udp, int iplen, int fraglen)
     51 {
     52 	char *data;
     53 	int udplen;
     54 	int sunrpc;
     55 	char *pname;
     56 	char buff [32];
     57 
     58 	if (fraglen < sizeof (struct udphdr))
     59 		return (fraglen);	/* incomplete header */
     60 
     61 	data = (char *)udp + sizeof (struct udphdr);
     62 	udplen = ntohs((ushort_t)udp->uh_ulen) - sizeof (struct udphdr);
     63 	fraglen -= sizeof (struct udphdr);
     64 	if (fraglen > udplen)
     65 		fraglen = udplen;
     66 
     67 	if (flags & F_SUM) {
     68 		(void) sprintf(get_sum_line(),
     69 			"UDP D=%d S=%d LEN=%d",
     70 			ntohs(udp->uh_dport),
     71 			ntohs(udp->uh_sport),
     72 			ntohs((ushort_t)udp->uh_ulen));
     73 	}
     74 
     75 	sunrpc = !reservedport(IPPROTO_UDP, ntohs(udp->uh_dport)) &&
     76 		!reservedport(IPPROTO_UDP, ntohs(udp->uh_sport)) &&
     77 		valid_rpc(data, udplen);
     78 
     79 	if (flags & F_DTAIL) {
     80 		show_header("UDP:  ", "UDP Header", udplen);
     81 		show_space();
     82 		(void) sprintf(get_line((char *)(uintptr_t)udp->uh_sport -
     83 		    dlc_header, 1), "Source port = %d", ntohs(udp->uh_sport));
     84 
     85 		if (sunrpc) {
     86 			pname = "(Sun RPC)";
     87 		} else {
     88 			pname = getportname(IPPROTO_UDP, ntohs(udp->uh_dport));
     89 			if (pname == NULL) {
     90 				pname = "";
     91 			} else {
     92 				(void) sprintf(buff, "(%s)", pname);
     93 				pname = buff;
     94 			}
     95 		}
     96 		(void) sprintf(get_line((char *)(uintptr_t)udp->uh_dport -
     97 		    dlc_header, 1), "Destination port = %d %s",
     98 		    ntohs(udp->uh_dport), pname);
     99 		(void) sprintf(get_line((char *)(uintptr_t)udp->uh_ulen -
    100 		    dlc_header, 1), "Length = %d %s",
    101 		    ntohs((ushort_t)udp->uh_ulen),
    102 		    udplen > fraglen ?
    103 			"(Not all data contained in this fragment)"
    104 			: "");
    105 		    (void) sprintf(get_line((char *)(uintptr_t)udp->uh_sum -
    106 			dlc_header, 1),	"Checksum = %04X %s",
    107 			ntohs(udp->uh_sum),
    108 			udp->uh_sum == 0 ? "(no checksum)" : "");
    109 		show_space();
    110 	}
    111 
    112 
    113 	/* go to the next protocol layer */
    114 
    115 	if (!interpret_reserved(flags, IPPROTO_UDP,
    116 		ntohs(udp->uh_sport),
    117 		ntohs(udp->uh_dport),
    118 		data, fraglen)) {
    119 		if (fraglen > 0 && sunrpc)
    120 			interpret_rpc(flags, data, fraglen, IPPROTO_UDP);
    121 	}
    122 
    123 	return (fraglen);
    124 }
    125