コード例 #1
0
/*
 * Print ntp requests
 */
void
ntp_print(register const u_char *cp, u_int length)
{
	register const struct ntpdata *bp;
	int mode, version, leapind;

	bp = (struct ntpdata *)cp;

	TCHECK(bp->status);

	version = (int)(bp->status & VERSIONMASK) >> 3;
	printf("NTPv%d", version);

	mode = bp->status & MODEMASK;
        if (!vflag) {
            printf (", %s, length %u",
                    tok2str(ntp_mode_values, "Unknown mode", mode),
                    length);
            return;
        }
        
        printf (", length %u\n\t%s",
                length,
                tok2str(ntp_mode_values, "Unknown mode", mode));        

	leapind = bp->status & LEAPMASK;
        printf (", Leap indicator: %s (%u)",
                tok2str(ntp_leapind_values, "Unknown", leapind),
                leapind);

	TCHECK(bp->stratum);
	printf(", Stratum %u (%s)", 	
		bp->stratum,
		tok2str(ntp_stratum_values, (bp->stratum >=2 && bp->stratum<=15) ? "secondary reference" : "reserved", bp->stratum));

	TCHECK(bp->ppoll);
	printf(", poll %u (%us)", bp->ppoll, 1 << bp->ppoll);

	/* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */
	TCHECK2(bp->root_delay, 0);
	printf(", precision %d", bp->precision);

	TCHECK(bp->root_delay);
	fputs("\n\tRoot Delay: ", stdout);
	p_sfix(&bp->root_delay);

	TCHECK(bp->root_dispersion);
	fputs(", Root dispersion: ", stdout);
	p_sfix(&bp->root_dispersion);

	TCHECK(bp->refid);
	fputs(", Reference-ID: ", stdout);
	/* Interpretation depends on stratum */
	switch (bp->stratum) {

	case UNSPECIFIED:
		printf("(unspec)");
		break;

	case PRIM_REF:
		if (fn_printn((u_char *)&(bp->refid), 4, snapend))
			goto trunc;
		break;

	case INFO_QUERY:
		printf("%s INFO_QUERY", ipaddr_string(&(bp->refid)));
		/* this doesn't have more content */
		return;

	case INFO_REPLY:
		printf("%s INFO_REPLY", ipaddr_string(&(bp->refid)));
		/* this is too complex to be worth printing */
		return;

	default:
		printf("%s", ipaddr_string(&(bp->refid)));
		break;
	}

	TCHECK(bp->ref_timestamp);
	fputs("\n\t  Reference Timestamp:  ", stdout);
	p_ntp_time(&(bp->ref_timestamp));

	TCHECK(bp->org_timestamp);
	fputs("\n\t  Originator Timestamp: ", stdout);
	p_ntp_time(&(bp->org_timestamp));

	TCHECK(bp->rec_timestamp);
	fputs("\n\t  Receive Timestamp:    ", stdout);
	p_ntp_time(&(bp->rec_timestamp));

	TCHECK(bp->xmt_timestamp);
	fputs("\n\t  Transmit Timestamp:   ", stdout);
	p_ntp_time(&(bp->xmt_timestamp));

	fputs("\n\t    Originator - Receive Timestamp:  ", stdout);
	p_ntp_delta(&(bp->org_timestamp), &(bp->rec_timestamp));

	fputs("\n\t    Originator - Transmit Timestamp: ", stdout);
	p_ntp_delta(&(bp->org_timestamp), &(bp->xmt_timestamp));

	if ( (sizeof(struct ntpdata) - length) == 16) { 	/* Optional: key-id */
		TCHECK(bp->key_id);
		printf("\n\tKey id: %u", bp->key_id);
	} else if ( (sizeof(struct ntpdata) - length) == 0) { 	/* Optional: key-id + authentication */
		TCHECK(bp->key_id);
		printf("\n\tKey id: %u", bp->key_id);
		TCHECK2(bp->message_digest, sizeof (bp->message_digest));
                printf("\n\tAuthentication: %08x%08x%08x%08x",
        		       EXTRACT_32BITS(bp->message_digest),
		               EXTRACT_32BITS(bp->message_digest + 4),
		               EXTRACT_32BITS(bp->message_digest + 8),
		               EXTRACT_32BITS(bp->message_digest + 12));
        }
	return;

trunc:
	fputs(" [|ntp]", stdout);
}
コード例 #2
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(']');
        }
コード例 #3
0
static void
ospf_print_ls_type(register u_int ls_type,
    register const struct in_addr *ls_stateid,
    register const struct in_addr *ls_router, register const char *fmt)
{

	switch (ls_type) {

	case LS_TYPE_ROUTER:
		printf(" rtr %s ", ipaddr_string(ls_router));
		break;

	case LS_TYPE_NETWORK:
		printf(" net dr %s if %s",
		    ipaddr_string(ls_router),
		    ipaddr_string(ls_stateid));
		break;

	case LS_TYPE_SUM_IP:
		printf(" sum %s abr %s",
		    ipaddr_string(ls_stateid),
		    ipaddr_string(ls_router));
		break;

	case LS_TYPE_SUM_ABR:
		printf(" abr %s rtr %s",
		    ipaddr_string(ls_router),
		    ipaddr_string(ls_stateid));
		break;

	case LS_TYPE_ASE:
		printf(" ase %s asbr %s",
		    ipaddr_string(ls_stateid),
		    ipaddr_string(ls_router));
		break;

	case LS_TYPE_GROUP:
		printf(" group %s rtr %s",
		    ipaddr_string(ls_stateid),
		    ipaddr_string(ls_router));
		break;

	default:
		putchar(' ');
		printf(fmt, ls_type);
		break;
	}
}
コード例 #4
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");
}
コード例 #5
0
ファイル: print-msdp.c プロジェクト: deval-maker/rtems-libbsd
void
msdp_print(const unsigned char *sp, u_int length)
{
	unsigned int type, len;

	TCHECK2(*sp, 3);
	/* See if we think we're at the beginning of a compound packet */
	type = *sp;
	len = EXTRACT_16BITS(sp + 1);
	if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX)
		goto trunc;	/* not really truncated, but still not decodable */
	(void)printf(" msdp:");
	while (length > 0) {
		TCHECK2(*sp, 3);
		type = *sp;
		len = EXTRACT_16BITS(sp + 1);
		if (len > 1400 || vflag)
			printf(" [len %u]", len);
		if (len < 3)
			goto trunc;
		sp += 3;
		length -= 3;
		switch (type) {
		case 1:	/* IPv4 Source-Active */
		case 3: /* IPv4 Source-Active Response */
			if (type == 1)
				(void)printf(" SA");
			else
				(void)printf(" SA-Response");
			TCHECK(*sp);
			(void)printf(" %u entries", *sp);
			if ((u_int)((*sp * 12) + 8) < len) {
				(void)printf(" [w/data]");
				if (vflag > 1) {
					(void)printf(" ");
					ip_print(gndo, sp + *sp * 12 + 8 - 3,
					         len - (*sp * 12 + 8));
				}
			}
			break;
		case 2:
			(void)printf(" SA-Request");
			TCHECK2(*sp, 5);
			(void)printf(" for %s", ipaddr_string(sp + 1));
			break;
		case 4:
			(void)printf(" Keepalive");
			if (len != 3)
				(void)printf("[len=%d] ", len);
			break;
		case 5:
			(void)printf(" Notification");
			break;
		default:
			(void)printf(" [type=%d len=%d]", type, len);
			break;
		}
		sp += (len - 3);
		length -= (len - 3);
	}
	return;
trunc:
	(void)printf(" [|msdp]");
}
コード例 #6
0
ファイル: print-arp.c プロジェクト: deval-maker/rtems-libbsd
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]"));
}
コード例 #7
0
ファイル: print-ldp.c プロジェクト: lampmanyao/tcpdump
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 */
}
コード例 #8
0
ファイル: print-ospf6.c プロジェクト: enukane/netbsd-src
/*
 * Print a single link state advertisement.  If truncated return 1, else 0.
 */
