C libpcap解决了DLT条目,一些讨厌的bug

时间:2011-01-18 00:32:03

标签: c libpcap

在编写我自己的嗅探器时,我发现了一个只有在谈论以太网时才会启动的示例。其他DLT_types已被忽略。他们可以在pcap-bpf.h中找到我写的一些 试图实现缺少pcap_resolve_dlt()的行。这真是讨厌的代码(1),似乎工作,虽然我遇到了一个令人讨厌的错误,其中一个需要给相应的数字空间,如:

user@debian:~/tmp$ ./resolve_dlt 114
DLT_LTALK       114
user@debian:~/tmp$ ./resolve_dlt 14
DLT_ATM_RFC1483 11
user@debian:~/tmp$ ./resolve_dlt " 14"
DLT_RAW         14

也许这个方法本身是完全错误的,应该直接grep pcap-bpf.h。

1)http://nopaste.info/4a2470cc83.html,使用strstr()

亲切的问候,

查尔斯

标签:C libpcap DLT _

3 个答案:

答案 0 :(得分:0)

您正在执行strstr(dlt [i],argv [1]),因此第一个“14”与“DLT_ATM_RFC1483”中的文本匹配,但文本“14”与“DLT_RAW 14”中的文本匹配。

答案 1 :(得分:0)

您可以使用令牌粘贴操作符来使这项工作更好一点:

#include <stdlib.h>
#include <stdio.h>
#include <pcap-bpf.h>

#define TAB_ENTRY(x) { x, #x }

