📄 _ax25.c
字号:
/*
* Copyright (C) 1996
* Thomas Sailer (sailer@ife.ee.ethz.ch) (HB9JNX/AE4WA)
*
* print-ax25.c -- decode and print AX.25 packets
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* ---------------------------------------------------------------------- */
#include <stdio.h>
#include <sys/types.h>
#include "interfac.h"
#include "a2name.h"
#include "ip.h"
/* ---------------------------------------------------------------------- */
static void ax25_header (const u_char * bp, u_int length, int pr)
{
u_char v1 = 1, cmd = 0;
u_char i, j;
u_int len = length;
int nl = 1;
if (len < 8)
{
PRINTF ("truncated-ax25 %d", length);
return;
}
if (bp + 8 > snapend)
{
PRINTF ("[|ax25]");
return;
}
if (bp[1] & 1)
{
/*
* FlexNet Header Compression
*/
if (pr)
{
v1 = 0;
cmd = (bp[1] & 2) != 0;
PUTS (" ? > ");
i = (bp[2] >> 2) & 0x3f;
if (i)
PRINTF ("%c", i + 0x20);
i = ((bp[2] << 4) | ((bp[3] >> 4) & 0xf)) & 0x3f;
if (i)
PRINTF ("%c", i + 0x20);
i = ((bp[3] << 2) | ((bp[4] >> 6) & 3)) & 0x3f;
if (i)
PRINTF ("%c", i + 0x20);
i = bp[4] & 0x3f;
if (i)
PRINTF ("%c", i + 0x20);
i = (bp[5] >> 2) & 0x3f;
if (i)
PRINTF ("%c", i + 0x20);
i = ((bp[5] << 4) | ((bp[6] >> 4) & 0xf)) & 0x3f;
if (i)
PRINTF ("%c", i + 0x20);
PRINTF ("-%u qso %u:", bp[6] & 0xf, (bp[0] << 6) | (bp[1] >> 2));
}
bp += 7;
len -= 7;
}
else
{
/*
* normal header
*/
if (len < 15)
{
PRINTF ("truncated-ax25 %d", length);
return;
}
if (bp + 15 > snapend)
{
PUTS ("[|ax25]");
return;
}
if (pr)
{
if ((bp[6] & 0x80) != (bp[13] & 0x80))
{
v1 = 0;
cmd = (bp[6] & 0x80);
}
PUTCHAR (' ');
for (i = 7; i < 13; i++)
if ((bp[i] & 0xfe) != 0x40)
PRINTF ("%c", bp[i] >> 1);
PRINTF ("-%u > ", (bp[13] >> 1) & 0xf);
for (i = 0; i < 6; i++)
if ((bp[i] & 0xfe) != 0x40)
PRINTF ("%c", bp[i] >> 1);
PRINTF ("-%u", (bp[6] >> 1) & 0xf);
}
bp += 14;
len -= 14;
if (!(bp[-1] & 1) && len >= 7 && !qflag && pr)
PUTS (" v ");
while ((!(bp[-1] & 1)) && (len >= 7))
{
if (bp + 7 > snapend)
{
PUTS ("[|ax25]");
return;
}
if (qflag || !pr)
{
bp += 7;
len -= 7;
continue;
}
for (i = 0; i < 6; i++)
if ((bp[i] & 0xfe) != 0x40)
PRINTF ("%c", bp[i] >> 1);
PRINTF ("-%u", (bp[6] >> 1) & 0xf);
bp += 7;
len -= 7;
if ((!(bp[-1] & 1)) && (len >= 7))
PUTCHAR (',');
}
}
if (len < 1)
{
PRINTF (" truncated-ax25 %d", length);
return;
}
if (bp + 1 > snapend)
{
PUTS (" [|ax25]");
return;
}
i = *bp++;
len--;
if (pr)
{
j = v1 ? ((i & 0x10) ? '!' : ' ') :
((i & 0x10) ? (cmd ? '+' : '-') :
(cmd ? '^' : 'v'));
if (!(i & 1))
{
/*
* Info frame
*/
PRINTF (" i%u%u%c", (i >> 5) & 7, (i >> 1) & 7, j);
}
else if (i & 2)
{
/*
* U frame
*/
switch (i & (~0x10))
{
case 0x03:
PRINTF (" ui%c", j);
break;
case 0x2f:
PRINTF (" sabm%c", j);
break;
case 0x43:
PRINTF (" disc%c", j);
break;
case 0x0f:
PRINTF (" dm%c", j);
break;
case 0x63:
PRINTF (" ua%c", j);
break;
case 0x87:
PRINTF (" frmr%c", j);
break;
default:
PRINTF (" unknown u (0x%x)%c", i & (~0x10), j);
break;
}
}
else
{
/*
* supervisory
*/
switch (i & 0xf)
{
case 0x1:
PRINTF (" rr%u%c", (i >> 5) & 7, j);
break;
case 0x5:
PRINTF (" rnr%u%c", (i >> 5) & 7, j);
break;
case 0x9:
PRINTF (" rej%u%c", (i >> 5) & 7, j);
break;
default:
PRINTF (" unknown s (0x%x)%u%c", i & 0xf, (i >> 5) & 7, j);
break;
}
}
}
if (len < 1)
return;
if (bp + 1 > snapend)
{
PUTS (" [|ax25]");
return;
}
#define PID_X25 0x01 /* CCITT X.25 PLP */
#define PID_SEGMENT 0x08 /* Segmentation fragment */
#define PID_TEXNET 0xc3 /* TEXNET datagram protocol */
#define PID_LQ 0xc4 /* Link quality protocol */
#define PID_APPLETALK 0xca /* Appletalk */
#define PID_APPLEARP 0xcb /* Appletalk ARP */
#define PID_IP 0xcc /* ARPA Internet Protocol */
#define PID_ARP 0xcd /* ARPA Address Resolution Protocol */
#define PID_FLEXNET 0xce /* FLEXNET */
#define PID_NETROM 0xcf /* NET/ROM */
#define PID_NO_L3 0xf0 /* No level 3 protocol */
switch (*bp)
{
case PID_NO_L3:
PUTS (" text");
break;
case PID_NETROM:
PUTS (" net/rom");
break;
case PID_FLEXNET:
PUTS (" flexnet");
break;
case PID_ARP:
arp_print (bp + 1, len - 1, snapend - 1 - bp);
nl = 0;
break;
case PID_IP:
ip_print (bp + 1, len - 1);
nl = 0;
break;
case PID_APPLEARP:
aarp_print (bp + 1, len - 1);
nl = 0;
break;
case PID_APPLETALK:
atalk_print (bp + 1, len - 1);
nl = 0;
break;
case PID_LQ:
PUTS (" lq");
break;
case PID_TEXNET:
PUTS (" texnet");
break;
case PID_SEGMENT:
PUTS (" segment");
break;
case PID_X25:
PUTS (" x25");
break;
default:
PRINTF (" pid %02X", *bp);
break;
}
if (nl)
PUTCHAR ('\n');
}
/* ---------------------------------------------------------------------- */
void ax25_if_print (u_char * user, const struct pcap_pkthdr *h, const u_char * p)
{
static u_int32_t num_pkt = 0;
u_int caplen = h->caplen;
u_int length = h->len;
snapend = p + caplen;
if (caplen <= 2)
{
PUTS ("[|kiss]");
return;
}
if (length <= 2)
{
PRINTF ("truncated-kiss %d", length);
return;
}
switch (*p)
{
case 0:
ax25_header (p + 1, length - 1, eflag);
break;
default:
if (!qflag)
PRINTF ("kiss 0x%x 0x%x", p[0], p[1]);
break;
}
PUTCHAR ('\n');
status_write ("AX25: %lu (%lu)", ++num_pkt, pcap_mac_packets());
}
/* ---------------------------------------------------------------------- */
void axipudp_print (const u_char * bp, u_int len)
{
if (len <= 3)
{
PRINTF ("truncated-axip %d", len);
return;
}
if (bp + 3 >= snapend)
{
PUTS ("[|axip]");
return;
}
ax25_header (bp, len - 2, 1);
}
/* ---------------------------------------------------------------------- */
void axip_print (const u_char * bp, u_int len, const u_char * bp2)
{
const struct ip *ip = (struct ip *) bp2;
PRINTF ("%s > %s: ", ipaddr_string (&ip->ip_src), ipaddr_string (&ip->ip_dst));
axipudp_print (bp, len);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -