mirror of
https://github.com/wangyu-/udp2raw.git
synced 2025-02-07 23:59:36 +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;
|
||||
|
||||
const int max_data_len=1800;
|
||||
const int buf_len=max_data_len+400;
|
||||
|
||||
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 pack_u64(u32_t a,u32_t b);
|
||||
|
55
main.cpp
55
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_debug,"pcap cnt :%d\n",pcap_cnt);
|
||||
|
||||
if(raw_info.disabled)
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
assert(0==1);
|
||||
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||
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)
|
||||
{
|
||||
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
|
||||
@ -677,11 +709,19 @@ int client_event_loop()
|
||||
// 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;
|
||||
@ -825,9 +865,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
local_ip_uint32=inet_addr(local_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);
|
||||
mylog(log_info,"remote_ip=[%s], make sure this is a vaild IP address\n",remote_ip);
|
||||
remote_ip_uint32=inet_addr(remote_ip);
|
||||
|
||||
init_random_number_fd();
|
||||
@ -845,7 +885,6 @@ int main(int argc, char *argv[])
|
||||
md5((uint8_t*)tmp,strlen(tmp),(uint8_t*)key);
|
||||
|
||||
iptables_rule();
|
||||
init_raw_socket();
|
||||
|
||||
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 force_socket_buf=0;
|
||||
|
||||
|
||||
|
||||
//char lower_level_arg[1000];
|
||||
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;
|
||||
|
||||
|
||||
|
||||
|
||||
int process_lower_level_arg();
|
||||
void print_help();
|
||||
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;
|
||||
|
||||
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[] = {
|
||||
{ 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()
|
||||
{
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
struct sockaddr_ll saddr={0};
|
||||
socklen_t saddr_size = sizeof(saddr);
|
||||
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)
|
||||
{
|
||||
@ -758,7 +878,6 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
char *ip_begin=recv_raw_ip_buf+link_level_header_len; //14 is eth net header
|
||||
|
||||
iph = (struct iphdr *) (ip_begin);
|
||||
|
12
network.h
12
network.h
@ -27,6 +27,18 @@ extern int random_drop;
|
||||
|
||||
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
|
||||
{
|
||||
uint8_t type;
|
||||
|
Loading…
x
Reference in New Issue
Block a user