Exemplo n.º 1
0
static int
juniper_parse_header (packetbody_t p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) {

    struct juniper_cookie_table_t *lp = juniper_cookie_table;
    u_int idx, jnx_ext_len, jnx_header_len = 0;
    u_int8_t tlv_type,tlv_len;
    u_int32_t control_word;
    int tlv_value;
    packetbody_t tptr;


    l2info->header_len = 0;
    l2info->cookie_len = 0;
    l2info->proto = 0;


    l2info->length = h->len;
    l2info->caplen = h->caplen;
    PACKET_HAS_SPACE_OR_TRUNC(p,4);
    l2info->flags = p[3];
    l2info->direction = p[3]&JUNIPER_BPF_PKT_IN;
    
    if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */
        printf("no magic-number found!");
        return 0;
    } 

    if (eflag) /* print direction */
        printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction));

    /* magic number + flags */
    jnx_header_len = 4;

    if (vflag>1)
        printf("\n\tJuniper PCAP Flags [%s]",
               bittok2str(jnx_flag_values, "none", l2info->flags));

    /* extensions present ?  - calculate how much bytes to skip */
    if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) {

        tptr = p+jnx_header_len;

        /* ok to read extension length ? */
        PACKET_HAS_SPACE_OR_TRUNC(tptr, 2);
        jnx_ext_len = EXTRACT_16BITS(tptr);
        jnx_header_len += 2;
        tptr +=2;
        
        /* nail up the total length -
         * just in case something goes wrong
         * with TLV parsing */
        jnx_header_len += jnx_ext_len;
        
        if (vflag>1)
            printf(", PCAP Extension(s) total length %u",
                   jnx_ext_len);
        
        PACKET_HAS_SPACE_OR_TRUNC(tptr, jnx_ext_len);
        while (jnx_ext_len > JUNIPER_EXT_TLV_OVERHEAD) {
            tlv_type = *(tptr++);
            tlv_len = *(tptr++);
            tlv_value = 0;
            
            /* sanity check */
            if (tlv_type == 0 || tlv_len == 0)
                break;
            
            if (vflag>1)
                printf("\n\t  %s Extension TLV #%u, length %u, value ",
                       tok2str(jnx_ext_tlv_values,"Unknown",tlv_type),
                       tlv_type,
                       tlv_len);
            
            tlv_value = juniper_read_tlv_value(tptr, tlv_type, tlv_len);
            switch (tlv_type) {
            case JUNIPER_EXT_TLV_IFD_NAME:
                /* FIXME */
                break;
            case JUNIPER_EXT_TLV_IFD_MEDIATYPE:
            case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE:
                if (tlv_value != -1) {
                    if (vflag>1)
                        printf("%s (%u)",
                               tok2str(juniper_ifmt_values, "Unknown", tlv_value),
                               tlv_value);
                }
                break;
            case JUNIPER_EXT_TLV_IFL_ENCAPS:
            case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS:
                if (tlv_value != -1) {
                    if (vflag>1)
                        printf("%s (%u)",
                               tok2str(juniper_ifle_values, "Unknown", tlv_value),
                               tlv_value);
                }
                break;
            case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */
            case JUNIPER_EXT_TLV_IFL_UNIT:
            case JUNIPER_EXT_TLV_IFD_IDX:
            default:
                if (tlv_value != -1) {
                    if (vflag>1)
                        printf("%u",tlv_value);
                }
                break;
            }
            
            tptr+=tlv_len;
            jnx_ext_len -= tlv_len+JUNIPER_EXT_TLV_OVERHEAD;
        }
        
        if (vflag>1)
            printf("\n\t-----original packet-----\n\t");
    } 
    
    if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {            
        if (eflag)
            printf("no-L2-hdr, ");

        /* there is no link-layer present -
         * perform the v4/v6 heuristics
         * to figure out what it is
         */
        PACKET_HAS_SPACE_OR_TRUNC(p, (jnx_header_len+4) + 1);
        if(ip_heuristic_guess(p+jnx_header_len+4,l2info->length-(jnx_header_len+4)) == 0)
            printf("no IP-hdr found!");

        l2info->header_len=jnx_header_len+4;
        return 0; /* stop parsing the output further */
        
    }
    l2info->header_len = jnx_header_len;
    p+=l2info->header_len;
    l2info->length -= l2info->header_len;
    l2info->caplen -= l2info->header_len;

    /* search through the cookie table and copy values matching for our PIC type */
    while (lp->s != NULL) {
        if (lp->pictype == l2info->pictype) {

            l2info->cookie_len += lp->cookie_len;

            switch (p[0]) {
            case LS_COOKIE_ID:
                l2info->cookie_type = LS_COOKIE_ID;
                l2info->cookie_len += 2;
                break;
            case AS_COOKIE_ID:
                l2info->cookie_type = AS_COOKIE_ID;
                l2info->cookie_len = 8;
                break;
            
            default:
                l2info->bundle = l2info->cookie[0];
                break;
            }


#ifdef DLT_JUNIPER_MFR
            /* MFR child links don't carry cookies */
            if (l2info->pictype == DLT_JUNIPER_MFR &&
                (p[0] & MFR_BE_MASK) == MFR_BE_MASK) {
                l2info->cookie_len = 0;
            }
#endif

            l2info->header_len += l2info->cookie_len;
            l2info->length -= l2info->cookie_len;
            l2info->caplen -= l2info->cookie_len;

            if (eflag)
                printf("%s-PIC, cookie-len %u",
                       lp->s,
                       l2info->cookie_len);

            if (l2info->cookie_len > 0) {
                PACKET_HAS_SPACE_OR_TRUNC(p,l2info->cookie_len);
                if (eflag)
                    printf(", cookie 0x");
                for (idx = 0; idx < l2info->cookie_len; idx++) {
                    l2info->cookie[idx] = p[idx]; /* copy cookie data */
                    if (eflag) printf("%02x",p[idx]);
                }
            }

            if (eflag) printf(": "); /* print demarc b/w L2/L3*/
            

            l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); 
            break;
        }
        ++lp;
    }
    p+=l2info->cookie_len;

    /* DLT_ specific parsing */
    switch(l2info->pictype) {
#ifdef DLT_JUNIPER_MLPPP
    case DLT_JUNIPER_MLPPP:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(cheri_ptr(&l2info->cookie[6], 2))>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;            
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MLFR
    case DLT_JUNIPER_MLFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(cheri_ptr(&l2info->cookie[6], 2))>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MFR
    case DLT_JUNIPER_MFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(cheri_ptr(&l2info->cookie[6], 2))>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_ATM2
    case DLT_JUNIPER_ATM2:
        PACKET_HAS_SPACE_OR_TRUNC(p,4);
        /* ATM cell relay control word present ? */
        if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) {
            control_word = EXTRACT_32BITS(p);
            /* some control word heuristics */
            switch(control_word) {
            case 0: /* zero control word */
            case 0x08000000: /* < JUNOS 7.4 control-word */
            case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
                l2info->header_len += 4;
                break;
            default:
                break;
            }
            
            if (eflag)
                printf("control-word 0x%08x ", control_word);
        }
        break;
#endif
#ifdef DLT_JUNIPER_GGSN
    case DLT_JUNIPER_GGSN:
        break;
#endif
#ifdef DLT_JUNIPER_ATM1
    case DLT_JUNIPER_ATM1:
        break;
#endif
#ifdef DLT_JUNIPER_PPP
    case DLT_JUNIPER_PPP:
        break;
#endif
#ifdef DLT_JUNIPER_CHDLC
    case DLT_JUNIPER_CHDLC:
        break;
#endif
#ifdef DLT_JUNIPER_ETHER
    case DLT_JUNIPER_ETHER:
        break;
#endif
#ifdef DLT_JUNIPER_FRELAY
    case DLT_JUNIPER_FRELAY:
        break;
#endif

    default:
        printf("Unknown Juniper DLT_ type %u: ", l2info->pictype);
        break;
    }
    
    if (eflag > 1)
        printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto);

    return 1; /* everything went ok so far. continue parsing */
 trunc:
    printf("[|juniper_hdr], length %u",h->len);
    return 0;
}
Exemplo n.º 2
0
void
ospf_print(register const u_char *bp, register u_int length,
    register const u_char *bp2)
{
	register const struct ospfhdr *op;
	register const struct ip *ip;
	register const u_char *dataend;
	register const char *cp;

	op = (struct ospfhdr *)bp;
	ip = (struct ip *)bp2;
	/* Print the source and destination address  */
	(void) printf("%s > %s:",
	    ipaddr_string(&ip->ip_src),
	    ipaddr_string(&ip->ip_dst));

        /* XXX Before we do anything else, strip off the MD5 trailer */
        TCHECK(op->ospf_authtype);
        if (ntohs(op->ospf_authtype) == OSPF_AUTH_MD5) {
                length -= OSPF_AUTH_MD5_LEN;
                snapend -= OSPF_AUTH_MD5_LEN;
        }

	/* If the type is valid translate it, or just print the type */
	/* value.  If it's not valid, say so and return */
	TCHECK(op->ospf_type);
	cp = tok2str(type2str, "type%d", op->ospf_type);
	printf(" OSPFv%d-%s %d:", op->ospf_version, cp, length);
	if (*cp == 't')
		return;

	TCHECK(op->ospf_len);
	if (length != ntohs(op->ospf_len)) {
		printf(" [len %d]", ntohs(op->ospf_len));
		return;
	}
	dataend = bp + length;

	/* Print the routerid if it is not the same as the source */
	TCHECK(op->ospf_routerid);
	if (ip->ip_src.s_addr != op->ospf_routerid.s_addr)
		printf(" rtrid %s", ipaddr_string(&op->ospf_routerid));

	TCHECK(op->ospf_areaid);
	if (op->ospf_areaid.s_addr != 0)
		printf(" area %s", ipaddr_string(&op->ospf_areaid));
	else
		printf(" backbone");

	if (vflag) {
		/* Print authentication data (should we really do this?) */
		TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata));
		switch (ntohs(op->ospf_authtype)) {

		case OSPF_AUTH_NONE:
			break;

		case OSPF_AUTH_SIMPLE:
			printf(" auth \"");
			(void)fn_printn(op->ospf_authdata,
			    sizeof(op->ospf_authdata), NULL);
			printf("\"");
			break;

		case OSPF_AUTH_MD5:
			printf(" auth MD5");
			break;

		default:
			printf(" ??authtype-%d??", ntohs(op->ospf_authtype));
			return;
		}
	}
	/* Do rest according to version.	 */
	switch (op->ospf_version) {

	case 2:
		/* ospf version 2 */
		if (ospf_decode_v2(op, dataend))
			goto trunc;
		break;

	default:
		printf(" ospf [version %d]", op->ospf_version);
		break;
	}			/* end switch on version */

	return;
trunc:
	fputs(tstr, stdout);
}
Exemplo n.º 3
0
void
vtp_print (netdissect_options *ndo,
           const u_char *pptr, u_int length)
{
    int type, len, tlv_len, tlv_value;
    const u_char *tptr;
    const struct vtp_vlan_ *vtp_vlan;

    if (length < VTP_HEADER_LEN)
        goto trunc;

    tptr = pptr;

    if (!ND_TTEST2(*tptr, VTP_HEADER_LEN))
	goto trunc;

    type = *(tptr+1);
    ND_PRINT((ndo, "VTPv%u, Message %s (0x%02x), length %u",
	   *tptr,
	   tok2str(vtp_message_type_values,"Unknown message type", type),
	   *(tptr+1),
	   length));

    /* In non-verbose mode, just print version and message type */
    if (ndo->ndo_vflag < 1) {
        return;
    }

    /* verbose mode print all fields */
    ND_PRINT((ndo, "\n\tDomain name: %s, %s: %u",
	   (tptr+4),
	   tok2str(vtp_header_values,"Unknown",*(tptr+1)),
	   *(tptr+2)));

    tptr += VTP_HEADER_LEN;

    switch (type) {

    case VTP_SUMMARY_ADV:

	/*
	 *  SUMMARY ADVERTISEMENT
	 *
	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |     Version   |     Code      |    Followers  |    MmgtD Len  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Management Domain Name                     |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Configuration revision number              |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                  Updater Identity IP address                  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Update Timestamp (12 bytes)                |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                        MD5 digest (16 bytes)                  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	ND_PRINT((ndo, "\n\t  Config Rev %x, Updater %s",
	       EXTRACT_32BITS(tptr),
	       ipaddr_string(tptr+4)));
	tptr += 8;
	ND_PRINT((ndo, ", Timestamp 0x%08x 0x%08x 0x%08x",
	       EXTRACT_32BITS(tptr),
	       EXTRACT_32BITS(tptr + 4),
	       EXTRACT_32BITS(tptr + 8)));
	tptr += VTP_UPDATE_TIMESTAMP_LEN;
	ND_PRINT((ndo, ", MD5 digest: %08x%08x%08x%08x",
	       EXTRACT_32BITS(tptr),
	       EXTRACT_32BITS(tptr + 4),
	       EXTRACT_32BITS(tptr + 8),
	       EXTRACT_32BITS(tptr + 12)));
	tptr += VTP_MD5_DIGEST_LEN;
	break;

    case VTP_SUBSET_ADV:

	/*
	 *  SUBSET ADVERTISEMENT
	 *
	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |     Version   |     Code      |   Seq number  |    MmgtD Len  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Management Domain Name                     |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Configuration revision number              |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         VLAN info field 1                     |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         ................                      |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         VLAN info field N                     |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	ND_PRINT((ndo, ", Config Rev %x", EXTRACT_32BITS(tptr)));

	/*
	 *  VLAN INFORMATION
	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  | V info len    |    Status     |  VLAN type    | VLAN name len |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |       ISL vlan id             |            MTU size           |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                     802.10 index (SAID)                       |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         VLAN name                             |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	tptr += 4;
	while (tptr < (pptr+length)) {

	    len = *tptr;
	    if (len == 0)
		break;

	    if (!ND_TTEST2(*tptr, len))
		goto trunc;

	    vtp_vlan = (struct vtp_vlan_*)tptr;
	    ND_PRINT((ndo, "\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name %s",
		   tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status),
		   tok2str(vtp_vlan_type_values,"Unknown",vtp_vlan->type),
		   EXTRACT_16BITS(&vtp_vlan->vlanid),
		   EXTRACT_16BITS(&vtp_vlan->mtu),
		   EXTRACT_32BITS(&vtp_vlan->index),
		   (tptr + VTP_VLAN_INFO_OFFSET)));

            /*
             * Vlan names are aligned to 32-bit boundaries.
             */
            len  -= VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);
            tptr += VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);

            /* TLV information follows */

            while (len > 0) {

                /*
                 * Cisco specs says 2 bytes for type + 2 bytes for length, take only 1
                 * See: http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
                 */
                type = *tptr;
                tlv_len = *(tptr+1);

                ND_PRINT((ndo, "\n\t\t%s (0x%04x) TLV",
                       tok2str(vtp_vlan_tlv_values, "Unknown", type),
                       type));

                /*
                 * infinite loop check
                 */
                if (type == 0 || tlv_len == 0) {
                    return;
                }

                if (!ND_TTEST2(*tptr, tlv_len*2 +2))
                    goto trunc;

                tlv_value = EXTRACT_16BITS(tptr+2);

                switch (type) {
                case VTP_VLAN_STE_HOP_COUNT:
                    ND_PRINT((ndo, ", %u", tlv_value));
                    break;

                case VTP_VLAN_PRUNING:
                    ND_PRINT((ndo, ", %s (%u)",
                           tlv_value == 1 ? "Enabled" : "Disabled",
                           tlv_value));
                    break;

                case VTP_VLAN_STP_TYPE:
                    ND_PRINT((ndo, ", %s (%u)",
                           tok2str(vtp_stp_type_values, "Unknown", tlv_value),
                           tlv_value));
                    break;

                case VTP_VLAN_BRIDGE_TYPE:
                    ND_PRINT((ndo, ", %s (%u)",
                           tlv_value == 1 ? "SRB" : "SRT",
                           tlv_value));
                    break;

                case VTP_VLAN_BACKUP_CRF_MODE:
                    ND_PRINT((ndo, ", %s (%u)",
                           tlv_value == 1 ? "Backup" : "Not backup",
                           tlv_value));
                    break;

                    /*
                     * FIXME those are the defined TLVs that lack a decoder
                     * you are welcome to contribute code ;-)
                     */

                case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
                case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
                case VTP_VLAN_PARENT_VLAN:
                case VTP_VLAN_TRANS_BRIDGED_VLAN:
                case VTP_VLAN_ARP_HOP_COUNT:
                default:
		    print_unknown_data(ndo, tptr, "\n\t\t  ", 2 + tlv_len*2);
                    break;
                }
                len -= 2 + tlv_len*2;
                tptr += 2 + tlv_len*2;
            }
	}
	break;

    case VTP_ADV_REQUEST:

	/*
	 *  ADVERTISEMENT REQUEST
	 *
	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |     Version   |     Code      |   Reserved    |    MmgtD Len  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Management Domain Name                     |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                          Start value                          |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	ND_PRINT((ndo, "\n\tStart value: %u", EXTRACT_32BITS(tptr)));
	break;

    case VTP_JOIN_MESSAGE:

	/* FIXME - Could not find message format */
	break;

    default:
	break;
    }

    return;

 trunc:
    ND_PRINT((ndo, "[|vtp]"));
}
Exemplo n.º 4
0
void
dtp_print (netdissect_options *ndo, const u_char *pptr, u_int length)
{
    int type, len;
    const u_char *tptr;

    if (length < DTP_HEADER_LEN)
        goto trunc;

    tptr = pptr;

    ND_TCHECK2(*tptr, DTP_HEADER_LEN);

    ND_PRINT((ndo, "DTPv%u, length %u",
           (*tptr),
           length));

    /*
     * In non-verbose mode, just print version.
     */
    if (ndo->ndo_vflag < 1) {
	return;
    }

    tptr += DTP_HEADER_LEN;

    while (tptr < (pptr+length)) {

        ND_TCHECK2(*tptr, 4);

	type = EXTRACT_16BITS(tptr);
        len  = EXTRACT_16BITS(tptr+2);

        /* infinite loop check */
        if (type == 0 || len == 0) {
            return;
        }

        ND_PRINT((ndo, "\n\t%s (0x%04x) TLV, length %u",
               tok2str(dtp_tlv_values, "Unknown", type),
               type, len));

        switch (type) {
	case DTP_DOMAIN_TLV:
		ND_PRINT((ndo, ", %s", tptr+4));
		break;

	case DTP_STATUS_TLV:
	case DTP_DTP_TYPE_TLV:
                ND_PRINT((ndo, ", 0x%x", *(tptr+4)));
                break;

	case DTP_NEIGHBOR_TLV:
                ND_PRINT((ndo, ", %s", etheraddr_string(ndo, tptr+4)));
                break;

        default:
            break;
        }
        tptr += len;
    }

    return;

 trunc:
    ND_PRINT((ndo, "[|dtp]"));
}
Exemplo n.º 5
0
static void
print_attr_string(netdissect_options *ndo,
                  register u_char *data, u_int length, u_short attr_code)
{
   register u_int i;

   ND_TCHECK2(data[0],length);

   switch(attr_code)
   {
      case TUNNEL_PASS:
           if (length < 3)
           {
              ND_PRINT((ndo, "%s", tstr));
              return;
           }
           if (*data && (*data <=0x1F) )
              ND_PRINT((ndo, "Tag[%u] ", *data));
           else
              ND_PRINT((ndo, "Tag[Unused] "));
           data++;
           length--;
           ND_PRINT((ndo, "Salt %u ", EXTRACT_16BITS(data)));
           data+=2;
           length-=2;
        break;
      case TUNNEL_CLIENT_END:
      case TUNNEL_SERVER_END:
      case TUNNEL_PRIV_GROUP:
      case TUNNEL_ASSIGN_ID:
      case TUNNEL_CLIENT_AUTH:
      case TUNNEL_SERVER_AUTH:
           if (*data <= 0x1F)
           {
              if (length < 1)
              {
                 ND_PRINT((ndo, "%s", tstr));
                 return;
              }
              if (*data)
                ND_PRINT((ndo, "Tag[%u] ", *data));
              else
                ND_PRINT((ndo, "Tag[Unused] "));
              data++;
              length--;
           }
        break;
      case EGRESS_VLAN_NAME:
           ND_PRINT((ndo, "%s (0x%02x) ",
                  tok2str(rfc4675_tagged,"Unknown tag",*data),
                  *data));
           data++;
           length--;
        break;
   }

   for (i=0; *data && i < length ; i++, data++)
       ND_PRINT((ndo, "%c", (*data < 32 || *data > 128) ? '.' : *data));

   return;

   trunc:
      ND_PRINT((ndo, "%s", tstr));
}
Exemplo n.º 6
0
u_int
juniper_es_print(const struct pcap_pkthdr *h, register const u_char *p)
{
        struct juniper_l2info_t l2info;
        struct juniper_ipsec_header {
            u_int8_t sa_index[2];
            u_int8_t ttl;
            u_int8_t type;
            u_int8_t spi[4];
            u_int8_t src_ip[4];
            u_int8_t dst_ip[4];
        };
        u_int rewrite_len,es_type_bundle;
        const struct juniper_ipsec_header *ih;

        l2info.pictype = DLT_JUNIPER_ES;
        if(juniper_parse_header(p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;
        ih = (struct juniper_ipsec_header *)p;

        switch (ih->type) {
        case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
        case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
            rewrite_len = 0;
            es_type_bundle = 1;
            break;
        case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE:
        case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE:
        case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE:
            rewrite_len = 16;
            es_type_bundle = 0;
        default:
            printf("ES Invalid type %u, length %u",
                   ih->type,
                   l2info.length);
            return l2info.header_len;
        }

        l2info.length-=rewrite_len;
        p+=rewrite_len;

        if (eflag) {
            if (!es_type_bundle) {
                printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n", 
                       EXTRACT_16BITS(&ih->sa_index),
                       ih->ttl, 
                       tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
                       ih->type,
                       EXTRACT_32BITS(&ih->spi),
                       ipaddr_string(EXTRACT_32BITS(&ih->src_ip)),
                       ipaddr_string(EXTRACT_32BITS(&ih->dst_ip)),
                       l2info.length);
            } else {
                printf("ES SA, index %u, ttl %u type %s (%u), length %u\n", 
                       EXTRACT_16BITS(&ih->sa_index),
                       ih->ttl, 
                       tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
                       ih->type,
                       l2info.length);
            }
        }

        ip_print(gndo, p, l2info.length);
        return l2info.header_len;
}
Exemplo n.º 7
0
static void
krb4_print(const u_char *cp)
{
	register const struct krb *kp;
	u_char type;
	u_short len;

#define PRINT		if ((cp = c_print(cp, snapend)) == NULL) goto trunc
/*  True if struct krb is little endian */
#define IS_LENDIAN(kp)	(((kp)->type & 0x01) != 0)
#define KTOHSP(kp, cp)	(IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp))

	kp = (struct krb *)cp;

	if ((&kp->type) >= snapend) {
		fputs(tstr, stdout);
		return;
	}

	type = kp->type & (0xFF << 1);

	printf(" %s %s: ",
	    IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type));

	switch (type) {

	case AUTH_MSG_KDC_REQUEST:
		if ((cp = krb4_print_hdr(cp)) == NULL)
			return;
		cp += 4;	/* ctime */
		TCHECK(*cp);
		printf(" %dmin ", *cp++ * 5);
		PRINT;
		putchar('.');
		PRINT;
		break;

	case AUTH_MSG_APPL_REQUEST:
		cp += 2;
		TCHECK(*cp);
		printf("v%d ", *cp++);
		PRINT;
		TCHECK(*cp);
		printf(" (%d)", *cp++);
		TCHECK(*cp);
		printf(" (%d)", *cp);
		break;

	case AUTH_MSG_KDC_REPLY:
		if ((cp = krb4_print_hdr(cp)) == NULL)
			return;
		cp += 10;	/* timestamp + n + exp + kvno */
		TCHECK2(*cp, sizeof(short));
		len = KTOHSP(kp, cp);
		printf(" (%d)", len);
		break;

	case AUTH_MSG_ERR_REPLY:
		if ((cp = krb4_print_hdr(cp)) == NULL)
			return;
		cp += 4; 	  /* timestamp */
		TCHECK2(*cp, sizeof(short));
		printf(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp)));
		cp += 4;
		PRINT;
		break;

	default:
		fputs("(unknown)", stdout);
		break;
	}

	return;