struct {
    long dlt_code;
    const char *dlt_name;
} dlt_tab[] = {
    TAB_ENTRY(DLT_NULL),
    TAB_ENTRY(DLT_EN10MB),
    TAB_ENTRY(DLT_EN3MB),
    TAB_ENTRY(DLT_AX25),
    TAB_ENTRY(DLT_PRONET),
    TAB_ENTRY(DLT_CHAOS),
    TAB_ENTRY(DLT_IEEE802),
    TAB_ENTRY(DLT_ARCNET),
    TAB_ENTRY(DLT_SLIP),
    TAB_ENTRY(DLT_PPP),
    TAB_ENTRY(DLT_FDDI),
    TAB_ENTRY(DLT_ATM_RFC1483),
    TAB_ENTRY(DLT_RAW),
    TAB_ENTRY(DLT_RAW),
    TAB_ENTRY(DLT_SLIP_BSDOS),
    TAB_ENTRY(DLT_PPP_BSDOS),
    TAB_ENTRY(DLT_SLIP_BSDOS),
    TAB_ENTRY(DLT_PPP_BSDOS),
    TAB_ENTRY(DLT_ATM_CLIP),
    TAB_ENTRY(DLT_REDBACK_SMARTEDGE),
    TAB_ENTRY(DLT_PPP_SERIAL),
    TAB_ENTRY(DLT_PPP_ETHER),
    TAB_ENTRY(DLT_SYMANTEC_FIREWALL),
    TAB_ENTRY(DLT_C_HDLC),
    TAB_ENTRY(DLT_C_HDLC),
    TAB_ENTRY(DLT_IEEE802_11),
    TAB_ENTRY(DLT_FRELAY),
    TAB_ENTRY(DLT_LOOP),
    TAB_ENTRY(DLT_LOOP),
    TAB_ENTRY(DLT_ENC),
    TAB_ENTRY(DLT_ENC),
    TAB_ENTRY(DLT_LINUX_SLL),
    TAB_ENTRY(DLT_LTALK),
    TAB_ENTRY(DLT_ECONET),
    TAB_ENTRY(DLT_IPFILTER),
    TAB_ENTRY(DLT_PFLOG),
    TAB_ENTRY(DLT_CISCO_IOS),
    TAB_ENTRY(DLT_PRISM_HEADER),
    TAB_ENTRY(DLT_AIRONET_HEADER),
    TAB_ENTRY(DLT_HHDLC),
    TAB_ENTRY(DLT_IP_OVER_FC),
    TAB_ENTRY(DLT_SUNATM),
    TAB_ENTRY(DLT_RIO),
    TAB_ENTRY(DLT_PCI_EXP),
    TAB_ENTRY(DLT_AURORA),
    TAB_ENTRY(DLT_IEEE802_11_RADIO),
    TAB_ENTRY(DLT_TZSP),
    TAB_ENTRY(DLT_ARCNET_LINUX),
    TAB_ENTRY(DLT_JUNIPER_MLPPP),
    TAB_ENTRY(DLT_JUNIPER_MLFR),
    TAB_ENTRY(DLT_JUNIPER_ES),
    TAB_ENTRY(DLT_JUNIPER_GGSN),
    TAB_ENTRY(DLT_JUNIPER_MFR),
    TAB_ENTRY(DLT_JUNIPER_ATM2),
    TAB_ENTRY(DLT_JUNIPER_SERVICES),
    TAB_ENTRY(DLT_JUNIPER_ATM1),
    TAB_ENTRY(DLT_APPLE_IP_OVER_IEEE1394),
    TAB_ENTRY(DLT_MTP2_WITH_PHDR),
    TAB_ENTRY(DLT_MTP2),
    TAB_ENTRY(DLT_MTP3),
    TAB_ENTRY(DLT_SCCP),
    TAB_ENTRY(DLT_DOCSIS),
    TAB_ENTRY(DLT_LINUX_IRDA),
    TAB_ENTRY(DLT_IBM_SP),
    TAB_ENTRY(DLT_IBM_SN),
    TAB_ENTRY(DLT_USER0),
    TAB_ENTRY(DLT_USER1),
    TAB_ENTRY(DLT_USER2),
    TAB_ENTRY(DLT_USER3),
    TAB_ENTRY(DLT_USER4),
    TAB_ENTRY(DLT_USER5),
    TAB_ENTRY(DLT_USER6),
    TAB_ENTRY(DLT_USER7),
    TAB_ENTRY(DLT_USER8),
    TAB_ENTRY(DLT_USER9),
    TAB_ENTRY(DLT_USER10),
    TAB_ENTRY(DLT_USER11),
    TAB_ENTRY(DLT_USER12),
    TAB_ENTRY(DLT_USER13),
    TAB_ENTRY(DLT_USER14),
    TAB_ENTRY(DLT_USER15),
    TAB_ENTRY(DLT_IEEE802_11_RADIO_AVS),
    TAB_ENTRY(DLT_JUNIPER_MONITOR),
    TAB_ENTRY(DLT_BACNET_MS_TP),
    TAB_ENTRY(DLT_PPP_PPPD),
    TAB_ENTRY(DLT_PPP_PPPD),
    TAB_ENTRY(DLT_PPP_PPPD),
    TAB_ENTRY(DLT_JUNIPER_PPPOE),
    TAB_ENTRY(DLT_JUNIPER_PPPOE_ATM),
    TAB_ENTRY(DLT_GPRS_LLC),
    TAB_ENTRY(DLT_GPF_T),
    TAB_ENTRY(DLT_GPF_F),
    TAB_ENTRY(DLT_GCOM_T1E1),
    TAB_ENTRY(DLT_GCOM_SERIAL),
    TAB_ENTRY(DLT_JUNIPER_PIC_PEER),
    TAB_ENTRY(DLT_ERF_ETH),
    TAB_ENTRY(DLT_ERF_POS),
    TAB_ENTRY(DLT_LINUX_LAPD),
    TAB_ENTRY(DLT_JUNIPER_ETHER),
    TAB_ENTRY(DLT_JUNIPER_PPP),
    TAB_ENTRY(DLT_JUNIPER_FRELAY),
    TAB_ENTRY(DLT_JUNIPER_CHDLC),
    TAB_ENTRY(DLT_MFR),
    TAB_ENTRY(DLT_JUNIPER_VP),
    TAB_ENTRY(DLT_A429),
    TAB_ENTRY(DLT_A653_ICM),
    TAB_ENTRY(DLT_USB),
    TAB_ENTRY(DLT_BLUETOOTH_HCI_H4),
    TAB_ENTRY(DLT_IEEE802_16_MAC_CPS),
    TAB_ENTRY(DLT_USB_LINUX),
    TAB_ENTRY(DLT_CAN20B),
    TAB_ENTRY(DLT_IEEE802_15_4_LINUX),
    TAB_ENTRY(DLT_PPI),
    TAB_ENTRY(DLT_IEEE802_16_MAC_CPS_RADIO),
    TAB_ENTRY(DLT_JUNIPER_ISM),
    TAB_ENTRY(DLT_IEEE802_15_4),
    TAB_ENTRY(DLT_SITA),
    TAB_ENTRY(DLT_ERF),
    TAB_ENTRY(DLT_RAIF1),
    TAB_ENTRY(DLT_IPMB),
    TAB_ENTRY(DLT_JUNIPER_ST),
    TAB_ENTRY(DLT_BLUETOOTH_HCI_H4_WITH_PHDR)
};

int main(int argc, char *argv[])
{
    char *endptr = NULL;
    long code;
    int i, found;

    if (argc > 1)
        code = strtol(argv[1], &endptr, 0);

    if (!endptr || endptr == argv[1]) {
        fprintf(stderr, "Usage: %s <dlt_code>\n", argv[0]);
        exit(2);
    }

    found = 0;
    for (i = 0; i < (sizeof dlt_tab / sizeof dlt_tab[0]); i++) {
        if (dlt_tab[i].dlt_code == code) {
            found = 1;
            break;
        }
    }

    if (!found) {
        printf("%ld not found\n", code);
        exit(1);
    }

    printf("%ld is %s\n", code, dlt_tab[i].dlt_name);
    return 0;
}

示例:

$ ./bpf 12
12 is DLT_RAW
$ ./bpf 120
120 is DLT_AIRONET_HEADER

(注意12在Linux系统上是DLT_RAW,而不是14)。

答案 2 :(得分:0)

至少在较新版本的libpcap / WinPcap中,您可以使用pcap_datalink_val_to_name将DLT_值映射到DLT_名称。 resolve_dlt可以在其第一个参数上使用strtol()并将结果传递给pcap_datalink_val_to_name(当然,检查错误后,以及不适合int的值)。