summaryrefslogtreecommitdiff
path: root/print-arp.c
diff options
context:
space:
mode:
authorguy <guy>2002-09-04 11:22:13 +0000
committerguy <guy>2002-09-04 11:22:13 +0000
commitf4c699b58752234cadf18b12ec44c596a930c883 (patch)
tree4195eef9739427f571c9b402c6d3abe2397e3d33 /print-arp.c
parent5dd4a8b71eda5ca158e163c1860d70f257e933f8 (diff)
downloadtcpdump-f4c699b58752234cadf18b12ec44c596a930c883.tar.gz
Fix the ATMARP dissector to correctly dissect RFC 2225 ATM ARP.
Fix the ARP dissector to check the hardware type before checking whether the addresses are in the captured data, and call the ATMARP dissector if the hardware type is 19. Also fix it to return after the ATMARP dissector returns. Use "TTEST2()" to check whether the addresses are in the captured data.
Diffstat (limited to 'print-arp.c')
-rw-r--r--print-arp.c191
1 files changed, 118 insertions, 73 deletions
diff --git a/print-arp.c b/print-arp.c
index 3f09d63c..a06c1901 100644
--- a/print-arp.c
+++ b/print-arp.c
@@ -21,7 +21,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.56 2002-09-04 10:11:44 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.57 2002-09-04 11:22:13 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -98,66 +98,97 @@ struct arp_pkthdr {
/*
* ATM Address Resolution Protocol.
*
- * See RFC 2225 for protocol description. ARP packets are variable
- * in size; the arphdr structure defines the fixed-length portion.
- * Protocol type values are the same as those for 10 Mb/s Ethernet.
- * It is followed by the variable-sized fields ar_sha, arp_spa,
- * arp_tha and arp_tpa in that order, according to the lengths
- * specified. Field names used correspond to RFC 826.
+ * See RFC 2225 for protocol description. ATMARP packets are similar
+ * to ARP packets, except that there are no length fields for the
+ * protocol address - instead, there are type/length fields for
+ * the ATM number and subaddress - and the hardware addresses consist
+ * of an ATM number and an ATM subaddress.
*/
struct atmarp_pkthdr {
- u_short ar_hrd; /* format of hardware address */
+ u_short aar_hrd; /* format of hardware address */
#define ARPHRD_ATM2225 19 /* ATM (RFC 2225) */
- u_short ar_pro; /* format of protocol address */
- u_char ar_shtl; /* length of hardware address */
- u_char ar_sstl; /* length of hardware address */
- u_short ar_op; /* same as regular ARP */
- u_char ar_spln;
- u_char ar_thtl;
- u_char ar_tstl;
- u_char ar_tpln;
+ u_short aar_pro; /* format of protocol address */
+ u_char aar_shtl; /* length of source ATM number */
+ u_char aar_sstl; /* length of source ATM subaddress */
+#define ATMARP_IS_E164 0x40 /* bit in type/length for E.164 format */
+#define ATMARP_LEN_MASK 0x3F /* length of {sub}address in type/length */
+ u_short aar_op; /* same as regular ARP */
+#define ATMARPOP_NAK 10 /* NAK */
+ u_char aar_spln; /* length of source protocol address */
+ u_char aar_thtl; /* length of target ATM number */
+ u_char aar_tstl; /* length of target ATM subaddress */
+ u_char aar_tpln; /* length of target protocol address */
/*
* The remaining fields are variable in size,
* according to the sizes above.
*/
#ifdef COMMENT_ONLY
- u_char ar_sha[]; /* sender hardware address */
- u_char ar_spa[]; /* sender protocol address */
- u_char ar_tha[]; /* target hardware address */
- u_char ar_tpa[]; /* target protocol address */
+ u_char aar_sha[]; /* source ATM number */
+ u_char aar_ssa[]; /* source ATM subaddress */
+ u_char aar_spa[]; /* sender protocol address */
+ u_char aar_tha[]; /* target ATM number */
+ u_char aar_tsa[]; /* target ATM subaddress */
+ u_char aar_tpa[]; /* target protocol address */
#endif
-#define ar_sha(ap) (((const u_char *)((ap)+1))+0)
-#define ar_spa(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln)
-#define ar_tha(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln+(ap)->ar_pln)
-#define ar_tpa(ap) (((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln)
+
+#define ATMHRD(ap) ((ap)->aar_hrd)
+#define ATMSHLN(ap) ((ap)->aar_shtl & ATMARP_LEN_MASK)
+#define ATMSSLN(ap) ((ap)->aar_sstl & ATMARP_LEN_MASK)
+#define ATMSPLN(ap) ((ap)->aar_spln)
+#define ATMOP(ap) ((ap)->aar_op)
+#define ATMPRO(ap) ((ap)->aar_pro)
+#define ATMTHLN(ap) ((ap)->aar_thtl & ATMARP_LEN_MASK)
+#define ATMTSLN(ap) ((ap)->aar_tstl & ATMARP_LEN_MASK)
+#define ATMTPLN(ap) ((ap)->aar_tpln)
+#define aar_sha(ap) ((const u_char *)((ap)+1))
+#define aar_ssa(ap) (aar_sha(ap) + ATMSHLN(ap))
+#define aar_spa(ap) (aar_ssa(ap) + ATMSSLN(ap))
+#define aar_tha(ap) (aar_spa(ap) + ATMSPLN(ap))
+#define aar_tsa(ap) (aar_tha(ap) + ATMTHLN(ap))
+#define aar_tpa(ap) (aar_tsa(ap) + ATMTSLN(ap))
};
+#define ATMSHA(ap) (aar_sha(ap))
+#define ATMSSA(ap) (aar_ssa(ap))
+#define ATMSPA(ap) (aar_spa(ap))
+#define ATMTHA(ap) (aar_tha(ap))
+#define ATMTSA(ap) (aar_tsa(ap))
+#define ATMTPA(ap) (aar_tpa(ap))
+
static u_char ezero[6];
static void
+atmarp_addr_print(const u_char *ha, u_int ha_len, const u_char *sa,
+ u_int sa_len)
+{
+ (void)printf("%s", linkaddr_string(ha, ha_len));
+ if (sa_len != 0)
+ (void)printf(",%s", linkaddr_string(sa, sa_len));
+}
+
+static void
atmarp_print(const u_char *bp, u_int length, u_int caplen)
{
- const struct arp_pkthdr *ap;
+ const struct atmarp_pkthdr *ap;
u_short pro, hrd, op;
- ap = (const struct arp_pkthdr *)bp;
+ ap = (const struct atmarp_pkthdr *)bp;
TCHECK(*ap);
- if ((const u_char *)(ar_tpa(ap) + PLN(ap)) > snapend) {
- (void)printf("truncated-arp");
+
+ hrd = EXTRACT_16BITS(&ATMHRD(ap));
+ pro = EXTRACT_16BITS(&ATMPRO(ap));
+ op = EXTRACT_16BITS(&ATMOP(ap));
+
+ if (!TTEST2(*aar_tpa(ap), ATMTPLN(ap))) {
+ (void)printf("truncated-atmarp");
default_print((const u_char *)ap, length);
return;
}
- hrd = EXTRACT_16BITS(&HRD(ap));
- if (hrd == ARPHRD_ATM2225)
- atmarp_print(bp, length, caplen);
- pro = EXTRACT_16BITS(&PRO(ap));
- op = EXTRACT_16BITS(&OP(ap));
-
if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) ||
- PLN(ap) != 4 || HLN(ap) == 0) {
- (void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)",
- op, pro, PLN(ap), hrd, HLN(ap));
+ ATMSPLN(ap) != 4 || ATMTPLN(ap) != 4) {
+ (void)printf("atmarp-#%d for proto #%d (%d/%d) hardware #%d",
+ op, pro, ATMSPLN(ap), ATMTPLN(ap), hrd);
return;
}
if (pro == ETHERTYPE_TRAIL)
@@ -165,52 +196,64 @@ atmarp_print(const u_char *bp, u_int length, u_int caplen)
switch (op) {
case ARPOP_REQUEST:
- (void)printf("arp who-has %s", ipaddr_string(TPA(ap)));
- if (memcmp((const char *)ezero, (const char *)THA(ap), HLN(ap)) != 0)
- (void)printf(" (%s)",
- linkaddr_string(THA(ap), HLN(ap)));
- (void)printf(" tell %s", ipaddr_string(SPA(ap)));
+ (void)printf("arp who-has %s", ipaddr_string(ATMTPA(ap)));
+ if (ATMTHLN(ap) != 0) {
+ (void)printf(" (");
+ atmarp_addr_print(ATMTHA(ap), ATMTHLN(ap),
+ ATMTSA(ap), ATMTSLN(ap));
+ (void)printf(")");
+ }
+ (void)printf(" tell %s", ipaddr_string(ATMSPA(ap)));
break;
case ARPOP_REPLY:
- (void)printf("arp reply %s", ipaddr_string(SPA(ap)));
- (void)printf(" is-at %s", linkaddr_string(SHA(ap), HLN(ap)));
- break;
-
- case ARPOP_REVREQUEST:
- (void)printf("rarp who-is %s tell %s",
- linkaddr_string(THA(ap), HLN(ap)),
- linkaddr_string(SHA(ap), HLN(ap)));
- break;
-
- case ARPOP_REVREPLY:
- (void)printf("rarp reply %s at %s",
- linkaddr_string(THA(ap), HLN(ap)),
- ipaddr_string(TPA(ap)));
+ (void)printf("arp reply %s", ipaddr_string(ATMSPA(ap)));
+ (void)printf(" is-at ");
+ if (ATMSHLN(ap) != 0)
+ atmarp_addr_print(ATMSHA(ap), ATMSHLN(ap),
+ ATMSSA(ap), ATMSSLN(ap));
+ else
+ (void)printf("<No address>");
break;
case ARPOP_INVREQUEST:
- (void)printf("invarp who-is %s tell %s",
- linkaddr_string(THA(ap), HLN(ap)),
- linkaddr_string(SHA(ap), HLN(ap)));
+ (void)printf("invarp who-is ");
+ if (ATMTHLN(ap) != 0)
+ atmarp_addr_print(ATMTHA(ap), ATMTHLN(ap),
+ ATMTSA(ap), ATMTSLN(ap));
+ else
+ (void)printf("<No address>");
+ (void)printf(" tell ");
+ if (ATMSHLN(ap) != 0)
+ atmarp_addr_print(ATMSHA(ap), ATMSHLN(ap),
+ ATMSSA(ap), ATMSSLN(ap));
+ else
+ (void)printf("<No address>");
break;
case ARPOP_INVREPLY:
- (void)printf("invarp reply %s at %s",
- linkaddr_string(THA(ap), HLN(ap)),
- ipaddr_string(TPA(ap)));
+ (void)printf("invarp reply ");
+ if (ATMSHLN(ap) != 0)
+ atmarp_addr_print(ATMSHA(ap), ATMSHLN(ap),
+ ATMSSA(ap), ATMSSLN(ap));
+ else
+ (void)printf("<No address>");
+ (void)printf(" at %s", ipaddr_string(ATMSPA(ap)));
+ break;
+
+ case ATMARPOP_NAK:
+ (void)printf("nak reply for %s",
+ ipaddr_string(ATMSPA(ap)));
break;
default:
- (void)printf("arp-#%d", op);
+ (void)printf("atmarp-#%d", op);
default_print((const u_char *)ap, caplen);
return;
}
- if (hrd != ARPHRD_ETHER)
- printf(" hardware #%d", hrd);
return;
trunc:
- (void)printf("[|arp]");
+ (void)printf("[|atmarp]");
}
void
@@ -221,18 +264,20 @@ arp_print(const u_char *bp, u_int length, u_int caplen)
ap = (const struct arp_pkthdr *)bp;
TCHECK(*ap);
- if ((const u_char *)(ar_tpa(ap) + PLN(ap)) > snapend) {
- (void)printf("truncated-arp");
- default_print((const u_char *)ap, length);
- return;
- }
-
hrd = EXTRACT_16BITS(&HRD(ap));
- if (hrd == ARPHRD_ATM2225)
+ if (hrd == ARPHRD_ATM2225) {
atmarp_print(bp, length, caplen);
+ return;
+ }
pro = EXTRACT_16BITS(&PRO(ap));
op = EXTRACT_16BITS(&OP(ap));
+ if (!TTEST2(*ar_tpa(ap), PLN(ap))) {
+ (void)printf("truncated-arp");
+ default_print((const u_char *)ap, length);
+ return;
+ }
+
if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) ||
PLN(ap) != 4 || HLN(ap) == 0) {
(void)printf("arp-#%d for proto #%d (%d) hardware #%d (%d)",