static int
ospf6_print_lsa(register const struct lsa6 *lsap)
{
	register const struct rlalink6 *rlp;
#if 0
	register const struct tos_metric *tosp;
#endif
	register const rtrid_t *ap;
#if 0
	register const struct aslametric *almp;
	register const struct mcla *mcp;
#endif
	register const struct llsa *llsap;
	register const struct lsa6_prefix *lsapp;
#if 0
	register const u_int32_t *lp;
#endif
	register u_int prefixes;
	register int bytelen;
	register u_int length, lsa_length;
	u_int32_t flags32;
	const u_int8_t *tptr;

	if (ospf6_print_lshdr(&lsap->ls_hdr))
		return (1);
	TCHECK(lsap->ls_hdr.ls_length);
        length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length);

	/*
	 * The LSA length includes the length of the header;
	 * it must have a value that's at least that length.
	 * If it does, find the length of what follows the
	 * header.
	 */
        if (length < sizeof(struct lsa6_hdr))
        	return (1);
        lsa_length = length - sizeof(struct lsa6_hdr);
        tptr = (u_int8_t *)lsap+sizeof(struct lsa6_hdr);

	switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) {
	case LS_TYPE_ROUTER | LS_SCOPE_AREA:
		if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options))
			return (1);
		lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options);
		TCHECK(lsap->lsa_un.un_rla.rla_options);
                printf("\n\t      Options [%s]",
                       bittok2str(ospf6_option_values, "none",
                                  EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options)));
                printf(", RLA-Flags [%s]",
                       bittok2str(ospf6_rla_flag_values, "none",
                                  lsap->lsa_un.un_rla.rla_flags));

		rlp = lsap->lsa_un.un_rla.rla_link;
		while (lsa_length != 0) {
			if (lsa_length < sizeof (*rlp))
				return (1);
			lsa_length -= sizeof (*rlp);
			TCHECK(*rlp);
			switch (rlp->link_type) {

			case RLA_TYPE_VIRTUAL:
				printf("\n\t      Virtual Link: Neighbor Router-ID %s"
                                       "\n\t      Neighbor Interface-ID %s, Interface %s",
                                       ipaddr_string(&rlp->link_nrtid),
                                       ipaddr_string(&rlp->link_nifid),
                                       ipaddr_string(&rlp->link_ifid)); 
                                break;

			case RLA_TYPE_ROUTER:
				printf("\n\t      Neighbor Router-ID %s"
                                       "\n\t      Neighbor Interface-ID %s, Interface %s",
                                       ipaddr_string(&rlp->link_nrtid),
                                       ipaddr_string(&rlp->link_nifid),
                                       ipaddr_string(&rlp->link_ifid)); 
				break;

			case RLA_TYPE_TRANSIT:
				printf("\n\t      Neighbor Network-ID %s"
                                       "\n\t      Neighbor Interface-ID %s, Interface %s",
				    ipaddr_string(&rlp->link_nrtid),
				    ipaddr_string(&rlp->link_nifid),
				    ipaddr_string(&rlp->link_ifid));
				break;

			default:
				printf("\n\t      Unknown Router Links Type 0x%02x",
				    rlp->link_type);
				return (0);
			}
			printf(", metric %d", EXTRACT_16BITS(&rlp->link_metric));
			rlp++;
		}
		break;

	case LS_TYPE_NETWORK | LS_SCOPE_AREA:
		if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options))
			return (1);
		lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options);
		TCHECK(lsap->lsa_un.un_nla.nla_options);
                printf("\n\t      Options [%s]",
                       bittok2str(ospf6_option_values, "none",
                                  EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options)));

		printf("\n\t      Connected Routers:");
		ap = lsap->lsa_un.un_nla.nla_router;
		while (lsa_length != 0) {
			if (lsa_length < sizeof (*ap))
				return (1);
			lsa_length -= sizeof (*ap);
			TCHECK(*ap);
			printf("\n\t\t%s", ipaddr_string(ap));
			++ap;
		}
		break;

	case LS_TYPE_INTER_AP | LS_SCOPE_AREA:
		if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric))
			return (1);
		lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric);
		TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric);
		printf(", metric %u",
			EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC);

		tptr = (u_int8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix;
		while (lsa_length != 0) {
			bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
			if (bytelen < 0)
				goto trunc;
			lsa_length -= bytelen;
			tptr += bytelen;
		}
		break;

	case LS_TYPE_ASE | LS_SCOPE_AS:
		if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric))
			return (1);
		lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric);
		TCHECK(lsap->lsa_un.un_asla.asla_metric);
		flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric);
                printf("\n\t     Flags [%s]",
                       bittok2str(ospf6_asla_flag_values, "none", flags32));
		printf(" metric %u",
		       EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) &
		       ASLA_MASK_METRIC);

		tptr = (u_int8_t *)lsap->lsa_un.un_asla.asla_prefix;
		lsapp = (struct lsa6_prefix *)tptr;
		bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
		if (bytelen < 0)
			goto trunc;
		lsa_length -= bytelen;
		tptr += bytelen;

		if ((flags32 & ASLA_FLAG_FWDADDR) != 0) {
			struct in6_addr *fwdaddr6;

			fwdaddr6 = (struct in6_addr *)tptr;
			if (lsa_length < sizeof (*fwdaddr6))
				return (1);
			lsa_length -= sizeof (*fwdaddr6);
			TCHECK(*fwdaddr6);
			printf(" forward %s",
			       ip6addr_string(fwdaddr6));
			tptr += sizeof(*fwdaddr6);
		}

		if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) {
			if (lsa_length < sizeof (u_int32_t))
				return (1);
			lsa_length -= sizeof (u_int32_t);
			TCHECK(*(u_int32_t *)tptr);
			printf(" tag %s",
			       ipaddr_string((u_int32_t *)tptr));
			tptr += sizeof(u_int32_t);
		}

		if (lsapp->lsa_p_metric) {
			if (lsa_length < sizeof (u_int32_t))
				return (1);
			lsa_length -= sizeof (u_int32_t);
			TCHECK(*(u_int32_t *)tptr);
			printf(" RefLSID: %s",
			       ipaddr_string((u_int32_t *)tptr));
			tptr += sizeof(u_int32_t);
		}
		break;

	case LS_TYPE_LINK:
		/* Link LSA */
		llsap = &lsap->lsa_un.un_llsa;
		if (lsa_length < sizeof (llsap->llsa_priandopt))
			return (1);
		lsa_length -= sizeof (llsap->llsa_priandopt);
		TCHECK(llsap->llsa_priandopt);
                printf("\n\t      Options [%s]",
                       bittok2str(ospf6_option_values, "none",
                                  EXTRACT_32BITS(&llsap->llsa_options)));

		if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix))
			return (1);
		lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix);
                prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix);
		printf("\n\t      Priority %d, Link-local address %s, Prefixes %d:",
                       llsap->llsa_priority,
                       ip6addr_string(&llsap->llsa_lladdr),
                       prefixes);

		tptr = (u_int8_t *)llsap->llsa_prefix;
		while (prefixes > 0) {
			bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
			if (bytelen < 0)
				goto trunc;
			prefixes--;
			lsa_length -= bytelen;
			tptr += bytelen;
		}
		break;

	case LS_TYPE_INTRA_AP | LS_SCOPE_AREA:
		/* Intra-Area-Prefix LSA */
		if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid))
			return (1);
		lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid);
		TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid);
		ospf6_print_ls_type(
			EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype),
			&lsap->lsa_un.un_intra_ap.intra_ap_lsid);

		if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix))
			return (1);
		lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
		TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
                prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
		printf("\n\t      Prefixes %d:", prefixes);

		tptr = (u_int8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix;
		while (prefixes > 0) {
			bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
			if (bytelen < 0)
				goto trunc;
			prefixes--;
			lsa_length -= bytelen;
			tptr += bytelen;
		}
		break;

        case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL:
                if (ospf_print_grace_lsa(tptr, lsa_length) == -1) {
                    return 1;
                }
                break;

        case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL:
                if (ospf_print_te_lsa(tptr, lsa_length) == -1) {
                    return 1;
                }
                break;

	default:
                if(!print_unknown_data(tptr,
                                       "\n\t      ",
                                       lsa_length)) {
                    return (1);
                }
                break;
	}

	return (0);
trunc:
	return (1);
}
コード例 #9
0
ファイル: print-ospf6.c プロジェクト: enukane/netbsd-src
static int
ospf6_decode_v3(register const struct ospf6hdr *op,
    register const u_char *dataend)
{
	register const rtrid_t *ap;
	register const struct lsr6 *lsrp;
	register const struct lsa6_hdr *lshp;
	register const struct lsa6 *lsap;
	register int i;

	switch (op->ospf6_type) {

	case OSPF_TYPE_HELLO:
                printf("\n\tOptions [%s]",
                       bittok2str(ospf6_option_values, "none",
                                  EXTRACT_32BITS(&op->ospf6_hello.hello_options)));

                TCHECK(op->ospf6_hello.hello_deadint);
                printf("\n\t  Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u",
                       EXTRACT_16BITS(&op->ospf6_hello.hello_helloint),
                       EXTRACT_16BITS(&op->ospf6_hello.hello_deadint),
                       ipaddr_string(&op->ospf6_hello.hello_ifid),
                       op->ospf6_hello.hello_priority);

		TCHECK(op->ospf6_hello.hello_dr);
		if (op->ospf6_hello.hello_dr != 0)
			printf("\n\t  Designated Router %s",
			    ipaddr_string(&op->ospf6_hello.hello_dr));
		TCHECK(op->ospf6_hello.hello_bdr);
		if (op->ospf6_hello.hello_bdr != 0)
			printf(", Backup Designated Router %s",
			    ipaddr_string(&op->ospf6_hello.hello_bdr));
		if (vflag) {
			printf("\n\t  Neighbor List:");
			ap = op->ospf6_hello.hello_neighbor;
			while ((u_char *)ap < dataend) {
				TCHECK(*ap);
				printf("\n\t    %s", ipaddr_string(ap));
				++ap;
			}
		}
		break;	/* HELLO */

	case OSPF_TYPE_DD:
		TCHECK(op->ospf6_db.db_options);
                printf("\n\tOptions [%s]",
                       bittok2str(ospf6_option_values, "none",
                                  EXTRACT_32BITS(&op->ospf6_db.db_options)));
		TCHECK(op->ospf6_db.db_flags);
                printf(", DD Flags [%s]",
                       bittok2str(ospf6_dd_flag_values,"none",op->ospf6_db.db_flags));

		TCHECK(op->ospf6_db.db_seq);
		printf(", MTU %u, DD-Sequence 0x%08x",
                       EXTRACT_16BITS(&op->ospf6_db.db_mtu),
                       EXTRACT_32BITS(&op->ospf6_db.db_seq));

                /* Print all the LS adv's */
                lshp = op->ospf6_db.db_lshdr;
                while (!ospf6_print_lshdr(lshp)) {
                    ++lshp;
                }
		break;

	case OSPF_TYPE_LS_REQ:
		if (vflag) {
			lsrp = op->ospf6_lsr;
			while ((u_char *)lsrp < dataend) {
				TCHECK(*lsrp);
                                printf("\n\t  Advertising Router %s",
                                       ipaddr_string(&lsrp->ls_router));
				ospf6_print_ls_type(EXTRACT_16BITS(&lsrp->ls_type),
                                                    &lsrp->ls_stateid);
				++lsrp;
			}
		}
		break;

	case OSPF_TYPE_LS_UPDATE:
		if (vflag) {
			lsap = op->ospf6_lsu.lsu_lsa;
			TCHECK(op->ospf6_lsu.lsu_count);
			i = EXTRACT_32BITS(&op->ospf6_lsu.lsu_count);
			while (i--) {
				if (ospf6_print_lsa(lsap))
					goto trunc;
				lsap = (struct lsa6 *)((u_char *)lsap +
				    EXTRACT_16BITS(&lsap->ls_hdr.ls_length));
			}
		}
		break;


	case OSPF_TYPE_LS_ACK:
		if (vflag) {
			lshp = op->ospf6_lsa.lsa_lshdr;

			while (!ospf6_print_lshdr(lshp)) {
				++lshp;
			}
		}
		break;

	default:
		break;
	}
	return (0);
trunc:
	return (1);
}
コード例 #10
0
ファイル: tb_userspace.c プロジェクト: 1Conan/tb-tun
int main(int argc, char  *argv[])
{
        int tun;
        in_addr_t remote_ip;
        char tun_name[IFNAMSIZ];
	openlog("tb_userspace", 0, LOG_DAEMON);
	if (argc != 5) {
		fprintf(stderr,
			"Usage: %s tun_name remote_ipv4 local_ipv4 mode\r\n",
		       	argv[0]);
		return 1;
	}
        strcpy(tun_name, argv[1]);
        tun = tun_create(tun_name, IFF_TUN );//| IFF_NO_PI);
        if (tun < 0) {
                perror("tun_create");
                return 1;
        }
        fprintf(stderr, "TUN name is %s\r\n", tun_name);
	int sockv6, if_bind, tun_mode;
	sockv6 = socket(AF_INET, SOCK_RAW, IPPROTO_IPV6);
	if (sockv6 < 0) {
		perror("v4_socket_create");
		return 1;
	}
	fprintf(stderr, "IPv4 SOCK_RAW created: %d\r\n", sockv6);
	struct sockaddr_in localaddr;
	localaddr.sin_family = AF_INET;
        localaddr.sin_port = htons(IPPROTO_IPV6);
        localaddr.sin_addr.s_addr = inet_addr(argv[3]);
	bzero(&(localaddr.sin_zero), 8);
	if (localaddr.sin_addr.s_addr != -1) {
		if_bind = bind(sockv6, (struct sockaddr *)&localaddr, sizeof(struct sockaddr));
		if (if_bind < 0) {
			perror("bind local address");
			return 1;
		}
		fprintf(stderr, "Bind local IPv4 address %s\r\n", ipaddr_string(localaddr.sin_addr.s_addr));
	}/*If local_ipv4(argv[3]) is "any", do not bind local IPv4 address*/
	else fprintf(stderr, "Do not bind local IPv4 address, using default.\r\n");
	pthread_t ids2t, idt2s;
	struct Threadargs s2targs, t2sargs;
	s2targs.sockv6 = sockv6;
	s2targs.tun = tun;
	if (!strcmp(argv[4],"sit")) {
		if (strcmp(argv[2],"any")) {
			remote_ip = inet_addr(argv[2]);
			tun_mode = 1;
		}
		else {
			remote_ip = inet_addr("192.88.99.1");
			tun_mode = 0;
		}
	}/*If remote_ipv4(argv[2]) is "any", use 6to4 mode and set default gateway 192.88.99.1*/
	else if (!strcmp(argv[4],"isatap")) {
		remote_ip = inet_addr(argv[2]);
		tun_mode = 2;
	}
	else {
		fprintf(stderr, "tunnel mode %s not found.\r\n", argv[4]);
		return 1;
	}
	s2targs.tun_mode = tun_mode;
        if (remote_ip == INADDR_NONE) {
                fprintf(stderr, "Bad remote ipv4 address.\r\n");
                return 1;
        }
	else {
		t2sargs.remote_ip = remote_ip;
		s2targs.remote_ip = remote_ip;
	}
        fprintf(stderr, "Using remote IPv4 %s\r\n", ipaddr_string(remote_ip));
	pthread_create(&ids2t, NULL, (void *)s2t_thread, (void *)&s2targs);
	t2sargs.sockv6 = sockv6;
	t2sargs.tun = tun;
	t2sargs.tun_mode = tun_mode;
        pthread_create(&idt2s, NULL, (void *)t2s_thread, (void *)&t2sargs);
	pthread_join(ids2t, NULL);
	pthread_join(idt2s, NULL);
        return 0;
}
コード例 #11
0
ファイル: print-dccp.c プロジェクト: jaredmcneill/netbsd-src
/**
 * dccp_print - show dccp packet
 * @bp - beginning of dccp packet
 * @data2 - beginning of enclosing
 * @len - lenght of ip packet
 */
