/*
 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
 *	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
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Format and print AppleTalk packets.
 */

#ifndef lint
static const char rcsid[] _U_ =
    "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.81 2004-05-01 09:41:50 hannes Exp $ (LBL)";
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <tcpdump-stdinc.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcap.h>

#include "interface.h"
#include "addrtoname.h"
#include "ethertype.h"
#include "extract.h"			/* must come after interface.h */
#include "appletalk.h"

static const struct tok type2str[] = {
	{ ddpRTMP,		"rtmp" },
	{ ddpRTMPrequest,	"rtmpReq" },
	{ ddpECHO,		"echo" },
	{ ddpIP,		"IP" },
	{ ddpARP,		"ARP" },
	{ ddpKLAP,		"KLAP" },
	{ 0,			NULL }
};

struct aarp {
	u_int16_t	htype, ptype;
	u_int8_t	halen, palen;
	u_int16_t	op;
	u_int8_t	hsaddr[6];
	u_int8_t	psaddr[4];
	u_int8_t	hdaddr[6];
	u_int8_t	pdaddr[4];
};

static char tstr[] = "[|atalk]";

static void atp_print(const struct atATP *, u_int);
static void atp_bitmap_print(u_char);
static void nbp_print(const struct atNBP *, u_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 *, u_int, int, u_short, u_char, u_char);
static const char *ddpskt_string(int);

/*
 * Print LLAP packets received on a physical LocalTalk interface.
 */
u_int
ltalk_if_print(const struct pcap_pkthdr *h, const u_char *p)
{
	return (llap_print(p, h->caplen));
}

/*
 * Print AppleTalk LLAP packets.
 */
u_int
llap_print(register const u_char *bp, u_int length)
{
	register const struct LAP *lp;
	register const struct atDDP *dp;
	register const struct atShortDDP *sdp;
	u_short snet;
	u_int hdrlen;

	if (length < sizeof(*lp)) {
		(void)printf(" [|llap %u]", length);
		return (length);
	}
	lp = (const struct LAP *)bp;
	bp += sizeof(*lp);
	length -= sizeof(*lp);
	hdrlen = sizeof(*lp);
	switch (lp->type) {

	case lapShortDDP:
		if (length < ddpSSize) {
			(void)printf(" [|sddp %u]", length);
			return (length);
		}
		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;
		hdrlen += ddpSSize;
		ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt);
		break;

	case lapDDP:
		if (length < ddpSize) {
			(void)printf(" [|ddp %u]", length);
			return (length);
		}
		dp = (const struct atDDP *)bp;
		snet = EXTRACT_16BITS(&dp->srcNet);
		printf("%s.%s", ataddr_string(snet, dp->srcNode),
		    ddpskt_string(dp->srcSkt));
		printf(" > %s.%s:",
		    ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
		    ddpskt_string(dp->dstSkt));
		bp += ddpSize;
		length -= ddpSize;
		hdrlen += ddpSize;
		ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
		break;

#ifdef notdef
	case lapKLAP:
		klap_print(bp, length);
		break;
#endif

	default:
		printf("%d > %d at-lap#%d %u",
		    lp->src, lp->dst, lp->type, length);
		break;
	}
	return (hdrlen);
}

/*
 * Print EtherTalk/TokenTalk packets (or FDDITalk, or whatever it's called
 * when it runs over FDDI; yes, I've seen FDDI captures with AppleTalk
 * packets in them).
 */
void
atalk_print(register const u_char *bp, u_int length)
{
	register const struct atDDP *dp;
	u_short snet;

        if(!eflag)
            printf("AT ");

	if (length < ddpSize) {
		(void)printf(" [|ddp %u]", length);
		return;
	}
	dp = (const struct atDDP *)bp;
	snet = EXTRACT_16BITS(&dp->srcNet);
	printf("%s.%s", ataddr_string(snet, dp->srcNode),
	       ddpskt_string(dp->srcSkt));
	printf(" > %s.%s: ",
	       ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
	       ddpskt_string(dp->dstSkt));
	bp += ddpSize;
	length -= ddpSize;
	ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
}

/* XXX should probably pass in the snap header and do checks like arp_print() */
void
aarp_print(register const u_char *bp, u_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 (EXTRACT_16BITS(&ap->htype) == 1 &&
	    EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK &&
	    ap->halen == 6 && ap->palen == 4 )
		switch (EXTRACT_16BITS(&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(psaddr), etheraddr_string(ap->hsaddr));
			return;

		case 3:				/* probe (oy!) */
			(void)printf("probe %s tell %s",
			    AT(pdaddr), AT(psaddr));
			return;
		}
	(void)printf("len %u op %u htype %u ptype %#x halen %u palen %u",
	    length, EXTRACT_16BITS(&ap->op), EXTRACT_16BITS(&ap->htype),
	    EXTRACT_16BITS(&ap->ptype), ap->halen, ap->palen);
}

/*
 * Print AppleTalk Datagram Delivery Protocol packets.
 */
