#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.110 2005-05-08 20:35:20 hannes Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.114 2005-12-05 11:35:58 hannes Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
{ 0, NULL }
};
+#define IPCPOPT_IPCOMP_HDRCOMP 0x61 /* rfc3544 */
+#define IPCPOPT_IPCOMP_MINLEN 14
+
+struct tok ipcpopt_compproto_values[] = {
+ { PPP_VJC, "VJ-Comp" },
+ { IPCPOPT_IPCOMP_HDRCOMP, "IP Header Compression" },
+ { 0, NULL }
+};
+
+struct tok ipcpopt_compproto_subopt_values[] = {
+ { 1, "RTP-Compression" },
+ { 2, "Enhanced RTP-Compression" },
+ { 0, NULL }
+};
/* IP6CP Config Options */
#define IP6CP_IFID 1
EXTRACT_16BITS(tptr));
/* XXX: need to decode Rejected-Information? - hexdump for now */
if (len > 6) {
- printf("\n\t Unknown Data");
+ printf("\n\t Rejected Packet");
print_unknown_data(tptr+2,"\n\t ",len-2);
}
break;
case CPCODES_ECHO_REQ:
case CPCODES_ECHO_RPL:
case CPCODES_DISC_REQ:
- case CPCODES_ID:
if (length < 8)
break;
TCHECK2(*tptr, 4);
printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
/* XXX: need to decode Data? - hexdump for now */
if (len > 8) {
- printf("\n\t Unknown Data");
- print_unknown_data(tptr+4,"\n\t ",len-4);
+ printf("\n\t -----trailing data-----");
+ TCHECK2(tptr[4], len-8);
+ print_unknown_data(tptr+4,"\n\t ",len-8);
+ }
+ break;
+ case CPCODES_ID:
+ if (length < 8)
+ break;
+ TCHECK2(*tptr, 4);
+ printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
+ /* RFC 1661 says this is intended to be human readable */
+ if (len > 8) {
+ printf("\n\t Message\n\t ");
+ fn_printn(tptr+4,len-4,snapend);
}
break;
case CPCODES_TIME_REM:
opt = p[0];
if (length < len)
return 0;
+ if (len < 2) {
+ if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", lcpconfopts[opt],opt,len);
+ else
+ printf("\n\tunknown LCP option 0x%02x", opt);
+ return 0;
+ }
if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
printf("\n\t %s Option (0x%02x), length %u: ", lcpconfopts[opt],opt,len);
else {
print_ipcp_config_options(const u_char *p, int length)
{
int len, opt;
+ u_int compproto, ipcomp_subopttotallen, ipcomp_subopt, ipcomp_suboptlen;
if (length < 2)
return 0;
opt = p[0];
if (length < len)
return 0;
+ if (len < 2) {
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
+ tok2str(ipcpopt_values,"unknown",opt),
+ opt,
+ len);
+ return 0;
+ }
printf("\n\t %s Option (0x%02x), length %u: ",
tok2str(ipcpopt_values,"unknown",opt),
if (len < 4)
goto invlen;
TCHECK2(*(p + 2), 2);
- if (EXTRACT_16BITS(p + 2) == PPP_VJC) {
- printf("VJ-Comp");
+ compproto = EXTRACT_16BITS(p+2);
+
+ printf("%s (0x%02x):",
+ tok2str(ipcpopt_compproto_values,"Unknown",compproto),
+ compproto);
+
+ switch (compproto) {
+ case PPP_VJC:
/* XXX: VJ-Comp parameters should be decoded */
- } else
- printf("unknown-comp-proto %04x", EXTRACT_16BITS(p + 2));
+ break;
+ case IPCPOPT_IPCOMP_HDRCOMP:
+ if (len < IPCPOPT_IPCOMP_MINLEN)
+ goto invlen;
+
+ TCHECK2(*(p + 2), IPCPOPT_IPCOMP_MINLEN);
+ printf("\n\t TCP Space %u, non-TCP Space %u" \
+ ", maxPeriod %u, maxTime %u, maxHdr %u",
+ EXTRACT_16BITS(p+4),
+ EXTRACT_16BITS(p+6),
+ EXTRACT_16BITS(p+8),
+ EXTRACT_16BITS(p+10),
+ EXTRACT_16BITS(p+12));
+
+ /* suboptions present ? */
+ if (len > IPCPOPT_IPCOMP_MINLEN) {
+ ipcomp_subopttotallen = len - IPCPOPT_IPCOMP_MINLEN;
+ p += IPCPOPT_IPCOMP_MINLEN;
+
+ printf("\n\t Suboptions, length %u", ipcomp_subopttotallen);
+
+ while (ipcomp_subopttotallen >= 2) {
+ TCHECK2(*p, 2);
+ ipcomp_subopt = *p;
+ ipcomp_suboptlen = *(p+1);
+
+ /* sanity check */
+ if (ipcomp_subopt == 0 ||
+ ipcomp_suboptlen == 0 )
+ break;
+
+ /* XXX: just display the suboptions for now */
+ printf("\n\t\t%s Suboption #%u, length %u",
+ tok2str(ipcpopt_compproto_subopt_values,
+ "Unknown",
+ ipcomp_subopt),
+ ipcomp_subopt,
+ ipcomp_suboptlen);
+
+ ipcomp_subopttotallen -= ipcomp_suboptlen;
+ p += ipcomp_suboptlen;
+ }
+ }
+ break;
+ default:
+ break;
+ }
break;
case IPCPOPT_ADDR: /* those options share the same format - fall through */
opt = p[0];
if (length < len)
return 0;
+ if (len < 2) {
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
+ tok2str(ip6cpopt_values,"unknown",opt),
+ opt,
+ len);
+ return 0;
+ }
printf("\n\t %s Option (0x%02x), length %u: ",
tok2str(ip6cpopt_values,"unknown",opt),
opt = p[0];
if (length < len)
return 0;
+ if (len < 2) {
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
+ tok2str(ccpconfopts_values, "Unknown", opt),
+ opt,
+ len);
+ return 0;
+ }
printf("\n\t %s Option (0x%02x), length %u:",
tok2str(ccpconfopts_values, "Unknown", opt),
opt = p[0];
if (length < len)
return 0;
+ if (len < 2) {
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
+ tok2str(bacconfopts_values, "Unknown", opt),
+ opt,
+ len);
+ return 0;
+ }
printf("\n\t %s Option (0x%02x), length %u:",
tok2str(bacconfopts_values, "Unknown", opt),
goto cleanup;
#ifdef INET6
case PPP_IPV6:
- ip6_print(b+1, t - b - 1);
- goto cleanup;
+ ip6_print(gndo, b+1, t - b - 1);
+ goto cleanup;
#endif
default: /* no luck - try next guess */
- break;
+ break;
}
proto = EXTRACT_16BITS(b); /* next guess - load two octets */
#ifdef INET6
case ETHERTYPE_IPV6: /*XXX*/
case PPP_IPV6:
- ip6_print(p, length);
+ ip6_print(gndo, p, length);
break;
#endif
case ETHERTYPE_IPX: /*XXX*/
hdrlength += 1;
} else {
/* Un-compressed protocol field */
- ptype = ntohs(*(u_int16_t *)p);
+ ptype = EXTRACT_16BITS(p);
if (eflag)
printf("%04x ", ptype);
p += 2;
&& ph->phdr_ctl == PPP_CONTROL) {
if (eflag)
printf("%02x %02x ", q[0], q[1]);
- ptype = ntohs(ph->phdr_type);
+ ptype = EXTRACT_16BITS(&ph->phdr_type);
if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
printf("%s ", tok2str(ppptype2str,
"proto-#%d", ptype));
p += hdrlength;
switch (ptype) {
case PPP_IP:
- ip_print(p, length);
+ ip_print(gndo, p, length);
break;
#ifdef INET6
case PPP_IPV6:
- ip6_print(p, length);
+ ip6_print(gndo, p, length);
break;
#endif
case PPP_MPLS_UCAST:
p += hdrlength;
switch (ptype) {
case PPP_IP:
- ip_print(p, length);
+ ip_print(gndo, p, length);
break;
#ifdef INET6
case PPP_IPV6:
- ip6_print(p, length);
+ ip6_print(gndo, p, length);
break;
#endif
case PPP_MPLS_UCAST:
break;
#ifdef INET6
case PPP_IPV6:
- ip6_print(p, length);
+ ip6_print(gndo, p, length);
break;
#endif
case PPP_MPLS_UCAST:
case PPP_MPLS_MCAST:
- mpls_print(p, length);
+ mpls_print(gndo, p, length);
break;
default:
printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype));