135 lines
3.4 KiB
C
135 lines
3.4 KiB
C
|
/*************************************************************************
|
|||
|
> File Name : icmp_proxy.c
|
|||
|
> Author : TL Song
|
|||
|
> EMail : songtianlun@frytea.com
|
|||
|
> Created Time : Thu Feb 18 19:23:50 2021
|
|||
|
************************************************************************/
|
|||
|
|
|||
|
#include <stdio.h>
|
|||
|
#include <string.h>
|
|||
|
#include <pcap.h>
|
|||
|
|
|||
|
|
|||
|
#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, ...) 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);\
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
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, "eth1");
|
|||
|
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, "eth0");
|
|||
|
|
|||
|
/* 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, "vlan and src host 192.168.1.123", 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;
|
|||
|
}
|