void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2,
		u_int len)
{
	const struct dccp_hdr *dh;
	const struct ip *ip;
	const struct ip6_hdr *ip6;
	const u_char *cp;
	u_short sport, dport;
	u_int hlen;
	u_int fixed_hdrlen;
	uint8_t	dccph_type;

	dh = (const struct dccp_hdr *)bp;

	ip = (const struct ip *)data2;
	if (IP_V(ip) == 6)
		ip6 = (const struct ip6_hdr *)data2;
	else
		ip6 = NULL;

	/* make sure we have enough data to look at the X bit */
	cp = (const u_char *)(dh + 1);
	if (cp > ndo->ndo_snapend) {
		ND_PRINT((ndo, "[Invalid packet|dccp]"));
		return;
	}
	if (len < sizeof(struct dccp_hdr)) {
		ND_PRINT((ndo, "truncated-dccp - %u bytes missing!",
			  len - (u_int)sizeof(struct dccp_hdr)));
		return;
	}

	/* get the length of the generic header */
	fixed_hdrlen = dccp_basic_hdr_len(dh);
	if (len < fixed_hdrlen) {
		ND_PRINT((ndo, "truncated-dccp - %u bytes missing!",
			  len - fixed_hdrlen));
		return;
	}
	ND_TCHECK2(*dh, fixed_hdrlen);

	sport = EXTRACT_16BITS(&dh->dccph_sport);
	dport = EXTRACT_16BITS(&dh->dccph_dport);
	hlen = dh->dccph_doff * 4;

	if (ip6) {
		ND_PRINT((ndo, "%s.%d > %s.%d: ",
			  ip6addr_string(ndo, &ip6->ip6_src), sport,
			  ip6addr_string(ndo, &ip6->ip6_dst), dport));
	} else {
		ND_PRINT((ndo, "%s.%d > %s.%d: ",
			  ipaddr_string(ndo, &ip->ip_src), sport,
			  ipaddr_string(ndo, &ip->ip_dst), dport));
	}

	ND_PRINT((ndo, "DCCP"));

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

	/* other variables in generic header */
	if (ndo->ndo_vflag) {
		ND_PRINT((ndo, " (CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh)));
	}

	/* checksum calculation */
	if (ndo->ndo_vflag && ND_TTEST2(bp[0], len)) {
		uint16_t sum = 0, dccp_sum;

		dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum);
		ND_PRINT((ndo, "cksum 0x%04x ", dccp_sum));
		if (IP_V(ip) == 4)
			sum = dccp_cksum(ndo, ip, dh, len);
		else if (IP_V(ip) == 6)
			sum = dccp6_cksum(ndo, ip6, dh, len);
		if (sum != 0)
			ND_PRINT((ndo, "(incorrect -> 0x%04x)",in_cksum_shouldbe(dccp_sum, sum)));
		else
			ND_PRINT((ndo, "(correct)"));
	}

	if (ndo->ndo_vflag)
		ND_PRINT((ndo, ")"));
	ND_PRINT((ndo, " "));

	dccph_type = DCCPH_TYPE(dh);
	switch (dccph_type) {
	case DCCP_PKT_REQUEST: {
		const struct dccp_hdr_request *dhr =
			(const struct dccp_hdr_request *)(bp + fixed_hdrlen);
		fixed_hdrlen += 4;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "%s (service=%d) ",
			  tok2str(dccp_pkt_type_str, "", dccph_type),
			  EXTRACT_32BITS(&dhr->dccph_req_service)));
		break;
	}
	case DCCP_PKT_RESPONSE: {
		const struct dccp_hdr_response *dhr =
			(const struct dccp_hdr_response *)(bp + fixed_hdrlen);
		fixed_hdrlen += 12;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "%s (service=%d) ",
			  tok2str(dccp_pkt_type_str, "", dccph_type),
			  EXTRACT_32BITS(&dhr->dccph_resp_service)));
		break;
	}
	case DCCP_PKT_DATA:
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	case DCCP_PKT_ACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	}
	case DCCP_PKT_DATAACK: {
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	}
	case DCCP_PKT_CLOSEREQ:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	case DCCP_PKT_CLOSE:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	case DCCP_PKT_RESET: {
		const struct dccp_hdr_reset *dhr =
			(const struct dccp_hdr_reset *)(bp + fixed_hdrlen);
		fixed_hdrlen += 12;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_TCHECK(*dhr);
		ND_PRINT((ndo, "%s (code=%s) ",
			  tok2str(dccp_pkt_type_str, "", dccph_type),
			  dccp_reset_code(dhr->dccph_reset_code)));
		break;
	}
	case DCCP_PKT_SYNC:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	case DCCP_PKT_SYNCACK:
		fixed_hdrlen += 8;
		if (len < fixed_hdrlen) {
			ND_PRINT((ndo, "truncated-%s - %u bytes missing!",
				  tok2str(dccp_pkt_type_str, "", dccph_type),
				  len - fixed_hdrlen));
			return;
		}
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type)));
		break;
	default:
		ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "unknown-type-%u", dccph_type)));
		break;
	}

	if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) &&
			(DCCPH_TYPE(dh) != DCCP_PKT_REQUEST))
		dccp_print_ack_no(ndo, bp);

	if (ndo->ndo_vflag < 2)
		return;

	ND_PRINT((ndo, "seq %" PRIu64, dccp_seqno(bp)));

	/* process options */
	if (hlen > fixed_hdrlen){
		u_int optlen;
		cp = bp + fixed_hdrlen;
		ND_PRINT((ndo, " <"));

		hlen -= fixed_hdrlen;
		while(1){
			optlen = dccp_print_option(ndo, cp, hlen);
			if (!optlen)
				break;
			if (hlen <= optlen)
				break;
			hlen -= optlen;
			cp += optlen;
			ND_PRINT((ndo, ", "));
		}
		ND_PRINT((ndo, ">"));
	}
	return;
trunc:
	ND_PRINT((ndo, "%s", tstr));
	return;
}
コード例 #12
0
ファイル: print-tcp.c プロジェクト: ajinkya93/OpenBSD
void
tcp_print(const u_char *bp, u_int length, const u_char *bp2)
{
	const struct tcphdr *tp;
	const struct ip *ip;
	u_char flags;
	int hlen;
	char ch;
	struct tcp_seq_hash *th = NULL;
	int rev = 0;
	u_int16_t sport, dport, win, urp;
	tcp_seq seq, ack;
#ifdef INET6
	const struct ip6_hdr *ip6;
#endif

	tp = (struct tcphdr *)bp;
	switch (((struct ip *)bp2)->ip_v) {
	case 4:
		ip = (struct ip *)bp2;
#ifdef INET6
		ip6 = NULL;
#endif
		break;
#ifdef INET6
	case 6:
		ip = NULL;
		ip6 = (struct ip6_hdr *)bp2;
		break;
#endif
	default:
		(void)printf("invalid ip version");
		return;
	}

	ch = '\0';
	if (length < sizeof(*tp)) {
		(void)printf("truncated-tcp %u", length);
		return;
	}

	if (!TTEST(tp->th_dport)) {
#ifdef INET6
		if (ip6) {
			(void)printf("%s > %s: [|tcp]",
				ip6addr_string(&ip6->ip6_src),
				ip6addr_string(&ip6->ip6_dst));
		} else
#endif /*INET6*/
		{
			(void)printf("%s > %s: [|tcp]",
				ipaddr_string(&ip->ip_src),
				ipaddr_string(&ip->ip_dst));
		}
		return;
	}

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

#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 (!qflag && TTEST(tp->th_seq) && !TTEST(tp->th_ack))
		(void)printf("%u ", ntohl(tp->th_seq));

	TCHECK(*tp);
	seq = ntohl(tp->th_seq);
	ack = ntohl(tp->th_ack);
	win = ntohs(tp->th_win);
	urp = ntohs(tp->th_urp);
	hlen = tp->th_off * 4;

	if (qflag) {
		(void)printf("tcp %d", length - tp->th_off * 4);
		return;
	} else if (packettype != PT_TCP) {

		/*
		 * If data present and NFS port used, assume NFS.
		 * Pass offset of data plus 4 bytes for RPC TCP msg length
		 * to NFS print routines.
		 */
		u_int len = length - hlen;
		if ((u_char *)tp + 4 + sizeof(struct rpc_msg) <= snapend &&
		    dport == NFS_PORT) {
			nfsreq_print((u_char *)tp + hlen + 4, len, bp2);
			return;
		} else if ((u_char *)tp + 4 + 
		    sizeof(struct rpc_msg) <= snapend && sport == NFS_PORT) {
			nfsreply_print((u_char *)tp + hlen + 4, len, bp2);
			return;
		}
	}
	if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH|
				      TH_ECNECHO|TH_CWR)) {
		if (flags & TH_SYN)
			putchar('S');
		if (flags & TH_FIN)
			putchar('F');
		if (flags & TH_RST)
			putchar('R');
		if (flags & TH_PUSH)
			putchar('P');
		if (flags & TH_CWR)
			putchar('W');	/* congestion _W_indow reduced (ECN) */
		if (flags & TH_ECNECHO)
			putchar('E');	/* ecn _E_cho sent (ECN) */
	} else
		putchar('.');

	if (!Sflag && (flags & TH_ACK)) {
		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
		bzero(&tha, sizeof(tha));
		rev = 0;
		if (ip6) {
			if (sport > dport) {
				rev = 1;
			} else if (sport == dport) {
			    int i;

			    for (i = 0; i < 4; i++) {
				if (((u_int32_t *)(&ip6->ip6_src))[i] >
				    ((u_int32_t *)(&ip6->ip6_dst))[i]) {
					rev = 1;
					break;
				}
			    }
			}
			if (rev) {
				tha.src = ip6->ip6_dst;
				tha.dst = ip6->ip6_src;
				tha.port = dport << 16 | sport;
			} else {
				tha.dst = ip6->ip6_dst;
				tha.src = ip6->ip6_src;
				tha.port = sport << 16 | dport;
			}
		} else {
			if (sport > dport ||
			    (sport == dport &&
			     ip->ip_src.s_addr > ip->ip_dst.s_addr)) {
				rev = 1;
			}
			if (rev) {
				*(struct in_addr *)&tha.src = ip->ip_dst;
				*(struct in_addr *)&tha.dst = ip->ip_src;
				tha.port = dport << 16 | sport;
			} else {
				*(struct in_addr *)&tha.dst = ip->ip_dst;
				*(struct in_addr *)&tha.src = ip->ip_src;
				tha.port = sport << 16 | dport;
			}
		}
#else
		if (sport < dport ||
		    (sport == dport &&
		     ip->ip_src.s_addr < ip->ip_dst.s_addr)) {
			tha.src = ip->ip_src, tha.dst = ip->ip_dst;
			tha.port = sport << 16 | dport;
			rev = 0;
		} else {
			tha.src = ip->ip_dst, tha.dst = ip->ip_src;
			tha.port = dport << 16 | sport;
			rev = 1;
		}
#endif

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

		if (!th->nxt || flags & TH_SYN) {
			/* didn't find it or new conversation */
			if (th->nxt == NULL) {
				th->nxt = 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;
		}
	}
	hlen = tp->th_off * 4;
	if (hlen > length) {
		(void)printf(" [bad hdr length]");
		return;
	}

	if (ip && ip->ip_v == 4 && vflag) {
		if (TTEST2(tp->th_sport, length)) {
			u_int16_t sum, tcp_sum;
			sum = tcp_cksum(ip, tp, length);
			if (sum != 0) {
				tcp_sum = EXTRACT_16BITS(&tp->th_sum);
				(void)printf(" [bad tcp cksum %x! -> %x]", tcp_sum,
				    in_cksum_shouldbe(tcp_sum, sum));
			} else
				(void)printf(" [tcp sum ok]");
		}
	}
#ifdef INET6
	if (ip6 && ip6->ip6_plen && vflag) {
		if (TTEST2(tp->th_sport, length)) {
			u_int16_t sum, tcp_sum;
			sum = tcp6_cksum(ip6, tp, length);
			if (sum != 0) {
				tcp_sum = EXTRACT_16BITS(&tp->th_sum);
				(void)printf(" [bad tcp cksum %x! -> %x]", tcp_sum,
				    in_cksum_shouldbe(tcp_sum, sum));
			} else
				(void)printf(" [tcp sum ok]");
		}
	}
#endif

	/* OS Fingerprint */
	if (oflag && (flags & (TH_SYN|TH_ACK)) == TH_SYN) {
		struct pf_osfp_enlist *head = NULL;
		struct pf_osfp_entry *fp;
		unsigned long left;
		left = (unsigned long)(snapend - (const u_char *)tp);

		if (left >= hlen)
			head = pf_osfp_fingerprint_hdr(ip, ip6, tp);
		if (head) {
			int prev = 0;
			printf(" (src OS:");
			SLIST_FOREACH(fp, head, fp_entry) {
				if (fp->fp_enflags & PF_OSFP_EXPANDED)
					continue;
				if (prev)
					printf(",");
				printf(" %s", fp->fp_class_nm);
				if (fp->fp_version_nm[0])
					printf(" %s", fp->fp_version_nm);
				if (fp->fp_subtype_nm[0])
					printf(" %s", fp->fp_subtype_nm);
				prev = 1;
			}
			printf(")");
		} else {
			if (left < hlen)
				printf(" (src OS: short-pkt)");
			else
				printf(" (src OS: unknown)");
		}
	}
コード例 #13
0
ファイル: print-ppp.c プロジェクト: jordanmessina/tcpdump
/* LCP config options */
static int
print_lcp_config_options(netdissect_options *ndo,
                         const u_char *p, int length)
{
	int len, opt;

	if (length < 2)
		return 0;
	ND_TCHECK2(*p, 2);
	len = p[1];
	opt = p[0];
	if (length < len)
		return 0;
	if (len < 2) {
		if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
			ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
			          lcpconfopts[opt], opt, len));
		else
			ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt));
		return 0;
	}
	if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
		ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u", lcpconfopts[opt], opt, len));
	else {
		ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt));
		return len;
	}

	switch (opt) {
	case LCPOPT_VEXT:
		if (len < 6) {
			ND_PRINT((ndo, " (length bogus, should be >= 6)"));
			return len;
		}
		ND_TCHECK2(*(p + 2), 3);
		ND_PRINT((ndo, ": Vendor: %s (%u)",
			tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)),
			EXTRACT_24BITS(p + 2)));
