mirror of
https://github.com/wangyu-/udp2raw.git
synced 2025-02-08 08:09:34 +08:00
libpcap roughly works
This commit is contained in:
parent
83e13ebc5f
commit
fed5bdc700
45
common.h
45
common.h
@ -87,14 +87,53 @@ struct ip_port_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef u64_t fd64_t;
|
typedef u64_t fd64_t;
|
||||||
|
|
||||||
const int max_data_len=1800;
|
const int max_data_len=1800;
|
||||||
const int buf_len=max_data_len+400;
|
const int buf_len=max_data_len+400;
|
||||||
|
|
||||||
const int max_address_len=512;
|
const int max_address_len=512;
|
||||||
|
const int queue_len=2000;
|
||||||
|
|
||||||
|
struct queue_t
|
||||||
|
{
|
||||||
|
char data[queue_len][buf_len];
|
||||||
|
int data_len[queue_len];
|
||||||
|
|
||||||
|
int head=0;
|
||||||
|
int tail=0;
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
head=tail=0;
|
||||||
|
}
|
||||||
|
int empty()
|
||||||
|
{
|
||||||
|
if(head==tail) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
int full()
|
||||||
|
{
|
||||||
|
if( (tail+1)%queue_len==head ) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
void peek_front(char * & p,int &len)
|
||||||
|
{
|
||||||
|
assert(!empty());
|
||||||
|
p=data[head];
|
||||||
|
len=data_len[head];
|
||||||
|
}
|
||||||
|
void pop_front()
|
||||||
|
{
|
||||||
|
assert(!empty());
|
||||||
|
head++;head%=queue_len;
|
||||||
|
}
|
||||||
|
void push_back(char * p,int len)
|
||||||
|
{
|
||||||
|
assert(!full());
|
||||||
|
memcpy(data[tail],p,len);
|
||||||
|
data_len[tail]=len;
|
||||||
|
tail++;tail%=queue_len;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
u64_t get_current_time();
|
u64_t get_current_time();
|
||||||
u64_t pack_u64(u32_t a,u32_t b);
|
u64_t pack_u64(u32_t a,u32_t b);
|
||||||
|
53
main.cpp
53
main.cpp
@ -24,6 +24,9 @@ int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is
|
|||||||
|
|
||||||
mylog(log_trace,"<client_on_timer,send_info.ts_ack= %u>\n",send_info.ts_ack);
|
mylog(log_trace,"<client_on_timer,send_info.ts_ack= %u>\n",send_info.ts_ack);
|
||||||
|
|
||||||
|
|
||||||
|
//mylog(log_debug,"pcap cnt :%d\n",pcap_cnt);
|
||||||
|
|
||||||
if(raw_info.disabled)
|
if(raw_info.disabled)
|
||||||
{
|
{
|
||||||
conn_info.state.client_current_state=client_idle;
|
conn_info.state.client_current_state=client_idle;
|
||||||
@ -278,7 +281,10 @@ int client_on_raw_recv(conn_info_t &conn_info) //called when raw fd received a p
|
|||||||
|
|
||||||
if(conn_info.state.client_current_state==client_idle )
|
if(conn_info.state.client_current_state==client_idle )
|
||||||
{
|
{
|
||||||
recv(raw_recv_fd, 0,0, 0 );
|
//recv(raw_recv_fd, 0,0, 0 );
|
||||||
|
pthread_mutex_lock(&queue_mutex);
|
||||||
|
my_queue.pop_front();
|
||||||
|
pthread_mutex_unlock(&queue_mutex);
|
||||||
}
|
}
|
||||||
else if(conn_info.state.client_current_state==client_tcp_handshake)//received syn ack
|
else if(conn_info.state.client_current_state==client_tcp_handshake)//received syn ack
|
||||||
{
|
{
|
||||||
@ -515,10 +521,36 @@ void udp_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
|||||||
|
|
||||||
void raw_recv_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
void raw_recv_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
||||||
{
|
{
|
||||||
|
assert(0==1);
|
||||||
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||||
client_on_raw_recv(conn_info);
|
client_on_raw_recv(conn_info);
|
||||||
}
|
}
|
||||||
|
void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents)
|
||||||
|
{
|
||||||
|
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||||
|
|
||||||
|
//mylog(log_info,"async_cb called\n");
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int empty=0;char *p;int len;
|
||||||
|
pthread_mutex_lock(&queue_mutex);
|
||||||
|
empty=my_queue.empty();
|
||||||
|
if(!empty)
|
||||||
|
{
|
||||||
|
my_queue.peek_front(p,len);
|
||||||
|
my_queue.pop_front();
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&queue_mutex);
|
||||||
|
|
||||||
|
if(empty) break;
|
||||||
|
|
||||||
|
memcpy(g_packet_buf,p,len);
|
||||||
|
g_packet_buf_len=len;
|
||||||
|
assert(g_packet_buf_cnt==0);
|
||||||
|
g_packet_buf_cnt++;
|
||||||
|
client_on_raw_recv(conn_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
void clear_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents)
|
void clear_timer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents)
|
||||||
{
|
{
|
||||||
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||||
@ -677,11 +709,19 @@ int client_event_loop()
|
|||||||
// myexit(-1);
|
// myexit(-1);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
struct ev_io raw_watcher;
|
//struct ev_io raw_watcher;
|
||||||
|
|
||||||
|
//raw_watcher.data=&conn_info;
|
||||||
|
// ev_io_init(&raw_watcher, raw_recv_cb, raw_recv_fd, EV_READ);
|
||||||
|
//ev_io_start(loop, &raw_watcher);
|
||||||
|
|
||||||
|
g_default_loop=loop;
|
||||||
|
async_watcher.data=&conn_info;
|
||||||
|
ev_async_init(&async_watcher,async_cb);
|
||||||
|
ev_async_start(loop,&async_watcher);
|
||||||
|
|
||||||
|
init_raw_socket();
|
||||||
|
|
||||||
raw_watcher.data=&conn_info;
|
|
||||||
ev_io_init(&raw_watcher, raw_recv_cb, raw_recv_fd, EV_READ);
|
|
||||||
ev_io_start(loop, &raw_watcher);
|
|
||||||
|
|
||||||
|
|
||||||
int unbind=1;
|
int unbind=1;
|
||||||
@ -826,8 +866,8 @@ int main(int argc, char *argv[])
|
|||||||
local_ip_uint32=inet_addr(local_ip);
|
local_ip_uint32=inet_addr(local_ip);
|
||||||
source_ip_uint32=inet_addr(source_ip);
|
source_ip_uint32=inet_addr(source_ip);
|
||||||
|
|
||||||
mylog(log_info,"remote_ip=[%s], make sure this is a vaild IP address\n",remote_ip);
|
|
||||||
strcpy(remote_ip,remote_address);
|
strcpy(remote_ip,remote_address);
|
||||||
|
mylog(log_info,"remote_ip=[%s], make sure this is a vaild IP address\n",remote_ip);
|
||||||
remote_ip_uint32=inet_addr(remote_ip);
|
remote_ip_uint32=inet_addr(remote_ip);
|
||||||
|
|
||||||
init_random_number_fd();
|
init_random_number_fd();
|
||||||
@ -845,7 +885,6 @@ int main(int argc, char *argv[])
|
|||||||
md5((uint8_t*)tmp,strlen(tmp),(uint8_t*)key);
|
md5((uint8_t*)tmp,strlen(tmp),(uint8_t*)key);
|
||||||
|
|
||||||
iptables_rule();
|
iptables_rule();
|
||||||
init_raw_socket();
|
|
||||||
|
|
||||||
if(program_mode==client_mode)
|
if(program_mode==client_mode)
|
||||||
{
|
{
|
||||||
|
2
misc.cpp
2
misc.cpp
@ -82,6 +82,8 @@ int about_to_exit=0;
|
|||||||
int socket_buf_size=1024*1024;
|
int socket_buf_size=1024*1024;
|
||||||
int force_socket_buf=0;
|
int force_socket_buf=0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//char lower_level_arg[1000];
|
//char lower_level_arg[1000];
|
||||||
int process_lower_level_arg()//handle --lower-level option
|
int process_lower_level_arg()//handle --lower-level option
|
||||||
{
|
{
|
||||||
|
2
misc.h
2
misc.h
@ -119,6 +119,8 @@ extern pthread_t keep_thread;
|
|||||||
extern int keep_thread_running;
|
extern int keep_thread_running;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int process_lower_level_arg();
|
int process_lower_level_arg();
|
||||||
void print_help();
|
void print_help();
|
||||||
void iptables_rule();
|
void iptables_rule();
|
||||||
|
131
network.cpp
131
network.cpp
@ -41,6 +41,22 @@ const u32_t receive_window_random_range=512;
|
|||||||
const unsigned char wscale=0x05;
|
const unsigned char wscale=0x05;
|
||||||
|
|
||||||
libnet_t *libnet_handle;
|
libnet_t *libnet_handle;
|
||||||
|
pcap_t *pcap_handle;
|
||||||
|
int pcap_link_header_len=-1;
|
||||||
|
//int pcap_cnt=0;
|
||||||
|
queue_t my_queue;
|
||||||
|
|
||||||
|
pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
ev_async async_watcher;
|
||||||
|
|
||||||
|
ev_loop* g_default_loop;
|
||||||
|
|
||||||
|
pthread_t pcap_recv_thread;
|
||||||
|
|
||||||
|
char g_packet_buf[buf_len]; //dirty code, fix it later
|
||||||
|
int g_packet_buf_len=1;
|
||||||
|
int g_packet_buf_cnt=0;
|
||||||
|
|
||||||
struct sock_filter code_tcp_old[] = {
|
struct sock_filter code_tcp_old[] = {
|
||||||
{ 0x28, 0, 0, 0x0000000c },//0
|
{ 0x28, 0, 0, 0x0000000c },//0
|
||||||
@ -173,14 +189,111 @@ packet_info_t::packet_info_t()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *pcap_recv_thread_entry(void *none)
|
||||||
|
{
|
||||||
|
struct pcap_pkthdr *packet_header;
|
||||||
|
const u_char *pkt_data;
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
//printf("!!!\n");
|
||||||
|
int ret=pcap_next_ex(pcap_handle,&packet_header,&pkt_data);
|
||||||
|
|
||||||
|
switch (ret)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
continue;
|
||||||
|
case 1:
|
||||||
|
assert(packet_header->caplen <= packet_header->len);
|
||||||
|
assert(packet_header->caplen <= max_data_len);
|
||||||
|
if(packet_header->caplen<packet_header->len) continue;
|
||||||
|
|
||||||
|
if((int)packet_header->caplen<pcap_link_header_len) continue;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&queue_mutex);
|
||||||
|
if(!my_queue.full())
|
||||||
|
my_queue.push_back((char *)pkt_data+pcap_link_header_len,(int)(packet_header->caplen)-pcap_link_header_len);
|
||||||
|
pthread_mutex_unlock(&queue_mutex);
|
||||||
|
|
||||||
|
//pcap_cnt++;
|
||||||
|
|
||||||
|
ev_async_send (g_default_loop,&async_watcher);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
mylog(log_fatal,"pcap_next_ex error [%s]\n",pcap_geterr(pcap_handle));
|
||||||
|
myexit(-1);
|
||||||
|
break;
|
||||||
|
case -2:
|
||||||
|
assert(0==1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0==1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents);
|
||||||
|
|
||||||
int init_raw_socket()
|
int init_raw_socket()
|
||||||
{
|
{
|
||||||
char errbuf[LIBNET_ERRBUF_SIZE];
|
char libnet_errbuf[LIBNET_ERRBUF_SIZE];
|
||||||
|
|
||||||
libnet_handle = libnet_init(LIBNET_RAW4, dev, errbuf);
|
libnet_handle = libnet_init(LIBNET_RAW4, dev, libnet_errbuf);
|
||||||
|
|
||||||
|
if(libnet_handle==0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"libnet_init failed bc of [%s]\n",libnet_errbuf);
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char pcap_errbuf[PCAP_ERRBUF_SIZE];
|
||||||
|
|
||||||
|
pcap_handle=pcap_open_live(dev,max_data_len,0,1000,pcap_errbuf);
|
||||||
|
|
||||||
|
if(pcap_handle==0)
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"pcap_open_live failed bc of [%s]\n",pcap_errbuf);
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret=pcap_datalink(pcap_handle);
|
||||||
|
|
||||||
|
if(ret==DLT_EN10MB)
|
||||||
|
{
|
||||||
|
pcap_link_header_len=14;
|
||||||
|
}
|
||||||
|
else if(ret==DLT_NULL)
|
||||||
|
{
|
||||||
|
pcap_link_header_len=4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mylog(log_fatal,"unknown pcap link type : %d\n",ret);
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(pthread_create(&pcap_recv_thread, NULL, pcap_recv_thread_entry, 0)) {
|
||||||
|
mylog(log_fatal, "Error creating thread\n");
|
||||||
|
myexit(-1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
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(2);
|
||||||
|
}
|
||||||
|
if (pcap_setfilter(handle, &fp) == -1) {
|
||||||
|
fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
|
||||||
|
return(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
assert(libnet_handle!=0);
|
|
||||||
|
|
||||||
g_ip_id_counter=get_true_random_number()%65535;
|
g_ip_id_counter=get_true_random_number()%65535;
|
||||||
if(lower_level==0)
|
if(lower_level==0)
|
||||||
@ -728,13 +841,20 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
|||||||
const packet_info_t &send_info=raw_info.send_info;
|
const packet_info_t &send_info=raw_info.send_info;
|
||||||
packet_info_t &recv_info=raw_info.recv_info;
|
packet_info_t &recv_info=raw_info.recv_info;
|
||||||
|
|
||||||
static char recv_raw_ip_buf[buf_len];
|
//static char recv_raw_ip_buf[buf_len];
|
||||||
|
|
||||||
iphdr * iph;
|
iphdr * iph;
|
||||||
struct sockaddr_ll saddr={0};
|
struct sockaddr_ll saddr={0};
|
||||||
socklen_t saddr_size = sizeof(saddr);
|
socklen_t saddr_size = sizeof(saddr);
|
||||||
int flag=0;
|
int flag=0;
|
||||||
int recv_len = recvfrom(raw_recv_fd, recv_raw_ip_buf, max_data_len+1, flag ,(sockaddr*)&saddr , &saddr_size);
|
|
||||||
|
//int recv_len = recvfrom(raw_recv_fd, recv_raw_ip_buf, max_data_len+1, flag ,(sockaddr*)&saddr , &saddr_size);
|
||||||
|
|
||||||
|
assert(g_packet_buf_cnt==1);
|
||||||
|
g_packet_buf_cnt--;
|
||||||
|
|
||||||
|
int recv_len=g_packet_buf_len;
|
||||||
|
char *recv_raw_ip_buf=g_packet_buf;
|
||||||
|
|
||||||
if(recv_len==max_data_len+1)
|
if(recv_len==max_data_len+1)
|
||||||
{
|
{
|
||||||
@ -758,7 +878,6 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *ip_begin=recv_raw_ip_buf+link_level_header_len; //14 is eth net header
|
char *ip_begin=recv_raw_ip_buf+link_level_header_len; //14 is eth net header
|
||||||
|
|
||||||
iph = (struct iphdr *) (ip_begin);
|
iph = (struct iphdr *) (ip_begin);
|
||||||
|
12
network.h
12
network.h
@ -27,6 +27,18 @@ extern int random_drop;
|
|||||||
|
|
||||||
extern int ifindex;
|
extern int ifindex;
|
||||||
|
|
||||||
|
extern queue_t my_queue;
|
||||||
|
|
||||||
|
extern ev_async async_watcher;
|
||||||
|
extern ev_loop* g_default_loop;
|
||||||
|
|
||||||
|
extern pthread_mutex_t queue_mutex;
|
||||||
|
extern int pcap_cnt;
|
||||||
|
|
||||||
|
extern char g_packet_buf[buf_len];
|
||||||
|
extern int g_packet_buf_len;
|
||||||
|
extern int g_packet_buf_cnt;
|
||||||
|
|
||||||
struct icmphdr
|
struct icmphdr
|
||||||
{
|
{
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user