mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-30 15:38:06 +01:00
Handle IS-IS IIH messages and print NSAPs in canonical format.
Submitted by: Tony Li <tli@jnx.com>
This commit is contained in:
parent
554c43cbee
commit
01bd0dbc7e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=17688
@ -467,15 +467,16 @@ isonsap_string(const u_char *nsap)
|
|||||||
if (tp->e_name)
|
if (tp->e_name)
|
||||||
return tp->e_name;
|
return tp->e_name;
|
||||||
|
|
||||||
tp->e_name = cp = (char *)malloc(nlen * 2 + 2);
|
tp->e_name = cp = (char *)malloc(nlen * 2 + 2 + (nlen>>1));
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
error("isonsap_string: malloc");
|
error("isonsap_string: malloc");
|
||||||
|
|
||||||
nsap++;
|
nsap++;
|
||||||
*cp++ = '/';
|
for (i = 0; i < nlen; i++) {
|
||||||
for (i = nlen; (int)--i >= 0;) {
|
|
||||||
*cp++ = hex[*nsap >> 4];
|
*cp++ = hex[*nsap >> 4];
|
||||||
*cp++ = hex[*nsap++ & 0xf];
|
*cp++ = hex[*nsap++ & 0xf];
|
||||||
|
if (((i & 1) == 0) && (i + 1 < nlen))
|
||||||
|
*cp++ = '.';
|
||||||
}
|
}
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
return (tp->e_name);
|
return (tp->e_name);
|
||||||
|
@ -46,14 +46,16 @@ struct rtentry;
|
|||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "addrtoname.h"
|
#include "addrtoname.h"
|
||||||
#include "ethertype.h"
|
#include "ethertype.h"
|
||||||
|
#include "extract.h"
|
||||||
|
|
||||||
#define CLNS 129
|
#define NLPID_CLNS 129 /* 0x81 */
|
||||||
#define ESIS 130
|
#define NLPID_ESIS 130 /* 0x82 */
|
||||||
#define ISIS 131
|
#define NLPID_ISIS 131 /* 0x83 */
|
||||||
#define NULLNS 0
|
#define NLPID_NULLNS 0
|
||||||
|
|
||||||
static int osi_cksum(const u_char *, u_int, const u_char *, u_char *, u_char *);
|
static int osi_cksum(const u_char *, u_int, const u_char *, u_char *, u_char *);
|
||||||
static void esis_print(const u_char *, u_int);
|
static void esis_print(const u_char *, u_int);
|
||||||
|
static int isis_print(const u_char *, u_int);
|
||||||
|
|
||||||
void
|
void
|
||||||
isoclns_print(const u_char *p, u_int length, u_int caplen,
|
isoclns_print(const u_char *p, u_int length, u_int caplen,
|
||||||
@ -70,17 +72,17 @@ isoclns_print(const u_char *p, u_int length, u_int caplen,
|
|||||||
|
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
|
|
||||||
case CLNS:
|
case NLPID_CLNS:
|
||||||
/* esis_print(&p, &length); */
|
/* esis_print(&p, &length); */
|
||||||
printf("iso-clns");
|
printf("iso clns");
|
||||||
if (!eflag)
|
if (!eflag)
|
||||||
(void)printf(" %s > %s",
|
(void)printf(" %s > %s",
|
||||||
etheraddr_string(esrc),
|
etheraddr_string(esrc),
|
||||||
etheraddr_string(edst));
|
etheraddr_string(edst));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ESIS:
|
case NLPID_ESIS:
|
||||||
printf("iso-esis");
|
printf("iso esis");
|
||||||
if (!eflag)
|
if (!eflag)
|
||||||
(void)printf(" %s > %s",
|
(void)printf(" %s > %s",
|
||||||
etheraddr_string(esrc),
|
etheraddr_string(esrc),
|
||||||
@ -88,20 +90,20 @@ isoclns_print(const u_char *p, u_int length, u_int caplen,
|
|||||||
esis_print(p, length);
|
esis_print(p, length);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ISIS:
|
case NLPID_ISIS:
|
||||||
printf("iso-isis");
|
printf("iso isis");
|
||||||
if (!eflag)
|
if (!eflag)
|
||||||
(void)printf(" %s > %s",
|
(void)printf(" %s > %s",
|
||||||
etheraddr_string(esrc),
|
etheraddr_string(esrc),
|
||||||
etheraddr_string(edst));
|
etheraddr_string(edst));
|
||||||
/* isis_print(&p, &length); */
|
|
||||||
(void)printf(" len=%d ", length);
|
(void)printf(" len=%d ", length);
|
||||||
if (caplen > 1)
|
if (!isis_print(p, length)) {
|
||||||
default_print_unaligned(p, caplen);
|
default_print_unaligned(p, caplen);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NULLNS:
|
case NLPID_NULLNS:
|
||||||
printf("iso-nullns");
|
printf("iso nullns");
|
||||||
if (!eflag)
|
if (!eflag)
|
||||||
(void)printf(" %s > %s",
|
(void)printf(" %s > %s",
|
||||||
etheraddr_string(esrc),
|
etheraddr_string(esrc),
|
||||||
@ -109,7 +111,7 @@ isoclns_print(const u_char *p, u_int length, u_int caplen,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("iso-clns %02x", p[0]);
|
printf("iso clns %02x", p[0]);
|
||||||
if (!eflag)
|
if (!eflag)
|
||||||
(void)printf(" %s > %s",
|
(void)printf(" %s > %s",
|
||||||
etheraddr_string(esrc),
|
etheraddr_string(esrc),
|
||||||
@ -206,7 +208,7 @@ esis_print(const u_char *p, u_int length)
|
|||||||
dst = p; p += *p + 1;
|
dst = p; p += *p + 1;
|
||||||
if (p > snapend)
|
if (p > snapend)
|
||||||
return;
|
return;
|
||||||
printf(" %s", isonsap_string(dst));
|
printf("\n\t\t\t %s", isonsap_string(dst));
|
||||||
snpa = p; p += *p + 1;
|
snpa = p; p += *p + 1;
|
||||||
is = p; p += *p + 1;
|
is = p; p += *p + 1;
|
||||||
if (p > snapend)
|
if (p > snapend)
|
||||||
@ -237,7 +239,7 @@ esis_print(const u_char *p, u_int length)
|
|||||||
}
|
}
|
||||||
if (p > snapend)
|
if (p > snapend)
|
||||||
return;
|
return;
|
||||||
printf(" %s", isonsap_string(is));
|
printf("\n\t\t\t %s", isonsap_string(is));
|
||||||
li = ep - p;
|
li = ep - p;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -284,6 +286,257 @@ esis_print(const u_char *p, u_int length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* print_nsap
|
||||||
|
* Print out an NSAP.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
print_nsap (register const u_char *cp, register int length)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
printf("%02x", *cp++);
|
||||||
|
if (((i & 1) == 0) && (i + 1 < length)) {
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* isis_print
|
||||||
|
* Decode IS-IS packets. Return 0 on error.
|
||||||
|
*
|
||||||
|
* So far, this is only smart enough to print IIH's. Someday...
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int
|
||||||
|
isis_print (const u_char *p, u_int length)
|
||||||
|
{
|
||||||
|
struct isis_header *header;
|
||||||
|
u_char pdu_type, max_area, priority, *pptr, type, len, *tptr, tmp, alen;
|
||||||
|
u_short packet_len, holding_time;
|
||||||
|
|
||||||
|
header = (struct isis_header *)p;
|
||||||
|
printf("\n\t\t\t");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sanity checking of the header.
|
||||||
|
*/
|
||||||
|
if (header->nlpid != NLPID_ISIS) {
|
||||||
|
printf(" coding error!");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header->version != ISIS_VERSION) {
|
||||||
|
printf(" version %d packet not supported", header->version);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((header->id_length != SYSTEM_ID_LEN) && (header->id_length != 0)) {
|
||||||
|
printf(" system ID length of %d is not supported",
|
||||||
|
header->id_length);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((header->fixed_len != ISIS_HEADER_SIZE)) {
|
||||||
|
printf(" bogus fixed header length %d should be %d",
|
||||||
|
header->fixed_len, ISIS_HEADER_SIZE);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdu_type = header->enc_pdu_type & PDU_TYPE_MASK;
|
||||||
|
if ((pdu_type != L1_LAN_IIH) && (pdu_type != L2_LAN_IIH)) {
|
||||||
|
printf(" PDU type (%d) not supported", pdu_type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header->pkt_version != ISIS_VERSION) {
|
||||||
|
printf(" version %d packet not supported", header->pkt_version);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_area = header->enc_max_area;
|
||||||
|
switch(max_area) {
|
||||||
|
case 0:
|
||||||
|
max_area = 3; /* silly shit */
|
||||||
|
break;
|
||||||
|
case 255:
|
||||||
|
printf(" bad packet -- 255 areas");
|
||||||
|
return(0);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (header->circuit) {
|
||||||
|
case 0:
|
||||||
|
printf(" PDU with circuit type 0");
|
||||||
|
return(0);
|
||||||
|
case 1:
|
||||||
|
if (pdu_type == L2_LAN_IIH) {
|
||||||
|
printf(" L2 IIH on an L1 only circuit");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (pdu_type == L1_LAN_IIH) {
|
||||||
|
printf(" L1 IIH on an L2 only circuit");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf(" unknown circuit type");
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
holding_time = EXTRACT_16BITS(header->enc_holding_time);
|
||||||
|
|
||||||
|
packet_len = EXTRACT_16BITS(header->enc_packet_len);
|
||||||
|
if ((packet_len < ISIS_HEADER_SIZE) ||
|
||||||
|
(packet_len > length)) {
|
||||||
|
printf(" bogus packet length %d, real length %d", packet_len,
|
||||||
|
length);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
priority = header->enc_priority & PRIORITY_MASK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now print the fixed header.
|
||||||
|
*/
|
||||||
|
switch (pdu_type) {
|
||||||
|
case L1_LAN_IIH:
|
||||||
|
printf(" L1 lan iih, ");
|
||||||
|
break;
|
||||||
|
case L2_LAN_IIH:
|
||||||
|
printf(" L2 lan iih, ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("circuit ");
|
||||||
|
switch (header->circuit) {
|
||||||
|
case 1:
|
||||||
|
printf("l1 only, ");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
printf("l2 only, ");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
printf("l1-l2, ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("holding time %d ", holding_time);
|
||||||
|
printf ("\n\t\t\t source %s, length %d",
|
||||||
|
etheraddr_string(header->enc_source_id), packet_len);
|
||||||
|
printf ("\n\t\t\t lan id %s(%d)", etheraddr_string(header->enc_lan_id),
|
||||||
|
header->enc_lan_id[SYSTEM_ID_LEN]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now print the TLV's.
|
||||||
|
*/
|
||||||
|
packet_len -= ISIS_HEADER_SIZE;
|
||||||
|
pptr = (char *)p + ISIS_HEADER_SIZE;
|
||||||
|
while (packet_len >= 2) {
|
||||||
|
if (pptr >= snapend) {
|
||||||
|
printf("\n\t\t\t packet exceeded snapshot");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
type = *pptr++;
|
||||||
|
len = *pptr++;
|
||||||
|
packet_len -= 2;
|
||||||
|
if (len > packet_len) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case TLV_AREA_ADDR:
|
||||||
|
printf("\n\t\t\t area addresses");
|
||||||
|
tmp = len;
|
||||||
|
tptr = pptr;
|
||||||
|
alen = *tptr++;
|
||||||
|
while (tmp && alen < tmp) {
|
||||||
|
printf("\n\t\t\t ");
|
||||||
|
print_nsap(tptr, alen);
|
||||||
|
printf(" (%d)", alen);
|
||||||
|
tptr += alen;
|
||||||
|
tmp -= alen + 1;
|
||||||
|
alen = *tptr++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TLV_ISNEIGH:
|
||||||
|
printf("\n\t\t\t neighbor addresses");
|
||||||
|
tmp = len;
|
||||||
|
tptr = pptr;
|
||||||
|
while (tmp >= sizeof(struct ether_addr)) {
|
||||||
|
printf("\n\t\t\t %s", etheraddr_string(tptr));
|
||||||
|
tmp -= sizeof(struct ether_addr);
|
||||||
|
tptr += sizeof(struct ether_addr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TLV_PADDING:
|
||||||
|
printf("\n\t\t\t padding for %d bytes", len);
|
||||||
|
break;
|
||||||
|
case TLV_AUTHENT:
|
||||||
|
printf("\n\t\t\t authentication data");
|
||||||
|
default_print(pptr, len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("\n\t\t\t unknown TLV, type %d, length %d", type, len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pptr += len;
|
||||||
|
packet_len -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet_len != 0) {
|
||||||
|
printf("\n\t\t\t %d straggler bytes", packet_len);
|
||||||
|
}
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
osi_cksum(register const u_char *p, register u_int len,
|
osi_cksum(register const u_char *p, register u_int len,
|
||||||
const u_char *toff, u_char *cksum, u_char *off)
|
const u_char *toff, u_char *cksum, u_char *off)
|
||||||
|
Loading…
Reference in New Issue
Block a user