#if 0
		ND_TCHECK(p[5]);
		ND_PRINT((ndo, ", kind: 0x%02x", p[5]));
		ND_PRINT((ndo, ", Value: 0x"));
		for (i = 0; i < len - 6; i++) {
			ND_TCHECK(p[6 + i]);
			ND_PRINT((ndo, "%02x", p[6 + i]));
		}
#endif
		break;
	case LCPOPT_MRU:
		if (len != 4) {
			ND_PRINT((ndo, " (length bogus, should be = 4)"));
			return len;
		}
		ND_TCHECK2(*(p + 2), 2);
		ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
		break;
	case LCPOPT_ACCM:
		if (len != 6) {
			ND_PRINT((ndo, " (length bogus, should be = 6)"));
			return len;
		}
		ND_TCHECK2(*(p + 2), 4);
		ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
		break;
	case LCPOPT_AP:
		if (len < 4) {
			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
			return len;
		}
		ND_TCHECK2(*(p + 2), 2);
		ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2))));

		switch (EXTRACT_16BITS(p+2)) {
		case PPP_CHAP:
			ND_TCHECK(p[4]);
			ND_PRINT((ndo, ", %s", tok2str(authalg_values, "Unknown Auth Alg %u", p[4])));
			break;
		case PPP_PAP: /* fall through */
		case PPP_EAP:
		case PPP_SPAP:
		case PPP_SPAP_OLD:
                        break;
		default:
			print_unknown_data(ndo, p, "\n\t", len);
		}
		break;
	case LCPOPT_QP:
		if (len < 4) {
			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
			return 0;
		}
		ND_TCHECK2(*(p + 2), 2);
		if (EXTRACT_16BITS(p+2) == PPP_LQM)
			ND_PRINT((ndo, ": LQR"));
		else
			ND_PRINT((ndo, ": unknown"));
		break;
	case LCPOPT_MN:
		if (len != 6) {
			ND_PRINT((ndo, " (length bogus, should be = 6)"));
			return 0;
		}
		ND_TCHECK2(*(p + 2), 4);
		ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
		break;
	case LCPOPT_PFC:
		break;
	case LCPOPT_ACFC:
		break;
	case LCPOPT_LD:
		if (len != 4) {
			ND_PRINT((ndo, " (length bogus, should be = 4)"));
			return 0;
		}
		ND_TCHECK2(*(p + 2), 2);
		ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2)));
		break;
	case LCPOPT_CBACK:
		if (len < 3) {
			ND_PRINT((ndo, " (length bogus, should be >= 3)"));
			return 0;
		}
		ND_PRINT((ndo, ": "));
		ND_TCHECK(p[2]);
		ND_PRINT((ndo, ": Callback Operation %s (%u)",
                       tok2str(ppp_callback_values, "Unknown", p[2]),
                       p[2]));
		break;
	case LCPOPT_MLMRRU:
		if (len != 4) {
			ND_PRINT((ndo, " (length bogus, should be = 4)"));
			return 0;
		}
		ND_TCHECK2(*(p + 2), 2);
		ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
		break;
	case LCPOPT_MLED:
		if (len < 3) {
			ND_PRINT((ndo, " (length bogus, should be >= 3)"));
			return 0;
		}
		ND_TCHECK(p[2]);
		switch (p[2]) {		/* class */
		case MEDCLASS_NULL:
			ND_PRINT((ndo, ": Null"));
			break;
		case MEDCLASS_LOCAL:
			ND_PRINT((ndo, ": Local")); /* XXX */
			break;
		case MEDCLASS_IPV4:
			if (len != 7) {
				ND_PRINT((ndo, " (length bogus, should be = 7)"));
				return 0;
			}
			ND_TCHECK2(*(p + 3), 4);
			ND_PRINT((ndo, ": IPv4 %s", ipaddr_string(ndo, p + 3)));
			break;
		case MEDCLASS_MAC:
			if (len != 9) {
				ND_PRINT((ndo, " (length bogus, should be = 9)"));
				return 0;
			}
			ND_TCHECK(p[8]);
			ND_PRINT((ndo, ": MAC %02x:%02x:%02x:%02x:%02x:%02x",
			       p[3], p[4], p[5], p[6], p[7], p[8]));
			break;
		case MEDCLASS_MNB:
			ND_PRINT((ndo, ": Magic-Num-Block")); /* XXX */
			break;
		case MEDCLASS_PSNDN:
			ND_PRINT((ndo, ": PSNDN")); /* XXX */
			break;
		default:
			ND_PRINT((ndo, ": Unknown class %u", p[2]));
			break;
		}
		break;

/* XXX: to be supported */
#if 0
	case LCPOPT_DEP6:
	case LCPOPT_FCSALT:
	case LCPOPT_SDP:
	case LCPOPT_NUMMODE:
	case LCPOPT_DEP12:
	case LCPOPT_DEP14:
	case LCPOPT_DEP15:
	case LCPOPT_DEP16:
        case LCPOPT_MLSSNHF:
	case LCPOPT_PROP:
	case LCPOPT_DCEID:
	case LCPOPT_MPP:
	case LCPOPT_LCPAOPT:
	case LCPOPT_COBS:
	case LCPOPT_PE:
	case LCPOPT_MLHF:
	case LCPOPT_I18N:
	case LCPOPT_SDLOS:
	case LCPOPT_PPPMUX:
		break;
#endif
	default:
		/*
		 * Unknown option; dump it as raw bytes now if we're
		 * not going to do so below.
		 */
		if (ndo->ndo_vflag < 2)
			print_unknown_data(ndo, &p[2], "\n\t    ", len - 2);
		break;
	}

	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, &p[2], "\n\t    ", len - 2); /* exclude TLV header */

	return len;

trunc:
	ND_PRINT((ndo, "[|lcp]"));
	return 0;
}
コード例 #14
0
ファイル: print-ppp.c プロジェクト: jordanmessina/tcpdump
/* IPCP config options */
static int
print_ipcp_config_options(netdissect_options *ndo,
                          const u_char *p, int length)
{
	int len, opt;
        u_int compproto, ipcomp_subopttotallen, ipcomp_subopt, ipcomp_suboptlen;

	if (length < 2)
		return 0;
	ND_TCHECK2(*p, 2);
	len = p[1];
	opt = p[0];
	if (length < len)
		return 0;
	if (len < 2) {
		ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
		       tok2str(ipcpopt_values,"unknown",opt),
		       opt,
		       len));
		return 0;
	}

	ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u",
	       tok2str(ipcpopt_values,"unknown",opt),
	       opt,
	       len));

	switch (opt) {
	case IPCPOPT_2ADDR:		/* deprecated */
		if (len != 10) {
			ND_PRINT((ndo, " (length bogus, should be = 10)"));
			return len;
		}
		ND_TCHECK2(*(p + 6), 4);
		ND_PRINT((ndo, ": src %s, dst %s",
		       ipaddr_string(ndo, p + 2),
		       ipaddr_string(ndo, p + 6)));
		break;
	case IPCPOPT_IPCOMP:
		if (len < 4) {
			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
			return 0;
		}
		ND_TCHECK2(*(p + 2), 2);
		compproto = EXTRACT_16BITS(p+2);

		ND_PRINT((ndo, ": %s (0x%02x):",
		          tok2str(ipcpopt_compproto_values, "Unknown", compproto),
		          compproto));

		switch (compproto) {
                case PPP_VJC:
			/* XXX: VJ-Comp parameters should be decoded */
                        break;
                case IPCPOPT_IPCOMP_HDRCOMP:
                        if (len < IPCPOPT_IPCOMP_MINLEN) {
                        	ND_PRINT((ndo, " (length bogus, should be >= %u)",
                        		IPCPOPT_IPCOMP_MINLEN));
                        	return 0;
                        }

                        ND_TCHECK2(*(p + 2), IPCPOPT_IPCOMP_MINLEN);
                        ND_PRINT((ndo, "\n\t    TCP Space %u, non-TCP Space %u" \
                               ", maxPeriod %u, maxTime %u, maxHdr %u",
                               EXTRACT_16BITS(p+4),
                               EXTRACT_16BITS(p+6),
                               EXTRACT_16BITS(p+8),
                               EXTRACT_16BITS(p+10),
                               EXTRACT_16BITS(p+12)));

                        /* suboptions present ? */
                        if (len > IPCPOPT_IPCOMP_MINLEN) {
                                ipcomp_subopttotallen = len - IPCPOPT_IPCOMP_MINLEN;
                                p += IPCPOPT_IPCOMP_MINLEN;

                                ND_PRINT((ndo, "\n\t      Suboptions, length %u", ipcomp_subopttotallen));

                                while (ipcomp_subopttotallen >= 2) {
                                        ND_TCHECK2(*p, 2);
                                        ipcomp_subopt = *p;
                                        ipcomp_suboptlen = *(p+1);

                                        /* sanity check */
                                        if (ipcomp_subopt == 0 ||
                                            ipcomp_suboptlen == 0 )
                                                break;

                                        /* XXX: just display the suboptions for now */
                                        ND_PRINT((ndo, "\n\t\t%s Suboption #%u, length %u",
                                               tok2str(ipcpopt_compproto_subopt_values,
                                                       "Unknown",
                                                       ipcomp_subopt),
                                               ipcomp_subopt,
                                               ipcomp_suboptlen));

                                        ipcomp_subopttotallen -= ipcomp_suboptlen;
                                        p += ipcomp_suboptlen;
                                }
                        }
                        break;
                default:
                        break;
		}
		break;

	case IPCPOPT_ADDR:     /* those options share the same format - fall through */
	case IPCPOPT_MOBILE4:
	case IPCPOPT_PRIDNS:
	case IPCPOPT_PRINBNS:
	case IPCPOPT_SECDNS:
	case IPCPOPT_SECNBNS:
		if (len != 6) {
			ND_PRINT((ndo, " (length bogus, should be = 6)"));
			return 0;
		}
		ND_TCHECK2(*(p + 2), 4);
		ND_PRINT((ndo, ": %s", ipaddr_string(ndo, p + 2)));
		break;
	default:
		/*
		 * Unknown option; dump it as raw bytes now if we're
		 * not going to do so below.
		 */
		if (ndo->ndo_vflag < 2)
			print_unknown_data(ndo, &p[2], "\n\t    ", len - 2);
		break;
	}
	if (ndo->ndo_vflag > 1)
		print_unknown_data(ndo, &p[2], "\n\t    ", len - 2); /* exclude TLV header */
	return len;

trunc:
	ND_PRINT((ndo, "[|ipcp]"));
	return 0;
}
コード例 #15
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]"));
}
コード例 #16
0
ファイル: print-sctp.c プロジェクト: enukane/netbsd-src
void sctp_print(const u_char *bp,        /* beginning of sctp packet */
		const u_char *bp2,       /* beginning of enclosing */
		u_int sctpPacketLength)  /* ip packet */
{
  const struct sctpHeader *sctpPktHdr;
  const struct ip *ip;
#ifdef INET6
  const struct ip6_hdr *ip6;
#endif
  const void *endPacketPtr;
  u_short sourcePort, destPort;
  int chunkCount;
  const struct sctpChunkDesc *chunkDescPtr;
  const void *nextChunk;
  const char *sep;
  int isforces = 0;


  sctpPktHdr = (const struct sctpHeader*) bp;
  endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;

  if( (u_long) endPacketPtr > (u_long) snapend)
    endPacketPtr = (const void *) snapend;
  ip = (struct ip *)bp2;
#ifdef INET6
  if (IP_V(ip) == 6)
    ip6 = (const struct ip6_hdr *)bp2;
  else
    ip6 = NULL;
#endif /*INET6*/
  TCHECK(*sctpPktHdr);

  if (sctpPacketLength < sizeof(struct sctpHeader))
    {
      (void)printf("truncated-sctp - %ld bytes missing!",
		   (long)sctpPacketLength-sizeof(struct sctpHeader));
      return;
    }

  /*    sctpPacketLength -= sizeof(struct sctpHeader);  packet length  */
  /*  			      is now only as long as the payload  */

  sourcePort = EXTRACT_16BITS(&sctpPktHdr->source);
  destPort = EXTRACT_16BITS(&sctpPktHdr->destination);

#ifdef INET6
  if (ip6) {
    (void)printf("%s.%d > %s.%d: sctp",
      ip6addr_string(&ip6->ip6_src),
      sourcePort,
      ip6addr_string(&ip6->ip6_dst),
      destPort);
  } else
#endif /*INET6*/
  {
    (void)printf("%s.%d > %s.%d: sctp",
      ipaddr_string(&ip->ip_src),
      sourcePort,
      ipaddr_string(&ip->ip_dst),
      destPort);
  }
  fflush(stdout);

  if (isForCES_port(sourcePort)) {
         printf("[%s]", tok2str(ForCES_channels, NULL, sourcePort));
         isforces = 1;
  }
  if (isForCES_port(destPort)) {
         printf("[%s]", tok2str(ForCES_channels, NULL, destPort));
         isforces = 1;
  }

  if (vflag >= 2)
    sep = "\n\t";
  else
    sep = " (";
  /* cycle through all chunks, printing information on each one */
  for (chunkCount = 0,
	 chunkDescPtr = (const struct sctpChunkDesc *)
	    ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader));
       chunkDescPtr != NULL &&
	 ( (const void *)
	    ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc))
	   <= endPacketPtr);

       chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++)
    {
      u_int16_t chunkLength;
      const u_char *chunkEnd;
      u_int16_t align;

      TCHECK(*chunkDescPtr);
      chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength);
      if (chunkLength < sizeof(*chunkDescPtr)) {
      	printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength);
      	break;
      }

      TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength);
      chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);

      align=chunkLength % 4;
      if (align != 0)
	align = 4 - align;

      nextChunk = (const void *) (chunkEnd + align);

      printf("%s%d) ", sep, chunkCount+1);
      switch (chunkDescPtr->chunkID)
	{
	case SCTP_DATA :
	  {
	    const struct sctpDataPart *dataHdrPtr;

	    printf("[DATA] ");

	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
		== SCTP_DATA_UNORDERED)
	      printf("(U)");

	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
		== SCTP_DATA_FIRST_FRAG)
	      printf("(B)");

	    if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
		== SCTP_DATA_LAST_FRAG)
	      printf("(E)");

	    if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
		 == SCTP_DATA_UNORDERED)
		||
		((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
		 == SCTP_DATA_FIRST_FRAG)
		||
		((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
		 == SCTP_DATA_LAST_FRAG) )
	      printf(" ");

	    dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1);

	    printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN));
	    printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId));
	    printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
	    printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
	    fflush(stdout);
	    if (isforces) {
		const u_char *payloadPtr;
		u_int chunksize = sizeof(struct sctpDataPart)+
			          sizeof(struct sctpChunkDesc);
		payloadPtr = (const u_char *) (dataHdrPtr + 1);
		if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
			sizeof(struct sctpDataPart)+
			sizeof(struct sctpChunkDesc)+1) {
		/* Less than 1 byte of chunk payload */
			printf("bogus ForCES chunk length %u]",
			    EXTRACT_16BITS(&chunkDescPtr->chunkLength));
			return;
		}

		forces_print(payloadPtr, EXTRACT_16BITS(&chunkDescPtr->chunkLength)- chunksize);
	   } else if (vflag >= 2) {	/* if verbose output is specified */
					/* at the command line */
		const u_char *payloadPtr;

		printf("[Payload");

		if (!suppress_default_print) {
			payloadPtr = (const u_char *) (++dataHdrPtr);
			printf(":");
			if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
			    sizeof(struct sctpDataPart)+
			    sizeof(struct sctpChunkDesc)+1) {
				/* Less than 1 byte of chunk payload */
				printf("bogus chunk length %u]",
				    EXTRACT_16BITS(&chunkDescPtr->chunkLength));
				return;
			}
			default_print(payloadPtr,
			      EXTRACT_16BITS(&chunkDescPtr->chunkLength) -
			      (sizeof(struct sctpDataPart)+
			      sizeof(struct sctpChunkDesc)));
		} else
			printf("]");
	      }
	    break;
	  }
	case SCTP_INITIATION :
	  {
	    const struct sctpInitiation *init;

	    printf("[INIT] ");
	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));

#if(0) /* ALC you can add code for optional params here */
	    if( (init+1) < chunkEnd )
	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
		     "Optional params present, but not printed.");
#endif
	    break;
	  }
	case SCTP_INITIATION_ACK :
	  {
	    const struct sctpInitiation *init;

	    printf("[INIT ACK] ");
	    init=(const struct sctpInitiation*)(chunkDescPtr+1);
	    printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
	    printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
	    printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
	    printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
	    printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));

#if(0) /* ALC you can add code for optional params here */
	    if( (init+1) < chunkEnd )
	      printf(" @@@@@ UNFINISHED @@@@@@%s\n",
		     "Optional params present, but not printed.");
#endif
	    break;
	  }
	case SCTP_SELECTIVE_ACK:
	  {
	    const struct sctpSelectiveAck *sack;
	    const struct sctpSelectiveFrag *frag;
	    int fragNo, tsnNo;
	    const u_char *dupTSN;

	    printf("[SACK] ");
	    sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1);
	    printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN));
	    printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd));
	    printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc));
	    printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns));


	    /* print gaps */
	    for (frag = ( (const struct sctpSelectiveFrag *)
			  ((const struct sctpSelectiveAck *) sack+1)),
		   fragNo=0;
		 (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc);
		 frag++, fragNo++)
	      printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ",
		     fragNo+1,
		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart),
		     EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd));


	    /* print duplicate TSNs */
	    for (dupTSN = (const u_char *)frag, tsnNo=0;
		 (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
		 dupTSN += 4, tsnNo++)
	      printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
	          EXTRACT_32BITS(dupTSN));

	    break;
	  }
	case SCTP_HEARTBEAT_REQUEST :
	  printf("[HB REQ] ");
	  break;
	case SCTP_HEARTBEAT_ACK :
	  printf("[HB ACK] ");
	  break;
	case SCTP_ABORT_ASSOCIATION :
	  printf("[ABORT] ");
	  break;
	case SCTP_SHUTDOWN :
	  printf("[SHUTDOWN] ");
	  break;
	case SCTP_SHUTDOWN_ACK :
	  printf("[SHUTDOWN ACK] ");
	  break;
	case SCTP_OPERATION_ERR :
	  printf("[OP ERR] ");
	  break;
	case SCTP_COOKIE_ECHO :
	  printf("[COOKIE ECHO] ");
	  break;
	case SCTP_COOKIE_ACK :
	  printf("[COOKIE ACK] ");
	  break;
	case SCTP_ECN_ECHO :
	  printf("[ECN ECHO] ");
	  break;
	case SCTP_ECN_CWR :
	  printf("[ECN CWR] ");
	  break;
	case SCTP_SHUTDOWN_COMPLETE :
	  printf("[SHUTDOWN COMPLETE] ");
	  break;
	case SCTP_FORWARD_CUM_TSN :
	  printf("[FOR CUM TSN] ");
	  break;
	case SCTP_RELIABLE_CNTL :
	  printf("[REL CTRL] ");
	  break;
	case SCTP_RELIABLE_CNTL_ACK :
	  printf("[REL CTRL ACK] ");
	  break;
	default :
	  printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID);
	  return;
	}

	if (vflag < 2)
	  sep = ", (";
    }
    return;

