Ejemplo n.º 1
0
/**
 * Cisco VLAN Trunking Protocol.
 */
void process_cisco_vtp(struct Ferret *ferret, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	struct vtp_summary {
     unsigned char  version;         
     unsigned char  code;            
     unsigned char  followers;       
     unsigned char  domain_length;
     unsigned char  domain[32]; 
     unsigned revision;                    
     unsigned updater;                     
     unsigned char  timestamp[12];    
     unsigned char  md5[16];
	} vtp;
	unsigned offset=0;
	const unsigned char *domain_name;
	
	if (offset+4 > length) {
		FRAMERR(frame, "%s: truncated\n", "VTP");
		return;
	}

	vtp.version = px[offset++];
	SAMPLE(ferret,"Cisco", JOT_NUM("VTP version",  vtp.version));
	if (vtp.version != 1) {
		FRAMERR(frame, "%s: unknown version %d\n", "VTP", vtp.version);
		return;
	}

	vtp.code = px[offset++];
	SAMPLE(ferret,"Cisco", JOT_NUM("VTP code",  vtp.code));
	vtp.followers = px[offset++];
	SAMPLE(ferret,"Cisco", JOT_NUM("VTP followers",  vtp.followers));
	vtp.domain_length = px[offset++];
	if (offset + vtp.domain_length > length) {
		FRAMERR(frame, "%s: truncated\n", "VTP");
		return;
	}
	domain_name = px+offset;
	offset += 32;
	
	if (offset + 8 > length) {
		FRAMERR(frame, "%s: truncated\n", "VTP");
		return;
	}
	vtp.revision = ex32be(px+offset);
	offset += 4;

	vtp.updater = ex32be(px+offset);
	offset += 4;

	JOTDOWN(ferret, 
		JOT_MACADDR("ID-MAC", frame->src_mac),
		JOT_PRINT("Cisco VTP Domain", domain_name, vtp.domain_length),
		JOT_NUM("Revision", vtp.revision),
		JOT_IPv4("Updater", vtp.updater),
		0);



}
Ejemplo n.º 2
0
void parse_dynamic_trunking_protocol(struct Ferret *ferret, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	unsigned offset;

	if (length < 1) {
		FRAMERR(frame, "truncated\n");
		return;
	}

	/* Version */
	if (px[0] != 0x01) {
		FRAMERR(frame, "unexpected\n");
		return;
	}

	/* Look for TLV values */
	for (offset=1; offset+4<length; ) {
		unsigned tag = ex16be(px+offset+0);
		unsigned length = ex16be(px+offset+2);

		if (tag == 0 && length == 0)
			break;

		if (length < 4) {
			FRAMERR(frame, "unexpected\n");
			return;
		}

		length -= 4;
		offset += 4;

		switch (tag) {
		case 0x0001: /* domain */
			JOTDOWN(ferret, 
				JOT_MACADDR("ID-MAC", frame->src_mac),
				JOT_PRINT("DTP-Domain", px+offset, length),
				0);
			break;
		case 0x0002: /* status */
			break;
		case 0x0003: /* Dtptype */
			break;
		case 0x0004: /* neighbor */
			/* TODO: is this interesting? */
			break;
		default:
			FRAMERR(frame, "unknown 0x%x\n", tag);
		}

		offset += length;
	}


}
Ejemplo n.º 3
0
void process_icmpv6(struct Ferret *ferret, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
    unsigned type = px[0];
    unsigned code = px[1];
    unsigned checksum = ex16be(px+2);

    UNUSEDPARM(length);
    UNUSEDPARM(frame);
    UNUSEDPARM(checksum);

    frame->layer4_protocol = LAYER4_ICMP;

    JOTDOWN(ferret,
            JOT_SZ("TEST","icmp"),
            JOT_NUM("type",type),
            JOT_NUM("code",code),
            0);

    if (frame->dst_ipv6[0] == 0xFF)
        JOTDOWN(ferret,
                JOT_MACADDR("ID-MAC", frame->src_mac),
                JOT_IPv6("ipv6", frame->src_ipv6, 16),
                0);
}
Ejemplo n.º 4
0
void parse_atalk_ddp(struct Ferret *ferret, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
    unsigned offset=0;
    struct {
        unsigned hop_count;
        unsigned datagram_length;
        unsigned checksum;
        unsigned protocol_type;
        unsigned address_src;
        unsigned address_dst;
        unsigned port_src;
        unsigned port_dst;
    } ddp;

    ferret->statistics.atalk++;

    if (length < 13) {
        FRAMERR(frame, "%s: truncated\n", "DDP");
        return;
    }



    ddp.hop_count = px[0]>>4;
    ddp.datagram_length = (px[0]&0xF)<<8 | px[1];
    ddp.checksum = ex16be(px+2);
    ddp.address_dst = ex16be(px+4)<<8;
    ddp.address_src = ex16be(px+6)<<8;
    ddp.address_dst |= px[8];
    ddp.address_src |= px[9];
    ddp.port_dst = px[10];
    ddp.port_src = px[11];
    ddp.protocol_type = px[12];

    if (length > ddp.datagram_length) {
        if (length-ddp.datagram_length == 4)
            ferret->statistics.remaining_4++; /*hints that an FCS trails*/
        length = ddp.datagram_length;
    }

    frame->ipver = ADDRESS_ATALK_EDDP;
    frame->src_ipv4 = ddp.address_src;
    frame->dst_ipv4 = ddp.address_dst;
    frame->src_port = ddp.port_src;
    frame->dst_port = ddp.port_dst;

    /* skip the header */
    offset += 13;

    /* If this is a broadcast packet, we can make the assumption
     * that the sender is on the local subnet */
    JOTDOWN(ferret,
            JOT_MACADDR("ID-MAC", frame->src_mac),
            JOT_SRC("AppleTalk", frame),
            0);

    /* Parse the next layer */
    SAMPLE(ferret, "ATALK-DDP",JOT_NUM("protocol", ddp.protocol_type));
    SAMPLE(ferret, "ATALK-DDP",JOT_NUM("dst-port", ddp.port_dst));

    switch (ddp.protocol_type) {
    case 0x02: /* NBP - Name Binding Protocol */
        parse_atalk_nbp(ferret, frame, px+offset, length-offset);
        break;
    case 0x06: /* ZIP (Zone Information Protocol) */
        break;
    case 0x01: /* RTMP (Routing Table Maintenance Protocol), works like RIP */
    case 0x03: /* ATP (Appletalk Transfer Protocol) */
    case 0x04: /* Echo, works like ICMP Echo */
    case 0x05: /* RTMP requests */
    case 0x07: /* ADSP (Appletalk Data Stream Protocol) */
    case 0x08: /* SNMP, same as normal SNMP */
    case 0x16: /* IP over AppleTalk */
    default:
        FRAMERR(frame, "%s: unknown protocol=%d, srcport=%d, dstport=%d\n", "DDP", ddp.protocol_type,
                ddp.port_src, ddp.port_dst);
    }

}
Ejemplo n.º 5
0
/*
 * Cisco Discovery Protocol 
 */