trunc:
	fputs(tstr, stdout);
}
Exemplo n.º 8
0
/*
 * Sub-TLVs consume the "extra data" of Babel TLVs (see Section 4.3 of RFC6126),
 * their encoding is similar to the encoding of TLVs, but the type namespace is
 * different:
 *
 * o Type 0 stands for Pad1 sub-TLV with the same encoding as the Pad1 TLV.
 * o Type 1 stands for PadN sub-TLV with the same encoding as the PadN TLV.
 * o Type 2 stands for Diversity sub-TLV, which propagates diversity routing
 *   data. Its body is a variable-length sequence of 8-bit unsigned integers,
 *   each representing per-hop number of interferring radio channel for the
 *   prefix. Channel 0 is invalid and must not be used in the sub-TLV, channel
 *   255 interferes with any other channel.
 * o Type 3 stands for Timestamp sub-TLV, used to compute RTT between
 *   neighbours. In the case of a Hello TLV, the body stores a 32-bits
 *   timestamp, while in the case of a IHU TLV, two 32-bits timestamps are
 *   stored.
 *
 * Sub-TLV types 0 and 1 are valid for any TLV type, whether sub-TLV type 2 is
 * only valid for TLV type 8 (Update). Note that within an Update TLV a missing
 * Diversity sub-TLV is not the same as a Diversity sub-TLV with an empty body.
 * The former would mean a lack of any claims about the interference, and the
 * latter would state that interference is definitely absent.
 * A type 3 sub-TLV is valid both for Hello and IHU TLVs, though the exact
 * semantic of the sub-TLV is different in each case.
 */
static void
subtlvs_print(netdissect_options *ndo,
              const u_char *cp, const u_char *ep, const uint8_t tlv_type)
{
    uint8_t subtype, sublen;
    const char *sep;
    uint32_t t1, t2;

    while (cp < ep) {
        subtype = *cp++;
        if(subtype == MESSAGE_SUB_PAD1) {
            ND_PRINT((ndo, " sub-pad1"));
            continue;
        }
        if(cp == ep)
            goto corrupt;
        sublen = *cp++;
        if(cp + sublen > ep)
            goto corrupt;

        switch(subtype) {
        case MESSAGE_SUB_PADN:
            ND_PRINT((ndo, " sub-padn"));
            cp += sublen;
            break;
        case MESSAGE_SUB_DIVERSITY:
            ND_PRINT((ndo, " sub-diversity"));
            if (sublen == 0) {
                ND_PRINT((ndo, " empty"));
                break;
            }
            sep = " ";
            while(sublen--) {
                ND_PRINT((ndo, "%s%s", sep, tok2str(diversity_str, "%u", *cp++)));
                sep = "-";
            }
            if(tlv_type != MESSAGE_UPDATE &&
               tlv_type != MESSAGE_UPDATE_SRC_SPECIFIC)
                ND_PRINT((ndo, " (bogus)"));
            break;
        case MESSAGE_SUB_TIMESTAMP:
            ND_PRINT((ndo, " sub-timestamp"));
            if(tlv_type == MESSAGE_HELLO) {
                if(sublen < 4)
                    goto corrupt;
                t1 = EXTRACT_32BITS(cp);
                ND_PRINT((ndo, " %s", format_timestamp(t1)));
            } else if(tlv_type == MESSAGE_IHU) {
                if(sublen < 8)
                    goto corrupt;
                t1 = EXTRACT_32BITS(cp);
                ND_PRINT((ndo, " %s", format_timestamp(t1)));
                t2 = EXTRACT_32BITS(cp + 4);
                ND_PRINT((ndo, "|%s", format_timestamp(t2)));
            } else
                ND_PRINT((ndo, " (bogus)"));
            cp += sublen;
            break;
        default:
            ND_PRINT((ndo, " sub-unknown-0x%02x", subtype));
            cp += sublen;
        } /* switch */
    } /* while */
    return;

 corrupt:
    ND_PRINT((ndo, " (corrupt)"));
}
Exemplo n.º 9
0
/*
 * Print a single PDU.
 */
static void
rpki_rtr_pdu_print (const u_char *tptr, u_int indent)
{
    const rpki_rtr_pdu *pdu_header;
    u_int pdu_type, pdu_len, hexdump;
    const u_char *msg;

    pdu_header = (rpki_rtr_pdu *)tptr;
    pdu_type = pdu_header->pdu_type;
    pdu_len = EXTRACT_32BITS(pdu_header->length);
    hexdump = FALSE;

    printf("%sRPKI-RTRv%u, %s PDU (%u), length: %u",
	   indent_string(8),
	   pdu_header->version,
	   tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type),
	   pdu_type, pdu_len);

    switch (pdu_type) {

	/*
	 * The following PDUs share the message format.
	 */
    case RPKI_RTR_SERIAL_NOTIFY_PDU:
    case RPKI_RTR_SERIAL_QUERY_PDU:
    case RPKI_RTR_END_OF_DATA_PDU:
        msg = (const u_char *)(pdu_header + 1);
	printf("%sCache-Nonce: 0x%04x, Serial: %u",
	       indent_string(indent+2),
	       EXTRACT_16BITS(pdu_header->u.cache_nonce),
	       EXTRACT_32BITS(msg));
	break;

	/*
	 * The following PDUs share the message format.
	 */
    case RPKI_RTR_RESET_QUERY_PDU:
    case RPKI_RTR_CACHE_RESET_PDU:

	/*
	 * Zero payload PDUs.
	 */
	break;

    case RPKI_RTR_CACHE_RESPONSE_PDU:
	printf("%sCache-Nonce: 0x%04x",
	       indent_string(indent+2),
	       EXTRACT_16BITS(pdu_header->u.cache_nonce));
	break;

    case RPKI_RTR_IPV4_PREFIX_PDU:
	{
	    rpki_rtr_pdu_ipv4_prefix *pdu;

	    pdu = (rpki_rtr_pdu_ipv4_prefix *)tptr;
	    printf("%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
		   indent_string(indent+2),
		   ipaddr_string(pdu->prefix),
		   pdu->prefix_length, pdu->max_length,
		   EXTRACT_32BITS(pdu->as), pdu->flags);
	}
	break;

#ifdef INET6
    case RPKI_RTR_IPV6_PREFIX_PDU:
	{
	    rpki_rtr_pdu_ipv6_prefix *pdu;

	    pdu = (rpki_rtr_pdu_ipv6_prefix *)tptr;
	    printf("%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
		   indent_string(indent+2),
		   ip6addr_string(pdu->prefix),
		   pdu->prefix_length, pdu->max_length,
		   EXTRACT_32BITS(pdu->as), pdu->flags);
	}
	break;
#endif

    case RPKI_RTR_ERROR_REPORT_PDU:
	{
	    rpki_rtr_pdu_error_report *pdu;
	    u_int encapsulated_pdu_length, text_length, tlen, error_code;
	    u_char buf[80];

	    pdu = (rpki_rtr_pdu_error_report *)tptr;
	    encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length);
	    tlen = pdu_len;

	    error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code);
	    printf("%sError code: %s (%u), Encapsulated PDU length: %u",
		   indent_string(indent+2),
		   tok2str(rpki_rtr_error_codes, "Unknown", error_code),
		   error_code, encapsulated_pdu_length);

	    tptr += sizeof(*pdu);
	    tlen -= sizeof(*pdu);

	    /*
	     * Recurse if there is an encapsulated PDU.
	     */
	    if (encapsulated_pdu_length &&
		(encapsulated_pdu_length <= tlen)) {
		printf("%s-----encapsulated PDU-----", indent_string(indent+4));
		rpki_rtr_pdu_print(tptr, indent+2);
	    }

	    tptr += encapsulated_pdu_length;
	    tlen -= encapsulated_pdu_length;

	    /*
	     * Extract, trail-zero and print the Error message.
	     */ 
	    text_length = 0;
	    if (tlen > 4) {
		text_length = EXTRACT_32BITS(tptr);
		tptr += 4;
		tlen -= 4;
	    }
	    if (text_length && (text_length <= tlen )) {
		memcpy(buf, tptr, MIN(sizeof(buf)-1, text_length));
		buf[text_length] = '\0';
		printf("%sError text: %s", indent_string(indent+2), buf);
	    }
	}
	break;

    default:

	/*
	 * Unknown data, please hexdump.
	 */ 
	hexdump = TRUE;
    }

    /* do we also want to see a hex dump ? */
    if (vflag > 1 || (vflag && hexdump)) {
	print_unknown_data(tptr,"\n\t  ", pdu_len);
    }
}
Exemplo n.º 10
0
/*
 * Print bootp requests
 */
