c语言怎样调取网卡信息,Linux/C语言实现网卡报文获取与内容修改转发

#include

#include

#include

#include

#include

#include

#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

{

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

{

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;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值