static void
ddp_print(register const u_char *bp, register u_int length, register int t,
	  register u_short snet, register u_char snode, u_char skt)
{

	switch (t) {

	case ddpNBP:
		nbp_print((const struct atNBP *)bp, length, snet, snode, skt);
		break;

	case ddpATP:
		atp_print((const struct atATP *)bp, length);
		break;

	case ddpEIGRP:
		eigrp_print(bp, length);
		break;

	default:
		(void)printf(" at-%s %d", tok2str(type2str, NULL, t), length);
		break;
	}
}

static void
atp_print(register const struct atATP *ap, u_int length)
{
	char c;
	u_int32_t data;

	if ((const u_char *)(ap + 1) > snapend) {
		/* Just bail if we don't have the whole chunk. */
		fputs(tstr, stdout);
		return;
	}
	if (length < sizeof(*ap)) {
		(void)printf(" [|atp %u]", length);
		return;
	}
	length -= sizeof(*ap);
	switch (ap->control & 0xc0) {

	case atpReqCode:
		(void)printf(" atp-req%s %d",
			     ap->control & atpXO? " " : "*",
			     EXTRACT_16BITS(&ap->transID));

		atp_bitmap_print(ap->bitmap);

		if (length != 0)
			(void)printf(" [len=%u]", length);

		switch (ap->control & (atpEOM|atpSTS)) {
		case atpEOM:
			(void)printf(" [EOM]");
			break;
		case atpSTS:
			(void)printf(" [STS]");
			break;
		case atpEOM|atpSTS:
			(void)printf(" [EOM,STS]");
			break;
		}
		break;

	case atpRspCode:
		(void)printf(" atp-resp%s%d:%d (%u)",
			     ap->control & atpEOM? "*" : " ",
			     EXTRACT_16BITS(&ap->transID), ap->bitmap, length);
		switch (ap->control & (atpXO|atpSTS)) {
		case atpXO:
			(void)printf(" [XO]");
			break;
		case atpSTS:
			(void)printf(" [STS]");
			break;
		case atpXO|atpSTS:
			(void)printf(" [XO,STS]");
			break;
		}
		break;

	case atpRelCode:
		(void)printf(" atp-rel  %d", EXTRACT_16BITS(&ap->transID));

		atp_bitmap_print(ap->bitmap);

		/* length should be zero */
		if (length)
			(void)printf(" [len=%u]", length);

		/* there shouldn't be any control flags */
		if (ap->control & (atpXO|atpEOM|atpSTS)) {
			c = '[';
			if (ap->control & atpXO) {
				(void)printf("%cXO", c);
				c = ',';
			}
			if (ap->control & atpEOM) {
				(void)printf("%cEOM", c);
				c = ',';
			}
			if (ap->control & atpSTS) {
				(void)printf("%cSTS", c);
				c = ',';
			}
			(void)printf("]");
		}
		break;

	default:
		(void)printf(" atp-0x%x  %d (%u)", ap->control,
			     EXTRACT_16BITS(&ap->transID), length);
		break;
	}
	data = EXTRACT_32BITS(&ap->userData);
	if (data != 0)
		(void)printf(" 0x%x", data);
}

static void
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).
	 */
	if ((bm + 1) & (bm & 0xff)) {
		c = '<';
		for (i = 0; bm; ++i) {
			if (bm & 1) {
				(void)printf("%c%d", c, i);
				c = ',';
			}
			bm >>= 1;
		}
		(void)printf(">");
	} else {
		for (i = 0; bm; ++i)
			bm >>= 1;
		if (i > 1)
			(void)printf("<0-%d>", i - 1);
		else
			(void)printf("<0>");
	}
}

static void
nbp_print(register const struct atNBP *np, u_int length, register u_short snet,
	  register u_char snode, register u_char skt)
{
	register const struct atNBPtuple *tp =
		(const struct atNBPtuple *)((u_char *)np + nbpHeaderSize);
	int i;
	const u_char *ep;

	if (length < nbpHeaderSize) {
		(void)printf(" truncated-nbp %u", length);
		return;
	}

	length -= nbpHeaderSize;
	if (length < 8) {
		/* must be room for at least one tuple */
		(void)printf(" truncated-nbp %u", length + nbpHeaderSize);
		return;
	}
	/* ep points to end of available data */
	ep = snapend;
	if ((const u_char *)tp > ep) {
		fputs(tstr, stdout);
		return;
	}
	switch (i = np->control & 0xf0) {

	case nbpBrRq:
	case nbpLkUp:
		(void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:",
			     np->id);
		if ((const u_char *)(tp + 1) > ep) {
			fputs(tstr, stdout);
			return;
		}
		(void)nbp_name_print(tp, ep);
		/*
		 * look for anomalies: the spec says there can only
		 * be one tuple, the address must match the source
		 * address and the enumerator should be zero.
		 */
		if ((np->control & 0xf) != 1)
			(void)printf(" [ntup=%d]", np->control & 0xf);
		if (tp->enumerator)
			(void)printf(" [enum=%d]", tp->enumerator);
		if (EXTRACT_16BITS(&tp->net) != snet ||
		    tp->node != snode || tp->skt != skt)
			(void)printf(" [addr=%s.%d]",
			    ataddr_string(EXTRACT_16BITS(&tp->net),
			    tp->node), tp->skt);
		break;

	case nbpLkUpReply:
		(void)printf(" nbp-reply %d:", np->id);

		/* print each of the tuples in the reply */
		for (i = np->control & 0xf; --i >= 0 && tp; )
			tp = nbp_tuple_print(tp, ep, snet, snode, skt);
		break;

	default:
		(void)printf(" nbp-0x%x  %d (%u)", np->control, np->id,
				length);
		break;
	}
}

