new option pcap-send

This commit is contained in:
wangyu- 2018-06-15 06:47:39 -05:00
parent 4b8776c67a
commit 63950e2b22
4 changed files with 132 additions and 19 deletions

@ -12,6 +12,10 @@ char hb_buf[buf_len];
int on_epoll_recv_event=0; //TODO, just a flag to help detect epoll infinite shoot
u32_t detect_interval=1500;
u64_t laste_detect_time=0;
int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is ready in epoll
{
packet_info_t &send_info=conn_info.raw_info.send_info;
@ -26,6 +30,47 @@ int client_on_timer(conn_info_t &conn_info) //for client. called when a timer is
//mylog(log_debug,"pcap cnt :%d\n",pcap_cnt);
if(send_with_pcap&&!pcap_header_captured)
{
if(get_current_time()-laste_detect_time>detect_interval)
{
laste_detect_time=get_current_time();
}
else
{
return 0;
}
struct sockaddr_in remote_addr_in={0};
socklen_t slen = sizeof(sockaddr_in);
//memset(&remote_addr_in, 0, sizeof(remote_addr_in));
remote_addr_in.sin_family = AF_INET;
remote_addr_in.sin_port = htons(remote_port);
remote_addr_in.sin_addr.s_addr = remote_ip_uint32;
int new_udp_fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(new_udp_fd<0)
{
mylog(log_warn,"create udp_fd error\n");
return -1;
}
setnonblocking(new_udp_fd);
u64_t tmp=get_true_random_number();
int ret=sendto(new_udp_fd,(char*)(&tmp),sizeof(tmp),0,(struct sockaddr *)&remote_addr_in,sizeof(remote_addr_in));
if(ret==-1)
{
mylog(log_warn,"sendto() failed\n");
}
close(new_udp_fd);
mylog(log_info,"waiting for a use-able packet to be captured\n");
return 0;
}
if(raw_info.disabled)
{
@ -530,6 +575,30 @@ void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents)
{
conn_info_t & conn_info= *((conn_info_t*)watcher->data);
if(send_with_pcap&&!pcap_header_captured)
{
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) return;
pcap_header_captured=1;
assert(pcap_link_header_len!=-1);
memcpy(pcap_header_buf,p,pcap_link_header_len);
log_bare(log_info,"link level header captured:\n");
for(int i=0;i<pcap_link_header_len;i++)
log_bare(log_info,"<%x>",(u32_t)(unsigned char)pcap_header_buf[i]);
log_bare(log_info,"\n");
return ;
}
//mylog(log_info,"async_cb called\n");
while(1)
{
@ -545,8 +614,9 @@ void async_cb(struct ev_loop *loop, struct ev_async *watcher, int revents)
if(empty) break;
memcpy(g_packet_buf,p,len);
g_packet_buf_len=len;
int new_len=len-pcap_link_header_len;
memcpy(g_packet_buf,p+pcap_link_header_len,new_len);
g_packet_buf_len=new_len;
assert(g_packet_buf_cnt==0);
g_packet_buf_cnt++;
client_on_raw_recv(conn_info);

@ -284,6 +284,7 @@ void process_arg(int argc, char *argv[]) //process all options
{"set-ttl", required_argument, 0, 1},
{"dev", required_argument, 0, 1},
{"dns-resolve", no_argument, 0, 1},
{"pcap-send", no_argument, 0, 1},
{NULL, 0, 0, 0}
};
@ -670,11 +671,16 @@ void process_arg(int argc, char *argv[]) //process all options
enable_dns_resolve=1;
mylog(log_info,"dns-resolve enabled\n");
}
else if(strcmp(long_options[option_index].name,"dev")==0) // currently not used
else if(strcmp(long_options[option_index].name,"dev")==0)
{
sscanf(optarg,"%s",dev);
mylog(log_info,"dev=[%s]\n",dev);
}
else if(strcmp(long_options[option_index].name,"pcap-send")==0)
{
send_with_pcap=1;
mylog(log_info,"--pcap-send enabled, now pcap will be used for sending packet instead of libnet\n");
}
else
{
mylog(log_warn,"ignored unknown long option ,option_index:%d code:<%x>\n",option_index, optopt);

@ -63,6 +63,10 @@ libnet_ptag_t g_ptag=0;
struct bpf_program g_filter;
int send_with_pcap=0;
int pcap_header_captured=0;
int pcap_header_buf[buf_len];
/*
struct sock_filter code_tcp_old[] = {
{ 0x28, 0, 0, 0x0000000c },//0
@ -209,7 +213,7 @@ void my_packet_handler(
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);
my_queue.push_back((char *)pkt_data,(int)(packet_header->caplen));
pthread_mutex_unlock(&queue_mutex);
//pcap_cnt++;
@ -280,6 +284,7 @@ int init_raw_socket()
pcap_handle = pcap_create( dev, pcap_errbuf );
if(pcap_handle==0)
{
mylog(log_fatal,"pcap_create failed bc of [%s]\n",pcap_errbuf);
@ -291,6 +296,11 @@ int init_raw_socket()
assert( pcap_set_timeout(pcap_handle, 1) ==0);
assert( pcap_set_immediate_mode(pcap_handle,1) ==0);
if(send_with_pcap)
{
pcap_setdirection(pcap_handle,PCAP_D_INOUT);
}
int ret = pcap_activate( pcap_handle );
if( ret < 0 )
{
@ -315,17 +325,22 @@ int init_raw_socket()
myexit(-1);
}
//mylog(log_info,"filter expression is [%s]\n",filter_exp);
if (pcap_compile(pcap_handle, &g_filter, "", 0, PCAP_NETMASK_UNKNOWN ) == -1) {
char filter_exp[1000];
assert(source_ip_uint32!=0);
sprintf(filter_exp,"src %s and dst %s and (tcp or udp or icmp)",my_ntoa(source_ip_uint32),remote_ip);
if (pcap_compile(pcap_handle, &g_filter, filter_exp, 0, PCAP_NETMASK_UNKNOWN ) == -1) {
printf("Bad filter - %s\n", pcap_geterr(pcap_handle));
assert(0==1);
}
/*
if (pcap_setfilter(pcap_handle, &g_filter) == -1) {
printf("Error setting filter - %s\n", pcap_geterr(pcap_handle));
assert(0==1);
}*/
}
if(pthread_create(&pcap_recv_thread, NULL, pcap_recv_thread_entry, 0)) {
@ -459,7 +474,7 @@ void init_filter(int port)
mylog(log_info,"filter expression is [%s]\n",filter_exp);
pthread_mutex_lock(&filter_mutex);//not sure if mutex is needed here
//pthread_mutex_lock(&filter_mutex);//not sure if mutex is needed here
pcap_freecode(&g_filter);
@ -474,7 +489,7 @@ void init_filter(int port)
assert(0==1);
}
pthread_mutex_unlock(&filter_mutex);
//pthread_mutex_unlock(&filter_mutex);
/*
if(disable_bpf_filter) return;
//if(raw_mode==mode_icmp) return ;
@ -778,7 +793,8 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
{
const packet_info_t &send_info=raw_info.send_info;
const packet_info_t &recv_info=raw_info.recv_info;
char send_raw_ip_buf[buf_len];
char send_raw_ip_buf0[buf_len+pcap_link_header_len];
char * send_raw_ip_buf=send_raw_ip_buf0+pcap_link_header_len;
if(raw_info.disabled)
{
@ -820,21 +836,35 @@ int send_raw_ip(raw_info_t &raw_info,const char * payload,int payloadlen)
/*if(lower_level) iph->check =
csum ((unsigned short *) send_raw_ip_buf, iph->ihl*4); //this is not necessary ,kernel will always auto fill this
else*/
else
iph->check=0;
*/
if(! send_with_pcap)
{
g_ptag=libnet_build_ipv4(ip_tot_len, iph->tos, ntohs(iph->id), ntohs(iph->frag_off),
iph->ttl , iph->protocol , iph->check , iph->saddr, iph->daddr,
(const unsigned char *)payload, payloadlen, libnet_handle, g_ptag);
g_ptag=libnet_build_ipv4(ip_tot_len, iph->tos, ntohs(iph->id), ntohs(iph->frag_off),
iph->ttl , send_info.protocol, iph->check , iph->saddr, iph->daddr,
(const unsigned char *)payload, payloadlen, libnet_handle, g_ptag);
assert(g_ptag!=-1 &&g_ptag!=0);
assert(g_ptag!=-1 &&g_ptag!=0);
int ret;
ret= libnet_write(libnet_handle);
int ret;
ret= libnet_write(libnet_handle);
assert(ret!=-1);
}
else
{
iph->tot_len=htons(ip_tot_len);
iph->check =csum ((unsigned short *) send_raw_ip_buf, iph->ihl*4);
assert(ret!=-1);
assert(pcap_header_captured==1);
assert(pcap_link_header_len!=-1);
memcpy(send_raw_ip_buf0,pcap_header_buf,pcap_link_header_len);
assert(pcap_sendpacket(pcap_handle,(const unsigned char *)send_raw_ip_buf0,ip_tot_len+pcap_link_header_len)==0);
}

@ -39,6 +39,12 @@ extern char g_packet_buf[buf_len];
extern int g_packet_buf_len;
extern int g_packet_buf_cnt;
extern int pcap_link_header_len;
extern int send_with_pcap;
extern int pcap_header_captured;
extern int pcap_header_buf[buf_len];
struct icmphdr
{
uint8_t type;
@ -210,6 +216,7 @@ struct raw_info_t
};//g_raw_info;
int init_raw_socket();
void init_filter(int port);