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)
{
tmp_pattern[0]=0;
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)
{
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)
{
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)
{
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)
{
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(local_addr.inner.ipv4.sin_addr.s_addr==0)
{
sprintf(tmp_pattern,"-p icmp");
}
if(raw_ip_version==AF_INET)
sprintf(tmp_pattern,"-p icmp --icmp-type 8");
else
{
sprintf(tmp_pattern,"-d %s/32 -p icmp",local_addr.get_ip());
}
sprintf(tmp_pattern,"-p icmpv6 --icmpv6-type 128");
}
pattern=tmp_pattern;
pattern+=tmp_pattern;
}
/*
if(!simple_rule)

@ -155,6 +155,18 @@ struct sock_filter code_icmp[] = {
{ 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
@ -227,7 +239,15 @@ packet_info_t::packet_info_t()
}
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;
}
@ -399,8 +419,15 @@ void init_filter(int port)
}
else if(raw_mode==mode_icmp)
{
bpf.len = sizeof(code_icmp)/sizeof(code_icmp[0]);
bpf.filter = code_icmp;
if(raw_ip_version==AF_INET)
{
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;
@ -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));
}
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;
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;
}
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)) {
// mylog(log_trace,"iph ihl error\n");
@ -1047,7 +1075,13 @@ int peek_raw(raw_info_t &raw_info)
}
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;
if(payload_len<int(sizeof(udphdr)))
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];
icmphdr *icmph=(struct icmphdr *) (send_raw_icmp_buf);
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
{
icmph->type=0;
if(program_mode==client_mode)
{
icmph->type=128;
}
else
{
icmph->type=129;
}
}
icmph->code=0;
icmph->id=htons(send_info.src_port);
icmph->seq=htons(send_info.icmp_seq); /////////////modify
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)
{
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->placeholder = 0;
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);
}
@ -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->dst=send_info.new_dst_ip.v6;
psh->next_header=IPPROTO_TCP;
psh->tcp_length=htons(tcph->doff * 4 + payloadlen);
psh->tcp_length=htons(tcp_totlen);
psh->placeholder1 = 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");
return -1;
}
if(recv_info.protocol!=IPPROTO_ICMP)
if(raw_ip_version==AF_INET)
{
//printf("not udp protocol\n");
return -1;
if(recv_info.protocol!=IPPROTO_ICMP)
{
//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.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)
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)
{

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