#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.109 2002-07-21 20:48:26 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.117 2002-12-11 07:14:02 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/socket.h>
+#include <tcpdump-stdinc.h>
-#include <netinet/in.h>
-
-#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
#include "addrtoname.h"
#include "interface.h"
printf("%s}", ptr == len? "#" : "");
}
+/*
+ * If source-routing is present, return the final destination.
+ * Otherwise, return IP destination.
+ *
+ * This is used for UDP and TCP pseudo-header in the checksum
+ * calculation.
+ */
+u_int32_t
+ip_finddst(const struct ip *ip)
+{
+ int length;
+ int len;
+ const u_char *cp;
+ u_int32_t retval;
+
+ cp = (const u_char *)(ip + 1);
+ length = (IP_HL(ip) << 2) - sizeof(struct ip);
+
+ for (; length > 0; cp += len, length -= len) {
+ int tt = *cp;
+
+ if (tt == IPOPT_NOP || tt == IPOPT_EOL)
+ len = 1;
+ else {
+ if (&cp[1] >= snapend) {
+ return 0;
+ }
+ len = cp[1];
+ }
+ if (len <= 0) {
+ return 0;
+ }
+ if (&cp[1] >= snapend || cp + len > snapend) {
+ return 0;
+ }
+ switch (tt) {
+
+ case IPOPT_SSRR:
+ case IPOPT_LSRR:
+ memcpy(&retval, cp + len - 4, 4);
+ return retval;
+ }
+ }
+ return ip->ip_dst.s_addr;
+}
+
static void
ip_printts(register const u_char *cp, u_int length)
{
register u_int ptr = cp[2] - 1;
register u_int len = 0;
int hoplen;
- char *type;
+ const char *type;
printf(" TS{");
hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
struct protoent *proto;
ip = (const struct ip *)bp;
-#ifdef LBL_ALIGN
- /*
- * If the IP header is not aligned, copy into abuf.
- */
- if ((long)ip & 3) {
- static u_char *abuf = NULL;
- static int didwarn = 0;
-
- if (abuf == NULL) {
- abuf = (u_char *)malloc(snaplen);
- if (abuf == NULL)
- error("ip_print: malloc");
- }
- memcpy((char *)abuf, (char *)ip, min(length, snaplen));
- snapend += abuf - (u_char *)ip;
- packetp = abuf;
- ip = (struct ip *)abuf;
- /* We really want libpcap to give us aligned packets */
- if (!didwarn) {
- warning("compensating for unaligned libpcap packets");
- ++didwarn;
- }
- }
-#endif
if ((u_char *)(ip + 1) > snapend) {
printf("[|ip]");
return;
return;
}
- len = ntohs(ip->ip_len);
+ len = EXTRACT_16BITS(&ip->ip_len);
if (length < len)
(void)printf("truncated-ip - %d bytes missing! ",
len - length);
printf("IP ");
- off = ntohs(ip->ip_off);
+ off = EXTRACT_16BITS(&ip->ip_off);
if (vflag) {
(void)printf("(tos 0x%x", (int)ip->ip_tos);
}
if (ip->ip_ttl >= 1)
- (void)printf(", ttl %d", (int)ip->ip_ttl);
+ (void)printf(", ttl %u", ip->ip_ttl);
if ((off & 0x3fff) == 0)
- (void)printf(", id %d", (int)ntohs(ip->ip_id));
- (void)printf(", len %d) ", (int)ntohs(ip->ip_len));
+ (void)printf(", id %u", EXTRACT_16BITS(&ip->ip_id));
+ (void)printf(", len %u) ", EXTRACT_16BITS(&ip->ip_len));
}
/*
#endif
case IPPROTO_AH:
nh = *cp;
- advance = ah_print(cp, (const u_char *)ip);
+ advance = ah_print(cp);
cp += advance;
len -= advance;
goto again;
case IPPROTO_IPCOMP:
{
int enh;
- advance = ipcomp_print(cp, (const u_char *)ip, &enh);
+ advance = ipcomp_print(cp, &enh);
cp += advance;
len -= advance;
if (enh < 0)
break;
case IPPROTO_EGP:
- egp_print(cp, len, (const u_char *)ip);
+ egp_print(cp);
break;
#ifndef IPPROTO_OSPF
break;
#endif /*INET6*/
+#ifndef IPPROTO_RSVP
+#define IPPROTO_RSVP 46
+#endif
+ case IPPROTO_RSVP:
+ rsvp_print(cp, len);
+ break;
#ifndef IPPROTO_GRE
#define IPPROTO_GRE 47
#ifndef IP_DF
#define IP_DF 0x4000
#endif /* IP_DF */
- (void)printf(" (frag %d:%u@%d%s)", ntohs(ip->ip_id), len,
+ (void)printf(" (frag %u:%u@%u%s)", EXTRACT_16BITS(&ip->ip_id), len,
(off & 0x1fff) * 8,
(off & IP_MF)? "+" : "");
if (vflag) {
u_int16_t sum, ip_sum;
- char *sep = "";
+ const char *sep = "";
if ((u_char *)ip + hlen <= snapend) {
sum = in_cksum((const u_short *)ip, hlen, 0);
if (sum != 0) {
- ip_sum = ntohs(ip->ip_sum);
+ ip_sum = EXTRACT_16BITS(&ip->ip_sum);
(void)printf("%sbad cksum %x (->%x)!", sep,
ip_sum,
in_cksum_shouldbe(ip_sum, sum));
}
+