trunc:
    printf("[|sctp]");
    return;
}
コード例 #17
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);
    }
}
コード例 #18
0
void
olsr_print (packetbody_t pptr, u_int length, int is_ipv6)
{
    union {
        __capability const struct olsr_common *common;
        __capability const struct olsr_msg4 *msg4;
        __capability const struct olsr_msg6 *msg6;
        __capability const struct olsr_hello *hello;
        __capability const struct olsr_hello_link *hello_link;
        __capability const struct olsr_tc *tc;
        __capability const struct olsr_hna4 *hna;
    } ptr;

    u_int msg_type, msg_len, msg_tlen, hello_len;
    u_int16_t name_entry_type, name_entry_len;
    u_int name_entry_padding;
    u_int8_t link_type, neighbor_type;
    packetbody_t tptr, msg_data;

    tptr = pptr;

    if (length < sizeof(struct olsr_common)) {
        goto trunc;
    }

    if (!PACKET_HAS_SPACE(tptr, sizeof(struct olsr_common))) {
        goto trunc;
    }

    ptr.common = (__capability struct olsr_common *)tptr;
    length = MIN(length, EXTRACT_16BITS(ptr.common->packet_len));

    printf("OLSRv%i, seq 0x%04x, length %u",
            (is_ipv6 == 0) ? 4 : 6,
            EXTRACT_16BITS(ptr.common->packet_seq),
            length);

    tptr += sizeof(struct olsr_common);

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

    while (tptr < (pptr+length)) {
        union
        {
            __capability struct olsr_msg4 *v4;
            __capability struct olsr_msg6 *v6;
        } msgptr;
        int msg_len_valid = 0;

        if (!PACKET_HAS_SPACE(tptr, sizeof(struct olsr_msg4)))
            goto trunc;

#if INET6
        if (is_ipv6)
        {
            msgptr.v6 = (__capability struct olsr_msg6 *) tptr;
            msg_type = msgptr.v6->msg_type;
            msg_len = EXTRACT_16BITS(msgptr.v6->msg_len);
            if ((msg_len >= sizeof (struct olsr_msg6))
                    && (msg_len <= length))
                msg_len_valid = 1;

            /* infinite loop check */
            if (msg_type == 0 || msg_len == 0) {
                return;
            }

            printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u"
                    "\n\t  vtime %.3lfs, msg-seq 0x%04x, length %u%s",
                    tok2str(olsr_msg_values, "Unknown", msg_type),
                    msg_type, ip6addr_string(msgptr.v6->originator),
                    msgptr.v6->ttl,
                    msgptr.v6->hopcount,
                    ME_TO_DOUBLE(msgptr.v6->vtime),
                    EXTRACT_16BITS(msgptr.v6->msg_seq),
                    msg_len, (msg_len_valid == 0) ? " (invalid)" : "");

            msg_tlen = msg_len - sizeof(struct olsr_msg6);
            msg_data = tptr + sizeof(struct olsr_msg6);
        }
        else /* (!is_ipv6) */
#endif /* INET6 */
        {
            msgptr.v4 = (__capability struct olsr_msg4 *) tptr;
            msg_type = msgptr.v4->msg_type;
            msg_len = EXTRACT_16BITS(msgptr.v4->msg_len);
            if ((msg_len >= sizeof (struct olsr_msg4))
                    && (msg_len <= length))
                msg_len_valid = 1;

            /* infinite loop check */
            if (msg_type == 0 || msg_len == 0) {
                return;
            }

            printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u"
                    "\n\t  vtime %.3lfs, msg-seq 0x%04x, length %u%s",
                    tok2str(olsr_msg_values, "Unknown", msg_type),
                    msg_type, ipaddr_string(msgptr.v4->originator),
                    msgptr.v4->ttl,
                    msgptr.v4->hopcount,
                    ME_TO_DOUBLE(msgptr.v4->vtime),
                    EXTRACT_16BITS(msgptr.v4->msg_seq),
                    msg_len, (msg_len_valid == 0) ? " (invalid)" : "");

            msg_tlen = msg_len - sizeof(struct olsr_msg4);
            msg_data = tptr + sizeof(struct olsr_msg4);
        }

        switch (msg_type) {
        case OLSR_HELLO_MSG:
        case OLSR_HELLO_LQ_MSG:
            if (!PACKET_HAS_SPACE(msg_data, sizeof(struct olsr_hello)))
                goto trunc;

            ptr.hello = (__capability struct olsr_hello *)msg_data;
            printf("\n\t  hello-time %.3lfs, MPR willingness %u",
                   ME_TO_DOUBLE(ptr.hello->htime), ptr.hello->will);
            msg_data += sizeof(struct olsr_hello);
            msg_tlen -= sizeof(struct olsr_hello);

            while (msg_tlen >= sizeof(struct olsr_hello_link)) {
                int hello_len_valid = 0;

                /*
                 * link-type.
                 */
                if (!PACKET_HAS_SPACE(msg_data, sizeof(struct olsr_hello_link)))
                    goto trunc;

                ptr.hello_link = (__capability struct olsr_hello_link *)msg_data;

                hello_len = EXTRACT_16BITS(ptr.hello_link->len);
                link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_link->link_code);
                neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_link->link_code);

                if ((hello_len <= msg_tlen)
                        && (hello_len >= sizeof(struct olsr_hello_link)))
                    hello_len_valid = 1;

                printf("\n\t    link-type %s, neighbor-type %s, len %u%s",
                       tok2str(olsr_link_type_values, "Unknown", link_type),
                       tok2str(olsr_neighbor_type_values, "Unknown", neighbor_type),
                       hello_len,
                       (hello_len_valid == 0) ? " (invalid)" : "");

                if (hello_len_valid == 0)
                    break;

                msg_data += sizeof(struct olsr_hello_link);
                msg_tlen -= sizeof(struct olsr_hello_link);
                hello_len -= sizeof(struct olsr_hello_link);

                if (msg_type == OLSR_HELLO_MSG) {
                    olsr_print_neighbor(msg_data, hello_len);
                } else {
#if INET6
                    if (is_ipv6)
                        olsr_print_lq_neighbor6(msg_data, hello_len);
                    else
#endif
                        olsr_print_lq_neighbor4(msg_data, hello_len);
                }

                msg_data += hello_len;
                msg_tlen -= hello_len;
            }
            break;

        case OLSR_TC_MSG:
        case OLSR_TC_LQ_MSG:
            if (!PACKET_HAS_SPACE(msg_data, sizeof(struct olsr_tc)))
                goto trunc;

            ptr.tc = (__capability struct olsr_tc *)msg_data;
            printf("\n\t    advertised neighbor seq 0x%04x",
                   EXTRACT_16BITS(ptr.tc->ans_seq));
            msg_data += sizeof(struct olsr_tc);
            msg_tlen -= sizeof(struct olsr_tc);

            if (msg_type == OLSR_TC_MSG) {
                olsr_print_neighbor(msg_data, msg_tlen);
            } else {
#if INET6
                if (is_ipv6)
                    olsr_print_lq_neighbor6(msg_data, msg_tlen);
                else
#endif
                    olsr_print_lq_neighbor4(msg_data, msg_tlen);
            }
            break;

        case OLSR_MID_MSG:
        {
            size_t addr_size = sizeof(struct in_addr);

#if INET6
            if (is_ipv6)
                addr_size = sizeof(struct in6_addr);
#endif

            while (msg_tlen >= addr_size) {
                if (!PACKET_HAS_SPACE(msg_data, addr_size))
                    goto trunc;

                printf("\n\t  interface address %s",
#if INET6
                        is_ipv6 ? ip6addr_string(msg_data) :
#endif
                        ipaddr_string(msg_data));
                msg_data += addr_size;
                msg_tlen -= addr_size;
            }
            break;
        }

        case OLSR_HNA_MSG:
            printf("\n\t  Advertised networks (total %u)",
                    (unsigned int) (msg_tlen / sizeof(struct olsr_hna6)));
#if INET6
            if (is_ipv6)
            {
                int i = 0;
                while (msg_tlen >= sizeof(struct olsr_hna6)) {
                    __capability struct olsr_hna6 *hna6;

                    if (!PACKET_HAS_SPACE(msg_data, sizeof(struct olsr_hna6)))
                        goto trunc;

                    hna6 = (__capability struct olsr_hna6 *)msg_data;

                    printf("\n\t    #%i: %s/%u",
                            i, ip6addr_string(hna6->network),
                            mask62plen (hna6->mask));

                    msg_data += sizeof(struct olsr_hna6);
                    msg_tlen -= sizeof(struct olsr_hna6);
                }
            }
            else
#endif
            {
                int col = 0;
                while (msg_tlen >= sizeof(struct olsr_hna4)) {
                    if (!PACKET_HAS_SPACE(msg_data, sizeof(struct olsr_hna4)))
                        goto trunc;

                    ptr.hna = (__capability struct olsr_hna4 *)msg_data;

                    /* print 4 prefixes per line */
                    if (col == 0)
                        printf ("\n\t    ");
                    else
                        printf (", ");

                    printf("%s/%u",
                            ipaddr_string(ptr.hna->network),
                            mask2plen(EXTRACT_32BITS(ptr.hna->mask)));

                    msg_data += sizeof(struct olsr_hna4);
                    msg_tlen -= sizeof(struct olsr_hna4);

                    col = (col + 1) % 4;
                }
            }
            break;

        case OLSR_NAMESERVICE_MSG:
        {
            u_int name_entries = EXTRACT_16BITS(msg_data+2);
            u_int addr_size = 4;
            int name_entries_valid = 0;
            u_int i;

            if (is_ipv6)
                addr_size = 16;

            if ((name_entries > 0)
                    && ((name_entries * (4 + addr_size)) <= msg_tlen))
                name_entries_valid = 1;

            if (msg_tlen < 4)
                goto trunc;
            if (!PACKET_HAS_SPACE(msg_data, 4))
                goto trunc;

            printf("\n\t  Version %u, Entries %u%s",
                   EXTRACT_16BITS(msg_data),
                   name_entries, (name_entries_valid == 0) ? " (invalid)" : "");

            if (name_entries_valid == 0)
                break;

            msg_data += 4;
            msg_tlen -= 4;

            for (i = 0; i < name_entries; i++) {
                int name_entry_len_valid = 0;

                if (msg_tlen < 4)
                    break;
                if (!PACKET_HAS_SPACE(msg_data, 4))
                    goto trunc;

                name_entry_type = EXTRACT_16BITS(msg_data);
                name_entry_len = EXTRACT_16BITS(msg_data+2);

                msg_data += 4;
                msg_tlen -= 4;

                if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen))
                    name_entry_len_valid = 1;

                printf("\n\t    #%u: type %#06x, length %u%s",
                        (unsigned int) i, name_entry_type,
                        name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : "");

                if (name_entry_len_valid == 0)
                    break;

                /* 32-bit alignment */
                name_entry_padding = 0;
                if (name_entry_len%4 != 0)
                    name_entry_padding = 4-(name_entry_len%4);

                if (msg_tlen < addr_size + name_entry_len + name_entry_padding)
                    goto trunc;

                if (!PACKET_HAS_SPACE(msg_data, addr_size + name_entry_len + name_entry_padding))
                    goto trunc;