void
bootp_print(netdissect_options *ndo,
	    register const u_char *cp, u_int length)
{
	register const struct bootp *bp;
	static const u_char vm_cmu[4] = VM_CMU;
	static const u_char vm_rfc1048[4] = VM_RFC1048;

	bp = (const struct bootp *)cp;
	ND_TCHECK(bp->bp_op);

	ND_PRINT((ndo, "BOOTP/DHCP, %s",
		  tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op)));

	if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) {
		ND_TCHECK2(bp->bp_chaddr[0], 6);
		ND_PRINT((ndo, " from %s", etheraddr_string(ndo, bp->bp_chaddr)));
	}

	ND_PRINT((ndo, ", length %u", length));

	if (!ndo->ndo_vflag)
		return;

	ND_TCHECK(bp->bp_secs);

	/* The usual hardware address type is 1 (10Mb Ethernet) */
	if (bp->bp_htype != 1)
		ND_PRINT((ndo, ", htype %d", bp->bp_htype));

	/* The usual length for 10Mb Ethernet address is 6 bytes */
	if (bp->bp_htype != 1 || bp->bp_hlen != 6)
		ND_PRINT((ndo, ", hlen %d", bp->bp_hlen));

	/* Only print interesting fields */
	if (bp->bp_hops)
		ND_PRINT((ndo, ", hops %d", bp->bp_hops));
	if (EXTRACT_32BITS(&bp->bp_xid))
		ND_PRINT((ndo, ", xid 0x%x", EXTRACT_32BITS(&bp->bp_xid)));
	if (EXTRACT_16BITS(&bp->bp_secs))
		ND_PRINT((ndo, ", secs %d", EXTRACT_16BITS(&bp->bp_secs)));

	ND_PRINT((ndo, ", Flags [%s]",
		  bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags))));
	if (ndo->ndo_vflag > 1)
		ND_PRINT((ndo, " (0x%04x)", EXTRACT_16BITS(&bp->bp_flags)));

	/* Client's ip address */
	ND_TCHECK(bp->bp_ciaddr);
	if (EXTRACT_32BITS(&bp->bp_ciaddr.s_addr))
		ND_PRINT((ndo, "\n\t  Client-IP %s", ipaddr_string(ndo, &bp->bp_ciaddr)));

	/* 'your' ip address (bootp client) */
	ND_TCHECK(bp->bp_yiaddr);
	if (EXTRACT_32BITS(&bp->bp_yiaddr.s_addr))
		ND_PRINT((ndo, "\n\t  Your-IP %s", ipaddr_string(ndo, &bp->bp_yiaddr)));

	/* Server's ip address */
	ND_TCHECK(bp->bp_siaddr);
	if (EXTRACT_32BITS(&bp->bp_siaddr.s_addr))
		ND_PRINT((ndo, "\n\t  Server-IP %s", ipaddr_string(ndo, &bp->bp_siaddr)));

	/* Gateway's ip address */
	ND_TCHECK(bp->bp_giaddr);
	if (EXTRACT_32BITS(&bp->bp_giaddr.s_addr))
		ND_PRINT((ndo, "\n\t  Gateway-IP %s", ipaddr_string(ndo, &bp->bp_giaddr)));

	/* Client's Ethernet address */
	if (bp->bp_htype == 1 && bp->bp_hlen == 6) {
		ND_TCHECK2(bp->bp_chaddr[0], 6);
		ND_PRINT((ndo, "\n\t  Client-Ethernet-Address %s", etheraddr_string(ndo, bp->bp_chaddr)));
	}

	ND_TCHECK2(bp->bp_sname[0], 1);		/* check first char only */
	if (*bp->bp_sname) {
		ND_PRINT((ndo, "\n\t  sname \""));
		if (fn_print(ndo, bp->bp_sname, ndo->ndo_snapend)) {
			ND_PRINT((ndo, "\""));
			ND_PRINT((ndo, "%s", tstr + 1));
			return;
		}
		ND_PRINT((ndo, "\""));
	}
	ND_TCHECK2(bp->bp_file[0], 1);		/* check first char only */
	if (*bp->bp_file) {
		ND_PRINT((ndo, "\n\t  file \""));
		if (fn_print(ndo, bp->bp_file, ndo->ndo_snapend)) {
			ND_PRINT((ndo, "\""));
			ND_PRINT((ndo, "%s", tstr + 1));
			return;
		}
		ND_PRINT((ndo, "\""));
	}

	/* Decode the vendor buffer */
	ND_TCHECK(bp->bp_vend[0]);
	if (memcmp((const char *)bp->bp_vend, vm_rfc1048,
		    sizeof(uint32_t)) == 0)
		rfc1048_print(ndo, bp->bp_vend);
	else if (memcmp((const char *)bp->bp_vend, vm_cmu,
			sizeof(uint32_t)) == 0)
		cmu_print(ndo, bp->bp_vend);
	else {
		uint32_t ul;

		ul = EXTRACT_32BITS(&bp->bp_vend);
		if (ul != 0)
			ND_PRINT((ndo, "\n\t  Vendor-#0x%x", ul));
	}

	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
}
Exemplo n.º 11
0
static void
rfc1048_print(netdissect_options *ndo,
	      register const u_char *bp)
{
	register uint16_t tag;
	register u_int len;
	register const char *cp;
	register char c;
	int first, idx;
	uint32_t ul;
	uint16_t us;
	uint8_t uc, subopt, suboptlen;

	ND_PRINT((ndo, "\n\t  Vendor-rfc1048 Extensions"));

	/* Step over magic cookie */
	ND_PRINT((ndo, "\n\t    Magic Cookie 0x%08x", EXTRACT_32BITS(bp)));
	bp += sizeof(int32_t);

	/* Loop while we there is a tag left in the buffer */
	while (ND_TTEST2(*bp, 1)) {
		tag = *bp++;
		if (tag == TAG_PAD && ndo->ndo_vflag < 3)
			continue;
		if (tag == TAG_END && ndo->ndo_vflag < 3)
			return;
		if (tag == TAG_EXTENDED_OPTION) {
			ND_TCHECK2(*(bp + 1), 2);
			tag = EXTRACT_16BITS(bp + 1);
			/* XXX we don't know yet if the IANA will
			 * preclude overlap of 1-byte and 2-byte spaces.
			 * If not, we need to offset tag after this step.
			 */
			cp = tok2str(xtag2str, "?xT%u", tag);
		} else
			cp = tok2str(tag2str, "?T%u", tag);
		c = *cp++;

		if (tag == TAG_PAD || tag == TAG_END)
			len = 0;
		else {
			/* Get the length; check for truncation */
			ND_TCHECK2(*bp, 1);
			len = *bp++;
		}

		ND_PRINT((ndo, "\n\t    %s Option %u, length %u%s", cp, tag, len,
			  len > 0 ? ": " : ""));

		if (tag == TAG_PAD && ndo->ndo_vflag > 2) {
			u_int ntag = 1;
			while (ND_TTEST2(*bp, 1) && *bp == TAG_PAD) {
				bp++;
				ntag++;
			}
			if (ntag > 1)
				ND_PRINT((ndo, ", occurs %u", ntag));
		}

		if (!ND_TTEST2(*bp, len)) {
			ND_PRINT((ndo, "[|rfc1048 %u]", len));
			return;
		}

		if (tag == TAG_DHCP_MESSAGE && len == 1) {
			uc = *bp++;
			ND_PRINT((ndo, "%s", tok2str(dhcp_msg_values, "Unknown (%u)", uc)));
			continue;
		}

		if (tag == TAG_PARM_REQUEST) {
			idx = 0;
			while (len-- > 0) {
				uc = *bp++;
				cp = tok2str(tag2str, "?Option %u", uc);
				if (idx % 4 == 0)
					ND_PRINT((ndo, "\n\t      "));
				else
					ND_PRINT((ndo, ", "));
				ND_PRINT((ndo, "%s", cp + 1));
				idx++;
			}
			continue;
		}

		if (tag == TAG_EXTENDED_REQUEST) {
			first = 1;
			while (len > 1) {
				len -= 2;
				us = EXTRACT_16BITS(bp);
				bp += 2;
				cp = tok2str(xtag2str, "?xT%u", us);
				if (!first)
					ND_PRINT((ndo, "+"));
				ND_PRINT((ndo, "%s", cp + 1));
				first = 0;
			}
			continue;
		}

		/* Print data */
		if (c == '?') {
			/* Base default formats for unknown tags on data size */
			if (len & 1)
				c = 'b';
			else if (len & 2)
				c = 's';
			else
				c = 'l';
		}
		first = 1;
		switch (c) {

		case 'a':
			/* ascii strings */
			ND_PRINT((ndo, "\""));
			if (fn_printn(ndo, bp, len, ndo->ndo_snapend)) {
				ND_PRINT((ndo, "\""));
				goto trunc;
			}
			ND_PRINT((ndo, "\""));
			bp += len;
			len = 0;
			break;

		case 'i':
		case 'l':
		case 'L':
			/* ip addresses/32-bit words */
			while (len >= sizeof(ul)) {
				if (!first)
					ND_PRINT((ndo, ","));
				ul = EXTRACT_32BITS(bp);
				if (c == 'i') {
					ul = htonl(ul);
					ND_PRINT((ndo, "%s", ipaddr_string(ndo, &ul)));
				} else if (c == 'L')
					ND_PRINT((ndo, "%d", ul));
				else
					ND_PRINT((ndo, "%u", ul));
				bp += sizeof(ul);
				len -= sizeof(ul);
				first = 0;
			}
			break;

		case 'p':
			/* IP address pairs */
			while (len >= 2*sizeof(ul)) {
				if (!first)
					ND_PRINT((ndo, ","));
				memcpy((char *)&ul, (const char *)bp, sizeof(ul));
				ND_PRINT((ndo, "(%s:", ipaddr_string(ndo, &ul)));
				bp += sizeof(ul);
				memcpy((char *)&ul, (const char *)bp, sizeof(ul));
				ND_PRINT((ndo, "%s)", ipaddr_string(ndo, &ul)));
				bp += sizeof(ul);
				len -= 2*sizeof(ul);
				first = 0;
			}
			break;

		case 's':
			/* shorts */
			while (len >= sizeof(us)) {
				if (!first)
					ND_PRINT((ndo, ","));
				us = EXTRACT_16BITS(bp);
				ND_PRINT((ndo, "%u", us));
				bp += sizeof(us);
				len -= sizeof(us);
				first = 0;
			}
			break;

		case 'B':
			/* boolean */
			while (len > 0) {
				if (!first)
					ND_PRINT((ndo, ","));
				switch (*bp) {
				case 0:
					ND_PRINT((ndo, "N"));
					break;
				case 1:
					ND_PRINT((ndo, "Y"));
					break;
				default:
					ND_PRINT((ndo, "%u?", *bp));
					break;
				}
				++bp;
				--len;
				first = 0;
			}
			break;

		case 'b':
		case 'x':
		default:
			/* Bytes */
			while (len > 0) {
				if (!first)
					ND_PRINT((ndo, c == 'x' ? ":" : "."));
				if (c == 'x')
					ND_PRINT((ndo, "%02x", *bp));
				else
					ND_PRINT((ndo, "%u", *bp));
				++bp;
				--len;
				first = 0;
			}
			break;

		case '$':
			/* Guys we can't handle with one of the usual cases */
			switch (tag) {

			case TAG_NETBIOS_NODE:
				/* this option should be at least 1 byte long */
				if (len < 1) {
					ND_PRINT((ndo, "ERROR: length < 1 bytes"));
					break;
				}
				tag = *bp++;
				--len;
				ND_PRINT((ndo, "%s", tok2str(nbo2str, NULL, tag)));
				break;

			case TAG_OPT_OVERLOAD:
				/* this option should be at least 1 byte long */
				if (len < 1) {
					ND_PRINT((ndo, "ERROR: length < 1 bytes"));
					break;
				}
				tag = *bp++;
				--len;
				ND_PRINT((ndo, "%s", tok2str(oo2str, NULL, tag)));
				break;

			case TAG_CLIENT_FQDN:
				/* this option should be at least 3 bytes long */
				if (len < 3) {
					ND_PRINT((ndo, "ERROR: length < 3 bytes"));
					bp += len;
					len = 0;
					break;
				}
				if (*bp)
					ND_PRINT((ndo, "[%s] ", client_fqdn_flags(*bp)));
				bp++;
				if (*bp || *(bp+1))
					ND_PRINT((ndo, "%u/%u ", *bp, *(bp+1)));
				bp += 2;
				ND_PRINT((ndo, "\""));
				if (fn_printn(ndo, bp, len - 3, ndo->ndo_snapend)) {
					ND_PRINT((ndo, "\""));
					goto trunc;
				}
				ND_PRINT((ndo, "\""));
				bp += len - 3;
				len = 0;
				break;

			case TAG_CLIENT_ID:
			    {
				int type;

				/* this option should be at least 1 byte long */
				if (len < 1) {
					ND_PRINT((ndo, "ERROR: length < 1 bytes"));
					break;
				}
				type = *bp++;
				len--;
				if (type == 0) {
					ND_PRINT((ndo, "\""));
					if (fn_printn(ndo, bp, len, ndo->ndo_snapend)) {
						ND_PRINT((ndo, "\""));
						goto trunc;
					}
					ND_PRINT((ndo, "\""));
					bp += len;
					len = 0;
					break;
				} else {
					ND_PRINT((ndo, "%s ", tok2str(arp2str, "hardware-type %u,", type)));
					while (len > 0) {
						if (!first)
							ND_PRINT((ndo, ":"));
						ND_PRINT((ndo, "%02x", *bp));
						++bp;
						--len;
						first = 0;
					}
				}
				break;
			    }

			case TAG_AGENT_CIRCUIT:
				while (len >= 2) {
					subopt = *bp++;
					suboptlen = *bp++;
					len -= 2;
					if (suboptlen > len) {
						ND_PRINT((ndo, "\n\t      %s SubOption %u, length %u: length goes past end of option",
							  tok2str(agent_suboption_values, "Unknown", subopt),
							  subopt,
							  suboptlen));
						bp += len;
						len = 0;
						break;
					}
					ND_PRINT((ndo, "\n\t      %s SubOption %u, length %u: ",
						  tok2str(agent_suboption_values, "Unknown", subopt),
						  subopt,
						  suboptlen));
					switch (subopt) {

					case AGENT_SUBOPTION_CIRCUIT_ID: /* fall through */
					case AGENT_SUBOPTION_REMOTE_ID:
					case AGENT_SUBOPTION_SUBSCRIBER_ID:
						if (fn_printn(ndo, bp, suboptlen, ndo->ndo_snapend))
							goto trunc;
						break;

					default:
						print_unknown_data(ndo, bp, "\n\t\t", suboptlen);
					}

					len -= suboptlen;
					bp += suboptlen;
				}
				break;

			case TAG_CLASSLESS_STATIC_RT:
			case TAG_CLASSLESS_STA_RT_MS:
			    {
				u_int mask_width, significant_octets, i;

				/* this option should be at least 5 bytes long */
				if (len < 5) {
					ND_PRINT((ndo, "ERROR: length < 5 bytes"));
					bp += len;
					len = 0;
					break;
				}
				while (len > 0) {
					if (!first)
						ND_PRINT((ndo, ","));
					mask_width = *bp++;
					len--;
					/* mask_width <= 32 */
					if (mask_width > 32) {
						ND_PRINT((ndo, "[ERROR: Mask width (%d) > 32]", mask_width));
						bp += len;
						len = 0;
						break;
					}
					significant_octets = (mask_width + 7) / 8;
					/* significant octets + router(4) */
					if (len < significant_octets + 4) {
						ND_PRINT((ndo, "[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4));
						bp += len;
						len = 0;
						break;
					}
					ND_PRINT((ndo, "("));
					if (mask_width == 0)
						ND_PRINT((ndo, "default"));
					else {
						for (i = 0; i < significant_octets ; i++) {
							if (i > 0)
								ND_PRINT((ndo, "."));
							ND_PRINT((ndo, "%d", *bp++));
						}
						for (i = significant_octets ; i < 4 ; i++)
							ND_PRINT((ndo, ".0"));
						ND_PRINT((ndo, "/%d", mask_width));
					}
					memcpy((char *)&ul, (const char *)bp, sizeof(ul));
					ND_PRINT((ndo, ":%s)", ipaddr_string(ndo, &ul)));
					bp += sizeof(ul);
					len -= (significant_octets + 4);
					first = 0;
				}
				break;
			    }

			case TAG_USER_CLASS:
			    {
				u_int suboptnumber = 1;

				first = 1;
				if (len < 2) {
					ND_PRINT((ndo, "ERROR: length < 2 bytes"));
					bp += len;
					len = 0;
					break;
				}
				while (len > 0) {
					suboptlen = *bp++;
					len--;
					ND_PRINT((ndo, "\n\t      "));
					ND_PRINT((ndo, "instance#%u: ", suboptnumber));
					if (suboptlen == 0) {
						ND_PRINT((ndo, "ERROR: suboption length must be non-zero"));
						bp += len;
						len = 0;
						break;
					}
					if (len < suboptlen) {
						ND_PRINT((ndo, "ERROR: invalid option"));
						bp += len;
						len = 0;
						break;
					}
					ND_PRINT((ndo, "\""));
					if (fn_printn(ndo, bp, suboptlen, ndo->ndo_snapend)) {
						ND_PRINT((ndo, "\""));
						goto trunc;
					}
					ND_PRINT((ndo, "\""));
					ND_PRINT((ndo, ", length %d", suboptlen));
					suboptnumber++;
					len -= suboptlen;
					bp += suboptlen;
				}
				break;
			    }

			default:
				ND_PRINT((ndo, "[unknown special tag %u, size %u]",
					  tag, len));
				bp += len;
				len = 0;
				break;
			}
			break;
		}
		/* Data left over? */
		if (len) {
			ND_PRINT((ndo, "\n\t  trailing data length %u", len));
			bp += len;
		}
	}
	return;
trunc:
	ND_PRINT((ndo, "|[rfc1048]"));
}
Exemplo n.º 12
0
static int
pdatacnt_print(netdissect_options *ndo,
               register const u_char * pptr, register u_int len,
               u_int16_t IDcnt, u_int16_t op_msk, int indent)
{
	u_int i;
	u_int32_t id;
	char *ib = indent_pr(indent, 0);

	if ((op_msk & B_APPND) && ndo->ndo_vflag >= 3) {
		ND_PRINT((ndo, "%sTABLE APPEND\n", ib));
	}
	for (i = 0; i < IDcnt; i++) {
		ND_TCHECK2(*pptr, 4);
		if (len < 4)
			goto trunc;
		id = EXTRACT_32BITS(pptr);
		if (ndo->ndo_vflag >= 3)
			ND_PRINT((ndo, "%sID#%02u: %d\n", ib, i + 1, id));
		len -= 4;
		pptr += 4;
	}

	if ((op_msk & B_TRNG) || (op_msk & B_KEYIN)) {
		if (op_msk & B_TRNG) {
			u_int32_t starti, endi;

			if (len < PTH_DESC_SIZE) {
				ND_PRINT((ndo, "pathlength %d with key/range too short %d\n",
				       len, PTH_DESC_SIZE));
				return -1;
			}

			pptr += sizeof(struct forces_tlv);
			len -= sizeof(struct forces_tlv);

			starti = EXTRACT_32BITS(pptr);
			pptr += 4;
			len -= 4;

			endi = EXTRACT_32BITS(pptr);
			pptr += 4;
			len -= 4;

			if (ndo->ndo_vflag >= 3)
				ND_PRINT((ndo, "%sTable range: [%d,%d]\n", ib, starti, endi));
		}

		if (op_msk & B_KEYIN) {
			struct forces_tlv *keytlv;
			u_int16_t tll;

			if (len < PTH_DESC_SIZE) {
				ND_PRINT((ndo, "pathlength %d with key/range too short %d\n",
				       len, PTH_DESC_SIZE));
				return -1;
			}

			/* skip keyid */
			pptr += 4;
			len -= 4;
			keytlv = (struct forces_tlv *)pptr;
			/* skip header */
			pptr += sizeof(struct forces_tlv);
			len -= sizeof(struct forces_tlv);
			/* skip key content */
			tll = EXTRACT_16BITS(&keytlv->length);
			if (tll < TLV_HDRL) {
				ND_PRINT((ndo, "key content length %u < %u\n",
					tll, TLV_HDRL));
				return -1;
			}
			tll -= TLV_HDRL;
			if (len < tll) {
				ND_PRINT((ndo, "key content too short\n"));
				return -1;
			}
			pptr += tll;
			len -= tll;
		}

	}

	if (len) {
		const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr;
		u_int16_t type;
		u_int16_t tll;
		int pad = 0;
		u_int aln;
		u_int invtlv;

		ND_TCHECK(*pdtlv);
		type = EXTRACT_16BITS(&pdtlv->type);
		invtlv = tlv_valid(pdtlv, len);
		if (invtlv) {
			ND_PRINT((ndo, "%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n",
			          tok2str(ForCES_TLV_err, NULL, invtlv), len, type,
			          EXTRACT_16BITS(&pdtlv->length)));
			goto pd_err;
		}
		/*
		 * At this point, tlv_valid() has ensured that the TLV
		 * length is large enough but not too large (it doesn't
		 * go past the end of the containing TLV).
		 */
		tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
		aln = F_ALN_LEN(EXTRACT_16BITS(&pdtlv->length));
		if (aln > EXTRACT_16BITS(&pdtlv->length)) {
			if (aln > len) {
				ND_PRINT((ndo,
				          "Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n",
				          type, EXTRACT_16BITS(&pdtlv->length), aln - len));
			} else {
				pad = aln - EXTRACT_16BITS(&pdtlv->length);
			}
		}
		if (pd_valid(type)) {
			const struct pdata_ops *ops = get_forces_pd(type);

			if (ndo->ndo_vflag >= 3 && ops->v != F_TLV_PDAT) {
				if (pad)
					ND_PRINT((ndo, "%s  %s (Length %d DataLen %d pad %d Bytes)\n",
					          ib, ops->s, EXTRACT_16BITS(&pdtlv->length), tll, pad));
				else
					ND_PRINT((ndo, "%s  %s (Length %d DataLen %d Bytes)\n",
					          ib, ops->s, EXTRACT_16BITS(&pdtlv->length), tll));
			}

			chk_op_type(ndo, type, op_msk, ops->op_msk);

			if (ops->print(ndo, (const u_char *)pdtlv,
					tll + pad + TLV_HDRL, op_msk,
					indent + 2) == -1)
				return -1;
			len -= (TLV_HDRL + pad + tll);
		} else {
			ND_PRINT((ndo, "Invalid path data content type 0x%x len %d\n",
			       type, EXTRACT_16BITS(&pdtlv->length)));
pd_err:
			if (EXTRACT_16BITS(&pdtlv->length)) {
                                hex_print_with_offset(ndo, "Bad Data val\n\t  [",
						      pptr, len, 0);
				ND_PRINT((ndo, "]\n"));

				return -1;
			}
		}
	}
	return len;

trunc:
	ND_PRINT((ndo, "%s", tstr));
	return -1;
}
Exemplo n.º 13
0
int
ether_encap_print(u_short ether_type, const u_char *p,
    u_int length, u_int caplen, u_short *extracted_ether_type)
{
 recurse:
   *extracted_ether_type = ether_type;

   switch (ether_type) {
/*
   case ETHERTYPE_DN:
      decnet_print(p, length, caplen);
      return (1);

   case ETHERTYPE_ATALK:
      if (ArgusParser->vflag)
         sprintf(&ArgusBuf[strlen(ArgusBuf)],"et1 ");
      atalk_print(p, length);
      return (1);

   case ETHERTYPE_AARP:
      aarp_print(p, length);
      return (1);

   case ETHERTYPE_IPX:
      sprintf(&ArgusBuf[strlen(ArgusBuf)],"(NOV-ETHII) ");
      ipx_print(p, length);
      return (1);

   case ETHERTYPE_8021Q:
           if (ArgusParser->eflag)
          sprintf(&ArgusBuf[strlen(ArgusBuf)],"vlan %u, p %u%s, ",
            ntohs(*(u_int16_t *)p) & 0xfff,
            ntohs(*(u_int16_t *)p) >> 13,
            (ntohs(*(u_int16_t *)p) & 0x1000) ? ", CFI" : "");

      ether_type = ntohs(*(u_int16_t *)(p + 2));
      p += 4;
      length -= 4;
      caplen -= 4;

      if (ether_type > ETHERMTU) {
              if (ArgusParser->eflag)
                 sprintf(&ArgusBuf[strlen(ArgusBuf)],"ethertype %s, ",
                   tok2str(ethertype_values,"0x%04x", ether_type));
         goto recurse;
      }

      *extracted_ether_type = 0;

      if (llc_print(p, length, caplen, p - 18, p - 12,
          extracted_ether_type) == 0) {
            ether_hdr_print(p - 18, length + 4);
      }

      if (!suppress_default_print)
              default_print(p - 18, caplen + 4);
      return (1);
*/
        case ETHERTYPE_JUMBO:
                ether_type = ntohs(*(u_int16_t *)(p));
                p += 2;
                length -= 2;      
                caplen -= 2;

                if (ether_type > ETHERMTU) {
                    if (ArgusParser->eflag)
                        sprintf(&ArgusBuf[strlen(ArgusBuf)],"ethertype %s, ",
                               tok2str(ethertype_values,"0x%04x", ether_type));
                    goto recurse;
                }

                *extracted_ether_type = 0;

/*
                if (llc_print(p, length, caplen, p - 16, p - 10,
                              extracted_ether_type) == 0) {
                    ether_hdr_print(p - 16, length + 2);
                }
                if (!suppress_default_print)
                    default_print(p - 16, caplen + 2);
*/
                return (1);

        case ETHERTYPE_ISO:
                isoclns_print(p+1, length-1, length-1);
                return(1);
/*
   case ETHERTYPE_PPPOED:
   case ETHERTYPE_PPPOES:
      pppoe_print(p, length);
      return (1);

   case ETHERTYPE_EAPOL:
           eap_print(gndo, p, length);
      return (1);

   case ETHERTYPE_PPP:
      if (length) {
         sprintf(&ArgusBuf[strlen(ArgusBuf)],": ");
         ppp_print(p, length);
      }
      return (1);

   case ETHERTYPE_SLOW:
           slow_print(p, length);
      return (1);

        case ETHERTYPE_LOOPBACK:
                return (1);

   case ETHERTYPE_MPLS:
   case ETHERTYPE_MPLS_MULTI:
      mpls_print(p, length);
      return (1);

   case ETHERTYPE_LAT:
   case ETHERTYPE_SCA:
   case ETHERTYPE_MOPRC:
   case ETHERTYPE_MOPDL:
*/
      /* default_print for now */
   default:
      return (0);
   }
}
Exemplo n.º 14
0
void
tcp_print(netdissect_options *ndo,
          const u_char *bp, u_int length,
          const u_char *bp2, int fragmented)
{
        const struct tcphdr *tp;
        const struct ip *ip;
        u_char flags;
        u_int hlen;
        char ch;
        uint16_t sport, dport, win, urp;
        uint32_t seq, ack, thseq, thack;
        u_int utoval;
        uint16_t magic;
        int rev;
        const struct ip6_hdr *ip6;

        ndo->ndo_protocol = "tcp";
        tp = (const struct tcphdr *)bp;
        ip = (const struct ip *)bp2;
        if (IP_V(ip) == 6)
                ip6 = (const struct ip6_hdr *)bp2;
        else
                ip6 = NULL;
        ch = '\0';
        if (!ND_TTEST_2(tp->th_dport)) {
                if (ip6) {
                        ND_PRINT("%s > %s:",
                                 ip6addr_string(ndo, ip6->ip6_src),
                                 ip6addr_string(ndo, ip6->ip6_dst));
                } else {
                        ND_PRINT("%s > %s:",
                                 ipaddr_string(ndo, ip->ip_src),
                                 ipaddr_string(ndo, ip->ip_dst));
                }
                nd_print_trunc(ndo);
                return;
        }

        sport = GET_BE_U_2(tp->th_sport);
        dport = GET_BE_U_2(tp->th_dport);

        if (ip6) {
                if (GET_U_1(ip6->ip6_nxt) == IPPROTO_TCP) {
                        ND_PRINT("%s.%s > %s.%s: ",
                                 ip6addr_string(ndo, ip6->ip6_src),
                                 tcpport_string(ndo, sport),
                                 ip6addr_string(ndo, ip6->ip6_dst),
                                 tcpport_string(ndo, dport));
                } else {
                        ND_PRINT("%s > %s: ",
                                 tcpport_string(ndo, sport), tcpport_string(ndo, dport));
                }
        } else {
                if (GET_U_1(ip->ip_p) == IPPROTO_TCP) {
                        ND_PRINT("%s.%s > %s.%s: ",
                                 ipaddr_string(ndo, ip->ip_src),
                                 tcpport_string(ndo, sport),
                                 ipaddr_string(ndo, ip->ip_dst),
                                 tcpport_string(ndo, dport));
                } else {
                        ND_PRINT("%s > %s: ",
                                 tcpport_string(ndo, sport), tcpport_string(ndo, dport));
                }
        }

        ND_TCHECK_SIZE(tp);

        hlen = TH_OFF(tp) * 4;

        if (hlen < sizeof(*tp)) {
                ND_PRINT(" tcp %u [bad hdr length %u - too short, < %lu]",
                         length - hlen, hlen, (unsigned long)sizeof(*tp));
                return;
        }

        seq = GET_BE_U_4(tp->th_seq);
        ack = GET_BE_U_4(tp->th_ack);
        win = GET_BE_U_2(tp->th_win);
        urp = GET_BE_U_2(tp->th_urp);

        if (ndo->ndo_qflag) {
                ND_PRINT("tcp %u", length - hlen);
                if (hlen > length) {
                        ND_PRINT(" [bad hdr length %u - too long, > %u]",
                                 hlen, length);
                }
                return;
        }

        flags = GET_U_1(tp->th_flags);
        ND_PRINT("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags));

        if (!ndo->ndo_Sflag && (flags & TH_ACK)) {
                /*
                 * Find (or record) the initial sequence numbers for
                 * this conversation.  (we pick an arbitrary
                 * collating order so there's only one entry for
                 * both directions).
                 */
                rev = 0;
                if (ip6) {
                        struct tcp_seq_hash6 *th;
                        struct tcp_seq_hash6 *tcp_seq_hash;
                        const void *src, *dst;
                        struct tha6 tha;

                        tcp_seq_hash = tcp_seq_hash6;
                        src = (const void *)ip6->ip6_src;
                        dst = (const void *)ip6->ip6_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (UNALIGNED_MEMCMP(src, dst, sizeof(ip6->ip6_dst)) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                UNALIGNED_MEMCPY(&tha.src, dst, sizeof(ip6->ip6_dst));
                                UNALIGNED_MEMCPY(&tha.dst, src, sizeof(ip6->ip6_src));
                                tha.port = ((u_int)dport) << 16 | sport;
                        } else {
                                UNALIGNED_MEMCPY(&tha.dst, dst, sizeof(ip6->ip6_dst));
                                UNALIGNED_MEMCPY(&tha.src, src, sizeof(ip6->ip6_src));
                                tha.port = ((u_int)sport) << 16 | dport;
                        }

                        for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
                             th->nxt; th = th->nxt)
                                if (memcmp((char *)&tha, (char *)&th->addr,
                                           sizeof(th->addr)) == 0)
                                        break;

                        if (!th->nxt || (flags & TH_SYN)) {
                                /* didn't find it or new conversation */
                                /* calloc() return used by the 'tcp_seq_hash6'
                                   hash table: do not free() */
                                if (th->nxt == NULL) {
                                        th->nxt = (struct tcp_seq_hash6 *)
                                                calloc(1, sizeof(*th));
                                        if (th->nxt == NULL)
                                                (*ndo->ndo_error)(ndo,
                                                        S_ERR_ND_MEM_ALLOC,
                                                        "tcp_print: calloc");
                                }
                                th->addr = tha;
                                if (rev)
                                        th->ack = seq, th->seq = ack - 1;
                                else
                                        th->seq = seq, th->ack = ack - 1;
                        } else {
                                if (rev)
                                        seq -= th->ack, ack -= th->seq;
                                else
                                        seq -= th->seq, ack -= th->ack;
                        }

                        thseq = th->seq;
                        thack = th->ack;
                } else {
                        struct tcp_seq_hash *th;
                        struct tcp_seq_hash *tcp_seq_hash;
                        struct tha tha;

                        tcp_seq_hash = tcp_seq_hash4;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (UNALIGNED_MEMCMP(ip->ip_src, ip->ip_dst, sizeof(ip->ip_dst)) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                UNALIGNED_MEMCPY(&tha.src, ip->ip_dst,
                                                 sizeof(ip->ip_dst));
                                UNALIGNED_MEMCPY(&tha.dst, ip->ip_src,
                                                 sizeof(ip->ip_src));
                                tha.port = ((u_int)dport) << 16 | sport;
                        } else {
                                UNALIGNED_MEMCPY(&tha.dst, ip->ip_dst,
                                                 sizeof(ip->ip_dst));
                                UNALIGNED_MEMCPY(&tha.src, ip->ip_src,
                                                 sizeof(ip->ip_src));
                                tha.port = ((u_int)sport) << 16 | dport;
                        }

                        for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
                             th->nxt; th = th->nxt)
                                if (memcmp((char *)&tha, (char *)&th->addr,
                                           sizeof(th->addr)) == 0)
                                        break;

                        if (!th->nxt || (flags & TH_SYN)) {
                                /* didn't find it or new conversation */
                                /* calloc() return used by the 'tcp_seq_hash4'
                                   hash table: do not free() */
                                if (th->nxt == NULL) {
                                        th->nxt = (struct tcp_seq_hash *)
                                                calloc(1, sizeof(*th));
                                        if (th->nxt == NULL)
                                                (*ndo->ndo_error)(ndo,
                                                        S_ERR_ND_MEM_ALLOC,
                                                        "tcp_print: calloc");
                                }
                                th->addr = tha;
                                if (rev)
                                        th->ack = seq, th->seq = ack - 1;
                                else
                                        th->seq = seq, th->ack = ack - 1;
                        } else {
                                if (rev)
                                        seq -= th->ack, ack -= th->seq;
                                else
                                        seq -= th->seq, ack -= th->ack;
                        }

                        thseq = th->seq;
                        thack = th->ack;
                }
        } else {
                /*fool gcc*/
                thseq = thack = rev = 0;
        }
        if (hlen > length) {
                ND_PRINT(" [bad hdr length %u - too long, > %u]",
                         hlen, length);
                return;
        }

        if (ndo->ndo_vflag && !ndo->ndo_Kflag && !fragmented) {
                /* Check the checksum, if possible. */
                uint16_t sum, tcp_sum;

                if (IP_V(ip) == 4) {
                        if (ND_TTEST_LEN(tp->th_sport, length)) {
                                sum = tcp_cksum(ndo, ip, tp, length);
                                tcp_sum = GET_BE_U_2(tp->th_sum);

                                ND_PRINT(", cksum 0x%04x", tcp_sum);
                                if (sum != 0)
                                        ND_PRINT(" (incorrect -> 0x%04x)",
                                            in_cksum_shouldbe(tcp_sum, sum));
                                else
                                        ND_PRINT(" (correct)");
                        }
                } else if (IP_V(ip) == 6 && ip6->ip6_plen) {
                        if (ND_TTEST_LEN(tp->th_sport, length)) {
                                sum = tcp6_cksum(ndo, ip6, tp, length);
                                tcp_sum = GET_BE_U_2(tp->th_sum);

                                ND_PRINT(", cksum 0x%04x", tcp_sum);
                                if (sum != 0)
                                        ND_PRINT(" (incorrect -> 0x%04x)",
                                            in_cksum_shouldbe(tcp_sum, sum));
                                else
                                        ND_PRINT(" (correct)");

                        }
                }
        }

        length -= hlen;
        if (ndo->ndo_vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) {
                ND_PRINT(", seq %u", seq);

                if (length > 0) {
                        ND_PRINT(":%u", seq + length);
                }
        }

        if (flags & TH_ACK) {
                ND_PRINT(", ack %u", ack);
        }

        ND_PRINT(", win %u", win);

        if (flags & TH_URG)
                ND_PRINT(", urg %u", urp);
        /*
         * Handle any options.
         */
        if (hlen > sizeof(*tp)) {
                const u_char *cp;
                u_int i, opt, datalen;
                u_int len;

                hlen -= sizeof(*tp);
                cp = (const u_char *)tp + sizeof(*tp);
                ND_PRINT(", options [");
                while (hlen > 0) {
                        if (ch != '\0')
                                ND_PRINT("%c", ch);
                        ND_TCHECK_1(cp);
                        opt = GET_U_1(cp);
                        cp++;
                        if (ZEROLENOPT(opt))
                                len = 1;
                        else {
                                ND_TCHECK_1(cp);
                                len = GET_U_1(cp);
                                cp++;	/* total including type, len */
                                if (len < 2 || len > hlen)
                                        goto bad;
                                --hlen;		/* account for length byte */
                        }
                        --hlen;			/* account for type byte */
                        datalen = 0;

/* Bail if "l" bytes of data are not left or were not captured  */
#define LENCHECK(l) { if ((l) > hlen) goto bad; ND_TCHECK_LEN(cp, l); }


                        ND_PRINT("%s", tok2str(tcp_option_values, "unknown-%u", opt));

                        switch (opt) {

                        case TCPOPT_MAXSEG:
                                datalen = 2;
                                LENCHECK(datalen);
                                ND_PRINT(" %u", GET_BE_U_2(cp));
                                break;

                        case TCPOPT_WSCALE:
                                datalen = 1;
                                LENCHECK(datalen);
                                ND_PRINT(" %u", GET_U_1(cp));
                                break;

                        case TCPOPT_SACK:
                                datalen = len - 2;
                                if (datalen % 8 != 0) {
                                        ND_PRINT(" invalid sack");
                                } else {
                                        uint32_t s, e;

                                        ND_PRINT(" %u ", datalen / 8);
                                        for (i = 0; i < datalen; i += 8) {
                                                LENCHECK(i + 4);
                                                s = GET_BE_U_4(cp + i);
                                                LENCHECK(i + 8);
                                                e = GET_BE_U_4(cp + i + 4);
                                                if (rev) {
                                                        s -= thseq;
                                                        e -= thseq;
                                                } else {
                                                        s -= thack;
                                                        e -= thack;
                                                }
                                                ND_PRINT("{%u:%u}", s, e);
                                        }
                                }
                                break;

                        case TCPOPT_CC:
                        case TCPOPT_CCNEW:
                        case TCPOPT_CCECHO:
                        case TCPOPT_ECHO:
                        case TCPOPT_ECHOREPLY:

                                /*
                                 * those options share their semantics.
                                 * fall through
                                 */
                                datalen = 4;
                                LENCHECK(datalen);
                                ND_PRINT(" %u", GET_BE_U_4(cp));
                                break;

                        case TCPOPT_TIMESTAMP:
                                datalen = 8;
                                LENCHECK(datalen);
                                ND_PRINT(" val %u ecr %u",
                                             GET_BE_U_4(cp),
                                             GET_BE_U_4(cp + 4));
                                break;

                        case TCPOPT_SIGNATURE:
                                datalen = TCP_SIGLEN;
                                LENCHECK(datalen);
                                ND_PRINT(" ");
#ifdef HAVE_LIBCRYPTO
                                switch (tcp_verify_signature(ndo, ip, tp,
                                                             bp + TH_OFF(tp) * 4, length, cp)) {

                                case SIGNATURE_VALID:
                                        ND_PRINT("valid");
                                        break;

                                case SIGNATURE_INVALID:
                                        nd_print_invalid(ndo);
                                        break;

                                case CANT_CHECK_SIGNATURE:
                                        ND_PRINT("can't check - ");
                                        for (i = 0; i < TCP_SIGLEN; ++i)
                                                ND_PRINT("%02x",
                                                         GET_U_1(cp + i));
                                        break;
                                }
#else
                                for (i = 0; i < TCP_SIGLEN; ++i)
                                        ND_PRINT("%02x", GET_U_1(cp + i));
#endif
                                break;

                        case TCPOPT_SCPS:
                                datalen = 2;
                                LENCHECK(datalen);
                                ND_PRINT(" cap %02x id %u", GET_U_1(cp),
                                         GET_U_1(cp + 1));
                                break;

                        case TCPOPT_TCPAO:
                                datalen = len - 2;
                                /* RFC 5925 Section 2.2:
                                 * "The Length value MUST be greater than or equal to 4."
                                 * (This includes the Kind and Length fields already processed
                                 * at this point.)
                                 */
                                if (datalen < 2) {
                                        nd_print_invalid(ndo);
                                } else {
                                        LENCHECK(1);
                                        ND_PRINT(" keyid %u", GET_U_1(cp));
                                        LENCHECK(2);
                                        ND_PRINT(" rnextkeyid %u",
                                                 GET_U_1(cp + 1));
                                        if (datalen > 2) {
                                                ND_PRINT(" mac 0x");
                                                for (i = 2; i < datalen; i++) {
                                                        LENCHECK(i + 1);
                                                        ND_PRINT("%02x",
                                                                 GET_U_1(cp + i));
                                                }
                                        }
                                }
                                break;

                        case TCPOPT_EOL:
                        case TCPOPT_NOP:
                        case TCPOPT_SACKOK:
                                /*
                                 * Nothing interesting.
                                 * fall through
                                 */
                                break;

                        case TCPOPT_UTO:
                                datalen = 2;
                                LENCHECK(datalen);
                                utoval = GET_BE_U_2(cp);
                                ND_PRINT(" 0x%x", utoval);
                                if (utoval & 0x0001)
                                        utoval = (utoval >> 1) * 60;
                                else
                                        utoval >>= 1;
                                ND_PRINT(" %u", utoval);
                                break;

                        case TCPOPT_MPTCP:
                                datalen = len - 2;
                                LENCHECK(datalen);
                                if (!mptcp_print(ndo, cp-2, len, flags))
                                        goto bad;
                                break;

                        case TCPOPT_FASTOPEN:
                                datalen = len - 2;
                                LENCHECK(datalen);
                                ND_PRINT(" ");
                                print_tcp_fastopen_option(ndo, cp, datalen, FALSE);
                                break;

                        case TCPOPT_EXPERIMENT2:
                                datalen = len - 2;
                                LENCHECK(datalen);
                                if (datalen < 2)
                                        goto bad;
                                /* RFC6994 */
                                magic = GET_BE_U_2(cp);
                                ND_PRINT("-");

                                switch(magic) {

                                case 0xf989: /* TCP Fast Open RFC 7413 */
                                        print_tcp_fastopen_option(ndo, cp + 2, datalen - 2, TRUE);
                                        break;

                                default:
                                        /* Unknown magic number */
                                        ND_PRINT("%04x", magic);
                                        break;
                                }
                                break;

                        default:
                                datalen = len - 2;
                                if (datalen)
                                        ND_PRINT(" 0x");
                                for (i = 0; i < datalen; ++i) {
                                        LENCHECK(i + 1);
                                        ND_PRINT("%02x", GET_U_1(cp + i));
                                }
                                break;
                        }

                        /* Account for data printed */
                        cp += datalen;
                        hlen -= datalen;

                        /* Check specification against observed length */
                        ++datalen;		/* option octet */
                        if (!ZEROLENOPT(opt))
                                ++datalen;	/* size octet */
                        if (datalen != len)
                                ND_PRINT("[len %u]", len);
                        ch = ',';
                        if (opt == TCPOPT_EOL)
                                break;
                }
                ND_PRINT("]");
        }
Exemplo n.º 15
0
void
mldv2_report_print(const u_char *bp, u_int len)
{
	struct icmp6_hdr *icp = (struct icmp6_hdr *) bp;
	u_int group, nsrcs, ngroups;
	u_int i, j;

	if (len < MLDV2_REPORT_MINLEN) {
		printf(" [invalid len %d]", len);
		return;
	}

	TCHECK(icp->icmp6_data16[1]);
	ngroups = ntohs(icp->icmp6_data16[1]);
	printf(", %d group record(s)", ngroups);
	if (vflag > 0) {
		/* Print the group records */
		group = MLDV2_REPORT_GROUP0;
		for (i = 0; i < ngroups; i++) {
			/* type(1) + auxlen(1) + numsrc(2) + grp(16) */
			if (len < group + MLDV2_REPORT_MINGRPLEN) {
				printf(" [invalid number of groups]");
				return;
			}
			TCHECK2(bp[group + MLDV2_RGROUP_MADDR],
			    sizeof(struct in6_addr));
			printf(" [gaddr %s",
			    ip6addr_string(&bp[group + MLDV2_RGROUP_MADDR]));
			printf(" %s", tok2str(mldv2report2str,
			    " [v2-report-#%d]", bp[group]));
			nsrcs = (bp[group + MLDV2_RGROUP_NSRCS] << 8) +
			    bp[group + MLDV2_RGROUP_NSRCS + 1];
			/* Check the number of sources and print them */
			if (len < group + MLDV2_REPORT_MINGRPLEN +
				    (nsrcs * sizeof(struct in6_addr))) {
				printf(" [invalid number of sources %d]", nsrcs);
				return;
			}
			if (vflag == 1)
				printf(", %d source(s)", nsrcs);
			else {
				/* Print the sources */
				(void)printf(" {");
				for (j = 0; j < nsrcs; j++) {
					TCHECK2(bp[group +
					    MLDV2_REPORT_MINGRPLEN +
					    j * sizeof(struct in6_addr)],
					    sizeof(struct in6_addr));
					printf(" %s", ip6addr_string(&bp[group +
					    MLDV2_REPORT_MINGRPLEN + j *
					    sizeof(struct in6_addr)]));
				}
				(void)printf(" }");
			}
			/* Next group record */
			group += MLDV2_REPORT_MINGRPLEN + nsrcs *
			    sizeof(struct in6_addr);
			printf("]");
		}
	}
	return;
trunc:
	(void)printf("[|icmp6]");
	return;
}
Exemplo n.º 16
0
static void
atmarp_print(netdissect_options *ndo,
	     const u_char *bp, u_int length, u_int caplen)
{
	const struct atmarp_pkthdr *ap;
	u_short pro, hrd, op;

	ap = (const struct atmarp_pkthdr *)bp;
	ND_TCHECK(*ap);

	hrd = ATMHRD(ap);
	pro = ATMPRO(ap);
	op = ATMOP(ap);

	if (!ND_TTEST2(*aar_tpa(ap), ATMTPROTO_LEN(ap))) {
		ND_PRINT((ndo, "[|ARP]"));
		ND_DEFAULTPRINT((const u_char *)ap, length);
		return;
	}

        if (!ndo->ndo_eflag) {
            ND_PRINT((ndo, "ARP, "));
        }

	if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) ||
	    ATMSPROTO_LEN(ap) != 4 ||
            ATMTPROTO_LEN(ap) != 4 ||
            ndo->ndo_vflag) {
                ND_PRINT((ndo, "%s, %s (len %u/%u)",
                          tok2str(arphrd_values, "Unknown Hardware (%u)", hrd),
                          tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro),
                          ATMSPROTO_LEN(ap),
                          ATMTPROTO_LEN(ap)));

                /* don't know know about the address formats */
                if (!ndo->ndo_vflag) {
                    goto out;
                }
	}

        /* print operation */
        printf("%s%s ",
               ndo->ndo_vflag ? ", " : "", 
               tok2str(arpop_values, "Unknown (%u)", op));

	switch (op) {

	case ARPOP_REQUEST:
		ND_PRINT((ndo, "who-has %s", ipaddr_string(ATMTPA(ap))));
		if (ATMTHRD_LEN(ap) != 0) {
			ND_PRINT((ndo, " ("));
			atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap),
			    ATMTSA(ap), ATMTSLN(ap));
			ND_PRINT((ndo, ")"));
		}
		ND_PRINT((ndo, "tell %s", ipaddr_string(ATMSPA(ap))));
		break;

	case ARPOP_REPLY:
		ND_PRINT((ndo, "%s is-at ", ipaddr_string(ATMSPA(ap))));
		atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
                                  ATMSSLN(ap));
		break;

	case ARPOP_INVREQUEST:
		ND_PRINT((ndo, "who-is "));
		atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap),
		    ATMTSLN(ap));
		ND_PRINT((ndo, " tell "));
		atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
		    ATMSSLN(ap));
		break;

	case ARPOP_INVREPLY:
		atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
		    ATMSSLN(ap));
		ND_PRINT((ndo, "at %s", ipaddr_string(ATMSPA(ap))));
		break;

	case ARPOP_NAK:
		ND_PRINT((ndo, "for %s", ipaddr_string(ATMSPA(ap))));
		break;

	default:
		ND_DEFAULTPRINT((const u_char *)ap, caplen);
		return;
	}

 out:
        ND_PRINT((ndo, ", length %u", length));
        return;

