icmpv6 works

This commit is contained in:
wangyu- 2018-07-24 08:33:42 -05:00
parent 2dc0670266
commit 184b198470
3 changed files with 167 additions and 47 deletions

@ -919,23 +919,45 @@ void iptables_rule() // handles -a -g --gen-add --keep-rule --clear --wait-loc
if(program_mode==client_mode) if(program_mode==client_mode)
{ {
tmp_pattern[0]=0;
if(raw_mode==mode_faketcp) if(raw_mode==mode_faketcp)
{ {
sprintf(tmp_pattern,"-s %s/32 -p tcp -m tcp --sport %d",remote_addr.get_ip(),remote_addr.get_port()); sprintf(tmp_pattern,"-s %s -p tcp -m tcp --sport %d",remote_addr.get_ip(),remote_addr.get_port());
} }
if(raw_mode==mode_udp) if(raw_mode==mode_udp)
{ {
sprintf(tmp_pattern,"-s %s/32 -p udp -m udp --sport %d",remote_addr.get_ip(),remote_addr.get_port()); sprintf(tmp_pattern,"-s %s -p udp -m udp --sport %d",remote_addr.get_ip(),remote_addr.get_port());
} }
if(raw_mode==mode_icmp) if(raw_mode==mode_icmp)
{ {
sprintf(tmp_pattern,"-s %s/32 -p icmp",remote_addr.get_ip()); if(raw_ip_version==AF_INET)
sprintf(tmp_pattern,"-s %s -p icmp --icmp-type 0",remote_addr.get_ip());
else
sprintf(tmp_pattern,"-s %s -p icmpv6 --icmpv6-type 129",remote_addr.get_ip());
} }
pattern=tmp_pattern; pattern+=tmp_pattern;
} }
if(program_mode==server_mode) if(program_mode==server_mode)
{ {
tmp_pattern[0]=0;
if(raw_ip_version==AF_INET)
{
if(local_addr.inner.ipv4.sin_addr.s_addr!=0)
{
sprintf(tmp_pattern,"-d %s ",local_addr.get_ip());
}
}
else
{
char zero_arr[16]={0};
if(memcmp(&local_addr.inner.ipv6.sin6_addr,zero_arr,16)!=0)
{
sprintf(tmp_pattern,"-d %s ",local_addr.get_ip());
}
}
pattern+=tmp_pattern;
tmp_pattern[0]=0;
if(raw_mode==mode_faketcp) if(raw_mode==mode_faketcp)
{ {
sprintf(tmp_pattern,"-p tcp -m tcp --dport %d",local_addr.get_port()); sprintf(tmp_pattern,"-p tcp -m tcp --dport %d",local_addr.get_port());
@ -946,16 +968,12 @@ void iptables_rule() // handles -a -g --gen-add --keep-rule --clear --wait-loc
} }
if(raw_mode==mode_icmp) if(raw_mode==mode_icmp)
{ {
if(local_addr.inner.ipv4.sin_addr.s_addr==0) if(raw_ip_version==AF_INET)
{ sprintf(tmp_pattern,"-p icmp --icmp-type 8");
sprintf(tmp_pattern,"-p icmp");
}
else else
{ sprintf(tmp_pattern,"-p icmpv6 --icmpv6-type 128");
sprintf(tmp_pattern,"-d %s/32 -p icmp",local_addr.get_ip());
}
} }
pattern=tmp_pattern; pattern+=tmp_pattern;
} }
/* /*
if(!simple_rule) if(!simple_rule)

@ -155,6 +155,18 @@ struct sock_filter code_icmp[] = {
{ 0x6, 0, 0, 0x00000000 }, { 0x6, 0, 0, 0x00000000 },
}; };
struct sock_filter code_icmp6[] = {
// { 0x28, 0, 0, 0x0000000c },
// { 0x15, 0, 6, 0x000086dd },
{ 0x30, 0, 0, 0x00000006 },
{ 0x15, 3, 0, 0x0000003a },
{ 0x15, 0, 3, 0x0000002c },
{ 0x30, 0, 0, 0x00000028 },
{ 0x15, 0, 1, 0x0000003a },
{ 0x6, 0, 0, 0x00040000 },
{ 0x6, 0, 0, 0x00000000 },
};
/* /*
tcpdump -i eth1 ip and icmp -d tcpdump -i eth1 ip and icmp -d
@ -227,7 +239,15 @@ packet_info_t::packet_info_t()
} }
else if (raw_mode == mode_icmp) else if (raw_mode == mode_icmp)
{ {
protocol = IPPROTO_ICMP; if(raw_ip_version==AF_INET)
{
protocol = IPPROTO_ICMP;
}
else
{
assert(raw_ip_version==AF_INET6);
protocol = IPPROTO_ICMPV6;
}
icmp_seq=0; icmp_seq=0;
} }
@ -399,8 +419,15 @@ void init_filter(int port)
} }
else if(raw_mode==mode_icmp) else if(raw_mode==mode_icmp)
{ {
bpf.len = sizeof(code_icmp)/sizeof(code_icmp[0]); if(raw_ip_version==AF_INET)
bpf.filter = code_icmp; {
bpf.len = sizeof(code_icmp)/sizeof(code_icmp[0]);
bpf.filter = code_icmp;
}else
{
bpf.len = sizeof(code_icmp6)/sizeof(code_icmp6[0]);
bpf.filter = code_icmp6;
}
} }
int dummy; int dummy;
@ -916,12 +943,7 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
memcpy(&recv_info.addr_ll,&g_sockaddr.ll,sizeof(recv_info.addr_ll)); memcpy(&recv_info.addr_ll,&g_sockaddr.ll,sizeof(recv_info.addr_ll));
} }
if(bind_addr_used && !recv_info.new_dst_ip.equal(bind_addr))
{
mylog(log_trace,"bind adress doenst match, dropped\n");
//printf(" bind adress doenst match, dropped\n");
return -1;
}
unsigned short iphdrlen; unsigned short iphdrlen;
int ip_len; int ip_len;
@ -943,6 +965,12 @@ int recv_raw_ip(raw_info_t &raw_info,char * &payload,int &payloadlen)
ip_len=ntohs(ip6h->payload_len)+iphdrlen; ip_len=ntohs(ip6h->payload_len)+iphdrlen;
} }
if(bind_addr_used && !recv_info.new_dst_ip.equal(bind_addr))
{
mylog(log_trace,"bind adress doenst match %s %s, dropped\n",recv_info.new_dst_ip.get_str1(), bind_addr.get_str2());
//printf(" bind adress doenst match, dropped\n");
return -1;
}
//if (!(iph->ihl > 0 && iph->ihl <=60)) { //if (!(iph->ihl > 0 && iph->ihl <=60)) {
// mylog(log_trace,"iph ihl error\n"); // mylog(log_trace,"iph ihl error\n");
@ -1047,7 +1075,13 @@ int peek_raw(raw_info_t &raw_info)
} }
case mode_icmp: case mode_icmp:
{ {
if(recv_info.protocol!=IPPROTO_ICMP) return -1; if(raw_ip_version==AF_INET)
{
if(recv_info.protocol!=IPPROTO_ICMP) return -1;
}else
{
if(recv_info.protocol!=IPPROTO_ICMPV6) return -1;
}
struct icmphdr *icmph=(icmphdr *)payload; struct icmphdr *icmph=(icmphdr *)payload;
if(payload_len<int(sizeof(udphdr))) if(payload_len<int(sizeof(udphdr)))
return -1; return -1;
@ -1066,24 +1100,53 @@ int send_raw_icmp(raw_info_t &raw_info, const char * payload, int payloadlen)
char send_raw_icmp_buf[buf_len]; char send_raw_icmp_buf[buf_len];
icmphdr *icmph=(struct icmphdr *) (send_raw_icmp_buf); icmphdr *icmph=(struct icmphdr *) (send_raw_icmp_buf);
memset(icmph,0,sizeof(icmphdr)); memset(icmph,0,sizeof(icmphdr));
if(program_mode==client_mode) if(raw_ip_version==AF_INET)
{ {
icmph->type=8; if(program_mode==client_mode)
{
icmph->type=8;
}
else
{
icmph->type=0;
}
} }
else else
{ {
icmph->type=0; if(program_mode==client_mode)
{
icmph->type=128;
}
else
{
icmph->type=129;
}
} }
icmph->code=0; icmph->code=0;
icmph->id=htons(send_info.src_port); icmph->id=htons(send_info.src_port);
icmph->seq=htons(send_info.icmp_seq); /////////////modify icmph->seq=htons(send_info.icmp_seq); /////////////modify
memcpy(send_raw_icmp_buf+sizeof(icmphdr),payload,payloadlen); memcpy(send_raw_icmp_buf+sizeof(icmphdr),payload,payloadlen);
icmph->check_sum = csum( (unsigned short*) send_raw_icmp_buf, sizeof(icmphdr)+payloadlen); if(raw_ip_version==AF_INET)
{
icmph->check_sum = csum( (unsigned short*) send_raw_icmp_buf, sizeof(icmphdr)+payloadlen);
}
else
{
pseudo_header6 v6;
struct pseudo_header6 *psh = &v6;
psh->src=send_info.new_src_ip.v6;
psh->dst=send_info.new_dst_ip.v6;
psh->next_header=IPPROTO_ICMPV6;
psh->tcp_length=htons(sizeof(icmphdr)+payloadlen);
psh->placeholder1 = 0;
psh->placeholder2 = 0;
icmph->check_sum = csum_with_header((char *)psh,sizeof(pseudo_header6), (unsigned short*) send_raw_icmp_buf, sizeof(icmphdr)+payloadlen);
}
if(send_raw_ip(raw_info,send_raw_icmp_buf,sizeof(icmphdr)+payloadlen)!=0) if(send_raw_ip(raw_info,send_raw_icmp_buf,sizeof(icmphdr)+payloadlen)!=0)
{ {
return -1; return -1;
@ -1276,7 +1339,7 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
psh->dest_address = send_info.new_dst_ip.v4; psh->dest_address = send_info.new_dst_ip.v4;
psh->placeholder = 0; psh->placeholder = 0;
psh->protocol = IPPROTO_TCP; psh->protocol = IPPROTO_TCP;
psh->tcp_length = htons(tcph->doff * 4 + payloadlen); psh->tcp_length = htons(tcp_totlen);
tcph->check = csum_with_header((char *)psh,sizeof(pseudo_header), (unsigned short*) send_raw_tcp_buf, tcp_totlen); tcph->check = csum_with_header((char *)psh,sizeof(pseudo_header), (unsigned short*) send_raw_tcp_buf, tcp_totlen);
} }
@ -1288,7 +1351,7 @@ int send_raw_tcp(raw_info_t &raw_info,const char * payload, int payloadlen) {
psh->src=send_info.new_src_ip.v6; psh->src=send_info.new_src_ip.v6;
psh->dst=send_info.new_dst_ip.v6; psh->dst=send_info.new_dst_ip.v6;
psh->next_header=IPPROTO_TCP; psh->next_header=IPPROTO_TCP;
psh->tcp_length=htons(tcph->doff * 4 + payloadlen); psh->tcp_length=htons(tcp_totlen);
psh->placeholder1 = 0; psh->placeholder1 = 0;
psh->placeholder2 = 0; psh->placeholder2 = 0;
@ -1489,10 +1552,21 @@ int recv_raw_icmp(raw_info_t &raw_info, char *&payload, int &payloadlen)
mylog(log_debug,"recv_raw_ip error\n"); mylog(log_debug,"recv_raw_ip error\n");
return -1; return -1;
} }
if(recv_info.protocol!=IPPROTO_ICMP) if(raw_ip_version==AF_INET)
{ {
//printf("not udp protocol\n"); if(recv_info.protocol!=IPPROTO_ICMP)
return -1; {
//printf("not udp protocol\n");
return -1;
}
}
else
{
if(recv_info.protocol!=IPPROTO_ICMPV6)
{
//printf("not udp protocol\n");
return -1;
}
} }
@ -1507,23 +1581,50 @@ int recv_raw_icmp(raw_info_t &raw_info, char *&payload, int &payloadlen)
recv_info.src_port=recv_info.dst_port=ntohs(icmph->id); recv_info.src_port=recv_info.dst_port=ntohs(icmph->id);
recv_info.icmp_seq=ntohs(icmph->seq); recv_info.icmp_seq=ntohs(icmph->seq);
if(program_mode==client_mode)
{
if(icmph->type!=0)
return -1;
}
else
{
if(icmph->type!=8)
return -1;
}
if(icmph->code!=0) if(icmph->code!=0)
return -1; return -1;
unsigned short check = csum( (unsigned short*) ip_payload, ip_payloadlen); unsigned short check ;
if(raw_ip_version==AF_INET)
{
if(program_mode==client_mode)
{
if(icmph->type!=0)
return -1;
}
else
{
if(icmph->type!=8)
return -1;
}
check= csum( (unsigned short*) ip_payload, ip_payloadlen);
}
else
{
if(program_mode==client_mode)
{
if(icmph->type!=129)
return -1;
}
else
{
if(icmph->type!=128)
return -1;
}
pseudo_header6 tmp_header;
struct pseudo_header6 *psh=&tmp_header ;
psh->src = recv_info.new_src_ip.v6;
psh->dst = recv_info.new_dst_ip.v6;
psh->placeholder1 = 0;
psh->placeholder2 = 0;
psh->next_header = IPPROTO_ICMPV6;
psh->tcp_length = htons(ip_payloadlen);
check = csum_with_header((char *)psh,sizeof(pseudo_header6), (unsigned short*) ip_payload, ip_payloadlen);
}
if(check!=0) if(check!=0)
{ {

@ -84,7 +84,8 @@ struct packet_info_t //todo change this to union
uint8_t protocol; uint8_t protocol;
//u32_t src_ip;
//u32_t dst_ip;
my_ip_t new_src_ip; my_ip_t new_src_ip;
my_ip_t new_dst_ip; my_ip_t new_dst_ip;