PracticeDev/study_clang/pcap/telnet_proxy.c

225 lines
6.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*************************************************************************
> File Name : telnet_proxy.c
> Author : TL Song
> EMail : songtianlun@frytea.com
> Created Time : Thu Feb 18 18:57:20 2021
************************************************************************/
#include <stdio.h>
#include <string.h>
// #include <pthread.h>
#include <pcap.h>
#define SNAP_LEN 65536
// #define Make_VLAN
#ifdef Make_VLAN
#define RECV_DEVICE "eth0.3000"
#else
#define RECV_DEVICE "eth0"
#endif
#define RECV_SEND_DEVICE "eth1"
#define RETU_DEVICE "linux_dal"
#define RETU_SEND_DEVICE "eth0"
#define RECV_FILTER "src host 192.168.8.123 and arp or icmp or dst port 23"
#define RETU_FILTER ""
static char g_vlan_tag[4] = {0x81, 0x00, 0x0B, 0xB8};
#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(char *dev, const u_char *pkt, int len)
{
static pcap_t *handle = NULL;
char dev_str[64];
char err_buf[PCAP_ERRBUF_SIZE];
strcpy(dev_str, dev);
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 recv_dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
HexPrint((const char *)pkt_data, header->caplen);
#ifdef Make_VLAN
u_char pkt_send[header->caplen + sizeof(g_vlan_tag)];
memset(pkt_send, 0x00, sizeof(pkt_send));
memcpy(pkt_send, pkt_data, header->caplen);
memcpy(pkt_send+16, pkt_send+12, header->caplen-12);
memcpy(pkt_send+12, g_vlan_tag, sizeof(g_vlan_tag));
#else
u_char pkt_send[header->caplen];
memset(pkt_send, 0x00, sizeof(pkt_send));
memcpy(pkt_send, pkt_data, header->caplen);
#endif
HexPrint((const char *)pkt_send, sizeof(pkt_send));
dPrint("Send to %s ret : %d\n", RECV_SEND_DEVICE, send_pkt_pcap(RECV_SEND_DEVICE, (const u_char *)pkt_send, sizeof(pkt_send)));
// sleep(1);
}
void retu_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];
memset(pkt_send, 0x00, sizeof(pkt_send));
memcpy(pkt_send, pkt_data, header->caplen);
// HexPrint((const char *)pkt_send, sizeof(pkt_send));
dPrint("Send to %s ret : %d\n",RETU_SEND_DEVICE, send_pkt_pcap(RETU_SEND_DEVICE, (const u_char *)pkt_send, sizeof(pkt_send)));
}
// 接收前面板 eth0 发来的消息,转发到 eth1
void *recv_handl(void *args)
{
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program fp; /* The compiled filter expression */
char filter_exp[] = RECV_FILTER; /* The filter expression (filter 53 port)*/
pcap_t *handle;
bpf_u_int32 mask; /* The netmask of our sniffing device */
bpf_u_int32 net; /* The IP of our sniffing device */
printf("Recv Device: %s\n", RECV_DEVICE);
/*get network mask*/
if (pcap_lookupnet(RECV_DEVICE, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Can't get netmask for device %s\n", RECV_DEVICE);
net = 0;
mask = 0;
}
/*Open the session in promiscuous mode*/
handle = pcap_open_live(RECV_DEVICE, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", RECV_DEVICE, errbuf);
return;
}
/* Compile and apply the filter */
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
return;
}
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
return;
}
pcap_loop(handle, -1, recv_dispatcher_handler, NULL);
/* cleanup */
pcap_freecode(&fp);
pcap_close(handle);
dPrint("Capture complete.");
}
// 接收 linux_dal 发来的流量,转发到 eth0
void *retu_handl(void *args)
{
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program fp; /* The compiled filter expression */
char filter_exp[] = RETU_FILTER; /* The filter expression (filter 53 port)*/
pcap_t *handle;
bpf_u_int32 mask; /* The netmask of our sniffing device */
bpf_u_int32 net; /* The IP of our sniffing device */
printf("Recv Device: %s\n", RETU_DEVICE);
/*get network mask*/
if (pcap_lookupnet(RETU_DEVICE, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Can't get netmask for device %s\n", RETU_DEVICE);
net = 0;
mask = 0;
}
/*Open the session in promiscuous mode*/
handle = pcap_open_live(RETU_DEVICE, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", RETU_DEVICE, errbuf);
return;
}
/* Compile and apply the filter */
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
return;
}
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
return;
}
pcap_loop(handle, -1, retu_dispatcher_handler, NULL);
/* cleanup */
pcap_freecode(&fp);
pcap_close(handle);
dPrint("Capture complete.");
}
int main()
{
int ret = 0;
pthread_t tid_recv, tid_return;
// pthread_attr_t attr;
// pthread_attr_init(&attr);
// pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); //设置线程可分离
// 创建线程参数依次是创建的线程id线程参数调用的函数传入的函数参数
// ret = pthread_create(&tid_recv, NULL, recv_handl, NULL);
// if (ret != 0) {
// printf("pthread_create error: error_code = %d\n", ret);
// }
// ret = pthread_create(&tid_return, NULL, retu_handl, NULL);
// if (ret != 0) {
// printf("pthread_create error: error_code = %d\n", ret);
// }
// while(1) {};
// 线程分离
// pthread_exit(NULL);
pid_t fpid=fork();
if(fpid==0)
{
retu_handl(NULL);
printf("son/n");
}
else
{
recv_handl(NULL);
printf("father/n");
}
return 0;
}