【libpcap】利用pcap实现抓包发包

#include 
#include 
#include 


#define SNAP_LEN 65536
static char g_ftag[6] = {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE};

/*
struct pcap_pkthdr
{
    struct timeval ts;  ts是一个结构struct timeval,它有两个部分,第一部分是1900开始以来的秒数,第二部分是当前秒之后的毫秒数
    bpf_u_int32 caplen;  表示抓到的数据长度
    bpf_u_int32 len;   表示数据包的实际长度
}

*/
#define dPrint(fmt, args...) printf("[%s:%d] "fmt"\r\n", __FUNCTION__, __LINE__, ##args)
#define HexPrint(_buf, _len) \
{\
    int _m_i = 0;\
    char *_m_buf = (char *)(_buf);\
    int _m_len = (int)(_len);\
    printf("[%s:%d] \r\n", __FUNCTION__, __LINE__);\
    printf("*****************************\n");\
    for(_m_i = 0; _m_i < _m_len; _m_i++)\
    {\
        printf("\033[32m%02x \033[0m", _m_buf[_m_i] & 0xff);\
        if(!((_m_i+1) % 10)) printf("\n");\
    }\
    printf("\nsize = %d\n*****************************\n", _m_len);\
}

int send_pkt_pcap(const u_char *pkt, int len)
{
    static pcap_t *handle = NULL;
    char dev_str[64];   
    char err_buf[PCAP_ERRBUF_SIZE];

    
    strcpy(dev_str, "linux_dal");
    if(NULL == handle)
    {
        handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf);
        if (handle == NULL) 
        {
            fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf);
            return 0;
        }       
    }
    
    return pcap_sendpacket(handle, pkt, len);   
}

void dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
    HexPrint((const char *)pkt_data, header->caplen);
    
    u_char pkt_send[header->caplen + sizeof(g_ftag)];
    
    memset(pkt_send, 0x00, sizeof(pkt_send));
    memcpy(pkt_send, g_ftag, sizeof(g_ftag));
    memcpy(pkt_send + sizeof(g_ftag), pkt_data, header->caplen);
    
    HexPrint((const char *)pkt_send, sizeof(pkt_send)); 
    
    dPrint("Send ret : %d", send_pkt_pcap((const u_char *)pkt_send, sizeof(pkt_send)));
}


int main()
{
    pcap_t *handle;
    char err_buf[PCAP_ERRBUF_SIZE];
    char dev_str[64];
    struct bpf_program fp;
    
    strcpy(dev_str, "ens33");
    
    /* open capture device */
    handle = pcap_open_live(dev_str, SNAP_LEN, 1, 1000, err_buf);
    if (handle == NULL) 
    {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev_str, err_buf);
        return 0;
    }
    
    /* make sure we're capturing on an Ethernet device*/
    if (pcap_datalink(handle) != DLT_EN10MB) 
    {
        fprintf(stderr, "%s is not an Ethernet\n", dev_str);
        return 0;
    }
    
    /* compile the filter expression */
    if (pcap_compile(handle, &fp, "src host 192.168.245.1 and icmp", 0, 24) == -1)
    {
        fprintf(stderr, "Couldn't parse filter %s: %s\n",
        "***", pcap_geterr(handle));
        return 0;
    }
    
    /* apply the compiled filter */
    if (pcap_setfilter(handle, &fp) == -1) 
    {
        fprintf(stderr, "Couldn't install filter %s: %s\n",
        "***", pcap_geterr(handle));
        return 0;
    }
    
    pcap_loop(handle, -1, dispatcher_handler, NULL);
    
    /* cleanup */
    pcap_freecode(&fp);
    pcap_close(handle);
    
    dPrint("Capture complete.");

    return 0;
}

你可能感兴趣的:(Linux积累,c语言,winpcap,linux)