trunc:
	ND_PRINT((ndo, "[|ARP]"));
}
Exemplo n.º 17
0
/*
 * Print trivial file transfer program requests
 */
void
tftp_print(register const u_char *bp, u_int length)
{
	register const struct tftphdr *tp;
	register const char *cp;
	register const u_char *p;
	register int opcode, i;
	static char tstr[] = " [|tftp]";

	tp = (const struct tftphdr *)bp;

	/* Print length */
	printf(" %d", length);

	/* Print tftp request type */
	TCHECK(tp->th_opcode);
	opcode = EXTRACT_16BITS(&tp->th_opcode);
	cp = tok2str(op2str, "tftp-#%d", opcode);
	printf(" %s", cp);
	/* Bail if bogus opcode */
	if (*cp == 't')
		return;

	switch (opcode) {

	case RRQ:
	case WRQ:
	case OACK:
		/*
		 * XXX Not all arpa/tftp.h's specify th_stuff as any
		 * array; use address of th_block instead
		 */
#ifdef notdef
		p = (u_char *)tp->th_stuff;
#else
		p = (u_char *)&tp->th_block;
#endif
		putchar(' ');
		/* Print filename or first option */
		if (opcode != OACK)
			putchar('"');
		i = fn_print(p, snapend);
		if (opcode != OACK)
			putchar('"');

		/* Print the mode (RRQ and WRQ only) and any options */
		while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) {
			if (length <= (u_int)(p - (const u_char *)&tp->th_block))
				break;
			p++;
			if (*p != '\0') {
				putchar(' ');
				fn_print(p, snapend);
			}
		}
		
		if (i)
			goto trunc;
		break;

	case ACK:
	case DATA:
		TCHECK(tp->th_block);
		printf(" block %d", EXTRACT_16BITS(&tp->th_block));
		break;

	case ERROR:
		/* Print error code string */
		TCHECK(tp->th_code);
		printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"",
				       EXTRACT_16BITS(&tp->th_code)));
		/* Print error message string */
		i = fn_print((const u_char *)tp->th_data, snapend);
		putchar('"');
		if (i)
			goto trunc;
		break;

	default:
		/* We shouldn't get here */
		printf("(unknown #%d)", opcode);
		break;
	}
	return;
