libpcap roughly works

This commit is contained in:
wangyu- 2018-06-14 08:01:03 -05:00
parent 83e13ebc5f
commit fed5bdc700
6 changed files with 230 additions and 17 deletions

View File

@ -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);

View File

@ -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)
{

View File

@ -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
View File

@ -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();

View File

@ -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);

View File

@ -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;