Don't bother copying the route header - we're using the EXTRACT_ macros,
so we don't have to worry about alignment.
Use the length field from the packet, not just the length of the
containing packet, and check to make sure the containing packet is long
enough to contain it.
Add a bunch of checks against the packet length.
In "default_print()" calls, cut the length off at the captured data
length. In other calls, don't - let the bounds checks handle caplen <
length.
#ifndef lint
static const char rcsid[] _U_ =
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-decnet.c,v 1.38 2003-11-16 09:36:17 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-decnet.c,v 1.39 2005-05-06 02:16:26 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#endif
#ifdef HAVE_CONFIG_H
#include "addrtoname.h"
/* Forwards */
#include "addrtoname.h"
/* Forwards */
-static void print_decnet_ctlmsg(const union routehdr *, u_int);
+static int print_decnet_ctlmsg(const union routehdr *, u_int, u_int);
static void print_t_info(int);
static void print_t_info(int);
-static void print_l1_routes(const char *, u_int);
-static void print_l2_routes(const char *, u_int);
+static int print_l1_routes(const char *, u_int);
+static int print_l2_routes(const char *, u_int);
static void print_i_info(int);
static void print_i_info(int);
-static void print_elist(const char *, u_int);
-static void print_nsp(const u_char *, u_int);
+static int print_elist(const char *, u_int);
+static int print_nsp(const u_char *, u_int);
static void print_reason(int);
#ifdef PRINT_NSPDATA
static void pdata(u_char *, int);
static void print_reason(int);
#ifdef PRINT_NSPDATA
static void pdata(u_char *, int);
decnet_print(register const u_char *ap, register u_int length,
register u_int caplen)
{
decnet_print(register const u_char *ap, register u_int length,
register u_int caplen)
{
- static union routehdr rhcopy;
- register union routehdr *rhp = &rhcopy;
+ register const union routehdr *rhp;
register int mflags;
int dst, src, hops;
register int mflags;
int dst, src, hops;
- u_int rhlen, nsplen, pktlen;
const u_char *nspp;
if (length < sizeof(struct shorthdr)) {
const u_char *nspp;
if (length < sizeof(struct shorthdr)) {
+ TCHECK2(*ap, sizeof(short));
pktlen = EXTRACT_LE_16BITS(ap);
pktlen = EXTRACT_LE_16BITS(ap);
+ if (pktlen < sizeof(struct shorthdr)) {
+ (void)printf("[|decnet]");
+ return;
+ }
+ if (pktlen > length) {
+ (void)printf("[|decnet]");
+ return;
+ }
+ length = pktlen;
- rhlen = min(length, caplen);
- rhlen = min(rhlen, sizeof(*rhp));
- memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
-
+ rhp = (const union routehdr *)&(ap[sizeof(short)]);
+ TCHECK(rhp->rh_short.sh_flags);
mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
if (mflags & RMF_PAD) {
mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
if (mflags & RMF_PAD) {
u_int padlen = mflags & RMF_PADMASK;
if (vflag)
(void) printf("[pad:%d] ", padlen);
u_int padlen = mflags & RMF_PADMASK;
if (vflag)
(void) printf("[pad:%d] ", padlen);
+ if (length < padlen + 2) {
+ (void)printf("[|decnet]");
+ return;
+ }
+ TCHECK2(ap[sizeof(short)], padlen);
ap += padlen;
length -= padlen;
caplen -= padlen;
ap += padlen;
length -= padlen;
caplen -= padlen;
- rhlen = min(length, caplen);
- rhlen = min(rhlen, sizeof(*rhp));
- memcpy((char *)rhp, (char *)&(ap[sizeof(short)]), rhlen);
+ rhp = (const union routehdr *)&(ap[sizeof(short)]);
mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
}
if (mflags & RMF_FVER) {
(void) printf("future-version-decnet");
mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
}
if (mflags & RMF_FVER) {
(void) printf("future-version-decnet");
- default_print(ap, length);
+ default_print(ap, min(length, caplen));
return;
}
/* is it a control message? */
if (mflags & RMF_CTLMSG) {
return;
}
/* is it a control message? */
if (mflags & RMF_CTLMSG) {
- print_decnet_ctlmsg(rhp, min(length, caplen));
+ if (!print_decnet_ctlmsg(rhp, length, caplen))
+ goto trunc;
return;
}
switch (mflags & RMF_MASK) {
case RMF_LONG:
return;
}
switch (mflags & RMF_MASK) {
case RMF_LONG:
+ if (length < sizeof(struct longhdr)) {
+ (void)printf("[|decnet]");
+ return;
+ }
+ TCHECK(rhp->rh_long);
dst =
EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
src =
EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits);
nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
dst =
EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
src =
EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits);
nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
- nsplen = min((length - sizeof(struct longhdr)),
- (caplen - sizeof(struct longhdr)));
+ nsplen = length - sizeof(struct longhdr);
dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst);
src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src);
hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst);
src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src);
hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
- nsplen = min((length - sizeof(struct shorthdr)),
- (caplen - sizeof(struct shorthdr)));
+ nsplen = length - sizeof(struct shorthdr);
break;
default:
(void) printf("unknown message flags under mask");
break;
default:
(void) printf("unknown message flags under mask");
- default_print((u_char *)ap, length);
+ default_print((u_char *)ap, min(length, caplen));
(void)printf("%d hops ", hops);
}
(void)printf("%d hops ", hops);
}
- print_nsp(nspp, nsplen);
+ if (!print_nsp(nspp, nsplen))
+ goto trunc;
+ return;
+
+trunc:
+ (void)printf("[|decnet]");
+ return;
-static void
-print_decnet_ctlmsg(register const union routehdr *rhp, u_int length)
+static int
+print_decnet_ctlmsg(register const union routehdr *rhp, u_int length,
+ u_int caplen)
{
int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
register union controlmsg *cmp = (union controlmsg *)rhp;
{
int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
register union controlmsg *cmp = (union controlmsg *)rhp;
etheraddr srcea, rtea;
int priority;
char *rhpx = (char *)rhp;
etheraddr srcea, rtea;
int priority;
char *rhpx = (char *)rhp;
switch (mflags & RMF_CTLMASK) {
case RMF_INIT:
(void)printf("init ");
switch (mflags & RMF_CTLMASK) {
case RMF_INIT:
(void)printf("init ");
+ if (length < sizeof(struct initmsg))
+ goto trunc;
+ TCHECK(cmp->cm_init);
src = EXTRACT_LE_16BITS(cmp->cm_init.in_src);
info = EXTRACT_LE_8BITS(cmp->cm_init.in_info);
blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize);
src = EXTRACT_LE_16BITS(cmp->cm_init.in_src);
info = EXTRACT_LE_8BITS(cmp->cm_init.in_info);
blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize);
"src %sblksize %d vers %d eco %d ueco %d hello %d",
dnaddr_string(src), blksize, vers, eco, ueco,
hello);
"src %sblksize %d vers %d eco %d ueco %d hello %d",
dnaddr_string(src), blksize, vers, eco, ueco,
hello);
break;
case RMF_VER:
(void)printf("verification ");
break;
case RMF_VER:
(void)printf("verification ");
+ if (length < sizeof(struct verifmsg))
+ goto trunc;
+ TCHECK(cmp->cm_ver);
src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src);
other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval);
(void)printf("src %s fcnval %o", dnaddr_string(src), other);
src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src);
other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval);
(void)printf("src %s fcnval %o", dnaddr_string(src), other);
break;
case RMF_TEST:
(void)printf("test ");
break;
case RMF_TEST:
(void)printf("test ");
+ if (length < sizeof(struct testmsg))
+ goto trunc;
+ TCHECK(cmp->cm_test);
src = EXTRACT_LE_16BITS(cmp->cm_test.te_src);
other = EXTRACT_LE_8BITS(cmp->cm_test.te_data);
(void)printf("src %s data %o", dnaddr_string(src), other);
src = EXTRACT_LE_16BITS(cmp->cm_test.te_src);
other = EXTRACT_LE_8BITS(cmp->cm_test.te_data);
(void)printf("src %s data %o", dnaddr_string(src), other);
break;
case RMF_L1ROUT:
(void)printf("lev-1-routing ");
break;
case RMF_L1ROUT:
(void)printf("lev-1-routing ");
+ if (length < sizeof(struct l1rout))
+ goto trunc;
+ TCHECK(cmp->cm_l1rou);
src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src);
(void)printf("src %s ", dnaddr_string(src));
src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src);
(void)printf("src %s ", dnaddr_string(src));
- print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
+ ret = print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
length - sizeof(struct l1rout));
break;
case RMF_L2ROUT:
(void)printf("lev-2-routing ");
length - sizeof(struct l1rout));
break;
case RMF_L2ROUT:
(void)printf("lev-2-routing ");
+ if (length < sizeof(struct l2rout))
+ goto trunc;
+ TCHECK(cmp->cm_l2rout);
src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src);
(void)printf("src %s ", dnaddr_string(src));
src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src);
(void)printf("src %s ", dnaddr_string(src));
- print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
+ ret = print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
length - sizeof(struct l2rout));
break;
case RMF_RHELLO:
(void)printf("router-hello ");
length - sizeof(struct l2rout));
break;
case RMF_RHELLO:
(void)printf("router-hello ");
+ if (length < sizeof(struct rhellomsg))
+ goto trunc;
+ TCHECK(cmp->cm_rhello);
vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers);
eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco);
ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco);
vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers);
eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco);
ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco);
"vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
vers, eco, ueco, dnaddr_string(src),
blksize, priority, hello);
"vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
vers, eco, ueco, dnaddr_string(src),
blksize, priority, hello);
- print_elist(&(rhpx[sizeof(struct rhellomsg)]),
+ ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]),
length - sizeof(struct rhellomsg));
break;
case RMF_EHELLO:
(void)printf("endnode-hello ");
length - sizeof(struct rhellomsg));
break;
case RMF_EHELLO:
(void)printf("endnode-hello ");
+ if (length < sizeof(struct ehellomsg))
+ goto trunc;
+ TCHECK(cmp->cm_ehello);
vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers);
eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco);
ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco);
vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers);
eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco);
ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco);
"vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
vers, eco, ueco, dnaddr_string(src),
blksize, dnaddr_string(dst), hello, other);
"vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
vers, eco, ueco, dnaddr_string(src),
blksize, dnaddr_string(dst), hello, other);
break;
default:
(void)printf("unknown control message");
break;
default:
(void)printf("unknown control message");
- default_print((u_char *)rhp, length);
+ default_print((u_char *)rhp, min(length, caplen));
+ ret = 1;
+ return (ret);
+
+trunc:
+ return (0);
print_l1_routes(const char *rp, u_int len)
{
int count;
print_l1_routes(const char *rp, u_int len)
{
int count;
/* The last short is a checksum */
while (len > (3 * sizeof(short))) {
/* The last short is a checksum */
while (len > (3 * sizeof(short))) {
+ TCHECK2(*rp, 3 * sizeof(short));
count = EXTRACT_LE_16BITS(rp);
if (count > 1024)
count = EXTRACT_LE_16BITS(rp);
if (count > 1024)
- return; /* seems to be bogus from here on */
+ return (1); /* seems to be bogus from here on */
rp += sizeof(short);
len -= sizeof(short);
id = EXTRACT_LE_16BITS(rp);
rp += sizeof(short);
len -= sizeof(short);
id = EXTRACT_LE_16BITS(rp);
(void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
RI_COST(info), RI_HOPS(info));
}
(void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
RI_COST(info), RI_HOPS(info));
}
+ return (1);
+
+trunc:
+ return (0);
print_l2_routes(const char *rp, u_int len)
{
int count;
print_l2_routes(const char *rp, u_int len)
{
int count;
/* The last short is a checksum */
while (len > (3 * sizeof(short))) {
/* The last short is a checksum */
while (len > (3 * sizeof(short))) {
+ TCHECK2(*rp, 3 * sizeof(short));
count = EXTRACT_LE_16BITS(rp);
if (count > 1024)
count = EXTRACT_LE_16BITS(rp);
if (count > 1024)
- return; /* seems to be bogus from here on */
+ return (1); /* seems to be bogus from here on */
rp += sizeof(short);
len -= sizeof(short);
area = EXTRACT_LE_16BITS(rp);
rp += sizeof(short);
len -= sizeof(short);
area = EXTRACT_LE_16BITS(rp);
(void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
RI_COST(info), RI_HOPS(info));
}
(void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
RI_COST(info), RI_HOPS(info));
}
+ return (1);
+
+trunc:
+ return (0);
print_elist(const char *elp _U_, u_int len _U_)
{
/* Not enough examples available for me to debug this */
print_elist(const char *elp _U_, u_int len _U_)
{
/* Not enough examples available for me to debug this */
-static void
-print_nsp(const u_char *nspp, u_int nsplen _U_)
+static int
+print_nsp(const u_char *nspp, u_int nsplen)
{
const struct nsphdr *nsphp = (struct nsphdr *)nspp;
int dst, src, flags;
{
const struct nsphdr *nsphp = (struct nsphdr *)nspp;
int dst, src, flags;
+ if (nsplen < sizeof(struct nsphdr))
+ goto trunc;
+ TCHECK(*nsphp);
flags = EXTRACT_LE_8BITS(nsphp->nh_flags);
dst = EXTRACT_LE_16BITS(nsphp->nh_dst);
src = EXTRACT_LE_16BITS(nsphp->nh_src);
flags = EXTRACT_LE_8BITS(nsphp->nh_flags);
dst = EXTRACT_LE_16BITS(nsphp->nh_dst);
src = EXTRACT_LE_16BITS(nsphp->nh_src);
#endif
u_int data_off = sizeof(struct minseghdr);
#endif
u_int data_off = sizeof(struct minseghdr);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[0]);
ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
(void)printf("nak %d ", ack & SGQ_MASK);
else
(void)printf("ack %d ", ack & SGQ_MASK);
ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
(void)printf("nak %d ", ack & SGQ_MASK);
else
(void)printf("ack %d ", ack & SGQ_MASK);
- ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
data_off += sizeof(short);
data_off += sizeof(short);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[1]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
if (ack & SGQ_OACK) { /* ackoth field */
if ((ack & SGQ_ONAK) == SGQ_ONAK)
(void)printf("onak %d ", ack & SGQ_MASK);
else
(void)printf("oack %d ", ack & SGQ_MASK);
if (ack & SGQ_OACK) { /* ackoth field */
if ((ack & SGQ_ONAK) == SGQ_ONAK)
(void)printf("onak %d ", ack & SGQ_MASK);
else
(void)printf("oack %d ", ack & SGQ_MASK);
- ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
data_off += sizeof(short);
data_off += sizeof(short);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[2]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
}
}
(void)printf("seg %d ", ack & SGQ_MASK);
#ifdef PRINT_NSPDATA
}
}
(void)printf("seg %d ", ack & SGQ_MASK);
#ifdef PRINT_NSPDATA
- dp = &(nspp[data_off]);
- pdata(dp, 10);
+ if (nsplen > data_off) {
+ dp = &(nspp[data_off]);
+ TCHECK2(*dp, nsplen - data_off);
+ pdata(dp, nsplen - data_off);
+ }
#endif
u_int data_off = sizeof(struct minseghdr);
#endif
u_int data_off = sizeof(struct minseghdr);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[0]);
ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
(void)printf("nak %d ", ack & SGQ_MASK);
else
(void)printf("ack %d ", ack & SGQ_MASK);
ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
(void)printf("nak %d ", ack & SGQ_MASK);
else
(void)printf("ack %d ", ack & SGQ_MASK);
- ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
data_off += sizeof(short);
data_off += sizeof(short);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[1]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
if (ack & SGQ_OACK) { /* ackdat field */
if ((ack & SGQ_ONAK) == SGQ_ONAK)
(void)printf("nakdat %d ", ack & SGQ_MASK);
else
(void)printf("ackdat %d ", ack & SGQ_MASK);
if (ack & SGQ_OACK) { /* ackdat field */
if ((ack & SGQ_ONAK) == SGQ_ONAK)
(void)printf("nakdat %d ", ack & SGQ_MASK);
else
(void)printf("ackdat %d ", ack & SGQ_MASK);
- ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
data_off += sizeof(short);
data_off += sizeof(short);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[2]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
}
}
(void)printf("seg %d ", ack & SGQ_MASK);
#ifdef PRINT_NSPDATA
}
}
(void)printf("seg %d ", ack & SGQ_MASK);
#ifdef PRINT_NSPDATA
- dp = &(nspp[data_off]);
- pdata(dp, 10);
+ if (nsplen > data_off) {
+ dp = &(nspp[data_off]);
+ TCHECK2(*dp, nsplen - data_off);
+ pdata(dp, nsplen - data_off);
+ }
int ack;
int lsflags, fcval;
int ack;
int lsflags, fcval;
+ if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg))
+ goto trunc;
+ TCHECK(shp->sh_seq[0]);
ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
(void)printf("nak %d ", ack & SGQ_MASK);
else
(void)printf("ack %d ", ack & SGQ_MASK);
ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
(void)printf("nak %d ", ack & SGQ_MASK);
else
(void)printf("ack %d ", ack & SGQ_MASK);
+ TCHECK(shp->sh_seq[1]);
ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
if (ack & SGQ_OACK) { /* ackdat field */
if ((ack & SGQ_ONAK) == SGQ_ONAK)
(void)printf("nakdat %d ", ack & SGQ_MASK);
else
(void)printf("ackdat %d ", ack & SGQ_MASK);
ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
if (ack & SGQ_OACK) { /* ackdat field */
if ((ack & SGQ_ONAK) == SGQ_ONAK)
(void)printf("nakdat %d ", ack & SGQ_MASK);
else
(void)printf("ackdat %d ", ack & SGQ_MASK);
+ TCHECK(shp->sh_seq[2]);
ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
}
}
(void)printf("seg %d ", ack & SGQ_MASK);
ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
}
}
(void)printf("seg %d ", ack & SGQ_MASK);
lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags);
fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval);
switch (lsflags & LSI_MASK) {
lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags);
fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval);
switch (lsflags & LSI_MASK) {
struct ackmsg *amp = (struct ackmsg *)nspp;
int ack;
struct ackmsg *amp = (struct ackmsg *)nspp;
int ack;
+ if (nsplen < sizeof(struct ackmsg))
+ goto trunc;
+ TCHECK(*amp);
ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
struct ackmsg *amp = (struct ackmsg *)nspp;
int ack;
struct ackmsg *amp = (struct ackmsg *)nspp;
int ack;
+ if (nsplen < sizeof(struct ackmsg))
+ goto trunc;
+ TCHECK(*amp);
ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
(void)printf("nak %d ", ack & SGQ_MASK);
else
(void)printf("ack %d ", ack & SGQ_MASK);
ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
if (ack & SGQ_ACK) { /* acknum field */
if ((ack & SGQ_NAK) == SGQ_NAK)
(void)printf("nak %d ", ack & SGQ_MASK);
else
(void)printf("ack %d ", ack & SGQ_MASK);
+ TCHECK(amp->ak_acknum[1]);
ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
if (ack & SGQ_OACK) { /* ackdat field */
if ((ack & SGQ_ONAK) == SGQ_ONAK)
ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
if (ack & SGQ_OACK) { /* ackdat field */
if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ if (nsplen < sizeof(struct cimsg))
+ goto trunc;
+ TCHECK(*cimp);
services = EXTRACT_LE_8BITS(cimp->ci_services);
info = EXTRACT_LE_8BITS(cimp->ci_info);
segsize = EXTRACT_LE_16BITS(cimp->ci_segsize);
services = EXTRACT_LE_8BITS(cimp->ci_services);
info = EXTRACT_LE_8BITS(cimp->ci_info);
segsize = EXTRACT_LE_16BITS(cimp->ci_segsize);
}
(void)printf("segsize %d ", segsize);
#ifdef PRINT_NSPDATA
}
(void)printf("segsize %d ", segsize);
#ifdef PRINT_NSPDATA
- dp = &(nspp[sizeof(struct cimsg)]);
- pdata(dp, nsplen - sizeof(struct cimsg));
+ if (nsplen > sizeof(struct cimsg)) {
+ dp = &(nspp[sizeof(struct cimsg)]);
+ TCHECK2(*dp, nsplen - sizeof(struct cimsg));
+ pdata(dp, nsplen - sizeof(struct cimsg));
+ }
+ if (nsplen < sizeof(struct ccmsg))
+ goto trunc;
+ TCHECK(*ccmp);
services = EXTRACT_LE_8BITS(ccmp->cc_services);
info = EXTRACT_LE_8BITS(ccmp->cc_info);
segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize);
services = EXTRACT_LE_8BITS(ccmp->cc_services);
info = EXTRACT_LE_8BITS(ccmp->cc_info);
segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize);
if (optlen) {
(void)printf("optlen %d ", optlen);
#ifdef PRINT_NSPDATA
if (optlen) {
(void)printf("optlen %d ", optlen);
#ifdef PRINT_NSPDATA
- optlen = min(optlen, nsplen - sizeof(struct ccmsg));
+ if (optlen > nsplen - sizeof(struct ccmsg))
+ goto trunc;
dp = &(nspp[sizeof(struct ccmsg)]);
dp = &(nspp[sizeof(struct ccmsg)]);
pdata(dp, optlen);
#endif
}
pdata(dp, optlen);
#endif
}
+ if (nsplen < sizeof(struct dimsg))
+ goto trunc;
+ TCHECK(*dimp);
reason = EXTRACT_LE_16BITS(dimp->di_reason);
optlen = EXTRACT_LE_8BITS(dimp->di_optlen);
reason = EXTRACT_LE_16BITS(dimp->di_reason);
optlen = EXTRACT_LE_8BITS(dimp->di_optlen);
if (optlen) {
(void)printf("optlen %d ", optlen);
#ifdef PRINT_NSPDATA
if (optlen) {
(void)printf("optlen %d ", optlen);
#ifdef PRINT_NSPDATA
- optlen = min(optlen, nsplen - sizeof(struct dimsg));
+ if (optlen > nsplen - sizeof(struct dimsg))
+ goto trunc;
dp = &(nspp[sizeof(struct dimsg)]);
dp = &(nspp[sizeof(struct dimsg)]);
pdata(dp, optlen);
#endif
}
pdata(dp, optlen);
#endif
}
struct dcmsg *dcmp = (struct dcmsg *)nspp;
int reason;
struct dcmsg *dcmp = (struct dcmsg *)nspp;
int reason;
reason = EXTRACT_LE_16BITS(dcmp->dc_reason);
print_reason(reason);
reason = EXTRACT_LE_16BITS(dcmp->dc_reason);
print_reason(reason);
(void)printf("reserved-type? %x %d > %d", flags, src, dst);
break;
}
(void)printf("reserved-type? %x %d > %d", flags, src, dst);
break;
}
+ return (1);
+
+trunc:
+ return (0);
}
static struct tok reason2str[] = {
}
static struct tok reason2str[] = {