mirror of
https://github.com/wangyu-/udp2raw.git
synced 2025-02-07 23:59:36 +08:00
new option pcap-send
This commit is contained in:
parent
4b8776c67a
commit
63950e2b22
74
main.cpp
74
main.cpp
@ -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);
|
||||
|
8
misc.cpp
8
misc.cpp
@ -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);
|
||||
|
62
network.cpp
62
network.cpp
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user