summaryrefslogtreecommitdiff
path: root/usr.sbin/tcpdump/tcpdump/print-atalk.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/tcpdump/tcpdump/print-atalk.c')
-rw-r--r--usr.sbin/tcpdump/tcpdump/print-atalk.c337
1 files changed, 215 insertions, 122 deletions
diff --git a/usr.sbin/tcpdump/tcpdump/print-atalk.c b/usr.sbin/tcpdump/tcpdump/print-atalk.c
index 203585ef5a8b..a6dceeae683f 100644
--- a/usr.sbin/tcpdump/tcpdump/print-atalk.c
+++ b/usr.sbin/tcpdump/tcpdump/print-atalk.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 1988-1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
@@ -22,111 +22,197 @@
*/
#ifndef lint
static char rcsid[] =
- "@(#)$Header: print-atalk.c,v 1.22 92/03/26 14:15:34 mccanne Exp $ (LBL)";
+ "@(#)$Header: print-atalk.c,v 1.36 94/06/20 19:44:34 leres Exp $ (LBL)";
#endif
-#ifdef __STDC__
-#include <stdlib.h>
-#endif
-#include <stdio.h>
-
#include <sys/param.h>
+#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
+
+#include <net/if.h>
+
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
+#include <netinet/if_ether.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <string.h>
+
#include "interface.h"
#include "addrtoname.h"
+#include "ethertype.h"
+#include "extract.h" /* must come after interface.h */
#include "appletalk.h"
-#include <strings.h>
-#include "extract.h"
-static char *ataddr_string();
-static struct atNBPtuple *nbp_tuple_print();
-static struct atNBPtuple *nbp_name_print();
-static void atp_print();
-static void nbp_print();
-static void atp_bitmap_print();
+static struct token type2str[] = {
+ { ddpRTMP, "rtmp" },
+ { ddpRTMPrequest, "rtmpReq" },
+ { ddpECHO, "echo" },
+ { ddpIP, "IP" },
+ { ddpARP, "ARP" },
+ { ddpKLAP, "KLAP" },
+ { 0, NULL }
+};
+
+struct aarp {
+ u_short htype, ptype;
+ u_char halen, palen;
+ u_short op;
+ u_char hsaddr[6];
+ u_char psaddr[4];
+ u_char hdaddr[6];
+ u_char pdaddr[4];
+};
+
+static char tstr[] = "[|atalk]";
+
+static void atp_print(const struct atATP *, int);
+static void atp_bitmap_print(u_char);
+static void nbp_print(const struct atNBP *, int, u_short, u_char, u_char);
+static const char *print_cstring(const char *, const u_char *);
+static const struct atNBPtuple *nbp_tuple_print(const struct atNBPtuple *,
+ const u_char *,
+ u_short, u_char, u_char);
+static const struct atNBPtuple *nbp_name_print(const struct atNBPtuple *,
+ const u_char *);
+static const char *ataddr_string(u_short, u_char);
+static void ddp_print(const u_char *, int, int, u_short, u_char, u_char);
+static const char *ddpskt_string(int);
/*
* Print AppleTalk Datagram Delivery Protocol packets.
*/
void
-ddp_print(dp, length)
- register struct atDDP *dp;
- int length;
+atalk_print(register const u_char *bp, int length)
{
- if (length < ddpSize) {
- (void)printf(" truncated-ddp %d", length);
- return;
- }
- (void)printf("%s.%d > %s.%d:",
- ataddr_string(EXTRACT_SHORT(&dp->srcNet), dp->srcNode),
- dp->srcSkt,
- ataddr_string(EXTRACT_SHORT(&dp->dstNet), dp->dstNode),
- dp->dstSkt);
-
- /* 'type' is the last field of 'dp' so we need the whole thing.
- If we cannot determine the type, bail out. (This last byte
- happens to be *one* byte past the end of tcpdump's minimum
- snapshot length.) */
- if ((u_char *)(dp + 1) > snapend) {
- printf(" [|atalk]");
- return;
- }
+ register const struct LAP *lp;
+ register const struct atDDP *dp;
+ register const struct atShortDDP *sdp;
+ u_short snet;
+
+ lp = (struct LAP *)bp;
+ bp += sizeof(*lp);
+ length -= sizeof(*lp);
+ switch (lp->type) {
+
+ case lapShortDDP:
+ if (length < ddpSSize) {
+ (void)printf(" [|sddp %d]", length);
+ return;
+ }
+ sdp = (const struct atShortDDP *)bp;
+ printf("%s.%s",
+ ataddr_string(0, lp->src), ddpskt_string(sdp->srcSkt));
+ printf(" > %s.%s:",
+ ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt));
+ bp += ddpSSize;
+ length -= ddpSSize;
+ ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt);
+ break;
- length -= ddpSize;
- switch (dp->type) {
+ case lapDDP:
+ if (length < ddpSize) {
+ (void)printf(" [|ddp %d]", length);
+ return;
+ }
+ dp = (const struct atDDP *)bp;
+ snet = EXTRACT_SHORT(&dp->srcNet);
+ printf("%s.%s", ataddr_string(snet, dp->srcNode),
+ ddpskt_string(dp->srcSkt));
+ printf(" > %s.%s:",
+ ataddr_string(EXTRACT_SHORT(&dp->dstNet), dp->dstNode),
+ ddpskt_string(dp->dstSkt));
+ bp += ddpSize;
+ length -= ddpSize;
+ ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
+ break;
- case ddpRTMP:
- (void)printf(" at-rtmp %d", length);
+#ifdef notdef
+ case lapKLAP:
+ klap_print(bp, length);
break;
- case ddpRTMPrequest:
- (void)printf(" at-rtmpReq %d", length);
+#endif
+
+ default:
+ printf("%d > %d at-lap#%d %d",
+ lp->src, lp->dst, lp->type, length);
break;
+ }
+}
+
+/* XXX should probably pass in the snap header and do checks like arp_print() */
+void
+aarp_print(register const u_char *bp, int length)
+{
+ register const struct aarp *ap;
+
+#define AT(member) ataddr_string((ap->member[1]<<8)|ap->member[2],ap->member[3])
+
+ printf("aarp ");
+ ap = (const struct aarp *)bp;
+ if (ap->htype == 1 && ap->ptype == ETHERTYPE_ATALK &&
+ ap->halen == 6 && ap->palen == 4 )
+ switch (ap->op) {
+
+ case 1: /* request */
+ (void)printf("who-has %s tell %s",
+ AT(pdaddr), AT(psaddr));
+ return;
+
+ case 2: /* response */
+ (void)printf("reply %s is-at %s",
+ AT(pdaddr), etheraddr_string(ap->hdaddr));
+ return;
+
+ case 3: /* probe (oy!) */
+ (void)printf("probe %s tell %s",
+ AT(pdaddr), AT(psaddr));
+ return;
+ }
+ (void)printf("len %d op %d htype %d ptype %#x halen %d palen %d",
+ length, ap->op, ap->htype, ap->ptype, ap->halen, ap->palen );
+}
+
+static void
+ddp_print(register const u_char *bp, register int length, register int t,
+ register u_short snet, register u_char snode, u_char skt)
+{
+
+ switch (t) {
+
case ddpNBP:
- nbp_print((struct atNBP *)((u_char *)dp + ddpSize),
- length, dp);
+ nbp_print((const struct atNBP *)bp, length, snet, snode, skt);
break;
+
case ddpATP:
- atp_print((struct atATP *)((u_char *)dp + ddpSize), length);
- break;
- case ddpECHO:
- (void)printf(" at-echo %d", length);
- break;
- case ddpIP:
- (void)printf(" at-IP %d", length);
- break;
- case ddpARP:
- (void)printf(" at-ARP %d", length);
- break;
- case ddpKLAP:
- (void)printf(" at-KLAP %d", length);
+ atp_print((const struct atATP *)bp, length);
break;
+
default:
- (void)printf(" at-#%d %d", length);
+ (void)printf(" at-%s %d", tok2str(type2str, NULL, t), length);
break;
}
}
static void
-atp_print(ap, length)
- register struct atATP *ap;
- int length;
+atp_print(register const struct atATP *ap, int length)
{
char c;
- long data;
+ u_int32 data;
- if ((u_char *)(ap + 1) > snapend) {
+ if ((const u_char *)(ap + 1) > snapend) {
/* Just bail if we don't have the whole chunk. */
- printf(" [|atalk]");
+ fputs(tstr, stdout);
return;
}
length -= sizeof(*ap);
@@ -201,7 +287,7 @@ atp_print(ap, length)
break;
default:
- (void)printf(" atp-0x%x %d (%d)", ap->control,
+ (void)printf(" atp-0x%x %d (%d)", ap->control,
EXTRACT_SHORT(&ap->transID), length);
break;
}
@@ -211,13 +297,12 @@ atp_print(ap, length)
}
static void
-atp_bitmap_print(bm)
- register u_char bm;
+atp_bitmap_print(register u_char bm)
{
register char c;
register int i;
- /*
+ /*
* The '& 0xff' below is needed for compilers that want to sign
* extend a u_char, which is the case with the Ultrix compiler.
* (gcc is smart enough to eliminate it, at least on the Sparc).
@@ -243,15 +328,13 @@ atp_bitmap_print(bm)
}
static void
-nbp_print(np, length, dp)
- register struct atNBP *np;
- int length;
- register struct atDDP *dp;
+nbp_print(register const struct atNBP *np, int length, register u_short snet,
+ register u_char snode, register u_char skt)
{
- register struct atNBPtuple *tp =
+ register const struct atNBPtuple *tp =
(struct atNBPtuple *)((u_char *)np + nbpHeaderSize);
int i = length;
- u_char *ep;
+ const u_char *ep;
length -= nbpHeaderSize;
if (length < 8) {
@@ -261,8 +344,8 @@ nbp_print(np, length, dp)
}
/* ep points to end of available data */
ep = snapend;
- if ((u_char *)tp > ep) {
- printf(" [|atalk]");
+ if ((const u_char *)tp > ep) {
+ fputs(tstr, stdout);
return;
}
switch (i = np->control & 0xf0) {
@@ -271,8 +354,8 @@ nbp_print(np, length, dp)
case nbpLkUp:
(void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:",
np->id);
- if ((u_char *)(tp + 1) > ep) {
- printf(" [|atalk]");
+ if ((const u_char *)(tp + 1) > ep) {
+ fputs(tstr, stdout);
return;
}
(void)nbp_name_print(tp, ep);
@@ -285,12 +368,11 @@ nbp_print(np, length, dp)
(void)printf(" [ntup=%d]", np->control & 0xf);
if (tp->enumerator)
(void)printf(" [enum=%d]", tp->enumerator);
- if (EXTRACT_SHORT(&tp->net) != EXTRACT_SHORT(&dp->srcNet) ||
- tp->node != dp->srcNode || tp->skt != dp->srcSkt)
+ if (EXTRACT_SHORT(&tp->net) != snet ||
+ tp->node != snode || tp->skt != skt)
(void)printf(" [addr=%s.%d]",
- ataddr_string(EXTRACT_SHORT(&tp->net),
- tp->node),
- tp->skt);
+ ataddr_string(EXTRACT_SHORT(&tp->net),
+ tp->node), tp->skt);
break;
case nbpLkUpReply:
@@ -298,7 +380,7 @@ nbp_print(np, length, dp)
/* print each of the tuples in the reply */
for (i = np->control & 0xf; --i >= 0 && tp; )
- tp = nbp_tuple_print(tp, ep, dp);
+ tp = nbp_tuple_print(tp, ep, snet, snode, skt);
break;
default:
@@ -309,15 +391,13 @@ nbp_print(np, length, dp)
}
/* print a counted string */
-static char *
-print_cstring(cp, ep)
- register char *cp;
- register u_char *ep;
+static const char *
+print_cstring(register const char *cp, register const u_char *ep)
{
register int length;
- if (cp >= (char *)ep) {
- (void)printf("[|atalk]");
+ if (cp >= (const char *)ep) {
+ fputs(tstr, stdout);
return (0);
}
length = *cp++;
@@ -329,7 +409,7 @@ print_cstring(cp, ep)
}
while (--length >= 0) {
if (cp >= (char *)ep) {
- (void)printf("[|atalk]");
+ fputs(tstr, stdout);
return (0);
}
putchar(*cp++);
@@ -337,16 +417,16 @@ print_cstring(cp, ep)
return (cp);
}
-static struct atNBPtuple *
-nbp_tuple_print(tp, ep, dp)
- register struct atNBPtuple *tp;
- register u_char *ep;
- register struct atDDP *dp;
+static const struct atNBPtuple *
+nbp_tuple_print(register const struct atNBPtuple *tp,
+ register const u_char *ep,
+ register u_short snet, register u_char snode,
+ register u_char skt)
{
- register struct atNBPtuple *tpn;
+ register const struct atNBPtuple *tpn;
- if ((u_char *)(tp + 1) > ep) {
- printf(" [|atalk]");
+ if ((const u_char *)(tp + 1) > ep) {
+ fputs(tstr, stdout);
return 0;
}
tpn = nbp_name_print(tp, ep);
@@ -356,40 +436,37 @@ nbp_tuple_print(tp, ep, dp)
(void)printf("(%d)", tp->enumerator);
/* if the socket doesn't match the src socket, print it */
- if (tp->skt != dp->srcSkt)
+ if (tp->skt != skt)
(void)printf(" %d", tp->skt);
/* if the address doesn't match the src address, it's an anomaly */
- if (EXTRACT_SHORT(&tp->net) != EXTRACT_SHORT(&dp->srcNet) ||
- tp->node != dp->srcNode)
+ if (EXTRACT_SHORT(&tp->net) != snet || tp->node != snode)
(void)printf(" [addr=%s]",
- ataddr_string(EXTRACT_SHORT(&tp->net), tp->node));
+ ataddr_string(EXTRACT_SHORT(&tp->net), tp->node));
return (tpn);
}
-static struct atNBPtuple *
-nbp_name_print(tp, ep)
- struct atNBPtuple *tp;
- register u_char *ep;
+static const struct atNBPtuple *
+nbp_name_print(const struct atNBPtuple *tp, register const u_char *ep)
{
- register char *cp = (char *)tp + nbpTupleSize;
+ register const char *cp = (const char *)tp + nbpTupleSize;
putchar(' ');
/* Object */
putchar('"');
- if (cp = print_cstring(cp, ep)) {
+ if ((cp = print_cstring(cp, ep)) != NULL) {
/* Type */
putchar(':');
- if (cp = print_cstring(cp, ep)) {
+ if ((cp = print_cstring(cp, ep)) != NULL) {
/* Zone */
putchar('@');
- if (cp = print_cstring(cp, ep))
+ if ((cp = print_cstring(cp, ep)) != NULL)
putchar('"');
}
}
- return ((struct atNBPtuple *)cp);
+ return ((const struct atNBPtuple *)cp);
}
@@ -403,10 +480,8 @@ struct hnamemem {
static struct hnamemem hnametable[HASHNAMESIZE];
-static char *
-ataddr_string(atnet, athost)
- u_short atnet;
- u_char athost;
+static const char *
+ataddr_string(u_short atnet, u_char athost)
{
register struct hnamemem *tp, *tp2;
register int i = (atnet << 8) | athost;
@@ -442,8 +517,7 @@ ataddr_string(atnet, athost)
;
tp->addr = i3;
tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
- i3 = strlen(nambuf) + 1;
- tp->name = strcpy(malloc((unsigned) i3), nambuf);
+ tp->name = savestr(nambuf);
}
fclose(fp);
}
@@ -459,8 +533,7 @@ ataddr_string(atnet, athost)
tp->addr = (atnet << 8) | athost;
tp->nxt = (struct hnamemem *)calloc(1, sizeof(*tp));
(void)sprintf(nambuf, "%s.%d", tp2->name, athost);
- i = strlen(nambuf) + 1;
- tp->name = strcpy(malloc((unsigned) i), nambuf);
+ tp->name = savestr(nambuf);
return (tp->name);
}
@@ -472,7 +545,27 @@ ataddr_string(atnet, athost)
else
(void)sprintf(nambuf, "%d.%d", atnet >> 8, atnet & 0xff);
i = strlen(nambuf) + 1;
- tp->name = strcpy(malloc((unsigned) i), nambuf);
+ tp->name = strcpy(malloc((u_int) i), nambuf);
return (tp->name);
}
+
+static struct token skt2str[] = {
+ { rtmpSkt, "rtmp" }, /* routing table maintenance */
+ { nbpSkt, "nis" }, /* name info socket */
+ { echoSkt, "echo" }, /* AppleTalk echo protocol */
+ { zipSkt, "zip" }, /* zone info protocol */
+ { 0, NULL }
+};
+
+static const char *
+ddpskt_string(register int skt)
+{
+ static char buf[8];
+
+ if (nflag) {
+ (void)sprintf(buf, "%d", skt);
+ return (buf);
+ }
+ return (tok2str(skt2str, "%d", skt));
+}