#if INET6
                if (is_ipv6)
                    printf(", address %s, name \"",
                            ip6addr_string(msg_data));
                else
#endif
                    printf(", address %s, name \"",
                            ipaddr_string(msg_data));
                fn_printn(msg_data + addr_size, name_entry_len, NULL);
                printf("\"");

                msg_data += addr_size + name_entry_len + name_entry_padding;
                msg_tlen -= addr_size + name_entry_len + name_entry_padding;
            } /* for (i = 0; i < name_entries; i++) */
            break;
        } /* case OLSR_NAMESERVICE_MSG */

            /*
             * FIXME those are the defined messages that lack a decoder
             * you are welcome to contribute code ;-)
             */
        case OLSR_POWERINFO_MSG:
        default:
            print_unknown_data(msg_data, "\n\t    ", msg_tlen);
            break;
        } /* switch (msg_type) */
        tptr += msg_len;
    } /* while (tptr < (pptr+length)) */

    return;

 trunc:
    printf("[|olsr]");
}
コード例 #19
0
ファイル: print-arp.c プロジェクト: deval-maker/rtems-libbsd
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]"));
}
コード例 #20
0
ファイル: print-chdlc.c プロジェクト: 0-kaladin/ad-away
static void
chdlc_slarp_print(netdissect_options *ndo, const u_char *cp, u_int length)
{
	const struct cisco_slarp *slarp;
        u_int sec,min,hrs,days;

	ND_PRINT((ndo, "SLARP (length: %u), ",length));
	if (length < SLARP_MIN_LEN)
		goto trunc;

	slarp = (const struct cisco_slarp *)cp;
	ND_TCHECK2(*slarp, SLARP_MIN_LEN);
	switch (EXTRACT_32BITS(&slarp->code)) {
	case SLARP_REQUEST:
		ND_PRINT((ndo, "request"));
		/*
		 * At least according to William "Chops" Westfield's
		 * message in
		 *
		 *	http://www.nethelp.no/net/cisco-hdlc.txt
		 *
		 * the address and mask aren't used in requests -
		 * they're just zero.
		 */
		break;
	case SLARP_REPLY:
		ND_PRINT((ndo, "reply %s/%s",
			ipaddr_string(ndo, &slarp->un.addr.addr),
			ipaddr_string(ndo, &slarp->un.addr.mask)));
		break;
	case SLARP_KEEPALIVE:
		ND_PRINT((ndo, "keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x",
                       EXTRACT_32BITS(&slarp->un.keep.myseq),
                       EXTRACT_32BITS(&slarp->un.keep.yourseq),
                       EXTRACT_16BITS(&slarp->un.keep.rel)));

                if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */
                        cp += SLARP_MIN_LEN;
                        ND_TCHECK2(*cp, 4);
                        sec = EXTRACT_32BITS(cp) / 1000;
                        min = sec / 60; sec -= min * 60;
                        hrs = min / 60; min -= hrs * 60;
                        days = hrs / 24; hrs -= days * 24;
                        ND_PRINT((ndo, ", link uptime=%ud%uh%um%us",days,hrs,min,sec));
                }
		break;
	default:
		ND_PRINT((ndo, "0x%02x unknown", EXTRACT_32BITS(&slarp->code)));
                if (ndo->ndo_vflag <= 1)
                    print_unknown_data(ndo,cp+4,"\n\t",length-4);
		break;
	}

	if (SLARP_MAX_LEN < length && ndo->ndo_vflag)
		ND_PRINT((ndo, ", (trailing junk: %d bytes)", length - SLARP_MAX_LEN));
        if (ndo->ndo_vflag > 1)
            print_unknown_data(ndo,cp+4,"\n\t",length-4);
	return;

trunc:
	ND_PRINT((ndo, "[|slarp]"));
}
コード例 #21
0
ファイル: print-ldp.c プロジェクト: lampmanyao/tcpdump
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;
}
コード例 #22
0
ファイル: print-vtp.c プロジェクト: RTEMS/rtems-libbsd
void
vtp_print (netdissect_options *ndo,
           const u_char *pptr, u_int length)
{
    int type, len, tlv_len, tlv_value, mgmtd_len;
    const u_char *tptr;
    const struct vtp_vlan_ *vtp_vlan;

    if (length < VTP_HEADER_LEN)
        goto trunc;

    tptr = pptr;

    ND_TCHECK2(*tptr, VTP_HEADER_LEN);

    type = *(tptr+1);
    ND_PRINT((ndo, "VTPv%u, Message %s (0x%02x), length %u",
	   *tptr,
	   tok2str(vtp_message_type_values,"Unknown message type", type),
	   type,
	   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: "));
    mgmtd_len = *(tptr + 3);
    if (mgmtd_len < 1 ||  mgmtd_len > 32) {
	ND_PRINT((ndo, " [invalid MgmtD Len %d]", mgmtd_len));
	return;
    }
    fn_printzp(ndo, tptr + 4, mgmtd_len, NULL);
    ND_PRINT((ndo, ", %s: %u",
	   tok2str(vtp_header_values, "Unknown", type),
	   *(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  |    MgmtD Len  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |       Management Domain Name  (zero-padded to 32 bytes)       |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Configuration revision number              |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                  Updater Identity IP address                  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Update Timestamp (12 bytes)                |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                        MD5 digest (16 bytes)                  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	ND_TCHECK2(*tptr, 8);
	ND_PRINT((ndo, "\n\t  Config Rev %x, Updater %s",
	       EXTRACT_32BITS(tptr),
	       ipaddr_string(ndo, tptr+4)));
	tptr += 8;
	ND_TCHECK2(*tptr, VTP_UPDATE_TIMESTAMP_LEN);
	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_TCHECK2(*tptr, VTP_MD5_DIGEST_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  |    MgmtD Len  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |       Management Domain Name  (zero-padded to 32 bytes)       |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                    Configuration revision number              |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         VLAN info field 1                     |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         ................                      |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                         VLAN info field N                     |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	ND_TCHECK_32BITS(tptr);
	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)) {

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

	    ND_TCHECK2(*tptr, len);

	    vtp_vlan = (const struct vtp_vlan_*)tptr;
	    if (len < VTP_VLAN_INFO_FIXED_PART_LEN)
		goto trunc;
	    ND_TCHECK(*vtp_vlan);
	    ND_PRINT((ndo, "\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name ",
		   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)));
	    len  -= VTP_VLAN_INFO_FIXED_PART_LEN;
	    tptr += VTP_VLAN_INFO_FIXED_PART_LEN;
	    if (len < 4*((vtp_vlan->name_len + 3)/4))
		goto trunc;
	    ND_TCHECK2(*tptr, vtp_vlan->name_len);
	    fn_printzp(ndo, tptr, vtp_vlan->name_len, NULL);

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

            /* TLV information follows */

            while (len > 0) {

                /*
                 * Cisco specs say 2 bytes for type + 2 bytes for length;
                 * see http://docstore.mik.ua/univercd/cc/td/doc/product/lan/trsrb/frames.htm
                 * However, actual packets on the wire appear to use 1
                 * byte for the type and 1 byte for the length, so that's
                 * what we do.
                 */
                if (len < 2)
                    goto trunc;
                ND_TCHECK2(*tptr, 2);
                type = *tptr;
                tlv_len = *(tptr+1);

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

                if (len < tlv_len * 2 + 2) {
                    ND_PRINT((ndo, " (TLV goes past the end of the packet)"));
                    return;
                }
                ND_TCHECK2(*tptr, tlv_len * 2 +2);

                /*
                 * We assume the value is a 2-byte integer; the length is
                 * in units of 16-bit words.
                 */
                if (tlv_len != 1) {
                    ND_PRINT((ndo, " (invalid TLV length %u != 1)", tlv_len));
                    return;
                } else {
                    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    |    MgmtD Len  |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |       Management Domain Name  (zero-padded to 32 bytes)       |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *  |                          Start value                          |
	 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 *
	 */

	ND_TCHECK2(*tptr, 4);
	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]"));
}
コード例 #23
0
void
tcp_print(register const u_char *bp, register u_int length,
	  register const u_char *bp2)
{
	register const struct tcphdr *tp;
	register const struct ip *ip;
	register u_char flags;
	register int hlen;
	register char ch;
	u_short sport, dport, win, urp;
	u_int32_t seq, ack;

	tp = (struct tcphdr *)bp;
	ip = (struct ip *)bp2;
	ch = '\0';
	TCHECK(*tp);
	if (length < sizeof(*tp)) {
		(void)printf("truncated-tcp %d", length);
		return;
	}

	sport = ntohs(tp->th_sport);
	dport = ntohs(tp->th_dport);
	seq = ntohl(tp->th_seq);
	ack = ntohl(tp->th_ack);
	win = ntohs(tp->th_win);
	urp = ntohs(tp->th_urp);

	(void)printf("%s.%s > %s.%s: ",
		ipaddr_string(&ip->ip_src), tcpport_string(sport),
		ipaddr_string(&ip->ip_dst), tcpport_string(dport));

	if (qflag) {
		(void)printf("tcp %d", length - tp->th_off * 4);
		return;
	}
	if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH)) {
		if (flags & TH_SYN)
			putchar('S');
		if (flags & TH_FIN)
			putchar('F');
		if (flags & TH_RST)
			putchar('R');
		if (flags & TH_PUSH)
			putchar('P');
	} else
		putchar('.');

	if (!Sflag && (flags & TH_ACK)) {
		register struct tcp_seq_hash *th;
		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).
		 */
		if (sport < dport ||
		    (sport == dport &&
		     ip->ip_src.s_addr < ip->ip_dst.s_addr)) {
			tha.src = ip->ip_src, tha.dst = ip->ip_dst;
			tha.port = sport << 16 | dport;
			rev = 0;
		} else {
			tha.src = ip->ip_dst, tha.dst = ip->ip_src;
			tha.port = dport << 16 | sport;
			rev = 1;
		}

		for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
		     th->nxt; th = th->nxt)
			if (!memcmp((char *)&tha, (char *)&th->addr,
				  sizeof(th->addr)))
				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;
		}
	}
	hlen = tp->th_off * 4;
	if (hlen > length) {
		(void)printf(" [bad hdr length]");
		return;
	}
	length -= hlen;
	if (length > 0 || flags & (TH_SYN | TH_FIN | TH_RST))
		(void)printf(" %u:%u(%d)", seq, seq + length, 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)) > 0) {
		register const u_char *cp;
		register int i, opt, len, datalen;

		cp = (const u_char *)tp + sizeof(*tp);
		putchar(' ');
		ch = '<';
		while (hlen > 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); }

			switch (opt) {

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

				break;

			case TCPOPT_EOL:
				(void)printf("eol");
				break;

			case TCPOPT_NOP:
				(void)printf("nop");
				break;

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

			case TCPOPT_SACKOK:
				(void)printf("sackOK");
				break;

			case TCPOPT_SACK:
				(void)printf("sack");
				datalen = len - 2;
				for (i = 0; i < datalen; i += 4) {
					LENCHECK(i + 4);
					/* block-size@relative-origin */
					(void)printf(" %u@%u",
					    EXTRACT_16BITS(cp + i + 2),
					    EXTRACT_16BITS(cp + i));
				}
				if (datalen % 4)
					(void)printf("[len %d]", len);
				break;

			case TCPOPT_ECHO:
				(void)printf("echo");
				datalen = 4;
				LENCHECK(datalen);
				(void)printf(" %u", EXTRACT_32BITS(cp));
				break;

			case TCPOPT_ECHOREPLY:
				(void)printf("echoreply");
				datalen = 4;
				LENCHECK(datalen);
				(void)printf(" %u", EXTRACT_32BITS(cp));
				break;

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

			case TCPOPT_CC:
				(void)printf("cc");
				datalen = 4;
				LENCHECK(datalen);
				(void)printf(" %u", EXTRACT_32BITS(cp));
				break;

			case TCPOPT_CCNEW:
				(void)printf("ccnew");
				datalen = 4;
				LENCHECK(datalen);
				(void)printf(" %u", EXTRACT_32BITS(cp));
				break;

			case TCPOPT_CCECHO:
				(void)printf("ccecho");
				datalen = 4;
				LENCHECK(datalen);
				(void)printf(" %u", EXTRACT_32BITS(cp));
				break;

			default:
				(void)printf("opt-%d:", opt);
				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('>');
	}
	return;
