📄 _ip.c
字号:
break;
}
}
}
#if !defined(USE_FAST_CKSUM) /* if not using fast version in libwatt.a */
/*
* compute an IP header checksum.
* don't modifiy the packet.
*/
u_short in_cksum (register u_short *addr, register int len, u_short csum)
{
register int nleft = len;
register u_short *w = addr;
register u_short answer;
register int sum = csum;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum),
* we add sequential 16 bit words to it, and at the end, fold
* back all the carry bits from the top 16 bits into the lower
* 16 bits.
*/
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary
*/
if (nleft == 1)
sum += htons (*(u_char*)w << 8);
/* add back carry outs from top 16 bits to low 16 bits
*/
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
#endif
/*
* print an IP datagram.
*/
void ip_print (const u_char *bp, u_int length)
{
const struct ip *ip = (const struct ip *) bp;
const u_char *cp;
u_int hlen, len, len0, off;
u_char nh;
u_long advance;
int enh; /* encapsulated header */
#ifdef TCPDUMP_ALIGN
/*
* If the IP header is not aligned, copy into abuf.
* This will never happen with BPF. It does happen raw packet
* dumps from -r.
*/
if ((long) ip & 3)
{
static u_char *abuf = NULL;
static int didwarn = 0;
if (abuf == NULL)
{
abuf = malloc (snaplen);
if (abuf == NULL)
error ("ip_print: malloc");
}
memcpy (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)
{
PUTS ("[|ip]");
return;
}
if (length < sizeof(struct ip))
{
if (partial_frame)
PRINTF ("[||ip]");
else PRINTF ("truncated-ip %d\n", length);
return;
}
if (IP_HL(ip) == 0)
{
PUTS ("bad packet - header length = 0");
return;
}
hlen = IP_HL(ip) * 4;
if (hlen < sizeof(struct ip))
{
PRINTF ("bad-hlen %d", hlen);
return;
}
len = ntohs (ip->ip_len);
if (length < len && !partial_frame)
PRINTF ("truncated-ip - %d bytes missing!\n", len - length);
len -= hlen;
len0 = len;
/*
* If this is fragment zero, hand it to the next higher
* level protocol.
*/
off = ntohs (ip->ip_off);
if (off & 0x2000)
partial_frame++;
if ((off & 0x1fff) == 0)
{
cp = (const u_char *) ip + hlen;
nh = ip->ip_p;
if (nh != IPPROTO_TCP && nh != IPPROTO_UDP)
PRINTF ("%s > %s: ",
ipaddr_string (&ip->ip_src),
ipaddr_string (&ip->ip_dst));
again:
switch (nh)
{
case IPPROTO_AH:
nh = *cp;
advance = ah_print (cp);
cp += advance;
len -= advance;
if (advance >= USHRT_MAX)
break;
goto again;
case IPPROTO_ESP:
advance = esp_print (cp, (const u_char*)ip, &enh);
cp += advance;
len -= advance;
if (enh < 0 || advance >= USHRT_MAX)
break;
nh = enh & 0xff;
goto again;
case IPPROTO_IPCOMP:
advance = ipcomp_print (cp, (const u_char *) ip, &enh);
cp += advance;
len -= advance;
if (enh < 0 || advance >= USHRT_MAX)
break;
nh = enh & 0xff;
goto again;
case IPPROTO_TCP:
tcp_print (cp, len, (const u_char *)ip, (off & ~0x6000));
break;
case IPPROTO_UDP:
udp_print (cp, len, (const u_char *)ip, (off & ~0x6000));
break;
case IPPROTO_XTP:
xtp_print (cp, len, (const u_char *)ip);
break;
case IPPROTO_ICMP:
icmp_print (cp, len, (const u_char *)ip);
break;
case IPPROTO_IGRP:
igrp_print (cp, len, (const u_char *) ip);
break;
case IPPROTO_ND:
PRINTF (" nd %d", len);
break;
case IPPROTO_EGP:
egp_print (cp, len, (const u_char *) ip);
break;
case IPPROTO_OSPF:
ospf_print (cp, len, (const u_char *) ip);
break;
case IPPROTO_IGMP:
igmp_print (cp, len, (const u_char *) ip);
break;
case IPPROTO_DVMRP: /* multicast tunnel (ip-in-ip encapsulation) */
ip_print (cp, len);
if (!vflag)
{
PUTS (" (ipip)");
return;
}
break;
#ifdef USE_INET6
case IP6PROTO_ENCAP: /* ip6-in-ip encapsulation */
case IPPROTO_IPV6:
ip6_print (cp, len);
if (!vflag)
{
PUTS (" (encap)");
return;
}
break;
#endif
case IPPROTO_GRE:
gre_print (cp, len);
if (!vflag)
{
PUTS (" (gre encap)");
return;
}
break;
case IPPROTO_MOBILE:
mobile_print (cp, len);
if (!vflag)
{
PUTS (" (mobile encap)");
return;
}
break;
case IPPROTO_PIM:
pim_print (cp, len);
break;
case IPPROTO_RSVP:
PUTS (" rsvp");
#ifdef USE_RSVP
ntoh_rsvp_packet (cp, len);
rsvp_print_pkt (cp, len);
#endif
break;
case IPPROTO_AXIP:
axip_print (cp, len, (const u_char *)ip);
break;
#ifndef IPPROTO_VRRP
#define IPPROTO_VRRP 112
#endif
case IPPROTO_VRRP:
if (vflag)
PRINTF ("vrrp %s > %s: ",
ipaddr_string (&ip->ip_src),
ipaddr_string (&ip->ip_dst));
vrrp_print (cp, len, ip->ip_ttl);
break;
default:
PRINTF (" ip-proto-%d %d", nh, len);
break;
}
}
if (off & 0x2000)
partial_frame--;
/* Ultra quiet now means that all this stuff should be suppressed
*/
if (qflag > 1)
return;
/*
* for fragmented datagrams, print id:size@offset. On all
* but the last stick a "+". For unfragmented datagrams, note
* the don't fragment flag.
*/
len = len0; /* get the original length */
if (off & 0x3fff)
{
/*
* if this isn't the first frag, we're missing the
* next level protocol header. print the ip addr.
*/
if (off & 0x1fff)
PRINTF ("%s > %s:", ipaddr_string (&ip->ip_src),
ipaddr_string (&ip->ip_dst));
PRINTF (" (frag %d:%d@%d%s)", ntohs (ip->ip_id), len,
(off & 0x1fff) * 8,
(off & IP_MF) ? "+" : "");
}
else if (off & IP_DF)
PUTS (" (DF)");
if (ip->ip_tos)
{
PRINTF (" [tos 0x%x", (int) ip->ip_tos);
/* ECN bits */
if (ip->ip_tos &0x01)
PUTS (",CE");
if (ip->ip_tos &0x02)
PUTS (",ECT");
PUTS ("] ");
}
if (ip->ip_ttl <= 1)
PRINTF (" [ttl %d]", (int) ip->ip_ttl);
if (vflag)
{
int sum;
char *sep = "";
PUTS (" (");
if (ip->ip_ttl > 1)
{
PRINTF ("%sttl %d", sep, (int)ip->ip_ttl);
sep = ", ";
}
if ((off & 0x3fff) == 0)
{
PRINTF ("%sid %d", sep, (int)ntohs(ip->ip_id));
sep = ", ";
}
if ((u_char*)ip + hlen <= snapend)
{
sum = in_cksum ((u_short*)ip, hlen, 0);
if (sum != 0)
{
PRINTF ("%sbad cksum %x!", sep, ntohs(ip->ip_sum));
sep = ", ";
}
}
hlen -= sizeof(struct ip);
if (hlen > 0)
{
PRINTF ("%soptlen=%d", sep, hlen);
ip_optprint ((u_char *) (ip + 1), hlen);
}
PUTCHAR (')');
}
}
void ipN_print (const u_char * bp, u_int length)
{
struct ip *ip, hdr;
ip = (struct ip *) bp;
if (length < 4)
{
PRINTF ("truncated-ip %d", length);
return;
}
memcpy (&hdr, (char*)ip, 4);
switch (IP_V (&hdr))
{
case 4:
ip_print (bp, length);
return;
#ifdef USE_INET6
case 6:
ip6_print (bp, length);
return;
#endif
default:
PRINTF ("unknown ip %d", IP_V(&hdr));
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -