Linux/C语言实现网卡报文获取与内容修改转发

该实例实现ARP反向代理

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <pcap.h>
#include <assert.h>
#include <stdbool.h>


#define RECV_SEND_DEVICE "ens38"
#define RECV_FILTER     "arp or icmp"


const char proxy_mac[6] = {0x00, 0x0c, 0x29, 0x93, 0x19, 0x97};




#define SNAP_LEN   65536
#define Host_Size  1024
#define uchar unsigned char
#define dPrint(fmt, ...) do{fprintf(stderr, "[%s:%d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);}while(0)
#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);\
}


typedef struct Ethernet_Head_S
{
    uchar dmac[6];
    uchar smac[6];
    uchar ftype[2];
}Ethernet_Head_T;


typedef struct Arp_Frame_S
{
    uchar hw_type[2];
    uchar pro_type[2];
    uchar hw_size;
    uchar pro_size;
    uchar opcode[2];
    uchar send_mac[6];
    uchar send_ip[4];
    uchar target_mac[6];
    uchar target_ip[4];
}Arp_Frame_T;


typedef struct Ipv4_Frame_S
{
    uchar ver_ihl;
    uchar tos;
    uchar total_len[2];
    uchar ident[2];
    uchar flags[2];
    uchar ttl;
    uchar protocol;
    uchar head_checksum[2];
    uchar src_ip[4];
    uchar dst_ip[4];         
}Ipv4_Frame_T;


typedef struct Host_Ip_Mac_S
{
    uchar ip[4];
    uchar mac[6];
}Host_Ip_Mac_T;


Host_Ip_Mac_T host_ip[Host_Size];
unsigned int host_num = 0;
char err_buf[PCAP_ERRBUF_SIZE];
struct bpf_program fp_recv;      /* The compiled filter expression */
char filter_recv[] = RECV_FILTER;  /* The filter expression (filter 53 port)*/
pcap_t *handle_recv;
bpf_u_int32 mask_recv;       /* The netmask of our sniffing device */
bpf_u_int32 net_recv;        /* The IP of our sniffing device */




bool is_broadcast(char *dmac, int len)
{   
    int i;
    for(i=0;i<len;i++)
    {
        uchar x = dmac[i];
        if(x != 0xff)
        {
            return false;      
        }
    }
    return true;
}


int is_host_exist(char *src_ip, size_t len)
{
    int i;
    if(host_num)
    {
        for(i=0; i<host_num; i++)
        {   
            if(memcmp(src_ip, &host_ip[i].ip, len) == 0)
                return i+1;
        }
        return 0;
    }
    return 0;
}


void make_arp_frame(const struct pcap_pkthdr *header, const u_char *pkt_data)
{
    int ret = 0;
    char dst_ip[4] = {0};
    memcpy(dst_ip, pkt_data+38, sizeof(dst_ip));
    ret = is_host_exist(dst_ip, sizeof(dst_ip));
    if(ret)
    {
        u_char pkt_send[header->caplen];
        memset(pkt_send, 0x00, sizeof(pkt_send));
        memcpy(pkt_send, pkt_data, header->caplen);
        memcpy(pkt_send, host_ip[ret-1].mac, sizeof(proxy_mac));
        memcpy(pkt_send+32, host_ip[ret-1].mac, sizeof(proxy_mac));
        memcpy(pkt_send+6, proxy_mac, sizeof(proxy_mac));
        memcpy(pkt_send+22, proxy_mac, sizeof(proxy_mac));
        pcap_sendpacket(handle_recv, pkt_send, sizeof(pkt_send));
    }
}


void make_icmp_frame(const struct pcap_pkthdr *header, const u_char *pkt_data)
{
    int ret = 0;
    char dst_ip[4] = {0};
    memcpy(dst_ip, pkt_data+30, sizeof(dst_ip));
    ret = is_host_exist(dst_ip, sizeof(dst_ip));
    if(ret)
    {
        u_char pkt_send[header->caplen];
        memset(pkt_send, 0x00, sizeof(pkt_send));
        memcpy(pkt_send, pkt_data, header->caplen);
        memcpy(pkt_send, host_ip[ret-1].mac, sizeof(proxy_mac));
        memcpy(pkt_send+6, proxy_mac, sizeof(proxy_mac));
        pcap_sendpacket(handle_recv, pkt_send, sizeof(pkt_send));
    }
}