trunc:
	fputs(tstr, stdout);
	return;
}
Exemplo n.º 18
0
void
arp_print(netdissect_options *ndo,
	  const u_char *bp, u_int length, u_int caplen)
{
	const struct arp_pkthdr *ap;
	u_short pro, hrd, op, linkaddr;

	ap = (const struct arp_pkthdr *)bp;
	ND_TCHECK(*ap);

	hrd = HRD(ap);
	pro = PRO(ap);
	op = OP(ap);

        
        /* if its ATM then call the ATM ARP printer
           for Frame-relay ARP most of the fields
           are similar to Ethernet so overload the Ethernet Printer
           and set the linkaddr type for linkaddr_string() accordingly */

        switch(hrd) {
        case ARPHRD_ATM2225:
            atmarp_print(ndo, bp, length, caplen);
            return;
        case ARPHRD_FRELAY:
            linkaddr = LINKADDR_FRELAY;
            break;
        default:
            linkaddr = LINKADDR_ETHER;
            break;
	}

	if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) {
		ND_PRINT((ndo, "[|ARP]"));
		ND_DEFAULTPRINT((const u_char *)ap, length);
		return;
	}

        if (!ndo->ndo_eflag) {
            ND_PRINT((ndo, "ARP, "));
        }

        /* print hardware type/len and proto type/len */
        if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) ||
	    PROTO_LEN(ap) != 4 ||
            HRD_LEN(ap) == 0 ||
            ndo->ndo_vflag) {
            ND_PRINT((ndo, "%s (len %u), %s (len %u)",
                      tok2str(arphrd_values, "Unknown Hardware (%u)", hrd),
                      HRD_LEN(ap),
                      tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro),
                      PROTO_LEN(ap)));

            /* don't know know about the address formats */
            if (!ndo->ndo_vflag) {
                goto out;
            }
	}

        /* print operation */
        printf("%s%s ",
               ndo->ndo_vflag ? ", " : "", 
               tok2str(arpop_values, "Unknown (%u)", op));

	switch (op) {

	case ARPOP_REQUEST:
		ND_PRINT((ndo, "who-has %s", ipaddr_string(TPA(ap))));
		if (memcmp((const char *)ezero, (const char *)THA(ap), HRD_LEN(ap)) != 0)
			ND_PRINT((ndo, " (%s)",
				  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap))));
		ND_PRINT((ndo, " tell %s", ipaddr_string(SPA(ap))));
		break;

	case ARPOP_REPLY:
		ND_PRINT((ndo, "%s is-at %s",
                          ipaddr_string(SPA(ap)),
                          linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap))));
		break;

	case ARPOP_REVREQUEST:
		ND_PRINT((ndo, "who-is %s tell %s",
			  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
			  linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap))));
		break;

	case ARPOP_REVREPLY:
		ND_PRINT((ndo, "%s at %s",
			  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
			  ipaddr_string(TPA(ap))));
		break;

	case ARPOP_INVREQUEST:
		ND_PRINT((ndo, "who-is %s tell %s",
			  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
			  linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap))));
		break;

	case ARPOP_INVREPLY:
		ND_PRINT((ndo,"%s at %s",
			  linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
			  ipaddr_string(TPA(ap))));
		break;

	default:
		ND_DEFAULTPRINT((const u_char *)ap, caplen);
		return;
	}

 out:
        ND_PRINT((ndo, ", length %u", length));

	return;
trunc:
	ND_PRINT((ndo, "[|ARP]"));
}
Exemplo n.º 19
0
static int
juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) {

    struct juniper_cookie_table_t *lp = juniper_cookie_table;
    u_int idx, offset;
#ifdef DLT_JUNIPER_ATM2
    u_int32_t control_word;
#endif

    l2info->header_len = 0;
    l2info->cookie_len = 0;
    l2info->proto = 0;


    l2info->length = h->len;
    l2info->caplen = h->caplen;
    l2info->direction = p[3]&JUNIPER_BPF_PKT_IN;
    
    TCHECK2(p[0],4);
    if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */
        printf("no magic-number found!");
        return 0;
    } 

    if (eflag) /* print direction */
        printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction));

    /* extensions present ?  - calculate how much bytes to skip */
    if ((p[3] & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) {
        offset = 6 + EXTRACT_16BITS(p+4);
        if (eflag>1)
            printf("ext-len %u, ",EXTRACT_16BITS(p+4));
    } else
        offset = 4;

    if ((p[3] & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {            
        if (eflag)
            printf("no-L2-hdr, ");

        /* there is no link-layer present -
         * perform the v4/v6 heuristics
         * to figure out what it is
         */
        TCHECK2(p[offset+4],1);
        if(ip_heuristic_guess(p+offset+4,l2info->length-(offset+4)) == 0)
            printf("no IP-hdr found!");

        l2info->header_len=offset+4;
        return 0; /* stop parsing the output further */
        
    }
    l2info->header_len = offset;
    p+=l2info->header_len;
    l2info->length -= l2info->header_len;
    l2info->caplen -= l2info->header_len;

    /* search through the cookie table and copy values matching for our PIC type */
    while (lp->s != NULL) {
        if (lp->pictype == l2info->pictype) {

            l2info->cookie_len += lp->cookie_len;

            switch (p[0]) {
            case LS_COOKIE_ID:
                l2info->cookie_type = LS_COOKIE_ID;
                l2info->cookie_len += 2;
                break;
            case AS_COOKIE_ID:
                l2info->cookie_type = AS_COOKIE_ID;
                l2info->cookie_len = 8;
                break;
            
            default:
                l2info->bundle = l2info->cookie[0];
                break;
            }


#ifdef DLT_JUNIPER_MFR
            /* MFR child links don't carry cookies */
            if (l2info->pictype == DLT_JUNIPER_MFR &&
                (p[0] & MFR_BE_MASK) == MFR_BE_MASK) {
                l2info->cookie_len = 0;
            }
#endif

            l2info->header_len += l2info->cookie_len;
            l2info->length -= l2info->cookie_len;
            l2info->caplen -= l2info->cookie_len;

            if (eflag)
                printf("%s-PIC, cookie-len %u",
                       lp->s,
                       l2info->cookie_len);

            if (l2info->cookie_len > 0) {
                TCHECK2(p[0],l2info->cookie_len);
                if (eflag)
                    printf(", cookie 0x");
                for (idx = 0; idx < l2info->cookie_len; idx++) {
                    l2info->cookie[idx] = p[idx]; /* copy cookie data */
                    if (eflag) printf("%02x",p[idx]);
                }
            }

            if (eflag) printf(": "); /* print demarc b/w L2/L3*/
            

            l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); 
            break;
        }
        ++lp;
    }
    p+=l2info->cookie_len;

    /* DLT_ specific parsing */
    switch(l2info->pictype) {
#ifdef DLT_JUNIPER_MLPPP
    case DLT_JUNIPER_MLPPP:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;            
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MLFR
    case DLT_JUNIPER_MLFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MFR
    case DLT_JUNIPER_MFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_ATM2
    case DLT_JUNIPER_ATM2:
        TCHECK2(p[0],4);
        /* ATM cell relay control word present ? */
        if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) {
            control_word = EXTRACT_32BITS(p);
            /* some control word heuristics */
            switch(control_word) {
            case 0: /* zero control word */
            case 0x08000000: /* < JUNOS 7.4 control-word */
            case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
                l2info->header_len += 4;
                break;
            default:
                break;
            }
            
            if (eflag)
                printf("control-word 0x%08x ", control_word);
        }
        break;
#endif
#ifdef DLT_JUNIPER_ATM1
    case DLT_JUNIPER_ATM1:
        break;
#endif
#ifdef DLT_JUNIPER_PPP
    case DLT_JUNIPER_PPP:
        break;
#endif
#ifdef DLT_JUNIPER_CHDLC
    case DLT_JUNIPER_CHDLC:
        break;
#endif
#ifdef DLT_JUNIPER_ETHER
    case DLT_JUNIPER_ETHER:
        break;
#endif
#ifdef DLT_JUNIPER_FRELAY
    case DLT_JUNIPER_FRELAY:
        break;
#endif

    default:
        printf("Unknown Juniper DLT_ type %u: ", l2info->pictype);
        break;
    }
    
    if (eflag > 1)
        printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto);

    return 1; /* everything went ok so far. continue parsing */
 trunc:
    printf("[|juniper_hdr], length %u",h->len);
    return 0;
}
Exemplo n.º 20
0
static int
ldp_tlv_print(netdissect_options *ndo,
              const u_char *tptr,
              u_short msg_tlen)
{
    struct ldp_tlv_header {
        nd_uint16_t type;
        nd_uint16_t length;
    };

    const struct ldp_tlv_header *ldp_tlv_header;
    u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags;
    u_char fec_type;
    u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx;
    char buf[100];
    int i;

    ldp_tlv_header = (const struct ldp_tlv_header *)tptr;
    ND_TCHECK_SIZE(ldp_tlv_header);
    tlv_len=EXTRACT_BE_U_2(ldp_tlv_header->length);
    if (tlv_len + 4 > msg_tlen) {
        ND_PRINT("\n\t\t TLV contents go past end of message");
        return 0;
    }
    tlv_tlen=tlv_len;
    tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_BE_U_2(ldp_tlv_header->type));

    /* FIXME vendor private / experimental check */
    ND_PRINT("\n\t    %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]",
           tok2str(ldp_tlv_values,
                   "Unknown",
                   tlv_type),
           tlv_type,
           tlv_len,
           LDP_MASK_U_BIT(EXTRACT_BE_U_2(ldp_tlv_header->type)) ? "continue processing" : "ignore",
           LDP_MASK_F_BIT(EXTRACT_BE_U_2(ldp_tlv_header->type)) ? "do" : "don't");

    tptr+=sizeof(struct ldp_tlv_header);

    switch(tlv_type) {

    case LDP_TLV_COMMON_HELLO:
        TLV_TCHECK(4);
        ND_PRINT("\n\t      Hold Time: %us, Flags: [%s Hello%s]",
               EXTRACT_BE_U_2(tptr),
               (EXTRACT_BE_U_2(tptr + 2)&0x8000) ? "Targeted" : "Link",
               (EXTRACT_BE_U_2(tptr + 2)&0x4000) ? ", Request for targeted Hellos" : "");
        break;

    case LDP_TLV_IPV4_TRANSPORT_ADDR:
        TLV_TCHECK(4);
        ND_PRINT("\n\t      IPv4 Transport Address: %s", ipaddr_string(ndo, tptr));
        break;
    case LDP_TLV_IPV6_TRANSPORT_ADDR:
        TLV_TCHECK(16);
        ND_PRINT("\n\t      IPv6 Transport Address: %s", ip6addr_string(ndo, tptr));
        break;
    case LDP_TLV_CONFIG_SEQ_NUMBER:
        TLV_TCHECK(4);
        ND_PRINT("\n\t      Sequence Number: %u", EXTRACT_BE_U_4(tptr));
        break;

    case LDP_TLV_ADDRESS_LIST:
        TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN);
	af = EXTRACT_BE_U_2(tptr);
	tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
        tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
	ND_PRINT("\n\t      Address Family: %s, addresses",
               tok2str(af_values, "Unknown (%u)", af));
        switch (af) {
        case AFNUM_INET:
	    while(tlv_tlen >= sizeof(struct in_addr)) {
		ND_TCHECK_LEN(tptr, sizeof(struct in_addr));
		ND_PRINT(" %s", ipaddr_string(ndo, tptr));
		tlv_tlen-=sizeof(struct in_addr);
		tptr+=sizeof(struct in_addr);
	    }
            break;
        case AFNUM_INET6:
	    while(tlv_tlen >= sizeof(struct in6_addr)) {
		ND_TCHECK_LEN(tptr, sizeof(struct in6_addr));
		ND_PRINT(" %s", ip6addr_string(ndo, tptr));
		tlv_tlen-=sizeof(struct in6_addr);
		tptr+=sizeof(struct in6_addr);
	    }
            break;
        default:
            /* unknown AF */
            break;
        }
	break;

    case LDP_TLV_COMMON_SESSION:
	TLV_TCHECK(8);
	ND_PRINT("\n\t      Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
	       EXTRACT_BE_U_2(tptr), EXTRACT_BE_U_2(tptr + 2),
	       (EXTRACT_BE_U_2(tptr + 6)&0x8000) ? "On Demand" : "Unsolicited",
	       (EXTRACT_BE_U_2(tptr + 6)&0x4000) ? "Enabled" : "Disabled"
	       );
	break;

    case LDP_TLV_FEC:
        TLV_TCHECK(1);
        fec_type = EXTRACT_U_1(tptr);
	ND_PRINT("\n\t      %s FEC (0x%02x)",
	       tok2str(ldp_fec_values, "Unknown", fec_type),
	       fec_type);

	tptr+=1;
	tlv_tlen-=1;
	switch(fec_type) {

	case LDP_FEC_WILDCARD:
	    break;
	case LDP_FEC_PREFIX:
	    TLV_TCHECK(2);
	    af = EXTRACT_BE_U_2(tptr);
	    tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
	    tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
	    if (af == AFNUM_INET) {
		i=decode_prefix4(ndo, tptr, tlv_tlen, buf, sizeof(buf));
		if (i == -2)
		    goto trunc;
		if (i == -3)
		    ND_PRINT(": IPv4 prefix (goes past end of TLV)");
		else if (i == -1)
		    ND_PRINT(": IPv4 prefix (invalid length)");
		else
		    ND_PRINT(": IPv4 prefix %s", buf);
	    }
	    else if (af == AFNUM_INET6) {
		i=decode_prefix6(ndo, tptr, tlv_tlen, buf, sizeof(buf));
		if (i == -2)
		    goto trunc;
		if (i == -3)
		    ND_PRINT(": IPv4 prefix (goes past end of TLV)");
		else if (i == -1)
		    ND_PRINT(": IPv6 prefix (invalid length)");
		else
		    ND_PRINT(": IPv6 prefix %s", buf);
	    }
	    else
		ND_PRINT(": Address family %u prefix", af);
	    break;
	case LDP_FEC_HOSTADDRESS:
	    break;
	case LDP_FEC_MARTINI_VC:
            /*
             * We assume the type was supposed to be one of the MPLS
             * Pseudowire Types.
             */
            TLV_TCHECK(7);
            vc_info_len = EXTRACT_U_1(tptr + 2);

            /*
	     * According to RFC 4908, the VC info Length field can be zero,
	     * in which case not only are there no interface parameters,
	     * there's no VC ID.
	     */
            if (vc_info_len == 0) {
                ND_PRINT(": %s, %scontrol word, group-ID %u, VC-info-length: %u",
                       tok2str(mpls_pw_types_values, "Unknown", EXTRACT_BE_U_2(tptr)&0x7fff),
                       EXTRACT_BE_U_2(tptr)&0x8000 ? "" : "no ",
                       EXTRACT_BE_U_4(tptr + 3),
                       vc_info_len);
                break;
            }

            /* Make sure we have the VC ID as well */
            TLV_TCHECK(11);
	    ND_PRINT(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u",
		   tok2str(mpls_pw_types_values, "Unknown", EXTRACT_BE_U_2(tptr)&0x7fff),
		   EXTRACT_BE_U_2(tptr)&0x8000 ? "" : "no ",
		   EXTRACT_BE_U_4(tptr + 3),
		   EXTRACT_BE_U_4(tptr + 7),
		   vc_info_len);
            if (vc_info_len < 4) {
                /* minimum 4, for the VC ID */
                ND_PRINT(" (invalid, < 4");
                return(tlv_len+4); /* Type & Length fields not included */
	    }
            vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */

            /* Skip past the fixed information and the VC ID */
            tptr+=11;
            tlv_tlen-=11;
            TLV_TCHECK(vc_info_len);

            while (vc_info_len > 2) {
                vc_info_tlv_type = EXTRACT_U_1(tptr);
                vc_info_tlv_len = EXTRACT_U_1(tptr + 1);
                if (vc_info_tlv_len < 2)
                    break;
                if (vc_info_len < vc_info_tlv_len)
                    break;

                ND_PRINT("\n\t\tInterface Parameter: %s (0x%02x), len %u",
                       tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type),
                       vc_info_tlv_type,
                       vc_info_tlv_len);

                switch(vc_info_tlv_type) {
                case LDP_FEC_MARTINI_IFPARM_MTU:
                    ND_PRINT(": %u", EXTRACT_BE_U_2(tptr + 2));
                    break;

                case LDP_FEC_MARTINI_IFPARM_DESC:
                    ND_PRINT(": ");
                    for (idx = 2; idx < vc_info_tlv_len; idx++)
                        safeputchar(ndo, EXTRACT_U_1(tptr + idx));
                    break;

                case LDP_FEC_MARTINI_IFPARM_VCCV:
                    ND_PRINT("\n\t\t  Control Channels (0x%02x) = [%s]",
                           EXTRACT_U_1((tptr + 2)),
                           bittok2str(ldp_fec_martini_ifparm_vccv_cc_values, "none", EXTRACT_U_1((tptr + 2))));
                    ND_PRINT("\n\t\t  CV Types (0x%02x) = [%s]",
                           EXTRACT_U_1((tptr + 3)),
                           bittok2str(ldp_fec_martini_ifparm_vccv_cv_values, "none", EXTRACT_U_1((tptr + 3))));
                    break;

                default:
                    print_unknown_data(ndo, tptr+2, "\n\t\t  ", vc_info_tlv_len-2);
                    break;
                }

                vc_info_len -= vc_info_tlv_len;
                tptr += vc_info_tlv_len;
            }
	    break;
	}

	break;

    case LDP_TLV_GENERIC_LABEL:
	TLV_TCHECK(4);
	ND_PRINT("\n\t      Label: %u", EXTRACT_BE_U_4(tptr) & 0xfffff);
	break;

    case LDP_TLV_STATUS:
	TLV_TCHECK(8);
	ui = EXTRACT_BE_U_4(tptr);
	tptr+=4;
	ND_PRINT("\n\t      Status: 0x%02x, Flags: [%s and %s forward]",
	       ui&0x3fffffff,
	       ui&0x80000000 ? "Fatal error" : "Advisory Notification",
	       ui&0x40000000 ? "do" : "don't");
	ui = EXTRACT_BE_U_4(tptr);
	tptr+=4;
	if (ui)
	    ND_PRINT(", causing Message ID: 0x%08x", ui);
	break;

    case LDP_TLV_FT_SESSION:
	TLV_TCHECK(8);
	ft_flags = EXTRACT_BE_U_2(tptr);
	ND_PRINT("\n\t      Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
	       ft_flags&0x8000 ? "" : "No ",
	       ft_flags&0x8 ? "" : "Don't ",
	       ft_flags&0x4 ? "" : "No ",
	       ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
	       ft_flags&0x1 ? "" : "Don't ");
	tptr+=4;
	ui = EXTRACT_BE_U_4(tptr);
	if (ui)
	    ND_PRINT(", Reconnect Timeout: %ums", ui);
	tptr+=4;
	ui = EXTRACT_BE_U_4(tptr);
	if (ui)
	    ND_PRINT(", Recovery Time: %ums", ui);
	break;

    case LDP_TLV_MTU:
	TLV_TCHECK(2);
	ND_PRINT("\n\t      MTU: %u", EXTRACT_BE_U_2(tptr));
	break;


    /*
     *  FIXME those are the defined TLVs that lack a decoder
     *  you are welcome to contribute code ;-)
     */

    case LDP_TLV_HOP_COUNT:
    case LDP_TLV_PATH_VECTOR:
    case LDP_TLV_ATM_LABEL:
    case LDP_TLV_FR_LABEL:
    case LDP_TLV_EXTD_STATUS:
    case LDP_TLV_RETURNED_PDU:
    case LDP_TLV_RETURNED_MSG:
    case LDP_TLV_ATM_SESSION_PARM:
    case LDP_TLV_FR_SESSION_PARM:
    case LDP_TLV_LABEL_REQUEST_MSG_ID:

    default:
        if (ndo->ndo_vflag <= 1)
            print_unknown_data(ndo, tptr, "\n\t      ", tlv_tlen);
        break;
    }
    return(tlv_len+4); /* Type & Length fields not included */

