225 lines
6.8 KiB
C
225 lines
6.8 KiB
C
/*************************************************************************
|
||
> 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;
|
||
}
|