/* print a counted string */
static const char *
print_cstring(register const char *cp, register const u_char *ep)
{
	register u_int length;

	if (cp >= (const char *)ep) {
		fputs(tstr, stdout);
		return (0);
	}
	length = *cp++;

	/* Spec says string can be at most 32 bytes long */
	if (length > 32) {
		(void)printf("[len=%u]", length);
		return (0);
	}
	while ((int)--length >= 0) {
		if (cp >= (const char *)ep) {
			fputs(tstr, stdout);
			return (0);
		}
		putchar(*cp++);
	}
	return (cp);
}

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 const struct atNBPtuple *tpn;

	if ((const u_char *)(tp + 1) > ep) {
		fputs(tstr, stdout);
		return 0;
	}
	tpn = nbp_name_print(tp, ep);

	/* if the enumerator isn't 1, print it */
	if (tp->enumerator != 1)
		(void)printf("(%d)", tp->enumerator);

	/* if the socket doesn't match the src socket, print it */
	if (tp->skt != skt)
		(void)printf(" %d", tp->skt);

	/* if the address doesn't match the src address, it's an anomaly */
	if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode)
		(void)printf(" [addr=%s]",
		    ataddr_string(EXTRACT_16BITS(&tp->net), tp->node));

	return (tpn);
}

static const struct atNBPtuple *
nbp_name_print(const struct atNBPtuple *tp, register const u_char *ep)
{
	register const char *cp = (const char *)tp + nbpTupleSize;

	putchar(' ');

	/* Object */
	putchar('"');
	if ((cp = print_cstring(cp, ep)) != NULL) {
		/* Type */
		putchar(':');
		if ((cp = print_cstring(cp, ep)) != NULL) {
			/* Zone */
			putchar('@');
			if ((cp = print_cstring(cp, ep)) != NULL)
				putchar('"');
		}
	}
	return ((const struct atNBPtuple *)cp);
}


#define HASHNAMESIZE 4096

struct hnamemem {
	int addr;
	char *name;
	struct hnamemem *nxt;
};

static struct hnamemem hnametable[HASHNAMESIZE];

static const char *
ataddr_string(u_short atnet, u_char athost)
{
	register struct hnamemem *tp, *tp2;
	register int i = (atnet << 8) | athost;
	char nambuf[256+1];
	static int first = 1;
	FILE *fp;

	/*
	 * if this is the first call, see if there's an AppleTalk
	 * number to name map file.
	 */
	if (first && (first = 0, !nflag)
	    && (fp = fopen("/etc/atalk.names", "r"))) {
		char line[256];
		int i1, i2;

		while (fgets(line, sizeof(line), fp)) {
			if (line[0] == '\n' || line[0] == 0 || line[0] == '#')
				continue;
			if (sscanf(line, "%d.%d %256s", &i1, &i2, nambuf) == 3)
				/* got a hostname. */
				i2 |= (i1 << 8);
			else if (sscanf(line, "%d %256s", &i1, nambuf) == 2)
				/* got a net name */
				i2 = (i1 << 8) | 255;
			else
				continue;

			for (tp = &hnametable[i2 & (HASHNAMESIZE-1)];
			     tp->nxt; tp = tp->nxt)
				;
			tp->addr = i2;
			tp->nxt = newhnamemem();
			tp->name = strdup(nambuf);
		}
		fclose(fp);
	}

	for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
		if (tp->addr == i)
			return (tp->name);

	/* didn't have the node name -- see if we've got the net name */
	i |= 255;
	for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt)
		if (tp2->addr == i) {
			tp->addr = (atnet << 8) | athost;
			tp->nxt = newhnamemem();
			(void)snprintf(nambuf, sizeof(nambuf), "%s.%d",
			    tp2->name, athost);
			tp->name = strdup(nambuf);
			return (tp->name);
		}

	tp->addr = (atnet << 8) | athost;
	tp->nxt = newhnamemem();
	if (athost != 255)
		(void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost);
	else
		(void)snprintf(nambuf, sizeof(nambuf), "%d", atnet);
	tp->name = strdup(nambuf);

	return (tp->name);
}

static const struct tok 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)snprintf(buf, sizeof(buf), "%d", skt);
		return (buf);
	}
	return (tok2str(skt2str, "%d", skt));
}