trunc:
    ND_PRINT("\n\t\t packet exceeded snapshot");
    return 0;

badtlv:
    ND_PRINT("\n\t\t TLV contents go past end of TLV");
    return(tlv_len+4); /* Type & Length fields not included */
}
Exemplo n.º 21
0
void
tcp_print(register const u_char *bp, register u_int length,
	  register const u_char *bp2, int fragmented)
{
        register const struct tcphdr *tp;
        register const struct ip *ip;
        register u_char flags;
        register u_int hlen;
        register char ch;
        u_int16_t sport, dport, win, urp;
        u_int32_t seq, ack, thseq, thack;
        u_int utoval;
        int threv;
#ifdef INET6
        register const struct ip6_hdr *ip6;
#endif

        tp = (struct tcphdr *)bp;
        ip = (struct ip *)bp2;
#ifdef INET6
        if (IP_V(ip) == 6)
                ip6 = (struct ip6_hdr *)bp2;
        else
                ip6 = NULL;
#endif /*INET6*/
        ch = '\0';
        if (!TTEST(tp->th_dport)) {
                (void)printf("%s > %s: [|tcp]",
                             ipaddr_string(&ip->ip_src),
                             ipaddr_string(&ip->ip_dst));
                return;
        }

        sport = EXTRACT_16BITS(&tp->th_sport);
        dport = EXTRACT_16BITS(&tp->th_dport);

        hlen = TH_OFF(tp) * 4;

        /*
	 * If data present, header length valid, and NFS port used,
	 * assume NFS.
	 * Pass offset of data plus 4 bytes for RPC TCP msg length
	 * to NFS print routines.
	 */
	if (!qflag && hlen >= sizeof(*tp) && hlen <= length &&
	    (length - hlen) >= 4) {
		u_char *fraglenp;
		u_int32_t fraglen;
		register struct sunrpc_msg *rp;
		enum sunrpc_msg_type direction;

		fraglenp = (u_char *)tp + hlen;
		if (TTEST2(*fraglenp, 4)) {
			fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF;
			if (fraglen > (length - hlen) - 4)
				fraglen = (length - hlen) - 4;
			rp = (struct sunrpc_msg *)(fraglenp + 4);
			if (TTEST(rp->rm_direction)) {
				direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
				if (dport == NFS_PORT &&
				    direction == SUNRPC_CALL) {
					nfsreq_print((u_char *)rp, fraglen,
					    (u_char *)ip);
					return;
				}
				if (sport == NFS_PORT &&
				    direction == SUNRPC_REPLY) {
					nfsreply_print((u_char *)rp, fraglen,
					    (u_char *)ip);
					return;
				}
			}
                }
        }
#ifdef INET6
        if (ip6) {
                if (ip6->ip6_nxt == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ip6addr_string(&ip6->ip6_src),
                                     tcpport_string(sport),
                                     ip6addr_string(&ip6->ip6_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        } else
#endif /*INET6*/
        {
                if (ip->ip_p == IPPROTO_TCP) {
                        (void)printf("%s.%s > %s.%s: ",
                                     ipaddr_string(&ip->ip_src),
                                     tcpport_string(sport),
                                     ipaddr_string(&ip->ip_dst),
                                     tcpport_string(dport));
                } else {
                        (void)printf("%s > %s: ",
                                     tcpport_string(sport), tcpport_string(dport));
                }
        }

        if (hlen < sizeof(*tp)) {
                (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
                             length - hlen, hlen, (unsigned long)sizeof(*tp));
                return;
        }

        TCHECK(*tp);

        seq = EXTRACT_32BITS(&tp->th_seq);
        ack = EXTRACT_32BITS(&tp->th_ack);
        win = EXTRACT_16BITS(&tp->th_win);
        urp = EXTRACT_16BITS(&tp->th_urp);

        if (qflag) {
                (void)printf("tcp %d", length - hlen);
                if (hlen > length) {
                        (void)printf(" [bad hdr length %u - too long, > %u]",
                                     hlen, length);
                }
                return;
        }

        flags = tp->th_flags;
        printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags));

        if (!Sflag && (flags & TH_ACK)) {
                register struct tcp_seq_hash *th;
                const void *src, *dst;
                register int rev;
                struct tha tha;
                /*
                 * Find (or record) the initial sequence numbers for
                 * this conversation.  (we pick an arbitrary
                 * collating order so there's only one entry for
                 * both directions).
                 */
#ifdef INET6
                rev = 0;
                if (ip6) {
                        src = &ip6->ip6_src;
                        dst = &ip6->ip6_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                memcpy(&tha.src, dst, sizeof ip6->ip6_dst);
                                memcpy(&tha.dst, src, sizeof ip6->ip6_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                memcpy(&tha.dst, dst, sizeof ip6->ip6_dst);
                                memcpy(&tha.src, src, sizeof ip6->ip6_src);
                                tha.port = sport << 16 | dport;
                        }
                } else {
                        /*
                         * Zero out the tha structure; the src and dst
                         * fields are big enough to hold an IPv6
                         * address, but we only have IPv4 addresses
                         * and thus must clear out the remaining 124
                         * bits.
                         *
                         * XXX - should we just clear those bytes after
                         * copying the IPv4 addresses, rather than
                         * zeroing out the entire structure and then
                         * overwriting some of the zeroes?
                         *
                         * XXX - this could fail if we see TCP packets
                         * with an IPv6 address with the lower 124 bits
                         * all zero and also see TCP packes with an
                         * IPv4 address with the same 32 bits as the
                         * upper 32 bits of the IPv6 address in question.
                         * Can that happen?  Is it likely enough to be
                         * an issue?
                         */
                        memset(&tha, 0, sizeof(tha));
                        src = &ip->ip_src;
                        dst = &ip->ip_dst;
                        if (sport > dport)
                                rev = 1;
                        else if (sport == dport) {
                                if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
                                        rev = 1;
                        }
                        if (rev) {
                                memcpy(&tha.src, dst, sizeof ip->ip_dst);
                                memcpy(&tha.dst, src, sizeof ip->ip_src);
                                tha.port = dport << 16 | sport;
                        } else {
                                memcpy(&tha.dst, dst, sizeof ip->ip_dst);
                                memcpy(&tha.src, src, sizeof ip->ip_src);
                                tha.port = sport << 16 | dport;
                        }
                }
#else
                rev = 0;
                src = &ip->ip_src;
                dst = &ip->ip_dst;
                if (sport > dport)
                        rev = 1;
                else if (sport == dport) {
                        if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
                                rev = 1;
                }
                if (rev) {
                        memcpy(&tha.src, dst, sizeof ip->ip_dst);
                        memcpy(&tha.dst, src, sizeof ip->ip_src);
                        tha.port = dport << 16 | sport;
                } else {
                        memcpy(&tha.dst, dst, sizeof ip->ip_dst);
                        memcpy(&tha.src, src, sizeof ip->ip_src);
                        tha.port = sport << 16 | dport;
                }
#endif

                threv = rev;
                for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
                     th->nxt; th = th->nxt)
                        if (memcmp((char *)&tha, (char *)&th->addr,
                                   sizeof(th->addr)) == 0)
                                break;

                if (!th->nxt || (flags & TH_SYN)) {
                        /* didn't find it or new conversation */
                        if (th->nxt == NULL) {
                                th->nxt = (struct tcp_seq_hash *)
                                        calloc(1, sizeof(*th));
                                if (th->nxt == NULL)
                                        error("tcp_print: calloc");
                        }
                        th->addr = tha;
                        if (rev)
                                th->ack = seq, th->seq = ack - 1;
                        else
                                th->seq = seq, th->ack = ack - 1;
                } else {
                        if (rev)
                                seq -= th->ack, ack -= th->seq;
                        else
                                seq -= th->seq, ack -= th->ack;
                }

                thseq = th->seq;
                thack = th->ack;
        } else {
                /*fool gcc*/
                thseq = thack = threv = 0;
        }
        if (hlen > length) {
                (void)printf(" [bad hdr length %u - too long, > %u]",
                             hlen, length);
                return;
        }

        if (IP_V(ip) == 4 && vflag && !Kflag && !fragmented) {
                u_int16_t sum, tcp_sum;
                if (TTEST2(tp->th_sport, length)) {
                        sum = tcp_cksum(ip, tp, length);

                        (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
                        if (sum != 0) {
                                tcp_sum = EXTRACT_16BITS(&tp->th_sum);
                                (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
                        } else
                                (void)printf(" (correct)");
                }
        }
#ifdef INET6
        if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) {
                u_int16_t sum,tcp_sum;
                if (TTEST2(tp->th_sport, length)) {
                        sum = nextproto6_cksum(ip6, (u_short *)tp, length, IPPROTO_TCP);
                        (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
                        if (sum != 0) {
                                tcp_sum = EXTRACT_16BITS(&tp->th_sum);
                                (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
                        } else
                                (void)printf(" (correct)");

                }
        }
#endif

        length -= hlen;
        if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) {
                (void)printf(", seq %u", seq);

                if (length > 0) {
                        (void)printf(":%u", seq + length);
                }
        }

        if (flags & TH_ACK) {
                (void)printf(", ack %u", ack);
        }

        (void)printf(", win %d", win);

        if (flags & TH_URG)
                (void)printf(", urg %d", urp);
        /*
         * Handle any options.
         */
        if (hlen > sizeof(*tp)) {
                register const u_char *cp;
                register u_int i, opt, datalen;
                register u_int len;

                hlen -= sizeof(*tp);
                cp = (const u_char *)tp + sizeof(*tp);
                printf(", options [");
                while (hlen > 0) {
                        if (ch != '\0')
                                putchar(ch);
                        TCHECK(*cp);
                        opt = *cp++;
                        if (ZEROLENOPT(opt))
                                len = 1;
                        else {
                                TCHECK(*cp);
                                len = *cp++;	/* total including type, len */
                                if (len < 2 || len > hlen)
                                        goto bad;
                                --hlen;		/* account for length byte */
                        }
                        --hlen;			/* account for type byte */
                        datalen = 0;

/* Bail if "l" bytes of data are not left or were not captured  */
#define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); }


                        printf("%s", tok2str(tcp_option_values, "Unknown Option %u", opt));

                        switch (opt) {

                        case TCPOPT_MAXSEG:
                                datalen = 2;
                                LENCHECK(datalen);
                                (void)printf(" %u", EXTRACT_16BITS(cp));
                                break;

                        case TCPOPT_WSCALE:
                                datalen = 1;
                                LENCHECK(datalen);
                                (void)printf(" %u", *cp);
                                break;

                        case TCPOPT_SACK:
                                datalen = len - 2;
                                if (datalen % 8 != 0) {
                                        (void)printf("malformed sack");
                                } else {
                                        u_int32_t s, e;

                                        (void)printf(" %d ", datalen / 8);
                                        for (i = 0; i < datalen; i += 8) {
                                                LENCHECK(i + 4);
                                                s = EXTRACT_32BITS(cp + i);
                                                LENCHECK(i + 8);
                                                e = EXTRACT_32BITS(cp + i + 4);
                                                if (threv) {
                                                        s -= thseq;
                                                        e -= thseq;
                                                } else {
                                                        s -= thack;
                                                        e -= thack;
                                                }
                                                (void)printf("{%u:%u}", s, e);
                                        }
                                }
                                break;

                        case TCPOPT_CC:
                        case TCPOPT_CCNEW:
                        case TCPOPT_CCECHO:
                        case TCPOPT_ECHO:
                        case TCPOPT_ECHOREPLY:

                                /*
                                 * those options share their semantics.
                                 * fall through
                                 */
                                datalen = 4;
                                LENCHECK(datalen);
                                (void)printf(" %u", EXTRACT_32BITS(cp));
                                break;

                        case TCPOPT_TIMESTAMP:
                                datalen = 8;
                                LENCHECK(datalen);
                                (void)printf(" val %u ecr %u",
                                             EXTRACT_32BITS(cp),
                                             EXTRACT_32BITS(cp + 4));
                                break;

                        case TCPOPT_SIGNATURE:
                                datalen = TCP_SIGLEN;
                                LENCHECK(datalen);
#ifdef HAVE_LIBCRYPTO
                                switch (tcp_verify_signature(ip, tp,
                                                             bp + TH_OFF(tp) * 4, length, cp)) {

                                case SIGNATURE_VALID:
                                        (void)printf("valid");
                                        break;

                                case SIGNATURE_INVALID:
                                        (void)printf("invalid");
                                        break;

                                case CANT_CHECK_SIGNATURE:
                                        (void)printf("can't check - ");
                                        for (i = 0; i < TCP_SIGLEN; ++i)
                                                (void)printf("%02x", cp[i]);
                                        break;
                                }
#else
                                for (i = 0; i < TCP_SIGLEN; ++i)
                                        (void)printf("%02x", cp[i]);
#endif
                                break;

                        case TCPOPT_AUTH:
                                (void)printf("keyid %d", *cp++);
                                datalen = len - 3;
                                for (i = 0; i < datalen; ++i) {
                                        LENCHECK(i);
                                        (void)printf("%02x", cp[i]);
                                }
                                break;


                        case TCPOPT_EOL:
                        case TCPOPT_NOP:
                        case TCPOPT_SACKOK:
                                /*
                                 * Nothing interesting.
                                 * fall through
                                 */
                                break;

                        case TCPOPT_UTO:
                                datalen = 2;
                                LENCHECK(datalen);
                                utoval = EXTRACT_16BITS(cp);
                                (void)printf("0x%x", utoval);
                                if (utoval & 0x0001)
                                        utoval = (utoval >> 1) * 60;
                                else
                                        utoval >>= 1;
                                (void)printf(" %u", utoval);
                                break;

                        default:
                                datalen = len - 2;
                                for (i = 0; i < datalen; ++i) {
                                        LENCHECK(i);
                                        (void)printf("%02x", cp[i]);
                                }
                                break;
                        }

                        /* Account for data printed */
                        cp += datalen;
                        hlen -= datalen;

                        /* Check specification against observed length */
                        ++datalen;			/* option octet */
                        if (!ZEROLENOPT(opt))
                                ++datalen;		/* size octet */
                        if (datalen != len)
                                (void)printf("[len %d]", len);
                        ch = ',';
                        if (opt == TCPOPT_EOL)
                                break;
                }
                putchar(']');
        }
Exemplo n.º 22
0
static int
ldp_pdu_print(netdissect_options *ndo,
              const u_char *pptr)
{
    const struct ldp_common_header *ldp_com_header;
    const struct ldp_msg_header *ldp_msg_header;
    const u_char *tptr,*msg_tptr;
    u_short tlen;
    u_short pdu_len,msg_len,msg_type,msg_tlen;
    int hexdump,processed;

    ldp_com_header = (const struct ldp_common_header *)pptr;
    ND_TCHECK_SIZE(ldp_com_header);

    /*
     * Sanity checking of the header.
     */
    if (EXTRACT_BE_U_2(ldp_com_header->version) != LDP_VERSION) {
	ND_PRINT("%sLDP version %u packet not supported",
               (ndo->ndo_vflag < 1) ? "" : "\n\t",
               EXTRACT_BE_U_2(ldp_com_header->version));
	return 0;
    }

    pdu_len = EXTRACT_BE_U_2(ldp_com_header->pdu_length);
    if (pdu_len < sizeof(struct ldp_common_header)-4) {
        /* length too short */
        ND_PRINT("%sLDP, pdu-length: %u (too short, < %u)",
               (ndo->ndo_vflag < 1) ? "" : "\n\t",
               pdu_len,
               (u_int)(sizeof(struct ldp_common_header)-4));
        return 0;
    }

    /* print the LSR-ID, label-space & length */
    ND_PRINT("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u",
           (ndo->ndo_vflag < 1) ? "" : "\n\t",
           ipaddr_string(ndo, &ldp_com_header->lsr_id),
           EXTRACT_BE_U_2(ldp_com_header->label_space),
           pdu_len);

    /* bail out if non-verbose */
    if (ndo->ndo_vflag < 1)
        return 0;

    /* ok they seem to want to know everything - lets fully decode it */
    tptr = pptr + sizeof(struct ldp_common_header);
    tlen = pdu_len - (sizeof(struct ldp_common_header)-4);	/* Type & Length fields not included */

    while(tlen>0) {
        /* did we capture enough for fully decoding the msg header ? */
        ND_TCHECK_LEN(tptr, sizeof(struct ldp_msg_header));

        ldp_msg_header = (const struct ldp_msg_header *)tptr;
        msg_len=EXTRACT_BE_U_2(ldp_msg_header->length);
        msg_type=LDP_MASK_MSG_TYPE(EXTRACT_BE_U_2(ldp_msg_header->type));

        if (msg_len < sizeof(struct ldp_msg_header)-4) {
            /* length too short */
            /* FIXME vendor private / experimental check */
            ND_PRINT("\n\t  %s Message (0x%04x), length: %u (too short, < %u)",
                   tok2str(ldp_msg_values,
                           "Unknown",
                           msg_type),
                   msg_type,
                   msg_len,
                   (u_int)(sizeof(struct ldp_msg_header)-4));
            return 0;
        }

        /* FIXME vendor private / experimental check */
        ND_PRINT("\n\t  %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]",
               tok2str(ldp_msg_values,
                       "Unknown",
                       msg_type),
               msg_type,
               msg_len,
               EXTRACT_BE_U_4(ldp_msg_header->id),
               LDP_MASK_U_BIT(EXTRACT_BE_U_2(ldp_msg_header->type)) ? "continue processing" : "ignore");

        msg_tptr=tptr+sizeof(struct ldp_msg_header);
        msg_tlen=msg_len-(sizeof(struct ldp_msg_header)-4); /* Type & Length fields not included */

        /* did we capture enough for fully decoding the message ? */
        ND_TCHECK_LEN(tptr, msg_len);
        hexdump=FALSE;

        switch(msg_type) {

        case LDP_MSG_NOTIF:
        case LDP_MSG_HELLO:
        case LDP_MSG_INIT:
        case LDP_MSG_KEEPALIVE:
        case LDP_MSG_ADDRESS:
        case LDP_MSG_LABEL_MAPPING:
        case LDP_MSG_ADDRESS_WITHDRAW:
        case LDP_MSG_LABEL_WITHDRAW:
            while(msg_tlen >= 4) {
                processed = ldp_tlv_print(ndo, msg_tptr, msg_tlen);
                if (processed == 0)
                    break;
                msg_tlen-=processed;
                msg_tptr+=processed;
            }
            break;

        /*
         *  FIXME those are the defined messages that lack a decoder
         *  you are welcome to contribute code ;-)
         */

        case LDP_MSG_LABEL_REQUEST:
        case LDP_MSG_LABEL_RELEASE:
        case LDP_MSG_LABEL_ABORT_REQUEST:

        default:
            if (ndo->ndo_vflag <= 1)
                print_unknown_data(ndo, msg_tptr, "\n\t  ", msg_tlen);
            break;
        }
        /* do we want to see an additionally hexdump ? */
        if (ndo->ndo_vflag > 1 || hexdump==TRUE)
            print_unknown_data(ndo, tptr+sizeof(struct ldp_msg_header), "\n\t  ",
                               msg_len);

        tptr += msg_len+4;
        tlen -= msg_len+4;
    }
    return pdu_len+4;
trunc:
    ND_PRINT("\n\t\t packet exceeded snapshot");
    return 0;
}
Exemplo n.º 23
0
/* print a reply */
static const u_char *
ns_rprint(register const u_char *cp, register const u_char *bp)
{
	register u_int i;
	register u_short typ, len;
	register const u_char *rp;

	if (vflag) {
		putchar(' ');
		cp = ns_nprint(cp, bp);
	} else
		cp = ns_nskip(cp, bp);

	if (cp + 10 > snapend)
		return (snapend);

	/* print the type/qtype and class (if it's not IN) */
	typ = *cp++ << 8;
	typ |= *cp++;
	i = *cp++ << 8;
	i |= *cp++;
	if (i != C_IN)
		printf(" %s", tok2str(class2str, "(Class %d)", i));

	/* ignore ttl */
	cp += 4;

	len = *cp++ << 8;
	len |= *cp++;

	rp = cp + len;

	printf(" %s", tok2str(type2str, "Type%d", typ));
	switch (typ) {

	case T_A:
		printf(" %s", ipaddr_string(cp));
		break;

	case T_NS:
	case T_CNAME:
	case T_PTR:
		putchar(' ');
		(void)ns_nprint(cp, bp);
		break;

	case T_MX:
		putchar(' ');
		(void)ns_nprint(cp + 2, bp);
		printf(" %d", EXTRACT_16BITS(cp));
		break;

	case T_TXT:
		putchar(' ');
		(void)ns_cprint(cp, bp);
		break;

	case T_UNSPECA:		/* One long string */
	        printf(" %.*s", len, cp);
		break;
	}
	return (rp);		/* XXX This isn't always right */
}
Exemplo n.º 24
0
void
lwapp_control_print(netdissect_options *ndo,
                    const u_char *pptr, u_int len, int has_ap_ident)
{
    const struct lwapp_transport_header *lwapp_trans_header;
    const struct lwapp_control_header *lwapp_control_header;
    const u_char *tptr;
    int  tlen;
    int  msg_tlen;

    tptr=pptr;

    if (has_ap_ident) {
        /* check if enough bytes for AP identity */
        ND_TCHECK2(*tptr, 6);
        lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6);
    } else {
        lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
    }
    ND_TCHECK(*lwapp_trans_header);

    /*
     * Sanity checking of the header.
     */
    if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) {
	ND_PRINT((ndo, "LWAPP version %u packet not supported",
               LWAPP_EXTRACT_VERSION(lwapp_trans_header->version)));
	return;
    }

    /* non-verbose */
    if (ndo->ndo_vflag < 1) {
        ND_PRINT((ndo, "LWAPPv%u, %s frame, Flags [%s], length %u",
               LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
               LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
               bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
               len));
        return;
    }

    /* ok they seem to want to know everything - lets fully decode it */
    tlen=EXTRACT_16BITS(lwapp_trans_header->length);

    ND_PRINT((ndo, "LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u",
           LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
           LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
           LWAPP_EXTRACT_RID(lwapp_trans_header->version),
           bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
	   lwapp_trans_header->frag_id,
	   tlen));

    if (has_ap_ident) {
        ND_PRINT((ndo, "\n\tAP identity: %s", etheraddr_string(ndo, tptr)));
        tptr+=sizeof(const struct lwapp_transport_header)+6;
    } else {
        tptr+=sizeof(const struct lwapp_transport_header);
    }

    while(tlen>0) {

        /* did we capture enough for fully decoding the object header ? */
        ND_TCHECK2(*tptr, sizeof(struct lwapp_control_header));

        lwapp_control_header = (const struct lwapp_control_header *)tptr;
	msg_tlen = EXTRACT_16BITS(lwapp_control_header->len);

	/* print message header */
        ND_PRINT((ndo, "\n\t  Msg type: %s (%u), Seqnum: %u, Msg len: %d, Session: 0x%08x",
               tok2str(lwapp_msg_type_values,"Unknown",lwapp_control_header->msg_type),
               lwapp_control_header->msg_type,
               lwapp_control_header->seq_num,
               msg_tlen,
               EXTRACT_32BITS(lwapp_control_header->session_id)));

        /* did we capture enough for fully decoding the message */
        ND_TCHECK2(*tptr, msg_tlen);

	/* XXX - Decode sub messages for each message */
        switch(lwapp_control_header->msg_type) {
        case LWAPP_MSGTYPE_DISCOVERY_REQUEST:
        case LWAPP_MSGTYPE_DISCOVERY_RESPONSE:
        case LWAPP_MSGTYPE_JOIN_REQUEST:
        case LWAPP_MSGTYPE_JOIN_RESPONSE:
        case LWAPP_MSGTYPE_JOIN_ACK:
        case LWAPP_MSGTYPE_JOIN_CONFIRM:
        case LWAPP_MSGTYPE_CONFIGURE_REQUEST:
        case LWAPP_MSGTYPE_CONFIGURE_RESPONSE:
        case LWAPP_MSGTYPE_CONF_UPDATE_REQUEST:
        case LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE:
        case LWAPP_MSGTYPE_WTP_EVENT_REQUEST:
        case LWAPP_MSGTYPE_WTP_EVENT_RESPONSE:
        case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST:
        case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE:
        case LWAPP_MSGTYPE_ECHO_REQUEST:
        case LWAPP_MSGTYPE_ECHO_RESPONSE:
        case LWAPP_MSGTYPE_IMAGE_DATA_REQUEST:
        case LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE:
        case LWAPP_MSGTYPE_RESET_REQUEST:
        case LWAPP_MSGTYPE_RESET_RESPONSE:
        case LWAPP_MSGTYPE_KEY_UPDATE_REQUEST:
        case LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE:
        case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST:
        case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE:
        case LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST:
        case LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE:
        case LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION:
        case LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST:
        case LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE:
        case LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST:
        case LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE:
        default:
            break;
        }

        tptr += sizeof(struct lwapp_control_header) + msg_tlen;
        tlen -= sizeof(struct lwapp_control_header) + msg_tlen;
    }
    return;

 trunc:
    ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
}
Exemplo n.º 25
0
static void
print_attr_num(netdissect_options *ndo,
               register u_char *data, u_int length, u_short attr_code)
{
   uint32_t timeout;

   if (length != 4)
   {
       ND_PRINT((ndo, "ERROR: length %u != 4", length));
       return;
   }

   ND_TCHECK2(data[0],4);
                          /* This attribute has standard values */
   if (attr_type[attr_code].siz_subtypes)
   {
      static const char **table;
      uint32_t data_value;
      table = attr_type[attr_code].subtypes;

      if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) )
      {
         if (!*data)
            ND_PRINT((ndo, "Tag[Unused] "));
         else
            ND_PRINT((ndo, "Tag[%d] ", *data));
         data++;
         data_value = EXTRACT_24BITS(data);
      }
      else
      {
         data_value = EXTRACT_32BITS(data);
      }
      if ( data_value <= (uint32_t)(attr_type[attr_code].siz_subtypes - 1 +
            attr_type[attr_code].first_subtype) &&
	   data_value >= attr_type[attr_code].first_subtype )
         ND_PRINT((ndo, "%s", table[data_value]));
      else
         ND_PRINT((ndo, "#%u", data_value));
   }
   else
   {
      switch(attr_code) /* Be aware of special cases... */
      {
        case FRM_IPX:
             if (EXTRACT_32BITS( data) == 0xFFFFFFFE )
                ND_PRINT((ndo, "NAS Select"));
             else
                ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
          break;

        case SESSION_TIMEOUT:
        case IDLE_TIMEOUT:
        case ACCT_DELAY:
        case ACCT_SESSION_TIME:
        case ACCT_INT_INTERVAL:
             timeout = EXTRACT_32BITS( data);
             if ( timeout < 60 )
                ND_PRINT((ndo,  "%02d secs", timeout));
             else
             {
                if ( timeout < 3600 )
                   ND_PRINT((ndo,  "%02d:%02d min",
                          timeout / 60, timeout % 60));
                else
                   ND_PRINT((ndo, "%02d:%02d:%02d hours",
                          timeout / 3600, (timeout % 3600) / 60,
                          timeout % 60));
             }
          break;

        case FRM_ATALK_LINK:
             if (EXTRACT_32BITS(data) )
                ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
             else
                ND_PRINT((ndo, "Unnumbered"));
          break;

        case FRM_ATALK_NETWORK:
             if (EXTRACT_32BITS(data) )
                ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
             else
                ND_PRINT((ndo, "NAS assigned"));
          break;

        case TUNNEL_PREFERENCE:
            if (*data)
               ND_PRINT((ndo, "Tag[%d] ", *data));
            else
               ND_PRINT((ndo, "Tag[Unused] "));
            data++;
            ND_PRINT((ndo, "%d", EXTRACT_24BITS(data)));
          break;

        case EGRESS_VLAN_ID:
            ND_PRINT((ndo, "%s (0x%02x) ",
                   tok2str(rfc4675_tagged,"Unknown tag",*data),
                   *data));
            data++;
            ND_PRINT((ndo, "%d", EXTRACT_24BITS(data)));
          break;

        default:
             ND_PRINT((ndo, "%d", EXTRACT_32BITS(data)));
          break;

      } /* switch */

   } /* if-else */

   return;

   trunc:
     ND_PRINT((ndo, "%s", tstr));
}
Exemplo n.º 26
0
void
eigrp_print(register const u_char *pptr, register u_int len) {

    const struct eigrp_common_header *eigrp_com_header;
    const struct eigrp_tlv_header *eigrp_tlv_header;
    const u_char *tptr,*tlv_tptr;
    u_int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen, byte_length, bit_length;
    u_int8_t prefix[4];

    union {
        const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm;
        const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version;
        const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int;
        const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext;
        const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup;
        const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int;
        const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext;
    } tlv_ptr;

    tptr=pptr;
    eigrp_com_header = (const struct eigrp_common_header *)pptr;
    TCHECK(*eigrp_com_header);

    /*
     * Sanity checking of the header.
     */
    if (eigrp_com_header->version != EIGRP_VERSION) {
	printf("EIGRP version %u packet not supported",eigrp_com_header->version);
	return;
    }

    /* in non-verbose mode just lets print the basic Message Type*/
    if (vflag < 1) {
        printf("EIGRP %s, length: %u",
               tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode),
               len);
        return;
    }

    /* ok they seem to want to know everything - lets fully decode it */

    tlen=len-sizeof(struct eigrp_common_header);

    /* FIXME print other header info */
    printf("\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]\n\tseq: 0x%08x, ack: 0x%08x, AS: %u, length: %u",
           eigrp_com_header->version,
           tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode),
           eigrp_com_header->opcode,
           EXTRACT_16BITS(&eigrp_com_header->checksum),
           tok2str(eigrp_common_header_flag_values,
                   "none",
                   EXTRACT_32BITS(&eigrp_com_header->flags)),
           EXTRACT_32BITS(&eigrp_com_header->seq),
           EXTRACT_32BITS(&eigrp_com_header->ack),
           EXTRACT_32BITS(&eigrp_com_header->asn),
           tlen);

    tptr+=sizeof(const struct eigrp_common_header);

    while(tlen>0) {
        /* did we capture enough for fully decoding the object header ? */
        TCHECK2(*tptr, sizeof(struct eigrp_tlv_header));

        eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr;
        eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length);
        eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type);


        if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) ||
            eigrp_tlv_len > tlen) {
            print_unknown_data(tptr+sizeof(sizeof(struct eigrp_tlv_header)),"\n\t    ",tlen);
            return;
        }

        printf("\n\t  %s TLV (0x%04x), length: %u",
               tok2str(eigrp_tlv_values,
                       "Unknown",
                       eigrp_tlv_type),
               eigrp_tlv_type,
               eigrp_tlv_len);

        tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
        tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);

        /* did we capture enough for fully decoding the object ? */
        TCHECK2(*tptr, eigrp_tlv_len);

        switch(eigrp_tlv_type) {

        case EIGRP_TLV_GENERAL_PARM:
            tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;

            printf("\n\t    holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
                   EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime),
                   tlv_ptr.eigrp_tlv_general_parm->k1,
                   tlv_ptr.eigrp_tlv_general_parm->k2,
                   tlv_ptr.eigrp_tlv_general_parm->k3,
                   tlv_ptr.eigrp_tlv_general_parm->k4,
                   tlv_ptr.eigrp_tlv_general_parm->k5);
            break;

        case EIGRP_TLV_SW_VERSION:
            tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;

            printf("\n\t    IOS version: %u.%u, EIGRP version %u.%u",
                   tlv_ptr.eigrp_tlv_sw_version->ios_major,
                   tlv_ptr.eigrp_tlv_sw_version->ios_minor,
                   tlv_ptr.eigrp_tlv_sw_version->eigrp_major,
                   tlv_ptr.eigrp_tlv_sw_version->eigrp_minor);
            break;

        case EIGRP_TLV_IP_INT:
            tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;

            bit_length = tlv_ptr.eigrp_tlv_ip_int->plen;
            if (bit_length > 32) {
                printf("\n\t    illegal prefix length %u",bit_length);
                break;
            }
            byte_length = (bit_length + 7) / 8; /* variable length encoding */
            memset(prefix, 0, 4);
            memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length);

            printf("\n\t    IPv4 prefix: %15s/%u, nexthop: ",
                   ipaddr_string(prefix),
                   bit_length);
            if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0)
                printf("self");
            else
                printf("%s",ipaddr_string(&tlv_ptr.eigrp_tlv_ip_int->nexthop));

            printf("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
                   (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth),
                   EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu),
                   tlv_ptr.eigrp_tlv_ip_int->hopcount,
                   tlv_ptr.eigrp_tlv_ip_int->reliability,
                   tlv_ptr.eigrp_tlv_ip_int->load);
            break;

        case EIGRP_TLV_IP_EXT:
            tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;

            bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen;
            if (bit_length > 32) {
                printf("\n\t    illegal prefix length %u",bit_length);
                break;
            }
            byte_length = (bit_length + 7) / 8; /* variable length encoding */
            memset(prefix, 0, 4);
            memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length);

            printf("\n\t    IPv4 prefix: %15s/%u, nexthop: ",
                   ipaddr_string(prefix),
                   bit_length);
            if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0)
                printf("self");
            else
                printf("%s",ipaddr_string(&tlv_ptr.eigrp_tlv_ip_ext->nexthop));

            printf("\n\t      origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
                   ipaddr_string(tlv_ptr.eigrp_tlv_ip_ext->origin_router),
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as),
                   tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id),
                   tlv_ptr.eigrp_tlv_ip_ext->flags,
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag),
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric));

            printf("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
                   (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth),
                   EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu),
                   tlv_ptr.eigrp_tlv_ip_ext->hopcount,
                   tlv_ptr.eigrp_tlv_ip_ext->reliability,
                   tlv_ptr.eigrp_tlv_ip_ext->load);
            break;

        case EIGRP_TLV_AT_CABLE_SETUP:
            tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;

            printf("\n\t    Cable-range: %u-%u, Router-ID %u",
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id));
            break;

        case EIGRP_TLV_AT_INT:
            tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;

            printf("\n\t     Cable-Range: %u-%u, nexthop: ",
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start),
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end));

            if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0)
                printf("self");
            else
                printf("%u.%u",
                       EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop),
                       EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2]));

            printf("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
                   (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth),
                   EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu),
                   tlv_ptr.eigrp_tlv_at_int->hopcount,
                   tlv_ptr.eigrp_tlv_at_int->reliability,
                   tlv_ptr.eigrp_tlv_at_int->load);
            break;

        case EIGRP_TLV_AT_EXT:
            tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;

            printf("\n\t     Cable-Range: %u-%u, nexthop: ",
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start),
                   EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end));

            if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0)
                printf("self");
            else
                printf("%u.%u",
                       EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop),
                       EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2]));

            printf("\n\t      origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router),
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as),
                   tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id),
                   tlv_ptr.eigrp_tlv_at_ext->flags,
                   EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag),
                   EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric));

            printf("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
                   (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100),
                   EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth),
                   EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu),
                   tlv_ptr.eigrp_tlv_at_ext->hopcount,
                   tlv_ptr.eigrp_tlv_at_ext->reliability,
                   tlv_ptr.eigrp_tlv_at_ext->load);
            break;

            /*
             * FIXME those are the defined TLVs that lack a decoder
             * you are welcome to contribute code ;-)
             */

        case EIGRP_TLV_AUTH:
        case EIGRP_TLV_SEQ:
        case EIGRP_TLV_MCAST_SEQ:
        case EIGRP_TLV_IPX_INT:
        case EIGRP_TLV_IPX_EXT:

        default:
            if (vflag <= 1)
                print_unknown_data(tlv_tptr,"\n\t    ",tlv_tlen);
            break;
        }
        /* do we want to see an additionally hexdump ? */
        if (vflag > 1)
            print_unknown_data(tptr+sizeof(sizeof(struct eigrp_tlv_header)),"\n\t    ",
                               eigrp_tlv_len-sizeof(struct eigrp_tlv_header));

        tptr+=eigrp_tlv_len;
        tlen-=eigrp_tlv_len;
    }
    return;
