print-ospf.c

来自「TCPDUMP的C语言源代码,是在数据链路层的应用」· C语言 代码 · 共 1,158 行 · 第 1/3 页

C
1,158
字号
                    }                    TCHECK2(*tptr, tlv_length);                    switch(tlv_type) {                    case LS_OPAQUE_RI_TLV_CAP:                        if (tlv_length != 4) {                            printf("\n\t    Bogus length %u != 4", tlv_length);                            return(ls_end);                        }                        printf("Capabilities: %s",                               bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", EXTRACT_32BITS(tptr)));                        break;                    default:                        if (vflag <= 1) {                            if(!print_unknown_data(tptr,"\n\t      ",tlv_length))                                return(ls_end);                        }                        break;                    }                    tptr+=tlv_length;                    ls_length-=tlv_length;                }                break;            case LS_OPAQUE_TYPE_GRACE:                if (ospf_print_grace_lsa((u_int8_t *)(&lsap->lsa_un.un_grace_tlv.type),                                         ls_length) == -1) {                    return(ls_end);                }                break;	    case LS_OPAQUE_TYPE_TE:                if (ospf_print_te_lsa((u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type),                                      ls_length) == -1) {                    return(ls_end);                }                break;            default:                if (vflag <= 1) {                    if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,                                           "\n\t    ", ls_length))                        return(ls_end);                }                 break;            }        }        /* do we want to see an additionally hexdump ? */        if (vflag> 1)            if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,                                   "\n\t    ", ls_length)) {                return(ls_end);            }        	return (ls_end);trunc:	return (NULL);}static intospf_decode_lls(register const struct ospfhdr *op,		register u_int length){    register const u_char *dptr;    register const u_char *dataend;    register u_int length2;    register u_int16_t lls_type, lls_len;    register u_int32_t lls_flags;    switch (op->ospf_type) {    case OSPF_TYPE_HELLO:        if (!(op->ospf_hello.hello_options & OSPF_OPTION_L))            return (0);        break;    case OSPF_TYPE_DD:        if (!(op->ospf_db.db_options & OSPF_OPTION_L))            return (0);        break;    default:        return (0);    }    /* dig deeper if LLS data is available; see RFC4813 */    length2 = EXTRACT_16BITS(&op->ospf_len);    dptr = (u_char *)op + length2;    dataend = (u_char *)op + length;    if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {        dptr = dptr + op->ospf_authdata[3];        length2 += op->ospf_authdata[3];    }    if (length2 >= length) {        printf("\n\t[LLS truncated]");        return (1);    }    TCHECK2(*dptr, 2);    printf("\n\t  LLS: checksum: 0x%04x", (u_int)EXTRACT_16BITS(dptr));    dptr += 2;    TCHECK2(*dptr, 2);    length2 = EXTRACT_16BITS(dptr);    printf(", length: %u", length2);    dptr += 2;    TCHECK(*dptr);    while (dptr < dataend) {        TCHECK2(*dptr, 2);        lls_type = EXTRACT_16BITS(dptr);        printf("\n\t    %s (%u)",               tok2str(ospf_lls_tlv_values,"Unknown TLV",lls_type),               lls_type);        dptr += 2;        TCHECK2(*dptr, 2);        lls_len = EXTRACT_16BITS(dptr);        printf(", length: %u", lls_len);        dptr += 2;        switch (lls_type) {        case OSPF_LLS_EO:            if (lls_len != 4) {                printf(" [should be 4]");                lls_len = 4;            }            TCHECK2(*dptr, 4);            lls_flags = EXTRACT_32BITS(dptr);            printf("\n\t      Options: 0x%08x [%s]", lls_flags,                   bittok2str(ospf_lls_eo_options,"?",lls_flags));            break;        case OSPF_LLS_MD5:            if (lls_len != 20) {                printf(" [should be 20]");                lls_len = 20;            }			TCHECK2(*dptr, 4);            printf("\n\t      Sequence number: 0x%08x", EXTRACT_32BITS(dptr));            break;        }        dptr += lls_len;    }    return (0);trunc:    return (1);}static intospf_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));                TCHECK(op->ospf_db.db_ifmtu);                if (op->ospf_db.db_ifmtu) {                        printf(", MTU: %u", ntohs(op->ospf_db.db_ifmtu));                }                TCHECK(op->ospf_db.db_seq);                printf(", Sequence: 0x%08x", EXTRACT_32BITS(&op->ospf_db.db_seq));                /* Print all the LS adv's */                lshp = op->ospf_db.db_lshdr;                while (((u_char *)lshp < dataend) && 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:		break;	}	return (0);trunc:	return (1);}voidospf_print(register const u_char *bp, register u_int length,    const u_char *bp2 _U_){	register const struct ospfhdr *op;	register const u_char *dataend;	register const char *cp;	op = (struct ospfhdr *)bp;        /* XXX Before we do anything else, strip off the MD5 trailer */        TCHECK(op->ospf_authtype);        if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {                length -= OSPF_AUTH_MD5_LEN;                snapend -= OSPF_AUTH_MD5_LEN;        }	/* If the type is valid translate it, or just print the type */	/* value.  If it's not valid, say so and return */	TCHECK(op->ospf_type);	cp = tok2str(type2str, "unknown LS-type", op->ospf_type);	printf("OSPFv%u, %s, length %u",	       op->ospf_version,	       cp,	       length);	if (*cp == 'u')		return;        if(!vflag) { /* non verbose - so lets bail out here */                return;        }	TCHECK(op->ospf_len);	if (length != EXTRACT_16BITS(&op->ospf_len)) {		printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len));	}	if (length > EXTRACT_16BITS(&op->ospf_len)) {		dataend = bp + EXTRACT_16BITS(&op->ospf_len);	} else {		dataend = bp + length;	}	TCHECK(op->ospf_routerid);        printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf_routerid));	TCHECK(op->ospf_areaid);	if (op->ospf_areaid.s_addr != 0)		printf(", Area %s", ipaddr_string(&op->ospf_areaid));	else		printf(", Backbone Area");	if (vflag) {		/* Print authentication data (should we really do this?) */		TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata));                printf(", Authentication Type: %s (%u)",                       tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)),                       EXTRACT_16BITS(&op->ospf_authtype));		switch (EXTRACT_16BITS(&op->ospf_authtype)) {		case OSPF_AUTH_NONE:			break;		case OSPF_AUTH_SIMPLE:                        printf("\n\tSimple text password: ");                        safeputs((const char *)op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN);			break;		case OSPF_AUTH_MD5:                        printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x",                               *((op->ospf_authdata)+2),                               *((op->ospf_authdata)+3),                               EXTRACT_32BITS((op->ospf_authdata)+4));			break;		default:			return;		}	}	/* Do rest according to version.	 */	switch (op->ospf_version) {	case 2:		/* ospf version 2 */		if (ospf_decode_v2(op, dataend))			goto trunc;		if (length > EXTRACT_16BITS(&op->ospf_len)) {			if (ospf_decode_lls(op, length))				goto trunc;		}		break;	default:		printf(" ospf [version %d]", op->ospf_version);		break;	}			/* end switch on version */	return;trunc:	fputs(tstr, stdout);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?