void recv_dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
    //HexPrint((const char *)pkt_data, header->caplen);
    char dst_mac[6] = {0};
    char src_mac[6] = {0};
    memcpy(dst_mac, pkt_data, sizeof(dst_mac));
    memcpy(src_mac, pkt_data+6, sizeof(src_mac));
    if(memcmp(src_mac, proxy_mac, sizeof(proxy_mac)) != 0)
    {
        int ret = is_broadcast(dst_mac,sizeof(dst_mac));
        if(ret)
        {
            char src_ip[4] = {0};
            memcpy(src_ip, pkt_data+28, sizeof(src_ip));
            ret = is_host_exist(src_ip, sizeof(src_ip));
            if(ret == 0)
            {   
                memcpy(&host_ip[host_num].ip, pkt_data+28, sizeof(int));
                memcpy(&host_ip[host_num].mac, pkt_data+22, sizeof(proxy_mac));
                host_num++;
            }
            u_char pkt_send[header->caplen];
            memset(pkt_send, 0x00, sizeof(pkt_send));
            memcpy(pkt_send, pkt_data, header->caplen);
            memcpy(pkt_send+6, proxy_mac, sizeof(proxy_mac));
            memcpy(pkt_send+22, proxy_mac, sizeof(proxy_mac));
            pcap_sendpacket(handle_recv, pkt_send, sizeof(pkt_send));   
        }
        else
        {
            if(memcmp(dst_mac, proxy_mac, sizeof(proxy_mac)) == 0)
            {  
                if(pkt_data[12] == 0x08 && pkt_data[13] == 0x06)
                {  
                    //arp
                    char src_ip[4] = {0};
                    memcpy(src_ip, pkt_data+28, sizeof(src_ip));
                    ret = is_host_exist(src_ip, sizeof(src_ip));
                    if(ret == 0)
                    {   
                        memcpy(&host_ip[host_num].ip, pkt_data+28, sizeof(int));
                        memcpy(&host_ip[host_num].mac, pkt_data+22, sizeof(proxy_mac));
                        host_num++;
                    }
                    make_arp_frame(header, pkt_data);     
               }
               if(pkt_data[12] == 0x08 && pkt_data[13] == 0x00)
               {
                    make_icmp_frame(header, pkt_data);
               }
            }
        }     
                              
    }
}


void *pcakage_recv(void *args)
{
    pcap_loop(handle_recv, -1, recv_dispatcher_handler, NULL);
    return NULL;
}


int main()
{
    int ret = 0;
    printf("Recv Device: %s\n", RECV_SEND_DEVICE);
    printf("Send Device: %s\n", RECV_SEND_DEVICE);


    /*get network mask*/
    if (pcap_lookupnet(RECV_SEND_DEVICE, &net_recv, &mask_recv, err_buf) == -1) {
        fprintf(stderr, "Can't get netmask for device %s\n", RECV_SEND_DEVICE);
        net_recv = 0;
        mask_recv = 0;
    }
  
    /*Open the session in promiscuous mode*/
    handle_recv = pcap_open_live(RECV_SEND_DEVICE, SNAP_LEN, 1, 1, err_buf);
    if (handle_recv == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", RECV_SEND_DEVICE, err_buf);
        return -1;
    }
    


    /* Compile and apply the filter */
    if (pcap_compile(handle_recv, &fp_recv, filter_recv, 0, net_recv) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_recv, pcap_geterr(handle_recv));
        return -1;
    }


    if (pcap_setfilter(handle_recv, &fp_recv) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n", filter_recv, pcap_geterr(handle_recv));
        return -1;
    }
   
    pthread_t recv_thread;
    ret = (pthread_create(&recv_thread, NULL, pcakage_recv, NULL) == 0);
    assert(ret == true);
    pthread_join(recv_thread,NULL);
    
    /* cleanup */
    pcap_freecode(&fp_recv);
    pcap_close(handle_recv);


    dPrint("Capture complete.");
    return 0;
}

Python实现网卡报文获取与内容修改转发

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云淡风轻ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值