trunc:
    printf("\n\t\t packet exceeded snapshot");
}
Exemplo n.º 27
0
void
icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented)
{
	char *cp;
	const struct icmp *dp;
        const struct icmp_ext_t *ext_dp;
	const struct ip *ip;
	const char *str, *fmt;
	const struct ip *oip;
	const struct udphdr *ouh;
        const u_int8_t *obj_tptr;
        u_int32_t raw_label;
        const u_char *snapend_save;
	const struct icmp_mpls_ext_object_header_t *icmp_mpls_ext_object_header;
	u_int hlen, dport, mtu, obj_tlen, obj_class_num, obj_ctype;
	char buf[MAXHOSTNAMELEN + 100];
	struct cksum_vec vec[1];

	dp = (struct icmp *)bp;
        ext_dp = (struct icmp_ext_t *)bp;
	ip = (struct ip *)bp2;
	str = buf;

	TCHECK(dp->icmp_code);
	switch (dp->icmp_type) {

	case ICMP_ECHO:
	case ICMP_ECHOREPLY:
		TCHECK(dp->icmp_seq);
		(void)snprintf(buf, sizeof(buf), "echo %s, id %u, seq %u",
                               dp->icmp_type == ICMP_ECHO ?
                               "request" : "reply",
                               EXTRACT_16BITS(&dp->icmp_id),
                               EXTRACT_16BITS(&dp->icmp_seq));
		break;

	case ICMP_UNREACH:
		TCHECK(dp->icmp_ip.ip_dst);
		switch (dp->icmp_code) {

		case ICMP_UNREACH_PROTOCOL:
			TCHECK(dp->icmp_ip.ip_p);
			(void)snprintf(buf, sizeof(buf),
			    "%s protocol %d unreachable",
			    ipaddr_string(&dp->icmp_ip.ip_dst),
			    dp->icmp_ip.ip_p);
			break;

		case ICMP_UNREACH_PORT:
			TCHECK(dp->icmp_ip.ip_p);
			oip = &dp->icmp_ip;
			hlen = IP_HL(oip) * 4;
			ouh = (struct udphdr *)(((u_char *)oip) + hlen);
			TCHECK(ouh->uh_dport);
			dport = EXTRACT_16BITS(&ouh->uh_dport);
			switch (oip->ip_p) {

			case IPPROTO_TCP:
				(void)snprintf(buf, sizeof(buf),
					"%s tcp port %s unreachable",
					ipaddr_string(&oip->ip_dst),
					tcpport_string(dport));
				break;

			case IPPROTO_UDP:
				(void)snprintf(buf, sizeof(buf),
					"%s udp port %s unreachable",
					ipaddr_string(&oip->ip_dst),
					udpport_string(dport));
				break;

			default:
				(void)snprintf(buf, sizeof(buf),
					"%s protocol %d port %d unreachable",
					ipaddr_string(&oip->ip_dst),
					oip->ip_p, dport);
				break;
			}
			break;

		case ICMP_UNREACH_NEEDFRAG:
		    {
			register const struct mtu_discovery *mp;
			mp = (struct mtu_discovery *)(u_char *)&dp->icmp_void;
			mtu = EXTRACT_16BITS(&mp->nexthopmtu);
			if (mtu) {
				(void)snprintf(buf, sizeof(buf),
				    "%s unreachable - need to frag (mtu %d)",
				    ipaddr_string(&dp->icmp_ip.ip_dst), mtu);
			} else {
				(void)snprintf(buf, sizeof(buf),
				    "%s unreachable - need to frag",
				    ipaddr_string(&dp->icmp_ip.ip_dst));
			}
		    }
			break;

		default:
			fmt = tok2str(unreach2str, "#%d %%s unreachable",
			    dp->icmp_code);
			(void)snprintf(buf, sizeof(buf), fmt,
			    ipaddr_string(&dp->icmp_ip.ip_dst));
			break;
		}
		break;

	case ICMP_REDIRECT:
		TCHECK(dp->icmp_ip.ip_dst);
		fmt = tok2str(type2str, "redirect-#%d %%s to net %%s",
		    dp->icmp_code);
		(void)snprintf(buf, sizeof(buf), fmt,
		    ipaddr_string(&dp->icmp_ip.ip_dst),
		    ipaddr_string(&dp->icmp_gwaddr));
		break;

	case ICMP_ROUTERADVERT:
	    {
		register const struct ih_rdiscovery *ihp;
		register const struct id_rdiscovery *idp;
		u_int lifetime, num, size;

		(void)snprintf(buf, sizeof(buf), "router advertisement");
		cp = buf + strlen(buf);

		ihp = (struct ih_rdiscovery *)&dp->icmp_void;
		TCHECK(*ihp);
		(void)strncpy(cp, " lifetime ", sizeof(buf) - (cp - buf));
		cp = buf + strlen(buf);
		lifetime = EXTRACT_16BITS(&ihp->ird_lifetime);
		if (lifetime < 60) {
			(void)snprintf(cp, sizeof(buf) - (cp - buf), "%u",
			    lifetime);
		} else if (lifetime < 60 * 60) {
			(void)snprintf(cp, sizeof(buf) - (cp - buf), "%u:%02u",
			    lifetime / 60, lifetime % 60);
		} else {
			(void)snprintf(cp, sizeof(buf) - (cp - buf),
			    "%u:%02u:%02u",
			    lifetime / 3600,
			    (lifetime % 3600) / 60,
			    lifetime % 60);
		}
		cp = buf + strlen(buf);

		num = ihp->ird_addrnum;
		(void)snprintf(cp, sizeof(buf) - (cp - buf), " %d:", num);
		cp = buf + strlen(buf);

		size = ihp->ird_addrsiz;
		if (size != 2) {
			(void)snprintf(cp, sizeof(buf) - (cp - buf),
			    " [size %d]", size);
			break;
		}
		idp = (struct id_rdiscovery *)&dp->icmp_data;
		while (num-- > 0) {
			TCHECK(*idp);
			(void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}",
			    ipaddr_string(&idp->ird_addr),
			    EXTRACT_32BITS(&idp->ird_pref));
			cp = buf + strlen(buf);
			++idp;
		}
	    }
		break;

	case ICMP_TIMXCEED:
		TCHECK(dp->icmp_ip.ip_dst);
		switch (dp->icmp_code) {

		case ICMP_TIMXCEED_INTRANS:
			str = "time exceeded in-transit";
			break;

		case ICMP_TIMXCEED_REASS:
			str = "ip reassembly time exceeded";
			break;

		default:
			(void)snprintf(buf, sizeof(buf), "time exceeded-#%d",
			    dp->icmp_code);
			break;
		}
		break;

	case ICMP_PARAMPROB:
		if (dp->icmp_code)
			(void)snprintf(buf, sizeof(buf),
			    "parameter problem - code %d", dp->icmp_code);
		else {
			TCHECK(dp->icmp_pptr);
			(void)snprintf(buf, sizeof(buf),
			    "parameter problem - octet %d", dp->icmp_pptr);
		}
		break;

	case ICMP_MASKREPLY:
		TCHECK(dp->icmp_mask);
		(void)snprintf(buf, sizeof(buf), "address mask is 0x%08x",
		    EXTRACT_32BITS(&dp->icmp_mask));
		break;

	case ICMP_TSTAMP:
		TCHECK(dp->icmp_seq);
		(void)snprintf(buf, sizeof(buf),
		    "time stamp query id %u seq %u",
		    EXTRACT_16BITS(&dp->icmp_id),
		    EXTRACT_16BITS(&dp->icmp_seq));
		break;

	case ICMP_TSTAMPREPLY:
		TCHECK(dp->icmp_ttime);
		(void)snprintf(buf, sizeof(buf),
		    "time stamp reply id %u seq %u: org %s",
                               EXTRACT_16BITS(&dp->icmp_id),
                               EXTRACT_16BITS(&dp->icmp_seq),
                               icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_otime)));

                (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", recv %s",
                         icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_rtime)));
                (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", xmit %s",
                         icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_ttime)));
                break;

	default:
		str = tok2str(icmp2str, "type-#%d", dp->icmp_type);
		break;
	}
	(void)printf("ICMP %s, length %u", str, plen);
	if (vflag && !fragmented) { /* don't attempt checksumming if this is a frag */
		u_int16_t sum, icmp_sum;
		struct cksum_vec vec[1];
		if (TTEST2(*bp, plen)) {
			vec[0].ptr = (const u_int8_t *)(void *)dp;
			vec[0].len = plen;
			sum = in_cksum(vec, 1);
			if (sum != 0) {
				icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum);
				(void)printf(" (wrong icmp cksum %x (->%x)!)",
					     icmp_sum,
					     in_cksum_shouldbe(icmp_sum, sum));
			}
		}
	}

        /*
         * print the remnants of the IP packet.
         * save the snaplength as this may get overidden in the IP printer.
         */
	if (vflag >= 1 && !ICMP_INFOTYPE(dp->icmp_type)) {
		bp += 8;
		(void)printf("\n\t");
		ip = (struct ip *)bp;
		snaplen = snapend - bp;
                snapend_save = snapend;
		ip_print(gndo, bp, EXTRACT_16BITS(&ip->ip_len));
                snapend = snapend_save;
	}

        /*
         * Attempt to decode the MPLS extensions only for some ICMP types.
         */
        if (vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) {

            TCHECK(*ext_dp);

            /*
             * Check first if the mpls extension header shows a non-zero length.
             * If the length field is not set then silently verify the checksum
             * to check if an extension header is present. This is expedient,
             * however not all implementations set the length field proper.
             */
            if (!ext_dp->icmp_length) {
                vec[0].ptr = (const u_int8_t *)(void *)&ext_dp->icmp_ext_version_res;
                vec[0].len = plen - ICMP_EXTD_MINLEN;
                if (in_cksum(vec, 1)) {
                    return;
                }
            }

            printf("\n\tMPLS extension v%u",
                   ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)));
            
            /*
             * Sanity checking of the header.
             */
            if (ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)) !=
                ICMP_MPLS_EXT_VERSION) {
                printf(" packet not supported");
                return;
            }

            hlen = plen - ICMP_EXTD_MINLEN;
            vec[0].ptr = (const u_int8_t *)(void *)&ext_dp->icmp_ext_version_res;
            vec[0].len = hlen;
            printf(", checksum 0x%04x (%scorrect), length %u",
                   EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
                   in_cksum(vec, 1) ? "in" : "",
                   hlen);

            hlen -= 4; /* subtract common header size */
            obj_tptr = (u_int8_t *)ext_dp->icmp_ext_data;

            while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) {

                icmp_mpls_ext_object_header = (struct icmp_mpls_ext_object_header_t *)obj_tptr;
                TCHECK(*icmp_mpls_ext_object_header);
                obj_tlen = EXTRACT_16BITS(icmp_mpls_ext_object_header->length);
                obj_class_num = icmp_mpls_ext_object_header->class_num;
                obj_ctype = icmp_mpls_ext_object_header->ctype;
                obj_tptr += sizeof(struct icmp_mpls_ext_object_header_t);

                printf("\n\t  %s Object (%u), Class-Type: %u, length %u",
                       tok2str(icmp_mpls_ext_obj_values,"unknown",obj_class_num),
                       obj_class_num,
                       obj_ctype,
                       obj_tlen);

                hlen-=sizeof(struct icmp_mpls_ext_object_header_t); /* length field includes tlv header */

                /* infinite loop protection */                
                if ((obj_class_num == 0) ||
                    (obj_tlen < sizeof(struct icmp_mpls_ext_object_header_t))) {
                    return;
                }
                obj_tlen-=sizeof(struct icmp_mpls_ext_object_header_t);

                switch (obj_class_num) {
                case 1:
                    switch(obj_ctype) {
                    case 1:
                        TCHECK2(*obj_tptr, 4);
                        raw_label = EXTRACT_32BITS(obj_tptr);
                        printf("\n\t    label %u, exp %u", MPLS_LABEL(raw_label), MPLS_EXP(raw_label));
                        if (MPLS_STACK(raw_label))
                            printf(", [S]");
                        printf(", ttl %u", MPLS_TTL(raw_label));
                        break;
                    default:
                        print_unknown_data(obj_tptr, "\n\t    ", obj_tlen);
                    }
                    break;

               /*
                *  FIXME those are the defined objects that lack a decoder
                *  you are welcome to contribute code ;-)
                */
                case 2:
                default:
                    print_unknown_data(obj_tptr, "\n\t    ", obj_tlen);
                    break;
                }
                if (hlen < obj_tlen)
                    break;
                hlen -= obj_tlen;
                obj_tptr += obj_tlen;
            }
        }

	return;
