📄 _isoclns.c
字号:
/*
* Copyright (c) 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.
*/
/*
* Original code by Matt Thomas, Digital Equipment Corporation
*/
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include "interfac.h"
#include "a2name.h"
#include "ethertyp.h"
#include "extract.h"
#define NLPID_CLNS 129 /* 0x81 */
#define NLPID_ESIS 130 /* 0x82 */
#define NLPID_ISIS 131 /* 0x83 */
#define NLPID_NULLNS 0
static int osi_cksum (const u_char*, u_int, const u_char*, u_char*, u_char*);
static void esis_print (const u_char *, int);
void isoclns_print (const u_char * p, u_int length, u_int caplen,
const u_char * esrc, const u_char * edst)
{
if (caplen < 1)
{
PUTS ("[|iso-clns] ");
if (!eflag)
PRINTF ("%s > %s",
etheraddr_string (esrc),
etheraddr_string (edst));
return;
}
switch (*p)
{
case NLPID_CLNS:
PUTS ("iso-clns");
if (!eflag)
PRINTF (" %s > %s",
etheraddr_string (esrc),
etheraddr_string (edst));
break;
case NLPID_ESIS:
PUTS ("iso-esis");
if (!eflag)
PRINTF (" %s > %s",
etheraddr_string (esrc),
etheraddr_string (edst));
esis_print (p, length);
return;
case NLPID_ISIS:
PUTS ("iso-isis");
if (!eflag)
PRINTF (" %s > %s",
etheraddr_string (esrc),
etheraddr_string (edst));
PRINTF (" len=%d ", length);
if (caplen > 1)
default_print_unaligned (p, caplen);
break;
case NLPID_NULLNS:
PUTS ("iso-nullns");
if (!eflag)
PRINTF (" %s > %s",
etheraddr_string (esrc),
etheraddr_string (edst));
break;
default:
PRINTF ("iso-clns %02x", p[0]);
if (!eflag)
PRINTF (" %s > %s",
etheraddr_string (esrc),
etheraddr_string (edst));
PRINTF (" len=%d ", length);
if (caplen > 1)
default_print_unaligned (p, caplen);
break;
}
}
#define ESIS_REDIRECT 6
#define ESIS_ESH 2
#define ESIS_ISH 4
struct esis_hdr {
u_char version;
u_char reserved;
u_char type;
u_char tmo[2];
u_char cksum[2];
};
static void esis_print (const u_char * p, int length)
{
const u_char *ep;
int li = p[1];
const struct esis_hdr *eh = (const struct esis_hdr *) &p[2];
u_char cksum[2];
u_char off[2];
if (length == 2)
{
if (qflag)
PUTS (" bad pkt!");
else PUTS (" no header at all!");
return;
}
ep = p + li;
if (li > length)
{
if (qflag)
PUTS (" bad pkt!");
else PRINTF (" LI(%d) > PDU size (%d)!", li, length);
return;
}
if (li < sizeof(struct esis_hdr) + 2)
{
if (qflag)
PUTS (" bad pkt!");
else
{
PRINTF (" too short for esis header %d:", li);
while (--length != 0)
PRINTF ("%02X", *p++);
}
return;
}
switch (eh->type & 0x1f)
{
case ESIS_REDIRECT:
PUTS (" redirect");
break;
case ESIS_ESH:
PUTS (" esh");
break;
case ESIS_ISH:
PUTS (" ish");
break;
default:
PRINTF (" type %d", eh->type & 0x1f);
break;
}
off[0] = eh->cksum[0];
off[1] = eh->cksum[1];
if (vflag && osi_cksum (p, li, eh->cksum, cksum, off))
{
PRINTF (" bad cksum (got %02x%02x want %02x%02x)",
eh->cksum[1], eh->cksum[0], cksum[1], cksum[0]);
return;
}
if (eh->version != 1)
{
PRINTF (" unsupported version %d", eh->version);
return;
}
p += sizeof(*eh) + 2;
li -= sizeof(*eh) + 2; /* protoid * li */
switch (eh->type & 0x1f)
{
case ESIS_REDIRECT:
{
const u_char *dst, *snpa, *is;
dst = p;
p += *p + 1;
if (p > snapend)
return;
PRINTF ("\n\t\t\t %s", isonsap_string (dst));
snpa = p;
p += *p + 1;
is = p;
p += *p + 1;
if (p > snapend)
return;
if (p > ep)
{
PUTS (" [bad li]");
return;
}
if (is[0] == 0)
PRINTF (" > %s", etheraddr_string (&snpa[1]));
else PRINTF (" > %s", isonsap_string (is));
li = ep - p;
break;
}
#if 0
case ESIS_ESH:
PUTS (" esh");
break;
#endif
case ESIS_ISH:
{
const u_char *is = p;
p += *p + 1;
if (p > ep)
{
PUTS (" [bad li]");
return;
}
if (p > snapend)
return;
PUTCHAR (' ');
PUTS (isonsap_string (is));
li = ep - p;
break;
}
default:
PRINTF (" len=%d", length);
if (length && p < snapend)
{
length = snapend - p;
default_print (p, length);
}
return;
}
if (vflag)
{
while (p < ep && li)
{
int op, opli;
const u_char *q;
if (snapend - p < 2)
return;
if (li < 2)
{
PUTS (" bad opts/li");
return;
}
op = *p++;
opli = *p++;
li -= 2;
if (opli > li)
{
PRINTF (" opt (%d) too long", op);
return;
}
li -= opli;
q = p;
p += opli;
if (snapend < p)
return;
if (op == 198 && opli == 2)
{
PRINTF (" tmo=%d", q[0] * 256 + q[1]);
continue;
}
PRINTF (" %d:<", op);
while (--opli >= 0)
PRINTF ("%02x", *q++);
PUTCHAR ('>');
}
}
}
static int osi_cksum (const u_char *p, u_int len,
const u_char *toff, u_char *cksum, u_char *off)
{
int x, y, f = (len - (toff-p+1));
int32_t c0 = 0, c1 = 0;
if ((cksum[0] = off[0]) == 0 && (cksum[1] = off[1]) == 0)
return 0;
off[0] = off[1] = 0;
while ((int) --len >= 0)
{
c0 += *p++;
c1 += c0;
c0 %= 255;
c1 %= 255;
}
x = (c0 * f - c1);
if (x < 0)
x = 255 - (-x % 255);
else x %= 255;
y = -1 * (x + c0);
if (y < 0)
y = 255 - (-y % 255);
else y %= 255;
off[0] = x;
off[1] = y;
return (off[0] != cksum[0] || off[1] != cksum[1]);
}
#if 0
/*
* IS-IS is defined in ISO 10589. Look there for protocol definitions.
*/
#define SYSTEM_ID_LEN sizeof(struct ether_addr)
#define ISIS_VERSION 1
#define PDU_TYPE_MASK 0x1F
#define PRIORITY_MASK 0x7F
#define L1_LAN_IIH 15
#define L2_LAN_IIH 16
#define PTP_IIH 17
#define TLV_AREA_ADDR 1
#define TLV_ISNEIGH 6
#define TLV_PADDING 8
#define TLV_AUTHENT 10
struct isis_header {
u_char nlpid;
u_char fixed_len;
u_char version; /* Protocol version? */
u_char id_length;
u_char enc_pdu_type; /* 3 MSbs are reserved */
u_char pkt_version; /* Packet format version? */
u_char reserved;
u_char enc_max_area;
u_char circuit;
u_char enc_source_id [SYSTEM_ID_LEN];
u_char enc_holding_time[2];
u_char enc_packet_len[2];
u_char enc_priority;
u_char enc_lan_id [SYSTEM_ID_LEN+1];
};
#define ISIS_HEADER_SIZE (15+(SYSTEM_ID_LEN<<1))
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -