PracticeDev/study_clang/pcap/telnet_proxy_single.c

187 lines
6.5 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 RECV_SEND_DEVICE "eth1"
#define RETU_DEVICE "linux_dal"
#define RETU_SEND_DEVICE RECV_DEVICE
#define RECV_FILTER "src host 192.168.8.123 and arp or icmp or dst port 23"
#define RETU_FILTER ""
// switch, 1、定义后以多进程模式运行2、定义后为抓到的包追加vlan标签。
// #define RUNNING_WITH_MULT_PROGRESS 0
// #define GREP_WITH_MAKE_VLAN 0
#define SNAP_LEN 65536
#ifndef GREP_WITH_MAKE_VLAN
#define RECV_DEVICE "eth0"
#else
#define RECV_DEVICE "eth0.3000"
#endif
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);\
}
char err_buf[PCAP_ERRBUF_SIZE];
struct bpf_program fp_recv; /* The compiled filter expression */
struct bpf_program fp_retu; /* The compiled filter expression */
char filter_recv[] = RECV_FILTER; /* The filter expression (filter 53 port)*/
char filter_retu[] = RETU_FILTER; /* The filter expression (filter 53 port)*/
pcap_t *handle_recv;
pcap_t *handle_retu;
pcap_t *handle_recv_send;
bpf_u_int32 mask_recv; /* The netmask of our sniffing device */
bpf_u_int32 mask_retu; /* The netmask of our sniffing device */
bpf_u_int32 net_recv; /* The IP of our sniffing device */
bpf_u_int32 net_retu; /* The IP of our sniffing device */
void recv_dispatcher_handler(u_char *temp1, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
// HexPrint((const char *)pkt_data, header->caplen);
#ifndef GREP_WITH_MAKE_VLAN
u_char pkt_send[header->caplen];
memset(pkt_send, 0x00, sizeof(pkt_send));
memcpy(pkt_send, pkt_data, header->caplen);
#else
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));
#endif
// HexPrint((const char *)pkt_send, sizeof(pkt_send));
dPrint("Send to %s ret : %d", RECV_SEND_DEVICE, pcap_sendpacket(handle_recv_send, pkt_send, sizeof(pkt_send)) );
}
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", RECV_DEVICE, pcap_sendpacket(handle_recv, pkt_send, sizeof(pkt_send)) );
}
// 接收前面板 eth0 发来的消息,转发到 eth1
void *recv_handl(void *args)
{
pcap_loop(handle_recv, -1, recv_dispatcher_handler, NULL);
dPrint("Capture complete.");
}
// 接收 linux_dal 发来的流量,转发到 eth0
void *retu_handl(void *args)
{
pcap_loop(handle_retu, -1, retu_dispatcher_handler, NULL);
dPrint("Capture complete.");
}
int main()
{
pthread_t tid_retu;
printf("Recv Device: %s\n", RECV_DEVICE);
printf("Retu Device: %s\n", RETU_DEVICE);
printf("Recv Send Device: %s\n", RECV_SEND_DEVICE);
printf("Retu Send Device: %s\n", RETU_SEND_DEVICE);
/*get network mask*/
if (pcap_lookupnet(RECV_DEVICE, &net_recv, &mask_recv, err_buf) == -1) {
fprintf(stderr, "Can't get netmask for device %s\n", RECV_DEVICE);
net_recv = 0;
mask_recv = 0;
}
if (pcap_lookupnet(RETU_DEVICE, &net_retu, &mask_retu, err_buf) == -1) {
fprintf(stderr, "Can't get netmask for device %s\n", RETU_DEVICE);
net_retu = 0;
mask_retu = 0;
}
/*Open the session in promiscuous mode*/
handle_recv = pcap_open_live(RECV_DEVICE, BUFSIZ, 1, 1000, err_buf);
if (handle_recv == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", RECV_DEVICE, err_buf);
return;
}
handle_recv_send = pcap_open_live(RECV_SEND_DEVICE, SNAP_LEN, 1, 1000, err_buf);
if (handle_recv_send == NULL)
{
fprintf(stderr, "Couldn't open device %s: %s\n", RECV_SEND_DEVICE, err_buf);
return 0;
}
handle_retu = pcap_open_live(RETU_DEVICE, BUFSIZ, 1, 1000, err_buf);
if (handle_retu == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", RETU_DEVICE, err_buf);
return;
}
/* 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;
}
if (pcap_compile(handle_retu, &fp_retu, filter_retu, 0, net_retu) == -1) {
fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_retu, pcap_geterr(handle_retu));
return;
}
if (pcap_setfilter(handle_recv, &fp_recv) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_recv, pcap_geterr(handle_recv));
return;
}
if (pcap_setfilter(handle_retu, &fp_retu) == -1) {
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_retu, pcap_geterr(handle_retu));
return;
}
#ifndef RUNNING_WITH_MULT_PROGRESS
int ret = pthread_create(&tid_retu, NULL, retu_handl, NULL);
if (ret != 0) {
printf("pthread_create error: error_code = %d\n", ret);
}
recv_handl(NULL);
pthread_exit(NULL);
#else
pid_t fpid=fork();
if(fpid==0)
{
retu_handl(NULL);
printf("son/n");
}
else
{
recv_handl(NULL);
printf("father/n");
}
#endif
/* cleanup */
pcap_freecode(&fp_recv);
pcap_close(handle_recv);
pcap_freecode(&fp_retu);
pcap_close(handle_retu);
dPrint("Capture complete.");
return 0;
}