trunc:
	fputs("[|icmp]", stdout);
}
Exemplo n.º 28
0
static int
stp_print_mstp_bpdu(netdissect_options *ndo, const struct stp_bpdu_ *stp_bpdu,
                    u_int length)
{
    const u_char *ptr;
    uint8_t	    bpdu_flags;
    uint16_t	    v3len;
    uint16_t	    len;
    uint16_t	    msti;
    u_int	    offset;

    ptr = (const u_char *)stp_bpdu;
    ND_TCHECK_1(stp_bpdu->flags);
    bpdu_flags = EXTRACT_U_1(stp_bpdu->flags);
    ND_PRINT(", CIST Flags [%s], length %u",
           bittok2str(stp_bpdu_flag_values, "none", bpdu_flags), length);

    /*
     * in non-verbose mode just print the flags.
     */
    if (!ndo->ndo_vflag) {
        return 1;
    }

    ND_PRINT("\n\tport-role %s, ",
           tok2str(rstp_obj_port_role_values, "Unknown",
                   RSTP_EXTRACT_PORT_ROLE(bpdu_flags)));

    ND_TCHECK_4(stp_bpdu->root_path_cost);
    ND_PRINT("CIST root-id %s, CIST ext-pathcost %u",
           stp_print_bridge_id((const u_char *)&stp_bpdu->root_id),
           EXTRACT_BE_U_4(stp_bpdu->root_path_cost));

    ND_TCHECK_SIZE(&stp_bpdu->bridge_id);
    ND_PRINT("\n\tCIST regional-root-id %s, ",
           stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id));

    ND_TCHECK_2(stp_bpdu->port_id);
    ND_PRINT("CIST port-id %04x,", EXTRACT_BE_U_2(stp_bpdu->port_id));

    ND_TCHECK_2(stp_bpdu->forward_delay);
    ND_PRINT("\n\tmessage-age %.2fs, max-age %.2fs"
           ", hello-time %.2fs, forwarding-delay %.2fs",
           (float) EXTRACT_BE_U_2(stp_bpdu->message_age) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->max_age) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->hello_time) / STP_TIME_BASE,
           (float) EXTRACT_BE_U_2(stp_bpdu->forward_delay) / STP_TIME_BASE);

    ND_TCHECK_2(ptr + MST_BPDU_VER3_LEN_OFFSET);
    ND_PRINT("\n\tv3len %u, ", EXTRACT_BE_U_2(ptr + MST_BPDU_VER3_LEN_OFFSET));
    ND_TCHECK_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12);
    ND_PRINT("MCID Name ");
    if (fn_printzp(ndo, ptr + MST_BPDU_CONFIG_NAME_OFFSET, 32, ndo->ndo_snapend))
	goto trunc;
    ND_PRINT(", rev %u,"
            "\n\t\tdigest %08x%08x%08x%08x, ",
	          EXTRACT_BE_U_2(ptr + MST_BPDU_CONFIG_NAME_OFFSET + 32),
	          EXTRACT_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET),
	          EXTRACT_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 4),
	          EXTRACT_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 8),
	          EXTRACT_BE_U_4(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12));

    ND_TCHECK_4(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET);
    ND_PRINT("CIST int-root-pathcost %u,",
            EXTRACT_BE_U_4(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET));

    ND_TCHECK_BRIDGE_ID(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET);
    ND_PRINT("\n\tCIST bridge-id %s, ",
           stp_print_bridge_id(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET));

    ND_TCHECK_1(ptr + MST_BPDU_CIST_REMAIN_HOPS_OFFSET);
    ND_PRINT("CIST remaining-hops %u", EXTRACT_U_1(ptr + MST_BPDU_CIST_REMAIN_HOPS_OFFSET));

    /* Dump all MSTI's */
    ND_TCHECK_2(ptr + MST_BPDU_VER3_LEN_OFFSET);
    v3len = EXTRACT_BE_U_2(ptr + MST_BPDU_VER3_LEN_OFFSET);
    if (v3len > MST_BPDU_CONFIG_INFO_LENGTH) {
        len = v3len - MST_BPDU_CONFIG_INFO_LENGTH;
        offset = MST_BPDU_MSTI_OFFSET;
        while (len >= MST_BPDU_MSTI_LENGTH) {
            ND_TCHECK_LEN(ptr + offset, MST_BPDU_MSTI_LENGTH);

            msti = EXTRACT_BE_U_2(ptr + offset + MST_BPDU_MSTI_ROOT_PRIO_OFFSET);
            msti = msti & 0x0FFF;

            ND_PRINT("\n\tMSTI %u, Flags [%s], port-role %s",
                   msti, bittok2str(stp_bpdu_flag_values, "none", EXTRACT_U_1(ptr + offset)),
                   tok2str(rstp_obj_port_role_values, "Unknown",
                           RSTP_EXTRACT_PORT_ROLE(EXTRACT_U_1(ptr + offset))));
            ND_PRINT("\n\t\tMSTI regional-root-id %s, pathcost %u",
                   stp_print_bridge_id(ptr + offset +
                                       MST_BPDU_MSTI_ROOT_PRIO_OFFSET),
                   EXTRACT_BE_U_4(ptr + offset + MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET));
            ND_PRINT("\n\t\tMSTI bridge-prio %u, port-prio %u, hops %u",
                   EXTRACT_U_1(ptr + offset + MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET) >> 4,
                   EXTRACT_U_1(ptr + offset + MST_BPDU_MSTI_PORT_PRIO_OFFSET) >> 4,
                   EXTRACT_U_1(ptr + offset + MST_BPDU_MSTI_REMAIN_HOPS_OFFSET));

            len -= MST_BPDU_MSTI_LENGTH;
            offset += MST_BPDU_MSTI_LENGTH;
        }
    }
Exemplo n.º 29
0
void
geneve_print(netdissect_options *ndo, const u_char *bp, u_int len)
{
    uint8_t ver_opt;
    u_int version;
    uint8_t flags;
    uint16_t prot;
    uint32_t vni;
    uint8_t reserved;
    u_int opts_len;

    ND_PRINT((ndo, "Geneve"));

    ND_TCHECK2(*bp, 8);

    ver_opt = *bp;
    bp += 1;
    len -= 1;

    version = ver_opt >> VER_SHIFT;
    if (version != 0) {
        ND_PRINT((ndo, " ERROR: unknown-version %u", version));
        return;
    }

    flags = *bp;
    bp += 1;
    len -= 1;

    prot = EXTRACT_16BITS(bp);
    bp += 2;
    len -= 2;

    vni = EXTRACT_24BITS(bp);
    bp += 3;
    len -= 3;

    reserved = *bp;
    bp += 1;
    len -= 1;

    ND_PRINT((ndo, ", Flags [%s]",
              bittok2str_nosep(geneve_flag_values, "none", flags)));
    ND_PRINT((ndo, ", vni 0x%x", vni));

    if (reserved)
        ND_PRINT((ndo, ", rsvd 0x%x", reserved));

    if (ndo->ndo_eflag)
        ND_PRINT((ndo, ", proto %s (0x%04x)",
                  tok2str(ethertype_values, "unknown", prot), prot));

    opts_len = (ver_opt & HDR_OPTS_LEN_MASK) * 4;

    if (len < opts_len) {
        ND_PRINT((ndo, " truncated-geneve - %u bytes missing",
                  opts_len - len));
        return;
    }

    ND_TCHECK2(*bp, opts_len);

    if (opts_len > 0) {
        ND_PRINT((ndo, ", options ["));

        if (ndo->ndo_vflag)
            geneve_opts_print(ndo, bp, opts_len);
        else
            ND_PRINT((ndo, "%u bytes", opts_len));

        ND_PRINT((ndo, "]"));
    }

    bp += opts_len;
    len -= opts_len;

    if (ndo->ndo_vflag < 1)
        ND_PRINT((ndo, ": "));
    else
        ND_PRINT((ndo, "\n\t"));

    if (ethertype_print(ndo, prot, bp, len, len) == 0) {
        if (prot == ETHERTYPE_TEB)
            ether_print(ndo, bp, len, len, NULL, NULL);
        else
            ND_PRINT((ndo, "geneve-proto-0x%x", prot));
    }

    return;

trunc:
    ND_PRINT((ndo, " [|geneve]"));
}
Exemplo n.º 30
0
void
vrrp_print(netdissect_options *ndo,
           register const u_char *bp, register u_int len,
           register const u_char *bp2, int ttl)
{
	int version, type, auth_type = VRRP_AUTH_NONE; /* keep compiler happy */
	const char *type_s;

	ND_TCHECK(bp[0]);
	version = (bp[0] & 0xf0) >> 4;
	type = bp[0] & 0x0f;
	type_s = tok2str(type2str, "unknown type (%u)", type);
	ND_PRINT((ndo, "VRRPv%u, %s", version, type_s));
	if (ttl != 255)
		ND_PRINT((ndo, ", (ttl %u)", ttl));
	if (version < 2 || version > 3 || type != VRRP_TYPE_ADVERTISEMENT)
		return;
	ND_TCHECK(bp[2]);
	ND_PRINT((ndo, ", vrid %u, prio %u", bp[1], bp[2]));
	ND_TCHECK(bp[5]);

	if (version == 2) {
		auth_type = bp[4];
		ND_PRINT((ndo, ", authtype %s", tok2str(auth2str, NULL, auth_type)));
		ND_PRINT((ndo, ", intvl %us, length %u", bp[5], len));
	} else { /* version == 3 */
		uint16_t intvl = (bp[4] & 0x0f) << 8 | bp[5];
		ND_PRINT((ndo, ", intvl %ucs, length %u", intvl, len));
	}

	if (ndo->ndo_vflag) {
		int naddrs = bp[3];
		int i;
		char c;

		if (version == 2 && ND_TTEST2(bp[0], len)) {
			struct cksum_vec vec[1];

			vec[0].ptr = bp;
			vec[0].len = len;
			if (in_cksum(vec, 1))
				ND_PRINT((ndo, ", (bad vrrp cksum %x)",
					EXTRACT_16BITS(&bp[6])));
		}

		if (version == 3 && ND_TTEST2(bp[0], len)) {
			uint16_t cksum = nextproto4_cksum(ndo, (const struct ip *)bp2, bp,
				len, len, IPPROTO_VRRP);
			if (cksum)
				ND_PRINT((ndo, ", (bad vrrp cksum %x)",
					EXTRACT_16BITS(&bp[6])));
		}

		ND_PRINT((ndo, ", addrs"));
		if (naddrs > 1)
			ND_PRINT((ndo, "(%d)", naddrs));
		ND_PRINT((ndo, ":"));
		c = ' ';
		bp += 8;
		for (i = 0; i < naddrs; i++) {
			ND_TCHECK(bp[3]);
			ND_PRINT((ndo, "%c%s", c, ipaddr_string(ndo, bp)));
			c = ',';
			bp += 4;
		}
		if (version == 2 && auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */
			ND_TCHECK(bp[7]);
			ND_PRINT((ndo, " auth \""));
			if (fn_printn(ndo, bp, 8, ndo->ndo_snapend)) {
				ND_PRINT((ndo, "\""));
				goto trunc;
			}
			ND_PRINT((ndo, "\""));
		}
	}
	return;
trunc:
	ND_PRINT((ndo, "[|vrrp]"));
}