117680Spst/*
239300Sfenner * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
317680Spst *	The Regents of the University of California.  All rights reserved.
417680Spst *
517680Spst * Redistribution and use in source and binary forms, with or without
617680Spst * modification, are permitted provided that: (1) source code distributions
717680Spst * retain the above copyright notice and this paragraph in its entirety, (2)
817680Spst * distributions including binary code include the above copyright notice and
917680Spst * this paragraph in its entirety in the documentation or other materials
1017680Spst * provided with the distribution, and (3) all advertising materials mentioning
1117680Spst * features or use of this software display the following acknowledgement:
1217680Spst * ``This product includes software developed by the University of California,
1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1417680Spst * the University nor the names of its contributors may be used to endorse
1517680Spst * or promote products derived from this software without specific prior
1617680Spst * written permission.
1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2056896Sfenner *
2156896Sfenner * $FreeBSD$
2217680Spst */
2317680Spst
2417680Spst#ifndef lint
25127675Sbmsstatic const char rcsid[] _U_ =
26190207Srpaulo    "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.57 2006-03-23 14:58:44 hannes Exp $ (LBL)";
2717680Spst#endif
2817680Spst
2956896Sfenner#ifdef HAVE_CONFIG_H
3056896Sfenner#include "config.h"
3156896Sfenner#endif
3256896Sfenner
33127675Sbms#include <tcpdump-stdinc.h>
3417680Spst
3526183Sfenner#include <pcap.h>
3617680Spst#include <stdio.h>
3717680Spst#include <string.h>
3817680Spst
3975118Sfenner#include "interface.h"
4075118Sfenner#include "addrtoname.h"
4175118Sfenner
4275118Sfenner#include "ip.h"
4356896Sfenner#ifdef INET6
4475118Sfenner#include "ip6.h"
4556896Sfenner#endif
46190207Srpaulo#include "af.h"
4756896Sfenner
4839300Sfenner/*
4975118Sfenner * The DLT_NULL packet header is 4 bytes long. It contains a host-byte-order
5075118Sfenner * 32-bit integer that specifies the family, e.g. AF_INET.
5175118Sfenner *
5275118Sfenner * Note here that "host" refers to the host on which the packets were
5375118Sfenner * captured; that isn't necessarily *this* host.
5475118Sfenner *
5575118Sfenner * The OpenBSD DLT_LOOP packet header is the same, except that the integer
5675118Sfenner * is in network byte order.
5739300Sfenner */
5839300Sfenner#define	NULL_HDRLEN 4
5939300Sfenner
6075118Sfenner/*
6175118Sfenner * Byte-swap a 32-bit number.
6275118Sfenner * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on
6375118Sfenner * big-endian platforms.)
6475118Sfenner */
6575118Sfenner#define	SWAPLONG(y) \
6675118Sfenner((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
6775118Sfenner
68147904Ssamstatic inline void
69147904Ssamnull_hdr_print(u_int family, u_int length)
70147904Ssam{
71147904Ssam	if (!qflag) {
72147904Ssam		(void)printf("AF %s (%u)",
73147904Ssam			tok2str(bsd_af_values,"Unknown",family),family);
74147904Ssam	} else {
75147904Ssam		(void)printf("%s",
76147904Ssam			tok2str(bsd_af_values,"Unknown AF %u",family));
77147904Ssam	}
78147904Ssam
79147904Ssam	(void)printf(", length %u: ", length);
80147904Ssam}
81147904Ssam
82127675Sbms/*
83127675Sbms * This is the top level routine of the printer.  'p' points
84127675Sbms * to the ether header of the packet, 'h->ts' is the timestamp,
85146778Ssam * 'h->len' is the length of the packet off the wire, and 'h->caplen'
86127675Sbms * is the number of bytes actually captured.
87127675Sbms */
88127675Sbmsu_int
89127675Sbmsnull_if_print(const struct pcap_pkthdr *h, const u_char *p)
9017680Spst{
9117680Spst	u_int length = h->len;
9217680Spst	u_int caplen = h->caplen;
9375118Sfenner	u_int family;
9417680Spst
95127675Sbms	if (caplen < NULL_HDRLEN) {
96127675Sbms		printf("[|null]");
97127675Sbms		return (NULL_HDRLEN);
98127675Sbms	}
9917680Spst
10075118Sfenner	memcpy((char *)&family, (char *)p, sizeof(family));
10175118Sfenner
10217680Spst	/*
10375118Sfenner	 * This isn't necessarily in our host byte order; if this is
10475118Sfenner	 * a DLT_LOOP capture, it's in network byte order, and if
10575118Sfenner	 * this is a DLT_NULL capture from a machine with the opposite
10675118Sfenner	 * byte-order, it's in the opposite byte order from ours.
10775118Sfenner	 *
10875118Sfenner	 * If the upper 16 bits aren't all zero, assume it's byte-swapped.
10975118Sfenner	 */
11075118Sfenner	if ((family & 0xFFFF0000) != 0)
11175118Sfenner		family = SWAPLONG(family);
11275118Sfenner
113147904Ssam	if (eflag)
114147904Ssam		null_hdr_print(family, length);
115147904Ssam
11617680Spst	length -= NULL_HDRLEN;
117127675Sbms	caplen -= NULL_HDRLEN;
118127675Sbms	p += NULL_HDRLEN;
11917680Spst
120127675Sbms	switch (family) {
121127675Sbms
122172686Smlaier	case BSD_AFNUM_INET:
123147904Ssam		ip_print(gndo, p, length);
12456896Sfenner		break;
125127675Sbms
12656896Sfenner#ifdef INET6
127172686Smlaier	case BSD_AFNUM_INET6_BSD:
128172686Smlaier	case BSD_AFNUM_INET6_FREEBSD:
129172686Smlaier	case BSD_AFNUM_INET6_DARWIN:
130235530Sdelphij		ip6_print(gndo, p, length);
13156896Sfenner		break;
132127675Sbms#endif
133127675Sbms
134172686Smlaier	case BSD_AFNUM_ISO:
135127675Sbms		isoclns_print(p, length, caplen);
136127675Sbms		break;
137127675Sbms
138172686Smlaier	case BSD_AFNUM_APPLETALK:
139127675Sbms		atalk_print(p, length);
140127675Sbms		break;
141127675Sbms
142172686Smlaier	case BSD_AFNUM_IPX:
143127675Sbms		ipx_print(p, length);
144127675Sbms		break;
145127675Sbms
14656896Sfenner	default:
147127675Sbms		/* unknown AF_ value */
148127675Sbms		if (!eflag)
149147904Ssam			null_hdr_print(family, length + NULL_HDRLEN);
150162021Ssam		if (!suppress_default_print)
151127675Sbms			default_print(p, caplen);
15256896Sfenner	}
15317680Spst
154127675Sbms	return (NULL_HDRLEN);
15517680Spst}
15617680Spst
157146778Ssam/*
158146778Ssam * Local Variables:
159146778Ssam * c-style: whitesmith
160146778Ssam * c-basic-offset: 8
161146778Ssam * End:
162146778Ssam */
163