bad:
	fputs("[bad opt]", stdout);
	if (ch != '\0')
		putchar('>');
	return;
trunc:
	fputs("[|tcp]", stdout);
	if (ch != '\0')
		putchar('>');
}
コード例 #24
0
ファイル: print-vrrp.c プロジェクト: EliseuTorres/tcpdump
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]"));
}
コード例 #25
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;
}
コード例 #26
0
ファイル: print-tcp.c プロジェクト: fenner/tcpdump
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("]");
        }
コード例 #27
0
ファイル: print-domain.c プロジェクト: aunali1/exopc
/* 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 */
}
コード例 #28
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));
}
コード例 #29
0
/*
 * Print a single link state advertisement.  If truncated return 1, else 0.
 */
static int
ospf_print_lsa(register const struct lsa *lsap)
{
	register const u_char *ls_end;
	register const struct rlalink *rlp;
	register const struct tos_metric *tosp;
	register const struct in_addr *ap;
	register const struct aslametric *almp;
	register const struct mcla *mcp;
	register const u_int32_t *lp;
	register int j, k;

	if (ospf_print_lshdr(&lsap->ls_hdr))
		return (1);
	TCHECK(lsap->ls_hdr.ls_length);
	ls_end = (u_char *)lsap + ntohs(lsap->ls_hdr.ls_length);
	switch (lsap->ls_hdr.ls_type) {

	case LS_TYPE_ROUTER:
		TCHECK(lsap->lsa_un.un_rla.rla_flags);
		ospf_print_bits(ospf_rla_flag_bits,
		    lsap->lsa_un.un_rla.rla_flags);

		TCHECK(lsap->lsa_un.un_rla.rla_count);
		j = ntohs(lsap->lsa_un.un_rla.rla_count);
		TCHECK(lsap->lsa_un.un_rla.rla_link);
		rlp = lsap->lsa_un.un_rla.rla_link;
		while (j--) {
			TCHECK(*rlp);
			printf(" {");				/* } (ctags) */
			switch (rlp->link_type) {

			case RLA_TYPE_VIRTUAL:
				printf(" virt");
				/* Fall through */

			case RLA_TYPE_ROUTER:
				printf(" nbrid %s if %s",
				    ipaddr_string(&rlp->link_id),
				    ipaddr_string(&rlp->link_data));
				break;

			case RLA_TYPE_TRANSIT:
				printf(" dr %s if %s",
				    ipaddr_string(&rlp->link_id),
				    ipaddr_string(&rlp->link_data));
				break;

			case RLA_TYPE_STUB:
				printf(" net %s mask %s",
				    ipaddr_string(&rlp->link_id),
				    ipaddr_string(&rlp->link_data));
				break;

			default:
								/* { (ctags) */
				printf(" ??RouterLinksType %d?? }",
				    rlp->link_type);
				return (0);
			}
			printf(" tos 0 metric %d", ntohs(rlp->link_tos0metric));
			tosp = (struct tos_metric *)
			    ((sizeof rlp->link_tos0metric) + (u_char *) rlp);
			for (k = 0; k < (int) rlp->link_toscount; ++k, ++tosp) {
				TCHECK(*tosp);
				printf(" tos %d metric %d",
				    tosp->tos_type,
				    ntohs(tosp->tos_metric));
			}
								/* { (ctags) */
			printf(" }");
			rlp = (struct rlalink *)((u_char *)(rlp + 1) +
			    ((rlp->link_toscount) * sizeof(*tosp)));
		}
		break;

	case LS_TYPE_NETWORK:
		TCHECK(lsap->lsa_un.un_nla.nla_mask);
		printf(" mask %s rtrs",
		    ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
		ap = lsap->lsa_un.un_nla.nla_router;
		while ((u_char *)ap < ls_end) {
			TCHECK(*ap);
			printf(" %s", ipaddr_string(ap));
			++ap;
		}
		break;

	case LS_TYPE_SUM_IP:
		TCHECK(lsap->lsa_un.un_nla.nla_mask);
		printf(" mask %s",
		    ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
		/* Fall through */

	case LS_TYPE_SUM_ABR:
		TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
		lp = lsap->lsa_un.un_sla.sla_tosmetric;
		while ((u_char *)lp < ls_end) {
			register u_int32_t ul;

			TCHECK(*lp);
			ul = ntohl(*lp);
			printf(" tos %d metric %d",
			    (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS,
			    ul & SLA_MASK_METRIC);
			++lp;
		}
		break;

	case LS_TYPE_ASE:
		TCHECK(lsap->lsa_un.un_nla.nla_mask);
		printf(" mask %s",
		    ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));

		TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
		almp = lsap->lsa_un.un_asla.asla_metric;
		while ((u_char *)almp < ls_end) {
			register u_int32_t ul;

			TCHECK(almp->asla_tosmetric);
			ul = ntohl(almp->asla_tosmetric);
			printf(" type %d tos %d metric %d",
			    (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1,
			    (ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS,
			    (ul & ASLA_MASK_METRIC));
			TCHECK(almp->asla_forward);
			if (almp->asla_forward.s_addr) {
				printf(" forward %s",
				    ipaddr_string(&almp->asla_forward));
			}
			TCHECK(almp->asla_tag);
			if (almp->asla_tag.s_addr) {
				printf(" tag %s",
				    ipaddr_string(&almp->asla_tag));
			}
			++almp;
		}
		break;

	case LS_TYPE_GROUP:
		/* Multicast extensions as of 23 July 1991 */
		mcp = lsap->lsa_un.un_mcla;
		while ((u_char *)mcp < ls_end) {
			TCHECK(mcp->mcla_vid);
			switch (ntohl(mcp->mcla_vtype)) {

			case MCLA_VERTEX_ROUTER:
				printf(" rtr rtrid %s",
				    ipaddr_string(&mcp->mcla_vid));
				break;

			case MCLA_VERTEX_NETWORK:
				printf(" net dr %s",
				    ipaddr_string(&mcp->mcla_vid));
				break;

			default:
				printf(" ??VertexType %u??",
				    (u_int32_t)ntohl(mcp->mcla_vtype));
				break;
			}
		++mcp;
		}
	}

								/* { (ctags) */
	fputs(" }", stdout);
	return (0);
trunc:
	fputs(" }", stdout);
	return (1);
}
コード例 #30
0
ファイル: print-ospf.c プロジェクト: hsluoyz/WinDump
static int
ospf_decode_v2(register const struct ospfhdr *op,
    register const u_char *dataend)
{
	register const struct in_addr *ap;
	register const struct lsr *lsrp;
	register const struct lsa_hdr *lshp;
	register const struct lsa *lsap;
	register u_int32_t lsa_count,lsa_count_max;

	switch (op->ospf_type) {

	case OSPF_TYPE_UMD:
		/*
		 * Rob Coltun's special monitoring packets;
		 * do nothing
		 */
		break;

	case OSPF_TYPE_HELLO:
                printf("\n\tOptions: [%s]",
                       bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options));

                TCHECK(op->ospf_hello.hello_deadint);
                printf("\n\t  Hello Timer: %us, Dead Timer %us, Mask: %s, Priority: %u",
                       EXTRACT_16BITS(&op->ospf_hello.hello_helloint),
                       EXTRACT_32BITS(&op->ospf_hello.hello_deadint),
                       ipaddr_string(&op->ospf_hello.hello_mask),
                       op->ospf_hello.hello_priority);

		TCHECK(op->ospf_hello.hello_dr);
		if (op->ospf_hello.hello_dr.s_addr != 0)
			printf("\n\t  Designated Router %s",
			    ipaddr_string(&op->ospf_hello.hello_dr));

		TCHECK(op->ospf_hello.hello_bdr);
		if (op->ospf_hello.hello_bdr.s_addr != 0)
			printf(", Backup Designated Router %s",
			    ipaddr_string(&op->ospf_hello.hello_bdr));

                ap = op->ospf_hello.hello_neighbor;
                if ((u_char *)ap < dataend)
                        printf("\n\t  Neighbor List:");
                while ((u_char *)ap < dataend) {
                        TCHECK(*ap);
                        printf("\n\t    %s", ipaddr_string(ap));
                        ++ap;
                }
		break;	/* HELLO */

	case OSPF_TYPE_DD:
		TCHECK(op->ospf_db.db_options);
                printf("\n\tOptions: [%s]",
                       bittok2str(ospf_option_values,"none",op->ospf_db.db_options));
		TCHECK(op->ospf_db.db_flags);
                printf(", DD Flags: [%s]",
                       bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags));

		if (vflag) {
			/* Print all the LS adv's */
			lshp = op->ospf_db.db_lshdr;
			while (ospf_print_lshdr(lshp) != -1) {
				++lshp;
			}
		}
		break;

	case OSPF_TYPE_LS_REQ:
                lsrp = op->ospf_lsr;
                while ((u_char *)lsrp < dataend) {
                    TCHECK(*lsrp);

                    printf("\n\t  Advertising Router: %s, %s LSA (%u)",
                           ipaddr_string(&lsrp->ls_router),
                           tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)),
                           EXTRACT_32BITS(&lsrp->ls_type));

                    switch (EXTRACT_32BITS(lsrp->ls_type)) {
                        /* the LSA header for opaque LSAs was slightly changed */
                    case LS_TYPE_OPAQUE_LL:
                    case LS_TYPE_OPAQUE_AL:
                    case LS_TYPE_OPAQUE_DW:
                        printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u",
                               tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type),
                               lsrp->un_ls_stateid.opaque_field.opaque_type,
                               EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id));
                        break;
                    default:
                        printf(", LSA-ID: %s",
                               ipaddr_string(&lsrp->un_ls_stateid.ls_stateid));
                        break;
                    }
                    
                    ++lsrp;
                }
		break;

	case OSPF_TYPE_LS_UPDATE:
                lsap = op->ospf_lsu.lsu_lsa;
                TCHECK(op->ospf_lsu.lsu_count);
                lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count);
                printf(", %d LSA%s",lsa_count_max, lsa_count_max > 1 ? "s" : "");
                for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) {
                    printf("\n\t  LSA #%u",lsa_count);
                        lsap = (const struct lsa *)ospf_print_lsa(lsap);
                        if (lsap == NULL)
                                goto trunc;
                }
		break;

	case OSPF_TYPE_LS_ACK:
                lshp = op->ospf_lsa.lsa_lshdr;
                while (ospf_print_lshdr(lshp) != -1) {
                    ++lshp;
                }
                break;

	default:
		printf("v2 type (%d)", op->ospf_type);
		break;
	}
	return (0);
trunc:
	return (1);
}