📄 _atalk.c
字号:
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/param.h>
#include <sys/socket.h>
#include "interfac.h"
#include "a2name.h"
#include "ethertyp.h"
#include "extract.h" /* must come after interface.h */
#include "appletal.h"
static struct tok 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 *, 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 AppleTalk LLAP packets.
*/
void llap_print (const u_char * bp, u_int length)
{
const struct LAP *lp;
const struct atDDP *dp;
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)
{
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;
case lapDDP:
if (length < ddpSize)
{
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);
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;
}
}
/*
* 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 (const u_char * bp, u_int length)
{
const struct LAP *lp;
const struct atDDP *dp;
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)
{
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;
case lapDDP:
if (length < ddpSize)
{
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);
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;
}
}
/*
* XXX should probably pass in the snap header and do checks like arp_print()
*/
void aarp_print (const u_char * bp, u_int length)
{
const struct aarp *ap;
#define AT(member) ataddr_string((ap->member[1]<<8)|ap->member[2],ap->member[3])
PUTS ("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 */
PRINTF ("who-has %s tell %s", AT(pdaddr), AT(psaddr));
return;
case 2: /* response */
PRINTF ("reply %s is-at %s", AT(psaddr), etheraddr_string(ap->hsaddr));
return;
case 3: /* probe (oy!) */
PRINTF ("probe %s tell %s", AT(pdaddr), AT(psaddr));
return;
}
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 (const u_char * bp, u_int length, int t,
u_short snet, 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;
default:
PRINTF (" at-%s %d", tok2str (type2str, "#%d", t), length);
break;
}
}
static void atp_print (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. */
PUTS (tstr);
return;
}
length -= sizeof(*ap);
switch (ap->control & 0xc0)
{
case atpReqCode:
PRINTF (" atp-req%s %d",
ap->control & atpXO ? " " : "*",
EXTRACT_16BITS (&ap->transID));
atp_bitmap_print (ap->bitmap);
if (length != 0)
PRINTF (" [len=%d]", length);
switch (ap->control & (atpEOM | atpSTS))
{
case atpEOM:
PUTS (" [EOM]");
break;
case atpSTS:
PUTS (" [STS]");
break;
case atpEOM | atpSTS:
PUTS (" [EOM,STS]");
break;
}
break;
case atpRspCode:
PRINTF (" atp-resp%s%d:%d (%d)",
ap->control & atpEOM ? "*" : " ",
EXTRACT_16BITS (&ap->transID), ap->bitmap, length);
switch (ap->control & (atpXO | atpSTS))
{
case atpXO:
PUTS (" [XO]");
break;
case atpSTS:
PUTS (" [STS]");
break;
case atpXO | atpSTS:
PUTS (" [XO,STS]");
break;
}
break;
case atpRelCode:
PRINTF (" atp-rel %d", EXTRACT_16BITS (&ap->transID));
atp_bitmap_print (ap->bitmap);
/* length should be zero */
if (length)
PRINTF (" [len=%d]", length);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -