1999-10-08 07:47:09 +08:00
|
|
|
/*
|
1999-10-18 06:18:00 +08:00
|
|
|
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
1999-10-08 07:47:09 +08:00
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that: (1) source code distributions
|
|
|
|
* retain the above copyright notice and this paragraph in its entirety, (2)
|
|
|
|
* distributions including binary code include the above copyright notice and
|
|
|
|
* this paragraph in its entirety in the documentation or other materials
|
|
|
|
* provided with the distribution, and (3) all advertising materials mentioning
|
|
|
|
* features or use of this software display the following acknowledgement:
|
|
|
|
* ``This product includes software developed by the University of California,
|
|
|
|
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
|
|
|
* the University nor the names of its contributors may be used to endorse
|
|
|
|
* or promote products derived from this software without specific prior
|
|
|
|
* written permission.
|
|
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
|
|
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
*/
|
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
#define NETDISSECT_REWORKED
|
1999-11-21 17:36:43 +08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
1999-10-08 07:47:09 +08:00
|
|
|
#endif
|
|
|
|
|
2002-08-01 16:52:55 +08:00
|
|
|
#include <tcpdump-stdinc.h>
|
1999-10-08 07:47:09 +08:00
|
|
|
|
1999-10-18 06:18:00 +08:00
|
|
|
#include <string.h>
|
1999-10-08 07:47:09 +08:00
|
|
|
|
1999-10-18 05:56:53 +08:00
|
|
|
#include "addrtoname.h"
|
1999-10-18 06:18:00 +08:00
|
|
|
#include "interface.h"
|
|
|
|
#include "extract.h" /* must come after interface.h */
|
|
|
|
|
2000-09-23 16:54:24 +08:00
|
|
|
#include "ip.h"
|
2003-06-07 19:57:51 +08:00
|
|
|
#include "ipproto.h"
|
1999-10-18 06:18:00 +08:00
|
|
|
|
2013-12-26 22:08:06 +08:00
|
|
|
static const char tstr[] = "[|ip]";
|
|
|
|
|
2013-09-25 00:46:24 +08:00
|
|
|
static const struct tok ip_option_values[] = {
|
2004-09-28 05:13:09 +08:00
|
|
|
{ IPOPT_EOL, "EOL" },
|
|
|
|
{ IPOPT_NOP, "NOP" },
|
|
|
|
{ IPOPT_TS, "timestamp" },
|
|
|
|
{ IPOPT_SECURITY, "security" },
|
|
|
|
{ IPOPT_RR, "RR" },
|
|
|
|
{ IPOPT_SSRR, "SSRR" },
|
|
|
|
{ IPOPT_LSRR, "LSRR" },
|
|
|
|
{ IPOPT_RA, "RA" },
|
2007-09-14 09:29:28 +08:00
|
|
|
{ IPOPT_RFC1393, "traceroute" },
|
2004-09-28 05:13:09 +08:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
1999-10-08 07:47:09 +08:00
|
|
|
/*
|
|
|
|
* print the recorded route in an IP RR, LSRR or SSRR option.
|
|
|
|
*/
|
|
|
|
static void
|
2014-03-26 19:47:29 +08:00
|
|
|
ip_printroute(netdissect_options *ndo,
|
|
|
|
register const u_char *cp, u_int length)
|
1999-10-08 07:47:09 +08:00
|
|
|
{
|
2004-03-24 09:26:56 +08:00
|
|
|
register u_int ptr;
|
1999-10-18 06:18:00 +08:00
|
|
|
register u_int len;
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2004-03-24 09:26:56 +08:00
|
|
|
if (length < 3) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, " [bad length %u]", length));
|
2004-03-24 09:26:56 +08:00
|
|
|
return;
|
|
|
|
}
|
1999-10-08 07:47:09 +08:00
|
|
|
if ((length + 1) & 3)
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, " [bad length %u]", length));
|
2004-03-24 09:26:56 +08:00
|
|
|
ptr = cp[2] - 1;
|
1999-10-08 07:47:09 +08:00
|
|
|
if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, " [bad ptr %u]", cp[2]));
|
1999-10-08 07:47:09 +08:00
|
|
|
|
|
|
|
for (len = 3; len < length; len += 4) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, " %s", ipaddr_string(&cp[len])));
|
|
|
|
if (ptr > len)
|
|
|
|
ND_PRINT((ndo, ","));
|
1999-10-08 07:47:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-07-28 12:14:21 +08:00
|
|
|
/*
|
2004-06-25 09:20:08 +08:00
|
|
|
* If source-routing is present and valid, return the final destination.
|
2002-07-28 12:14:21 +08:00
|
|
|
* Otherwise, return IP destination.
|
|
|
|
*
|
|
|
|
* This is used for UDP and TCP pseudo-header in the checksum
|
|
|
|
* calculation.
|
|
|
|
*/
|
2011-06-17 16:09:16 +08:00
|
|
|
static u_int32_t
|
2014-03-26 19:47:29 +08:00
|
|
|
ip_finddst(netdissect_options *ndo,
|
|
|
|
const struct ip *ip)
|
2002-07-28 12:14:21 +08:00
|
|
|
{
|
|
|
|
int length;
|
|
|
|
int len;
|
|
|
|
const u_char *cp;
|
2002-08-01 16:52:55 +08:00
|
|
|
u_int32_t retval;
|
2002-07-28 12:14:21 +08:00
|
|
|
|
|
|
|
cp = (const u_char *)(ip + 1);
|
|
|
|
length = (IP_HL(ip) << 2) - sizeof(struct ip);
|
|
|
|
|
|
|
|
for (; length > 0; cp += len, length -= len) {
|
2004-03-24 09:26:56 +08:00
|
|
|
int tt;
|
2002-07-28 12:14:21 +08:00
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_TCHECK(*cp);
|
2004-03-24 09:26:56 +08:00
|
|
|
tt = *cp;
|
2004-06-25 09:20:08 +08:00
|
|
|
if (tt == IPOPT_EOL)
|
|
|
|
break;
|
|
|
|
else if (tt == IPOPT_NOP)
|
2002-07-28 12:14:21 +08:00
|
|
|
len = 1;
|
|
|
|
else {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_TCHECK(cp[1]);
|
2002-07-28 12:14:21 +08:00
|
|
|
len = cp[1];
|
2004-06-25 09:20:08 +08:00
|
|
|
if (len < 2)
|
|
|
|
break;
|
2002-07-28 12:14:21 +08:00
|
|
|
}
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_TCHECK2(*cp, len);
|
2002-07-28 12:14:21 +08:00
|
|
|
switch (tt) {
|
|
|
|
|
|
|
|
case IPOPT_SSRR:
|
|
|
|
case IPOPT_LSRR:
|
2004-03-24 09:26:56 +08:00
|
|
|
if (len < 7)
|
2004-06-25 09:20:08 +08:00
|
|
|
break;
|
2014-01-18 09:51:04 +08:00
|
|
|
UNALIGNED_MEMCPY(&retval, cp + len - 4, 4);
|
2002-07-28 12:14:21 +08:00
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
}
|
2004-03-24 09:26:56 +08:00
|
|
|
trunc:
|
2014-01-18 09:51:04 +08:00
|
|
|
UNALIGNED_MEMCPY(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t));
|
2004-06-25 09:20:08 +08:00
|
|
|
return retval;
|
2002-07-28 12:14:21 +08:00
|
|
|
}
|
|
|
|
|
2011-06-17 16:09:16 +08:00
|
|
|
/*
|
|
|
|
* Compute a V4-style checksum by building a pseudoheader.
|
|
|
|
*/
|
|
|
|
int
|
2014-03-26 19:47:29 +08:00
|
|
|
nextproto4_cksum(netdissect_options *ndo,
|
|
|
|
const struct ip *ip, const u_int8_t *data,
|
|
|
|
u_int len, u_int covlen, u_int next_proto)
|
2011-06-17 16:09:16 +08:00
|
|
|
{
|
|
|
|
struct phdr {
|
|
|
|
u_int32_t src;
|
|
|
|
u_int32_t dst;
|
|
|
|
u_char mbz;
|
|
|
|
u_char proto;
|
|
|
|
u_int16_t len;
|
|
|
|
} ph;
|
|
|
|
struct cksum_vec vec[2];
|
|
|
|
|
|
|
|
/* pseudo-header.. */
|
|
|
|
ph.len = htons((u_int16_t)len);
|
|
|
|
ph.mbz = 0;
|
|
|
|
ph.proto = next_proto;
|
2014-01-18 09:51:04 +08:00
|
|
|
UNALIGNED_MEMCPY(&ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
|
2011-06-17 16:09:16 +08:00
|
|
|
if (IP_HL(ip) == 5)
|
2014-01-18 09:51:04 +08:00
|
|
|
UNALIGNED_MEMCPY(&ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));
|
2011-06-17 16:09:16 +08:00
|
|
|
else
|
2014-03-26 19:47:29 +08:00
|
|
|
ph.dst = ip_finddst(ndo, ip);
|
2011-06-17 16:09:16 +08:00
|
|
|
|
|
|
|
vec[0].ptr = (const u_int8_t *)(void *)&ph;
|
|
|
|
vec[0].len = sizeof(ph);
|
|
|
|
vec[1].ptr = data;
|
2014-02-15 19:32:44 +08:00
|
|
|
vec[1].len = covlen;
|
2011-06-17 16:09:16 +08:00
|
|
|
return (in_cksum(vec, 2));
|
|
|
|
}
|
|
|
|
|
1999-11-21 11:47:35 +08:00
|
|
|
static void
|
2014-03-26 19:47:29 +08:00
|
|
|
ip_printts(netdissect_options *ndo,
|
|
|
|
register const u_char *cp, u_int length)
|
1999-11-21 11:47:35 +08:00
|
|
|
{
|
2004-03-24 09:26:56 +08:00
|
|
|
register u_int ptr;
|
|
|
|
register u_int len;
|
1999-11-21 11:47:35 +08:00
|
|
|
int hoplen;
|
Add a few more GCC warnings on GCC >= 2 for ".devel" builds.
From Neil T. Spring: fixes for many of those warnings:
addrtoname.c, configure.in: Linux needs netinet/ether.h for
ether_ntohost
print-*.c: change char *foo = "bar" to const char *foo = "bar"
to appease -Wwrite-strings; should affect no run-time behavior.
print-*.c: make some variables unsigned.
print-bgp.c: plen ('prefix len') is unsigned, no reason to
validate by comparing to zero.
print-cnfp.c, print-rx.c: use intoa, provided by addrtoname,
instead of inet_ntoa.
print-domain.c: unsigned int l; (l=foo()) < 0 is guaranteed to
be false, so check for (u_int)-1, which represents failure,
explicitly.
print-isakmp.c: complete initialization of attrmap objects.
print-lwres.c: "if(x); print foo;" seemed much more likely to be
intended to be "if(x) { print foo; }".
print-smb.c: complete initialization of some structures.
In addition, add some fixes for the signed vs. unsigned comparison
warnings:
extract.h: cast the result of the byte-extraction-and-combining,
as, at least for the 16-bit version, C's integral promotions
will turn "u_int16_t" into "int" if there are other "int"s
nearby.
print-*.c: make some more variables unsigned, or add casts to an
unsigned type of signed values known not to be negative, or add
casts to "int" of unsigned values known to fit in an "int", and
make other changes needed to handle the aforementioned variables
now being unsigned.
print-isakmp.c: clean up the handling of error/status indicators
in notify messages.
print-ppp.c: get rid of a check that an unsigned quantity is >=
0.
print-radius.c: clean up some of the bounds checking.
print-smb.c: extract the word count into a "u_int" to avoid the
aforementioned problems with C's integral promotions.
print-snmp.c: change a check that an unsigned variable is >= 0
to a check that it's != 0.
Also, fix some formats to use "%u" rather than "%d" for unsigned
quantities.
2002-09-05 08:00:07 +08:00
|
|
|
const char *type;
|
1999-11-21 11:47:35 +08:00
|
|
|
|
2004-03-24 09:26:56 +08:00
|
|
|
if (length < 4) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "[bad length %u]", length));
|
2004-03-24 09:26:56 +08:00
|
|
|
return;
|
|
|
|
}
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, " TS{"));
|
1999-11-21 11:47:35 +08:00
|
|
|
hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
|
|
|
|
if ((length - 4) & (hoplen-1))
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "[bad length %u]", length));
|
2004-03-24 09:26:56 +08:00
|
|
|
ptr = cp[2] - 1;
|
|
|
|
len = 0;
|
1999-11-21 11:47:35 +08:00
|
|
|
if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "[bad ptr %u]", cp[2]));
|
1999-11-21 11:47:35 +08:00
|
|
|
switch (cp[3]&0xF) {
|
|
|
|
case IPOPT_TS_TSONLY:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "TSONLY"));
|
1999-11-21 11:47:35 +08:00
|
|
|
break;
|
|
|
|
case IPOPT_TS_TSANDADDR:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "TS+ADDR"));
|
1999-11-21 11:47:35 +08:00
|
|
|
break;
|
1999-11-22 00:26:59 +08:00
|
|
|
/*
|
|
|
|
* prespecified should really be 3, but some ones might send 2
|
|
|
|
* instead, and the IPOPT_TS_PRESPEC constant can apparently
|
|
|
|
* have both values, so we have to hard-code it here.
|
|
|
|
*/
|
|
|
|
|
1999-11-21 11:47:35 +08:00
|
|
|
case 2:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "PRESPEC2.0"));
|
1999-11-21 11:47:35 +08:00
|
|
|
break;
|
1999-11-22 00:26:59 +08:00
|
|
|
case 3: /* IPOPT_TS_PRESPEC */
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "PRESPEC"));
|
1999-11-21 11:47:35 +08:00
|
|
|
break;
|
2002-06-12 01:08:37 +08:00
|
|
|
default:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "[bad ts type %d]", cp[3]&0xF));
|
1999-11-21 11:47:35 +08:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
type = " ";
|
|
|
|
for (len = 4; len < length; len += hoplen) {
|
|
|
|
if (ptr == len)
|
|
|
|
type = " ^ ";
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]),
|
|
|
|
hoplen!=8 ? "" : ipaddr_string(&cp[len])));
|
1999-11-21 11:47:35 +08:00
|
|
|
type = " ";
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "%s", ptr == len ? " ^ " : ""));
|
1999-11-21 11:47:35 +08:00
|
|
|
|
|
|
|
if (cp[3]>>4)
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, " [%d hops not recorded]} ", cp[3]>>4));
|
1999-11-21 11:47:35 +08:00
|
|
|
else
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "}"));
|
1999-11-21 11:47:35 +08:00
|
|
|
}
|
|
|
|
|
1999-10-08 07:47:09 +08:00
|
|
|
/*
|
|
|
|
* print IP options.
|
|
|
|
*/
|
|
|
|
static void
|
2014-03-26 19:47:29 +08:00
|
|
|
ip_optprint(netdissect_options *ndo,
|
|
|
|
register const u_char *cp, u_int length)
|
1999-10-08 07:47:09 +08:00
|
|
|
{
|
2004-09-28 05:13:09 +08:00
|
|
|
register u_int option_len;
|
2006-02-19 13:00:19 +08:00
|
|
|
const char *sep = "";
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2004-09-28 05:13:09 +08:00
|
|
|
for (; length > 0; cp += option_len, length -= option_len) {
|
|
|
|
u_int option_code;
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "%s", sep));
|
2006-02-19 13:00:19 +08:00
|
|
|
sep = ",";
|
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_TCHECK(*cp);
|
2004-09-28 05:13:09 +08:00
|
|
|
option_code = *cp;
|
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "%s",
|
|
|
|
tok2str(ip_option_values,"unknown %u",option_code)));
|
2006-02-19 13:00:19 +08:00
|
|
|
|
2004-09-28 05:13:09 +08:00
|
|
|
if (option_code == IPOPT_NOP ||
|
|
|
|
option_code == IPOPT_EOL)
|
|
|
|
option_len = 1;
|
|
|
|
|
2000-05-10 13:11:27 +08:00
|
|
|
else {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_TCHECK(cp[1]);
|
2006-02-19 13:00:19 +08:00
|
|
|
option_len = cp[1];
|
|
|
|
if (option_len < 2) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, " [bad length %u]", option_len));
|
2006-02-19 13:00:19 +08:00
|
|
|
return;
|
|
|
|
}
|
2000-05-10 13:11:27 +08:00
|
|
|
}
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2006-02-19 13:00:19 +08:00
|
|
|
if (option_len > length) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, " [bad length %u]", option_len));
|
2006-02-19 13:00:19 +08:00
|
|
|
return;
|
|
|
|
}
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_TCHECK2(*cp, option_len);
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2004-09-28 05:13:09 +08:00
|
|
|
switch (option_code) {
|
|
|
|
case IPOPT_EOL:
|
|
|
|
return;
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2004-09-28 05:13:09 +08:00
|
|
|
case IPOPT_TS:
|
2014-03-26 19:47:29 +08:00
|
|
|
ip_printts(ndo, cp, option_len);
|
1999-10-08 07:47:09 +08:00
|
|
|
break;
|
|
|
|
|
2004-09-28 05:13:09 +08:00
|
|
|
case IPOPT_RR: /* fall through */
|
1999-10-08 07:47:09 +08:00
|
|
|
case IPOPT_SSRR:
|
|
|
|
case IPOPT_LSRR:
|
2014-03-26 19:47:29 +08:00
|
|
|
ip_printroute(ndo, cp, option_len);
|
1999-10-08 07:47:09 +08:00
|
|
|
break;
|
|
|
|
|
1999-11-21 11:47:35 +08:00
|
|
|
case IPOPT_RA:
|
2006-02-19 13:00:19 +08:00
|
|
|
if (option_len < 4) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, " [bad length %u]", option_len));
|
2006-02-19 13:00:19 +08:00
|
|
|
break;
|
|
|
|
}
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_TCHECK(cp[3]);
|
|
|
|
if (EXTRACT_16BITS(&cp[2]) != 0)
|
|
|
|
ND_PRINT((ndo, " value %u", EXTRACT_16BITS(&cp[2])));
|
2001-01-28 16:18:27 +08:00
|
|
|
break;
|
1999-11-21 11:47:35 +08:00
|
|
|
|
2004-09-28 05:13:09 +08:00
|
|
|
case IPOPT_NOP: /* nothing to print - fall through */
|
|
|
|
case IPOPT_SECURITY:
|
1999-10-08 07:47:09 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-03-24 09:26:56 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
trunc:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "%s", tstr));
|
1999-10-08 07:47:09 +08:00
|
|
|
}
|
|
|
|
|
2003-04-24 20:51:35 +08:00
|
|
|
#define IP_RES 0x8000
|
|
|
|
|
2013-09-25 00:46:24 +08:00
|
|
|
static const struct tok ip_frag_values[] = {
|
2003-04-24 20:51:35 +08:00
|
|
|
{ IP_MF, "+" },
|
|
|
|
{ IP_DF, "DF" },
|
|
|
|
{ IP_RES, "rsvd" }, /* The RFC3514 evil ;-) bit */
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
struct ip_print_demux_state {
|
|
|
|
const struct ip *ip;
|
|
|
|
const u_char *cp;
|
2005-04-07 08:28:17 +08:00
|
|
|
u_int len, off;
|
2005-04-07 05:32:38 +08:00
|
|
|
u_char nh;
|
|
|
|
int advance;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
ip_print_demux(netdissect_options *ndo,
|
|
|
|
struct ip_print_demux_state *ipds)
|
|
|
|
{
|
|
|
|
struct protoent *proto;
|
2011-06-14 05:08:51 +08:00
|
|
|
struct cksum_vec vec[1];
|
2005-04-07 05:32:38 +08:00
|
|
|
|
|
|
|
again:
|
|
|
|
switch (ipds->nh) {
|
|
|
|
|
|
|
|
case IPPROTO_AH:
|
|
|
|
ipds->nh = *ipds->cp;
|
2014-03-26 19:47:29 +08:00
|
|
|
ipds->advance = ah_print(ndo, ipds->cp);
|
2005-04-07 05:32:38 +08:00
|
|
|
if (ipds->advance <= 0)
|
|
|
|
break;
|
|
|
|
ipds->cp += ipds->advance;
|
|
|
|
ipds->len -= ipds->advance;
|
|
|
|
goto again;
|
|
|
|
|
|
|
|
case IPPROTO_ESP:
|
|
|
|
{
|
|
|
|
int enh, padlen;
|
|
|
|
ipds->advance = esp_print(ndo, ipds->cp, ipds->len,
|
|
|
|
(const u_char *)ipds->ip,
|
|
|
|
&enh, &padlen);
|
|
|
|
if (ipds->advance <= 0)
|
|
|
|
break;
|
|
|
|
ipds->cp += ipds->advance;
|
|
|
|
ipds->len -= ipds->advance + padlen;
|
|
|
|
ipds->nh = enh & 0xff;
|
|
|
|
goto again;
|
|
|
|
}
|
2012-03-29 22:05:15 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
case IPPROTO_IPCOMP:
|
|
|
|
{
|
|
|
|
int enh;
|
2014-02-28 17:42:37 +08:00
|
|
|
ipds->advance = ipcomp_print(ndo, ipds->cp, &enh);
|
2005-04-07 05:32:38 +08:00
|
|
|
if (ipds->advance <= 0)
|
|
|
|
break;
|
|
|
|
ipds->cp += ipds->advance;
|
|
|
|
ipds->len -= ipds->advance;
|
|
|
|
ipds->nh = enh & 0xff;
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
|
|
|
|
case IPPROTO_SCTP:
|
2014-03-26 19:47:29 +08:00
|
|
|
sctp_print(ndo, ipds->cp, (const u_char *)ipds->ip, ipds->len);
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
2005-09-20 14:01:20 +08:00
|
|
|
|
|
|
|
case IPPROTO_DCCP:
|
2014-03-15 00:05:27 +08:00
|
|
|
dccp_print(ndo, ipds->cp, (const u_char *)ipds->ip, ipds->len);
|
2005-09-20 14:01:20 +08:00
|
|
|
break;
|
2012-03-29 22:05:15 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
case IPPROTO_TCP:
|
2005-11-13 19:51:32 +08:00
|
|
|
/* pass on the MF bit plus the offset to detect fragments */
|
2005-04-07 05:32:38 +08:00
|
|
|
tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
|
2005-11-13 19:51:32 +08:00
|
|
|
ipds->off & (IP_MF|IP_OFFMASK));
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
2012-03-29 22:05:15 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
case IPPROTO_UDP:
|
2005-11-13 19:51:32 +08:00
|
|
|
/* pass on the MF bit plus the offset to detect fragments */
|
2014-03-16 03:25:06 +08:00
|
|
|
udp_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip,
|
2005-11-13 19:51:32 +08:00
|
|
|
ipds->off & (IP_MF|IP_OFFMASK));
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
2012-03-29 22:05:15 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
case IPPROTO_ICMP:
|
|
|
|
/* pass on the MF bit plus the offset to detect fragments */
|
2014-03-16 03:25:06 +08:00
|
|
|
icmp_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip,
|
2005-11-13 19:51:32 +08:00
|
|
|
ipds->off & (IP_MF|IP_OFFMASK));
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
2012-03-29 22:05:15 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
case IPPROTO_PIGP:
|
|
|
|
/*
|
|
|
|
* XXX - the current IANA protocol number assignments
|
|
|
|
* page lists 9 as "any private interior gateway
|
|
|
|
* (used by Cisco for their IGRP)" and 88 as
|
|
|
|
* "EIGRP" from Cisco.
|
|
|
|
*
|
|
|
|
* Recent BSD <netinet/in.h> headers define
|
|
|
|
* IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88.
|
|
|
|
* We define IP_PROTO_PIGP as 9 and
|
|
|
|
* IP_PROTO_EIGRP as 88; those names better
|
|
|
|
* match was the current protocol number
|
|
|
|
* assignments say.
|
|
|
|
*/
|
2014-03-04 17:55:24 +08:00
|
|
|
igrp_print(ndo, ipds->cp, ipds->len);
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
2012-03-29 22:05:15 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
case IPPROTO_EIGRP:
|
2014-03-16 03:25:06 +08:00
|
|
|
eigrp_print(ndo, ipds->cp, ipds->len);
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
2012-03-29 22:05:15 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
case IPPROTO_ND:
|
|
|
|
ND_PRINT((ndo, " nd %d", ipds->len));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IPPROTO_EGP:
|
2014-03-21 20:48:24 +08:00
|
|
|
egp_print(ndo, ipds->cp, ipds->len);
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IPPROTO_OSPF:
|
|
|
|
ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IPPROTO_IGMP:
|
2014-03-19 17:57:56 +08:00
|
|
|
igmp_print(ndo, ipds->cp, ipds->len);
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IPPROTO_IPV4:
|
|
|
|
/* DVMRP multicast tunnel (ip-in-ip encapsulation) */
|
2010-11-08 04:50:16 +08:00
|
|
|
ip_print(ndo, ipds->cp, ipds->len);
|
2014-03-26 19:47:29 +08:00
|
|
|
if (! ndo->ndo_vflag) {
|
2005-04-07 05:32:38 +08:00
|
|
|
ND_PRINT((ndo, " (ipip-proto-4)"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
break;
|
2012-03-29 22:05:15 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
#ifdef INET6
|
|
|
|
case IPPROTO_IPV6:
|
|
|
|
/* ip6-in-ip encapsulation */
|
2010-11-08 04:50:16 +08:00
|
|
|
ip6_print(ndo, ipds->cp, ipds->len);
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
|
|
|
#endif /*INET6*/
|
|
|
|
|
|
|
|
case IPPROTO_RSVP:
|
|
|
|
rsvp_print(ipds->cp, ipds->len);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IPPROTO_GRE:
|
|
|
|
/* do it */
|
2014-03-11 20:08:24 +08:00
|
|
|
gre_print(ndo, ipds->cp, ipds->len);
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IPPROTO_MOBILE:
|
2014-03-07 00:41:44 +08:00
|
|
|
mobile_print(ndo, ipds->cp, ipds->len);
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IPPROTO_PIM:
|
2011-06-14 05:08:51 +08:00
|
|
|
vec[0].ptr = ipds->cp;
|
|
|
|
vec[0].len = ipds->len;
|
2014-03-25 19:05:59 +08:00
|
|
|
pim_print(ndo, ipds->cp, ipds->len, in_cksum(vec, 1));
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IPPROTO_VRRP:
|
2014-03-26 19:47:29 +08:00
|
|
|
if (ndo->ndo_packettype == PT_CARP) {
|
|
|
|
if (ndo->ndo_vflag)
|
|
|
|
ND_PRINT((ndo, "carp %s > %s: ",
|
2011-11-24 03:53:13 +08:00
|
|
|
ipaddr_string(&ipds->ip->ip_src),
|
2014-03-26 19:47:29 +08:00
|
|
|
ipaddr_string(&ipds->ip->ip_dst)));
|
2014-02-25 22:23:45 +08:00
|
|
|
carp_print(ndo, ipds->cp, ipds->len, ipds->ip->ip_ttl);
|
2011-11-24 03:53:13 +08:00
|
|
|
} else {
|
2014-03-26 19:47:29 +08:00
|
|
|
if (ndo->ndo_vflag)
|
|
|
|
ND_PRINT((ndo, "vrrp %s > %s: ",
|
2011-11-24 03:53:13 +08:00
|
|
|
ipaddr_string(&ipds->ip->ip_src),
|
2014-03-26 19:47:29 +08:00
|
|
|
ipaddr_string(&ipds->ip->ip_dst)));
|
2014-03-23 14:28:40 +08:00
|
|
|
vrrp_print(ndo, ipds->cp, ipds->len,
|
2014-02-16 17:08:39 +08:00
|
|
|
(const u_char *)ipds->ip, ipds->ip->ip_ttl);
|
2011-11-24 03:53:13 +08:00
|
|
|
}
|
2005-04-07 05:32:38 +08:00
|
|
|
break;
|
|
|
|
|
2005-05-21 05:02:29 +08:00
|
|
|
case IPPROTO_PGM:
|
2014-03-19 17:57:56 +08:00
|
|
|
pgm_print(ndo, ipds->cp, ipds->len, (const u_char *)ipds->ip);
|
2005-05-21 05:02:29 +08:00
|
|
|
break;
|
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
default:
|
2012-04-08 08:32:04 +08:00
|
|
|
if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL)
|
2005-04-07 05:32:38 +08:00
|
|
|
ND_PRINT((ndo, " %s", proto->p_name));
|
|
|
|
else
|
|
|
|
ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
|
|
|
|
ND_PRINT((ndo, " %d", ipds->len));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-03-29 22:05:15 +08:00
|
|
|
|
2005-04-07 08:28:17 +08:00
|
|
|
void
|
|
|
|
ip_print_inner(netdissect_options *ndo,
|
|
|
|
const u_char *bp,
|
|
|
|
u_int length, u_int nh,
|
|
|
|
const u_char *bp2)
|
|
|
|
{
|
|
|
|
struct ip_print_demux_state ipd;
|
|
|
|
|
|
|
|
ipd.ip = (const struct ip *)bp2;
|
|
|
|
ipd.cp = bp;
|
|
|
|
ipd.len = length;
|
|
|
|
ipd.off = 0;
|
|
|
|
ipd.nh = nh;
|
|
|
|
ipd.advance = 0;
|
|
|
|
|
|
|
|
ip_print_demux(ndo, &ipd);
|
|
|
|
}
|
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
|
1999-10-08 07:47:09 +08:00
|
|
|
/*
|
|
|
|
* print an IP datagram.
|
|
|
|
*/
|
|
|
|
void
|
2005-04-07 05:32:38 +08:00
|
|
|
ip_print(netdissect_options *ndo,
|
|
|
|
const u_char *bp,
|
|
|
|
u_int length)
|
1999-10-08 07:47:09 +08:00
|
|
|
{
|
2005-04-07 05:32:38 +08:00
|
|
|
struct ip_print_demux_state ipd;
|
|
|
|
struct ip_print_demux_state *ipds=&ipd;
|
2003-11-19 08:17:32 +08:00
|
|
|
const u_char *ipend;
|
2005-04-07 08:28:17 +08:00
|
|
|
u_int hlen;
|
2011-06-14 05:08:51 +08:00
|
|
|
struct cksum_vec vec[1];
|
2003-04-24 20:51:35 +08:00
|
|
|
u_int16_t sum, ip_sum;
|
2005-04-07 05:32:38 +08:00
|
|
|
struct protoent *proto;
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
ipds->ip = (const struct ip *)bp;
|
|
|
|
if (IP_V(ipds->ip) != 4) { /* print version if != 4 */
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "IP%u ", IP_V(ipds->ip)));
|
2005-04-07 05:32:38 +08:00
|
|
|
if (IP_V(ipds->ip) == 6)
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ", wrong link-layer encapsulation"));
|
2003-05-26 00:40:48 +08:00
|
|
|
}
|
2014-03-26 19:47:29 +08:00
|
|
|
else if (!ndo->ndo_eflag)
|
|
|
|
ND_PRINT((ndo, "IP "));
|
2003-05-26 00:40:48 +08:00
|
|
|
|
2010-10-08 02:36:49 +08:00
|
|
|
if ((u_char *)(ipds->ip + 1) > ndo->ndo_snapend) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "%s", tstr));
|
1999-10-08 07:47:09 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (length < sizeof (struct ip)) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "truncated-ip %u", length));
|
1999-10-08 07:47:09 +08:00
|
|
|
return;
|
|
|
|
}
|
2005-04-07 08:28:17 +08:00
|
|
|
hlen = IP_HL(ipds->ip) * 4;
|
|
|
|
if (hlen < sizeof (struct ip)) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "bad-hlen %u", hlen));
|
2000-01-25 09:03:23 +08:00
|
|
|
return;
|
|
|
|
}
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len);
|
|
|
|
if (length < ipds->len)
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "truncated-ip - %u bytes missing! ",
|
|
|
|
ipds->len - length));
|
2005-04-07 08:28:17 +08:00
|
|
|
if (ipds->len < hlen) {
|
2005-01-21 16:02:06 +08:00
|
|
|
#ifdef GUESS_TSO
|
2005-04-07 05:32:38 +08:00
|
|
|
if (ipds->len) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "bad-len %u", ipds->len));
|
2005-01-21 16:02:06 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* we guess that it is a TSO send */
|
2005-04-07 05:32:38 +08:00
|
|
|
ipds->len = length;
|
2005-01-21 16:02:06 +08:00
|
|
|
}
|
|
|
|
#else
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "bad-len %u", ipds->len));
|
2005-01-21 16:02:06 +08:00
|
|
|
return;
|
|
|
|
#endif /* GUESS_TSO */
|
2003-11-19 08:17:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Cut off the snapshot length to the end of the IP payload.
|
|
|
|
*/
|
2005-04-07 05:32:38 +08:00
|
|
|
ipend = bp + ipds->len;
|
2010-10-08 02:36:49 +08:00
|
|
|
if (ipend < ndo->ndo_snapend)
|
|
|
|
ndo->ndo_snapend = ipend;
|
2003-11-19 08:17:32 +08:00
|
|
|
|
2005-04-07 08:28:17 +08:00
|
|
|
ipds->len -= hlen;
|
1999-10-08 07:47:09 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off);
|
2002-07-21 07:37:40 +08:00
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
if (ndo->ndo_vflag) {
|
|
|
|
ND_PRINT((ndo, "(tos 0x%x", (int)ipds->ip->ip_tos));
|
2002-07-15 03:46:51 +08:00
|
|
|
/* ECN bits */
|
2005-04-07 05:32:38 +08:00
|
|
|
if (ipds->ip->ip_tos & 0x03) {
|
|
|
|
switch (ipds->ip->ip_tos & 0x03) {
|
2002-07-15 03:46:51 +08:00
|
|
|
case 1:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ",ECT(1)"));
|
2002-07-15 03:46:51 +08:00
|
|
|
break;
|
|
|
|
case 2:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ",ECT(0)"));
|
2002-07-15 03:46:51 +08:00
|
|
|
break;
|
|
|
|
case 3:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ",CE"));
|
2002-07-15 03:46:51 +08:00
|
|
|
}
|
2002-07-14 22:14:50 +08:00
|
|
|
}
|
2002-07-15 03:46:51 +08:00
|
|
|
|
2005-04-07 05:32:38 +08:00
|
|
|
if (ipds->ip->ip_ttl >= 1)
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ", ttl %u", ipds->ip->ip_ttl));
|
2002-07-14 22:14:50 +08:00
|
|
|
|
2003-04-24 20:51:35 +08:00
|
|
|
/*
|
|
|
|
* for the firewall guys, print id, offset.
|
|
|
|
* On all but the last stick a "+" in the flags portion.
|
|
|
|
* For unfragmented datagrams, note the don't fragment flag.
|
|
|
|
*/
|
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ", id %u, offset %u, flags [%s], proto %s (%u)",
|
2005-04-07 05:32:38 +08:00
|
|
|
EXTRACT_16BITS(&ipds->ip->ip_id),
|
|
|
|
(ipds->off & 0x1fff) * 8,
|
2007-01-17 22:07:36 +08:00
|
|
|
bittok2str(ip_frag_values, "none", ipds->off&0xe000),
|
2005-04-07 05:32:38 +08:00
|
|
|
tok2str(ipproto_values,"unknown",ipds->ip->ip_p),
|
2014-03-26 19:47:29 +08:00
|
|
|
ipds->ip->ip_p));
|
2002-12-29 01:59:09 +08:00
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ", length %u", EXTRACT_16BITS(&ipds->ip->ip_len)));
|
2002-12-29 01:59:09 +08:00
|
|
|
|
2005-04-07 08:28:17 +08:00
|
|
|
if ((hlen - sizeof(struct ip)) > 0) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ", options ("));
|
|
|
|
ip_optprint(ndo, (u_char *)(ipds->ip + 1), hlen - sizeof(struct ip));
|
|
|
|
ND_PRINT((ndo, ")"));
|
2002-12-29 01:59:09 +08:00
|
|
|
}
|
2003-04-24 20:51:35 +08:00
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
if (!ndo->ndo_Kflag && (u_char *)ipds->ip + hlen <= ndo->ndo_snapend) {
|
2011-06-14 05:08:51 +08:00
|
|
|
vec[0].ptr = (const u_int8_t *)(void *)ipds->ip;
|
|
|
|
vec[0].len = hlen;
|
|
|
|
sum = in_cksum(vec, 1);
|
2003-04-24 20:51:35 +08:00
|
|
|
if (sum != 0) {
|
2005-04-07 05:32:38 +08:00
|
|
|
ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum);
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ", bad cksum %x (->%x)!", ip_sum,
|
|
|
|
in_cksum_shouldbe(ip_sum, sum)));
|
2003-04-24 20:51:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, ")\n "));
|
2002-07-14 22:14:50 +08:00
|
|
|
}
|
|
|
|
|
1999-10-08 07:47:09 +08:00
|
|
|
/*
|
|
|
|
* If this is fragment zero, hand it to the next higher
|
|
|
|
* level protocol.
|
|
|
|
*/
|
2005-04-07 05:32:38 +08:00
|
|
|
if ((ipds->off & 0x1fff) == 0) {
|
2005-04-07 08:28:17 +08:00
|
|
|
ipds->cp = (const u_char *)ipds->ip + hlen;
|
2005-04-07 05:32:38 +08:00
|
|
|
ipds->nh = ipds->ip->ip_p;
|
|
|
|
|
|
|
|
if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP &&
|
2005-09-20 14:01:20 +08:00
|
|
|
ipds->nh != IPPROTO_SCTP && ipds->nh != IPPROTO_DCCP) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "%s > %s: ",
|
2005-04-07 05:32:38 +08:00
|
|
|
ipaddr_string(&ipds->ip->ip_src),
|
2014-03-26 19:47:29 +08:00
|
|
|
ipaddr_string(&ipds->ip->ip_dst)));
|
1999-10-18 06:18:00 +08:00
|
|
|
}
|
2005-04-07 05:32:38 +08:00
|
|
|
ip_print_demux(ndo, ipds);
|
2003-04-24 20:51:35 +08:00
|
|
|
} else {
|
|
|
|
/* Ultra quiet now means that all this stuff should be suppressed */
|
2014-03-26 19:47:29 +08:00
|
|
|
if (ndo->ndo_qflag > 1) return;
|
2003-04-24 20:51:35 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* if this isn't the first frag, we're missing the
|
|
|
|
* next level protocol header. print the ip addr
|
|
|
|
* and the protocol.
|
|
|
|
*/
|
2014-03-26 19:47:29 +08:00
|
|
|
if (ipds->off & 0x1fff) {
|
|
|
|
ND_PRINT((ndo, "%s > %s:", ipaddr_string(&ipds->ip->ip_src),
|
|
|
|
ipaddr_string(&ipds->ip->ip_dst)));
|
|
|
|
if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
|
|
|
|
ND_PRINT((ndo, " %s", proto->p_name));
|
|
|
|
else
|
|
|
|
ND_PRINT((ndo, " ip-proto-%d", ipds->ip->ip_p));
|
|
|
|
}
|
1999-10-08 07:47:09 +08:00
|
|
|
}
|
|
|
|
}
|
2000-07-11 09:22:38 +08:00
|
|
|
|
|
|
|
void
|
2014-03-13 00:02:32 +08:00
|
|
|
ipN_print(netdissect_options *ndo, register const u_char *bp, register u_int length)
|
2000-07-11 09:22:38 +08:00
|
|
|
{
|
2014-01-19 04:06:36 +08:00
|
|
|
struct ip hdr;
|
2000-07-11 09:22:38 +08:00
|
|
|
|
|
|
|
if (length < 4) {
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "truncated-ip %d", length));
|
2000-07-11 09:22:38 +08:00
|
|
|
return;
|
|
|
|
}
|
2014-01-19 04:06:36 +08:00
|
|
|
memcpy (&hdr, bp, 4);
|
2000-10-03 10:54:54 +08:00
|
|
|
switch (IP_V(&hdr)) {
|
2000-07-11 09:22:38 +08:00
|
|
|
case 4:
|
2014-03-13 00:02:32 +08:00
|
|
|
ip_print (ndo, bp, length);
|
2001-01-28 16:18:27 +08:00
|
|
|
return;
|
2000-07-11 09:22:38 +08:00
|
|
|
#ifdef INET6
|
|
|
|
case 6:
|
2014-03-13 00:02:32 +08:00
|
|
|
ip6_print (ndo, bp, length);
|
2001-01-28 16:18:27 +08:00
|
|
|
return;
|
2000-07-11 09:22:38 +08:00
|
|
|
#endif
|
|
|
|
default:
|
2014-03-26 19:47:29 +08:00
|
|
|
ND_PRINT((ndo, "unknown ip %d", IP_V(&hdr)));
|
2001-01-28 16:18:27 +08:00
|
|
|
return;
|
2000-07-11 09:22:38 +08:00
|
|
|
}
|
|
|
|
}
|
2002-07-14 22:14:50 +08:00
|
|
|
|
2005-04-07 08:28:17 +08:00
|
|
|
/*
|
|
|
|
* Local Variables:
|
|
|
|
* c-style: whitesmith
|
|
|
|
* c-basic-offset: 8
|
|
|
|
* End:
|
|
|
|
*/
|
2002-07-14 22:14:50 +08:00
|
|
|
|
2002-10-04 00:00:32 +08:00
|
|
|
|