print-atalk.c

来自「TCPDUMP的C语言源代码,是在数据链路层的应用」· C语言 代码 · 共 628 行 · 第 1/2 页

C
628
字号
/* * 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 lintstatic 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 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_intltalk_if_print(const struct pcap_pkthdr *h, const u_char *p){	return (llap_print(p, h->caplen));}/* * Print AppleTalk LLAP packets. */u_intllap_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;	/*	 * Our packet is on a 4-byte boundary, as we're either called	 * directly from a top-level link-layer printer (ltalk_if_print)	 * or from the UDP printer.  The LLAP+DDP header is a multiple	 * of 4 bytes in length, so the DDP payload is also on a 4-byte	 * boundary, and we don't need to align it before calling	 * "ddp_print()".	 */	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 %d]", 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 %d]", 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 %d",		    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). */voidatalk_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 %d]", 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() */voidaarp_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(pdaddr), etheraddr_string(ap->hdaddr));			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 voidddp_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 voidatp_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;	}	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=%d]", 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 (%d)",			     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);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?