print-null.c revision 75118
12258Scsgr/*
22258Scsgr * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
32258Scsgr *	The Regents of the University of California.  All rights reserved.
42258Scsgr *
52258Scsgr * Redistribution and use in source and binary forms, with or without
62258Scsgr * modification, are permitted provided that: (1) source code distributions
72258Scsgr * retain the above copyright notice and this paragraph in its entirety, (2)
82258Scsgr * distributions including binary code include the above copyright notice and
92258Scsgr * this paragraph in its entirety in the documentation or other materials
102258Scsgr * provided with the distribution, and (3) all advertising materials mentioning
112258Scsgr * features or use of this software display the following acknowledgement:
122258Scsgr * ``This product includes software developed by the University of California,
132258Scsgr * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
142258Scsgr * the University nor the names of its contributors may be used to endorse
152258Scsgr * or promote products derived from this software without specific prior
162258Scsgr * written permission.
172258Scsgr * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
182258Scsgr * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
192258Scsgr * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
202258Scsgr *
212258Scsgr * $FreeBSD: head/contrib/tcpdump/print-null.c 75118 2001-04-03 07:50:46Z fenner $
222258Scsgr */
232258Scsgr
242258Scsgr#ifndef lint
252258Scsgrstatic const char rcsid[] =
262258Scsgr    "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.40 2000/12/16 22:00:50 guy Exp $ (LBL)";
272258Scsgr#endif
282258Scsgr
292258Scsgr#ifdef HAVE_CONFIG_H
302258Scsgr#include "config.h"
312258Scsgr#endif
322258Scsgr
332258Scsgr#include <sys/param.h>
342258Scsgr#include <sys/time.h>
352258Scsgr#include <sys/socket.h>
362258Scsgr#include <sys/file.h>
372258Scsgr#include <sys/ioctl.h>
382258Scsgr
392258Scsgrstruct mbuf;
402258Scsgrstruct rtentry;
412258Scsgr
422258Scsgr#include <netinet/in.h>
432258Scsgr
442258Scsgr#include <pcap.h>
452258Scsgr#include <stdio.h>
462258Scsgr#include <string.h>
472258Scsgr
482258Scsgr#include "interface.h"
492258Scsgr#include "addrtoname.h"
502258Scsgr
512258Scsgr#include "ip.h"
522258Scsgr#ifdef INET6
532258Scsgr#include "ip6.h"
542258Scsgr#endif
552258Scsgr
562258Scsgr#ifndef AF_NS
572258Scsgr#define AF_NS		6		/* XEROX NS protocols */
582258Scsgr#endif
592258Scsgr
602258Scsgr/*
612258Scsgr * The DLT_NULL packet header is 4 bytes long. It contains a host-byte-order
622258Scsgr * 32-bit integer that specifies the family, e.g. AF_INET.
632258Scsgr *
642258Scsgr * Note here that "host" refers to the host on which the packets were
652258Scsgr * captured; that isn't necessarily *this* host.
662258Scsgr *
672258Scsgr * The OpenBSD DLT_LOOP packet header is the same, except that the integer
682258Scsgr * is in network byte order.
692258Scsgr */
702258Scsgr#define	NULL_HDRLEN 4
712258Scsgr
722258Scsgrstatic void
732258Scsgrnull_print(u_int family, u_int length)
742258Scsgr{
752258Scsgr	if (nflag)
762258Scsgr		printf("AF %u ", family);
772258Scsgr	else {
782258Scsgr		switch (family) {
792258Scsgr
802258Scsgr		case AF_INET:
812258Scsgr			printf("ip ");
822258Scsgr			break;
832258Scsgr
842258Scsgr#ifdef INET6
852258Scsgr		case AF_INET6:
862258Scsgr			printf("ip6 ");
872258Scsgr			break;
882258Scsgr#endif
892258Scsgr
902258Scsgr		case AF_NS:
912258Scsgr			printf("ns ");
922258Scsgr			break;
932258Scsgr
942258Scsgr		default:
952258Scsgr			printf("AF %u ", family);
962258Scsgr			break;
972258Scsgr		}
982258Scsgr	}
992258Scsgr	printf("%d: ", length);
1002258Scsgr}
1012258Scsgr
1022258Scsgr/*
1032258Scsgr * Byte-swap a 32-bit number.
1042258Scsgr * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on
1052258Scsgr * big-endian platforms.)
1062258Scsgr */
1072258Scsgr#define	SWAPLONG(y) \
1082258Scsgr((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
1092258Scsgr
1102258Scsgrvoid
1112258Scsgrnull_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
1122258Scsgr{
1132258Scsgr	u_int length = h->len;
1142258Scsgr	u_int caplen = h->caplen;
1152258Scsgr	const struct ip *ip;
1162258Scsgr	u_int family;
1172258Scsgr
1182258Scsgr	ts_print(&h->ts);
1192258Scsgr
1202258Scsgr	memcpy((char *)&family, (char *)p, sizeof(family));
1212258Scsgr
1222258Scsgr	/*
1232258Scsgr	 * This isn't necessarily in our host byte order; if this is
1242258Scsgr	 * a DLT_LOOP capture, it's in network byte order, and if
1252258Scsgr	 * this is a DLT_NULL capture from a machine with the opposite
1262258Scsgr	 * byte-order, it's in the opposite byte order from ours.
1272258Scsgr	 *
1282258Scsgr	 * If the upper 16 bits aren't all zero, assume it's byte-swapped.
1292258Scsgr	 */
1302258Scsgr	if ((family & 0xFFFF0000) != 0)
1312258Scsgr		family = SWAPLONG(family);
1322258Scsgr
1332258Scsgr	/*
1342258Scsgr	 * Some printers want to get back at the link level addresses,
1352258Scsgr	 * and/or check that they're not walking off the end of the packet.
1362258Scsgr	 * Rather than pass them all the way down, we set these globals.
1372258Scsgr	 */
1382258Scsgr	packetp = p;
1392258Scsgr	snapend = p + caplen;
1402258Scsgr
1412258Scsgr	length -= NULL_HDRLEN;
1422258Scsgr
1432258Scsgr	ip = (struct ip *)(p + NULL_HDRLEN);
1442258Scsgr
1452258Scsgr	if (eflag)
1462258Scsgr		null_print(family, length);
1472258Scsgr
1482258Scsgr	switch (IP_V(ip)) {
1492258Scsgr	case 4:
1502258Scsgr		ip_print((const u_char *)ip, length);
1512258Scsgr		break;
1522258Scsgr#ifdef INET6
1532258Scsgr	case 6:
1542258Scsgr		ip6_print((const u_char *)ip, length);
1552258Scsgr		break;
1562258Scsgr#endif /* INET6 */
1572258Scsgr	default:
1582258Scsgr		printf("ip v%d", IP_V(ip));
1592258Scsgr		break;
1602258Scsgr	}
1612258Scsgr
1622258Scsgr	if (xflag)
1632258Scsgr		default_print((const u_char *)ip, caplen - NULL_HDRLEN);
1642258Scsgr	putchar('\n');
1652258Scsgr}
1662258Scsgr
1672258Scsgr