static void 
parse_CDP(struct Ferret *ferret, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	unsigned offset=0;
	unsigned version;
	//unsigned ttl;
	//unsigned checksum;

	if (offset+4 > length) {
		FRAMERR(frame, "%s: truncated\n", "cisco");
		return;
	}

	frame->layer3_protocol = LAYER3_MGMT;

	version = px[offset++];
	//ttl = px[offset++];
	//checksum = ex16be(px+2);
	offset += 2;

	SAMPLE(ferret,"Cisco Discovery Protocol", 
		JOT_NUM("version",version));

	while (offset < length) {
		unsigned tag;
		unsigned len;
		unsigned i;

		if (offset+4 > length) {
			FRAMERR(frame, "%s: truncated\n", "cisco");
			return;
		}

		tag = ex16be(px+offset);
		len = ex16be(px+offset+2);
		offset += 4;

		if (len < 4) {
			FRAMERR(frame, "%s: bad value: 0x%x\n", "cdp", tag);
			return;
		} else
			len -= 4;

		if (len > length-offset)
			len = length-offset;
		
		SAMPLE(ferret,"Cisco Discovery Protocol", JOT_NUM("tag",  tag));

		switch (tag) {
		case 0x0000:
			return;
		case 0x0001: /* Device ID */
			JOTDOWN(ferret, 
				JOT_MACADDR("ID-MAC", frame->src_mac),
				JOT_PRINT("Cisco Device ID", px+offset,len),
				0);
			break;
		case 0x0002: /* Addresses */
			if (len < 4) {
				FRAMERR(frame, "%s: truncated\n", "cdp");
				break;
			}
			i=0;
			{
				unsigned address_count = ex32be(px+offset);

				i += 4;

				while (address_count && i<len) {
					unsigned protocol_type;
					unsigned protocol_length;
					unsigned protocol = 0;
					unsigned address_length;
					if (i-len < 5)
						break;
					address_count--;

					protocol_type = px[offset+i++];
					protocol_length = px[offset+i++];
					if (protocol_length != 1)
						FRAMERR(frame, "%s: unknown value: 0x%x\n", "cdp", protocol_length);
					while (protocol_length && i<len) {
						protocol <<= 8;
						protocol |= px[offset+i++];
						protocol_length--;
					}
					address_length = ex16be(px+offset+i);
					i+= 2;
					switch (protocol_type) {
					case 1:
						switch (protocol) {
						case 0xCC: /*IPv4 address */
							if (address_length != 4)
								FRAMERR(frame, "%s: unknown value: 0x%x\n", "cdp", address_length);
							else if (len-i < 4)
								FRAMERR(frame, "%s: truncated\n", "cdp");
							else {
								unsigned ip = ex32be(px+offset+i);
								JOTDOWN(ferret, 
									JOT_MACADDR("ID-MAC", frame->src_mac),
									JOT_IPv4("ip", ip),
									0);
								JOTDOWN(ferret, 
									JOT_IPv4("ID-IP", ip),
									JOT_MACADDR("mac", frame->src_mac),
									0);
							}
							break;
						default:
							SAMPLE(ferret,"CDP", JOT_NUM("ip-protocol-type",  protocol));
							FRAMERR(frame, "%s: unknown value: 0x%x\n", "cdp", protocol);
						}
						break;
					default:
						SAMPLE(ferret,"CDP", JOT_NUM("address-protocol-type",  protocol_type));
						FRAMERR(frame, "%s: unknown value: 0x%x\n", "cdp", protocol_type);
						break;
					}
				}
			}


			break;
		case 0x0003: /* Port ID*/
			JOTDOWN(ferret, 
				JOT_MACADDR("ID-MAC", frame->src_mac),
				JOT_PRINT("Cisco Port ID", px+offset,len),
				0);
			break;
		case 0x0004:
			{
				unsigned n = 0;

				for (i=0; i<len; i++) {
					n <<= 8;
					n |= px[offset + i];
				}
				if (n & 0x00000001)
					JOTDOWN(ferret, JOT_MACADDR("ID-MAC", frame->src_mac), JOT_SZ("Capabilities", "router"), 0);
				if (n & 0x00000002)
					JOTDOWN(ferret, JOT_MACADDR("ID-MAC", frame->src_mac), JOT_SZ("Capabilities", "bridge"), 0);
				if (n & 0x00000004)
					JOTDOWN(ferret, JOT_MACADDR("ID-MAC", frame->src_mac), JOT_SZ("Capabilities", "source route bridge"), 0);
				if (n & 0x00000008)
					JOTDOWN(ferret, JOT_MACADDR("ID-MAC", frame->src_mac), JOT_SZ("Capabilities", "switch"), 0);
				if (n & 0x00000010)
					JOTDOWN(ferret, JOT_MACADDR("ID-MAC", frame->src_mac), JOT_SZ("Capabilities", "host"), 0);
				if (n & 0x00000020)
					JOTDOWN(ferret, JOT_MACADDR("ID-MAC", frame->src_mac), JOT_SZ("Capabilities", "IGMP"), 0);
				if (n & 0x00000040)
					JOTDOWN(ferret, JOT_MACADDR("ID-MAC", frame->src_mac), JOT_SZ("Capabilities", "repeater"), 0);
			}
			break;
		case 0x0005: /* IOS Version */
			for (i=0; i<len; i++)
				if (!isspace(px[offset+i]))
					break;
			JOTDOWN(ferret, 
				JOT_MACADDR("ID-MAC", frame->src_mac),
				JOT_PRINT("IOS Version", px+offset+i,len-i),
				0);
			break;
		case 0x0006: /* Platform*/
			JOTDOWN(ferret, 
				JOT_MACADDR("ID-MAC", frame->src_mac),
				JOT_PRINT("Cisco Platform", px+offset,len),
				0);
			break;
		case 0x0008: /* Hello: cluster mgmt */
			break;
		case 0x0009: /* VTP mgmnt domain */
			JOTDOWN(ferret, 
				JOT_MACADDR("ID-MAC", frame->src_mac),
				JOT_PRINT("VTP Mgmt Domain", px+offset,len),
				0);
			break;
		case 0x000a: /* Native VLAN */
			break;
		case 0x000b: /* Duplex */
			break;
		case 0x0012: /* Trust Bitmap */
			break;
		case 0x0013: /* Untrusted Port CoS */
			break;
		case 0x0016: /* Management Addresses */
			/* TODO: decode the management addresses */
			break;
		default:
			FRAMERR(frame, "%s: unknown value: 0x%x\n", "cdp", tag);
		}

		offset += len;
		
	}
}
Ejemplo n.º 6
0
void parse_PVSTP(struct Ferret *ferret, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	unsigned port_id;

	if (length < 4) {
		FRAMERR(frame, "truncated\n");
		return;
	}

	/* Protocol Identifier */
	if (ex16be(px+0) != 0) {
		FRAMERR(frame, "unexpected\n");
		return;
	}

	frame->layer3_protocol = LAYER3_STP;

	/* Protocol Version Identifier */
	if (px[2] != 0) {
		FRAMERR(frame, "unexpected\n");
		return;
	}

	/* BPDU type */
	switch (px[3]) {
	case 0:
		if (length < 28) {
			FRAMERR(frame, "truncated\n");
			return;
		}
		JOTDOWN(ferret, 
			JOT_MACADDR("ID-MAC", frame->src_mac),
			JOT_SZ("Type", "bridge"),
			JOT_MACADDR("root", px+7),
			0);
		JOTDOWN(ferret, 
			JOT_MACADDR("ID-MAC", frame->src_mac),
			JOT_SZ("Type", "bridge"),
			JOT_MACADDR("ID", px+19),
			0);
		port_id = ex16be(px+25);
		JOTDOWN(ferret, 
			JOT_MACADDR("ID-MAC", frame->src_mac),
			JOT_SZ("Type", "bridge"),
			JOT_NUM("port-id", port_id),
			0);
		break;
	case 0x80:
		JOTDOWN(ferret, 
			JOT_MACADDR("ID-MAC", frame->src_mac),
			JOT_SZ("Type", "bridge"),
			0);
		break;
	default:
		FRAMERR(frame, "unexpected\n");
		return;
	}



}