*/
#ifndef lint
-static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.107 2003-11-05 06:03:01 guy Exp $ (LBL)";
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.107.2.5 2004-07-28 20:11:31 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
static int tcp_cksum(register const struct ip *ip,
register const struct tcphdr *tp,
- register int len)
+ register u_int len)
{
union phu {
struct phdr {
const u_int16_t *sp;
/* pseudo-header.. */
- phu.ph.len = htons(len); /* XXX */
+ phu.ph.len = htons((u_int16_t)len);
phu.ph.mbz = 0;
phu.ph.proto = IPPROTO_TCP;
memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
#ifdef INET6
static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp,
- int len)
+ u_int len)
{
- size_t i, tlen;
+ size_t i;
register const u_int16_t *sp;
u_int32_t sum;
union {
u_int16_t pa[20];
} phu;
- tlen = EXTRACT_16BITS(&ip6->ip6_plen) + sizeof(struct ip6_hdr) -
- ((const char *)tp - (const char*)ip6);
-
/* pseudo-header */
memset(&phu, 0, sizeof(phu));
phu.ph.ph_src = ip6->ip6_src;
phu.ph.ph_dst = ip6->ip6_dst;
- phu.ph.ph_len = htonl(tlen);
+ phu.ph.ph_len = htonl(len);
phu.ph.ph_nxt = IPPROTO_TCP;
sum = 0;
sp = (const u_int16_t *)tp;
- for (i = 0; i < (tlen & ~1); i += 2)
+ for (i = 0; i < (len & ~1); i += 2)
sum += *sp++;
- if (tlen & 1)
+ if (len & 1)
sum += htons((*(const u_int8_t *)sp) << 8);
while (sum > 0xffff)
hlen = TH_OFF(tp) * 4;
/*
- * If data present and NFS port used, assume NFS.
+ * If data present, header length valid, and NFS port used,
+ * assume NFS.
* Pass offset of data plus 4 bytes for RPC TCP msg length
* to NFS print routines.
*/
- if (!qflag) {
+ if (!qflag && hlen >= sizeof(*tp) && hlen <= length) {
if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend &&
dport == NFS_PORT) {
nfsreq_print((u_char *)tp + hlen + 4, length - hlen,
}
}
+ if (hlen < sizeof(*tp)) {
+ (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
+ length - hlen, hlen, (unsigned long)sizeof(*tp));
+ return;
+ }
+
TCHECK(*tp);
seq = EXTRACT_32BITS(&tp->th_seq);
urp = EXTRACT_16BITS(&tp->th_urp);
if (qflag) {
- (void)printf("tcp %d", length - TH_OFF(tp) * 4);
+ (void)printf("tcp %d", length - hlen);
+ if (hlen > length) {
+ (void)printf(" [bad hdr length %u - too long, > %u]",
+ hlen, length);
+ }
return;
}
if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH|
thseq = thack = threv = 0;
}
if (hlen > length) {
- (void)printf(" [bad hdr length]");
+ (void)printf(" [bad hdr length %u - too long, > %u]",
+ hlen, length);
return;
}