print-fr.c

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

C
885
字号
            /* infinite loop check */            if (ie_type == 0 || ie_len <= sizeof(struct ie_tlv_header_t))                return hdr_len;            TCHECK2(*tptr,ie_len);            tptr+=sizeof(struct ie_tlv_header_t);            /* tlv len includes header */            ie_len-=sizeof(struct ie_tlv_header_t);            tlen-=sizeof(struct ie_tlv_header_t);            switch (ie_type) {            case MFR_CTRL_IE_MAGIC_NUM:                printf("0x%08x",EXTRACT_32BITS(tptr));                break;            case MFR_CTRL_IE_BUNDLE_ID: /* same message format */            case MFR_CTRL_IE_LINK_ID:                for (idx = 0; idx < ie_len && idx < MFR_ID_STRING_MAXLEN; idx++) {                    if (*(tptr+idx) != 0) /* don't print null termination */                        safeputchar(*(tptr+idx));                    else                        break;                }                break;            case MFR_CTRL_IE_TIMESTAMP:                if (ie_len == sizeof(struct timeval)) {                    ts_print((const struct timeval *)tptr);                    break;                }                /* fall through and hexdump if no unix timestamp */                /*                 * FIXME those are the defined IEs that lack a decoder                 * you are welcome to contribute code ;-)                 */            case MFR_CTRL_IE_VENDOR_EXT:            case MFR_CTRL_IE_CAUSE:            default:                if (vflag <= 1)                    print_unknown_data(tptr,"\n\t  ",ie_len);                break;            }            /* do we want to see a hexdump of the IE ? */            if (vflag > 1 )                print_unknown_data(tptr,"\n\t  ",ie_len);                        tlen-=ie_len;            tptr+=ie_len;        }        return hdr_len;    }/* * FRF.16 Fragmentation Frame *  *      7    6    5    4    3    2    1    0 *    +----+----+----+----+----+----+----+----+ *    | B  | E  | C=0|seq. (high 4 bits) | EA  | *    +----+----+----+----+----+----+----+----+ *    |        sequence  (low 8 bits)         | *    +----+----+----+----+----+----+----+----+ *    |        DLCI (6 bits)        | CR | EA  | *    +----+----+----+----+----+----+----+----+ *    |   DLCI (4 bits)   |FECN|BECN| DE | EA | *    +----+----+----+----+----+----+----+----+ */    sequence_num = (p[0]&0x1e)<<7 | p[1];    /* whole packet or first fragment ? */    if ((p[0] & MFR_BEC_MASK) == MFR_FRAG_FRAME ||        (p[0] & MFR_BEC_MASK) == MFR_B_BIT) {        printf("FRF.16 Frag, seq %u, Flags [%s], ",               sequence_num,               bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)));        hdr_len = 2;        fr_print(p+hdr_len,length-hdr_len);        return hdr_len;    }    /* must be a middle or the last fragment */    printf("FRF.16 Frag, seq %u, Flags [%s]",           sequence_num,           bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)));    print_unknown_data(p,"\n\t",length);    return hdr_len; trunc:    printf("[|mfr]");    return length;}/* an NLPID of 0xb1 indicates a 2-byte * FRF.15 header *  *      7    6    5    4    3    2    1    0 *    +----+----+----+----+----+----+----+----+ *    ~              Q.922 header             ~ *    +----+----+----+----+----+----+----+----+ *    |             NLPID (8 bits)            | NLPID=0xb1 *    +----+----+----+----+----+----+----+----+ *    | B  | E  | C  |seq. (high 4 bits) | R  | *    +----+----+----+----+----+----+----+----+ *    |        sequence  (low 8 bits)         | *    +----+----+----+----+----+----+----+----+ */#define FR_FRF15_FRAGTYPE 0x01static voidfrf15_print (const u_char *p, u_int length) {        u_int16_t sequence_num, flags;    flags = p[0]&MFR_BEC_MASK;    sequence_num = (p[0]&0x1e)<<7 | p[1];    printf("FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u",           sequence_num,           bittok2str(frf_flag_values,"none",flags),           p[0]&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End",           length);/* TODO: * depending on all permutations of the B, E and C bit * dig as deep as we can - e.g. on the first (B) fragment * there is enough payload to print the IP header * on non (B) fragments it depends if the fragmentation * model is end-to-end or interface based wether we want to print * another Q.922 header */}/* * Q.933 decoding portion for framerelay specific. *//* Q.933 packet format                      Format of Other Protocols                             using Q.933 NLPID                  +-------------------------------+                              |        Q.922 Address          |                   +---------------+---------------+                  |Control  0x03  | NLPID   0x08  |                          +---------------+---------------+                          |          L2 Protocol ID       |                  | octet 1       |  octet 2      |                  +-------------------------------+                  |          L3 Protocol ID       |                  | octet 2       |  octet 2      |                  +-------------------------------+                  |         Protocol Data         |                  +-------------------------------+                  | FCS                           |                  +-------------------------------+ *//* L2 (Octet 1)- Call Reference Usually is 0x0 *//* * L2 (Octet 2)- Message Types definition 1 byte long. *//* Call Establish */#define MSG_TYPE_ESC_TO_NATIONAL  0x00#define MSG_TYPE_ALERT            0x01#define MSG_TYPE_CALL_PROCEEDING  0x02#define MSG_TYPE_CONNECT          0x07#define MSG_TYPE_CONNECT_ACK      0x0F#define MSG_TYPE_PROGRESS         0x03#define MSG_TYPE_SETUP            0x05/* Call Clear */#define MSG_TYPE_DISCONNECT       0x45#define MSG_TYPE_RELEASE          0x4D#define MSG_TYPE_RELEASE_COMPLETE 0x5A#define MSG_TYPE_RESTART          0x46#define MSG_TYPE_RESTART_ACK      0x4E/* Status */#define MSG_TYPE_STATUS           0x7D#define MSG_TYPE_STATUS_ENQ       0x75struct tok fr_q933_msg_values[] = {    { MSG_TYPE_ESC_TO_NATIONAL, "ESC to National" },    { MSG_TYPE_ALERT, "Alert" },    { MSG_TYPE_CALL_PROCEEDING, "Call proceeding" },    { MSG_TYPE_CONNECT, "Connect" },    { MSG_TYPE_CONNECT_ACK, "Connect ACK" },    { MSG_TYPE_PROGRESS, "Progress" },    { MSG_TYPE_SETUP, "Setup" },    { MSG_TYPE_DISCONNECT, "Disconnect" },    { MSG_TYPE_RELEASE, "Release" },    { MSG_TYPE_RELEASE_COMPLETE, "Release Complete" },    { MSG_TYPE_RESTART, "Restart" },    { MSG_TYPE_RESTART_ACK, "Restart ACK" },    { MSG_TYPE_STATUS, "Status Reply" },    { MSG_TYPE_STATUS_ENQ, "Status Enquiry" },    { 0, NULL }};#define MSG_ANSI_LOCKING_SHIFT	0x95#define FR_LMI_ANSI_REPORT_TYPE_IE	0x01#define FR_LMI_ANSI_LINK_VERIFY_IE_91	0x19 /* details? */#define FR_LMI_ANSI_LINK_VERIFY_IE	0x03#define FR_LMI_ANSI_PVC_STATUS_IE	0x07#define FR_LMI_CCITT_REPORT_TYPE_IE	0x51#define FR_LMI_CCITT_LINK_VERIFY_IE	0x53#define FR_LMI_CCITT_PVC_STATUS_IE	0x57struct tok fr_q933_ie_values_codeset5[] = {    { FR_LMI_ANSI_REPORT_TYPE_IE, "ANSI Report Type" },    { FR_LMI_ANSI_LINK_VERIFY_IE_91, "ANSI Link Verify" },    { FR_LMI_ANSI_LINK_VERIFY_IE, "ANSI Link Verify" },    { FR_LMI_ANSI_PVC_STATUS_IE, "ANSI PVC Status" },    { FR_LMI_CCITT_REPORT_TYPE_IE, "CCITT Report Type" },    { FR_LMI_CCITT_LINK_VERIFY_IE, "CCITT Link Verify" },    { FR_LMI_CCITT_PVC_STATUS_IE, "CCITT PVC Status" },    { 0, NULL }};#define FR_LMI_REPORT_TYPE_IE_FULL_STATUS 0#define FR_LMI_REPORT_TYPE_IE_LINK_VERIFY 1#define FR_LMI_REPORT_TYPE_IE_ASYNC_PVC   2struct tok fr_lmi_report_type_ie_values[] = {    { FR_LMI_REPORT_TYPE_IE_FULL_STATUS, "Full Status" },    { FR_LMI_REPORT_TYPE_IE_LINK_VERIFY, "Link verify" },    { FR_LMI_REPORT_TYPE_IE_ASYNC_PVC, "Async PVC Status" },    { 0, NULL }};/* array of 16 codepages - currently we only support codepage 1,5 */static struct tok *fr_q933_ie_codesets[] = {    NULL,    fr_q933_ie_values_codeset5,    NULL,    NULL,    NULL,    fr_q933_ie_values_codeset5,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL};static int fr_q933_print_ie_codeset5(const struct ie_tlv_header_t  *ie_p,    const u_char *p);typedef int (*codeset_pr_func_t)(const struct ie_tlv_header_t  *ie_p,    const u_char *p);/* array of 16 codepages - currently we only support codepage 1,5 */static codeset_pr_func_t fr_q933_print_ie_codeset[] = {    NULL,    fr_q933_print_ie_codeset5,    NULL,    NULL,    NULL,    fr_q933_print_ie_codeset5,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL,    NULL};voidq933_print(const u_char *p, u_int length){	const u_char *ptemp = p;	struct ie_tlv_header_t  *ie_p;        int olen;	int is_ansi = 0;        u_int codeset;        u_int ie_is_known = 0;	if (length < 9) {	/* shortest: Q.933a LINK VERIFY */		printf("[|q.933]");		return;	}        codeset = p[2]&0x0f;   /* extract the codeset */	if (p[2] == MSG_ANSI_LOCKING_SHIFT) {	        is_ansi = 1;	}            printf("%s", eflag ? "" : "Q.933, ");	/* printing out header part */	printf("%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset);	if (p[0]) {	        printf(", Call Ref: 0x%02x", p[0]);	}        if (vflag) {                printf(", %s (0x%02x), length %u",		       tok2str(fr_q933_msg_values,			       "unknown message", p[1]),		       p[1],		       length);        } else {                printf(", %s",		       tok2str(fr_q933_msg_values,			       "unknown message 0x%02x", p[1]));	}        olen = length; /* preserve the original length for non verbose mode */	if (length < (u_int)(2 - is_ansi)) {		printf("[|q.933]");		return;	}	length -= 2 + is_ansi;	ptemp += 2 + is_ansi;		/* Loop through the rest of IE */	while (length > sizeof(struct ie_tlv_header_t)) {		ie_p = (struct ie_tlv_header_t  *)ptemp;		if (length < sizeof(struct ie_tlv_header_t) ||		    length < sizeof(struct ie_tlv_header_t) + ie_p->ie_len) {                    if (vflag) { /* not bark if there is just a trailer */                        printf("\n[|q.933]");                    } else {                        printf(", length %u",olen);		    }                    return;		}                /* lets do the full IE parsing only in verbose mode                 * however some IEs (DLCI Status, Link Verify)                 * are also interestting in non-verbose mode */                if (vflag) {                    printf("\n\t%s IE (0x%02x), length %u: ",                           tok2str(fr_q933_ie_codesets[codeset],				   "unknown", ie_p->ie_type),                           ie_p->ie_type,                           ie_p->ie_len);		}                /* sanity check */                if (ie_p->ie_type == 0 || ie_p->ie_len == 0) {                    return;		}                if (fr_q933_print_ie_codeset[codeset] != NULL) {                    ie_is_known = fr_q933_print_ie_codeset[codeset](ie_p, ptemp);		}                               if (vflag >= 1 && !ie_is_known) {                    print_unknown_data(ptemp+2,"\n\t",ie_p->ie_len);		}                /* do we want to see a hexdump of the IE ? */                if (vflag> 1 && ie_is_known) {                    print_unknown_data(ptemp+2,"\n\t  ",ie_p->ie_len);		}		length = length - ie_p->ie_len - 2;		ptemp = ptemp + ie_p->ie_len + 2;	}        if (!vflag) {            printf(", length %u",olen);	}}static intfr_q933_print_ie_codeset5(const struct ie_tlv_header_t  *ie_p, const u_char *p){        u_int dlci;        switch (ie_p->ie_type) {        case FR_LMI_ANSI_REPORT_TYPE_IE: /* fall through */        case FR_LMI_CCITT_REPORT_TYPE_IE:            if (vflag) {                printf("%s (%u)",                       tok2str(fr_lmi_report_type_ie_values,"unknown",p[2]),                       p[2]);	    }            return 1;        case FR_LMI_ANSI_LINK_VERIFY_IE: /* fall through */        case FR_LMI_CCITT_LINK_VERIFY_IE:        case FR_LMI_ANSI_LINK_VERIFY_IE_91:            if (!vflag) {                printf(", ");	    }            printf("TX Seq: %3d, RX Seq: %3d", p[2], p[3]);            return 1;        case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */        case FR_LMI_CCITT_PVC_STATUS_IE:            if (!vflag) {                printf(", ");	    }            /* now parse the DLCI information element. */                                if ((ie_p->ie_len < 3) ||                (p[2] & 0x80) ||                ((ie_p->ie_len == 3) && !(p[3] & 0x80)) ||                ((ie_p->ie_len == 4) && ((p[3] & 0x80) || !(p[4] & 0x80))) ||                ((ie_p->ie_len == 5) && ((p[3] & 0x80) || (p[4] & 0x80) ||                                   !(p[5] & 0x80))) ||                (ie_p->ie_len > 5) ||                !(p[ie_p->ie_len + 1] & 0x80)) {                printf("Invalid DLCI IE");	    }                                dlci = ((p[2] & 0x3F) << 4) | ((p[3] & 0x78) >> 3);            if (ie_p->ie_len == 4) {                dlci = (dlci << 6) | ((p[4] & 0x7E) >> 1);	    }            else if (ie_p->ie_len == 5) {                dlci = (dlci << 13) | (p[4] & 0x7F) | ((p[5] & 0x7E) >> 1);	    }            printf("DLCI %u: status %s%s", dlci,                    p[ie_p->ie_len + 1] & 0x8 ? "New, " : "",                    p[ie_p->ie_len + 1] & 0x2 ? "Active" : "Inactive");            return 1;	}        return 0;}

⌨️ 快捷键说明

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