* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#ifndef lint
-static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.159 2007-09-14 01:29:28 guy Exp $ (LBL)";
-#endif
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "ip.h"
#include "ipproto.h"
-struct tok ip_option_values[] = {
+static const char tstr[] = "[|ip]";
+
+static const struct tok ip_option_values[] = {
{ IPOPT_EOL, "EOL" },
{ IPOPT_NOP, "NOP" },
{ IPOPT_TS, "timestamp" },
* This is used for UDP and TCP pseudo-header in the checksum
* calculation.
*/
-u_int32_t
+static u_int32_t
ip_finddst(const struct ip *ip)
{
int length;
case IPOPT_LSRR:
if (len < 7)
break;
- memcpy(&retval, cp + len - 4, 4);
+ UNALIGNED_MEMCPY(&retval, cp + len - 4, 4);
return retval;
}
}
trunc:
- memcpy(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t));
+ UNALIGNED_MEMCPY(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t));
return retval;
}
+/*
+ * Compute a V4-style checksum by building a pseudoheader.
+ */
+int
+nextproto4_cksum(const struct ip *ip, const u_int8_t *data,
+ u_int len, u_int next_proto)
+{
+ 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;
+ UNALIGNED_MEMCPY(&ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
+ if (IP_HL(ip) == 5)
+ UNALIGNED_MEMCPY(&ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));
+ else
+ ph.dst = ip_finddst(ip);
+
+ vec[0].ptr = (const u_int8_t *)(void *)&ph;
+ vec[0].len = sizeof(ph);
+ vec[1].ptr = data;
+ vec[1].len = len;
+ return (in_cksum(vec, 2));
+}
+
static void
ip_printts(register const u_char *cp, u_int length)
{
return;
trunc:
- printf("[|ip]");
+ printf("%s", tstr);
}
#define IP_RES 0x8000
-static struct tok ip_frag_values[] = {
+static const struct tok ip_frag_values[] = {
{ IP_MF, "+" },
{ IP_DF, "DF" },
{ IP_RES, "rsvd" }, /* The RFC3514 evil ;-) bit */
ipds->nh = enh & 0xff;
goto again;
}
-
+
case IPPROTO_IPCOMP:
{
int enh;
case IPPROTO_DCCP:
dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
break;
-
+
case IPPROTO_TCP:
/* pass on the MF bit plus the offset to detect fragments */
tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
ipds->off & (IP_MF|IP_OFFMASK));
break;
-
+
case IPPROTO_UDP:
/* pass on the MF bit plus the offset to detect fragments */
udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
ipds->off & (IP_MF|IP_OFFMASK));
break;
-
+
case IPPROTO_ICMP:
/* pass on the MF bit plus the offset to detect fragments */
icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
ipds->off & (IP_MF|IP_OFFMASK));
break;
-
+
case IPPROTO_PIGP:
/*
* XXX - the current IANA protocol number assignments
*/
igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
break;
-
+
case IPPROTO_EIGRP:
eigrp_print(ipds->cp, ipds->len);
break;
-
+
case IPPROTO_ND:
ND_PRINT((ndo, " nd %d", ipds->len));
break;
return;
}
break;
-
+
#ifdef INET6
case IPPROTO_IPV6:
/* ip6-in-ip encapsulation */
break;
case IPPROTO_VRRP:
- vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
+ if (packettype == PT_CARP) {
+ if (vflag)
+ (void)printf("carp %s > %s: ",
+ ipaddr_string(&ipds->ip->ip_src),
+ ipaddr_string(&ipds->ip->ip_dst));
+ carp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
+ } else {
+ if (vflag)
+ (void)printf("vrrp %s > %s: ",
+ ipaddr_string(&ipds->ip->ip_src),
+ ipaddr_string(&ipds->ip->ip_dst));
+ vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
+ }
break;
case IPPROTO_PGM:
break;
default:
- if ((proto = getprotobynumber(ipds->nh)) != NULL)
+ if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL)
ND_PRINT((ndo, " %s", proto->p_name));
else
ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
break;
}
}
-
+
void
ip_print_inner(netdissect_options *ndo,
const u_char *bp,
printf("IP ");
if ((u_char *)(ipds->ip + 1) > ndo->ndo_snapend) {
- printf("[|ip]");
+ printf("%s", tstr);
return;
}
if (length < sizeof (struct ip)) {
}
if (ipds->ip->ip_ttl >= 1)
- (void)printf(", ttl %u", ipds->ip->ip_ttl);
+ (void)printf(", ttl %u", ipds->ip->ip_ttl);
/*
* for the firewall guys, print id, offset.
if (ipds->off & 0x1fff) {
(void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src),
ipaddr_string(&ipds->ip->ip_dst));
- if ((proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
+ if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
(void)printf(" %s", proto->p_name);
else
(void)printf(" ip-proto-%d", ipds->ip->ip_p);
- }
+ }
}
}
void
ipN_print(register const u_char *bp, register u_int length)
{
- struct ip *ip, hdr;
+ struct ip hdr;
- ip = (struct ip *)bp;
if (length < 4) {
(void)printf("truncated-ip %d", length);
return;
}
- memcpy (&hdr, (char *)ip, 4);
+ memcpy (&hdr, bp, 4);
switch (IP_V(&hdr)) {
case 4:
ip_print (gndo, bp, length);