增加ipv6支持

This commit is contained in:
崔一鸣
2019-06-14 11:13:15 +08:00
parent 3ed1bac877
commit 02abbae3d9
5 changed files with 546 additions and 225 deletions

View File

@@ -1,13 +1,25 @@
#include "kni_utils.h"
#include <sys/ioctl.h>
#include <netinet/ip6.h>
#include <net/if.h>
int kni_stream_addr_trans(const struct layer_addr *addr, char *output, int len){
char saddr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(addr->tuple4_v4->saddr), saddr, INET_ADDRSTRLEN);
char daddr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(addr->tuple4_v4->daddr), daddr, INET_ADDRSTRLEN);
snprintf(output, len, "%s:%d -> %s:%d", saddr, ntohs(addr->tuple4_v4->source), daddr, ntohs(addr->tuple4_v4->dest));
int kni_stream_addr_trans(const struct layer_addr *addr, addr_type_t addr_type, char *output, int len){
char saddr[INET6_ADDRSTRLEN];
char daddr[INET6_ADDRSTRLEN];
uint16_t source, dest;
if(addr_type == ADDR_TYPE_IPV6){
inet_ntop(AF_INET6, &(addr->tuple4_v6->saddr), saddr, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &(addr->tuple4_v6->daddr), daddr, INET6_ADDRSTRLEN);
source = ntohs(addr->tuple4_v6->source);
dest = ntohs(addr->tuple4_v6->dest);
}
else{
inet_ntop(AF_INET, &(addr->tuple4_v4->saddr), saddr, INET6_ADDRSTRLEN);
inet_ntop(AF_INET, &(addr->tuple4_v4->daddr), daddr, INET6_ADDRSTRLEN);
source = ntohs(addr->tuple4_v4->source);
dest = ntohs(addr->tuple4_v4->dest);
}
snprintf(output, len, "%s:%d -> %s:%d", saddr, source, daddr, dest);
return 0;
}
@@ -28,6 +40,43 @@ uint16_t kni_ip_checksum(const void *buf, size_t hdr_len){
return (~sum);
}
uint16_t kni_tcp_checksum_v6(const void *_buf, size_t len, struct in6_addr src_addr, struct in6_addr dest_addr){
const uint16_t *buf = (u_int16_t *)_buf;
uint16_t *ip_src=(uint16_t *)&src_addr, *ip_dst=(uint16_t *)&dest_addr;
uint32_t sum;
size_t length=len;
// Calculate the sum
sum = 0;
while(len > 1){
sum += *buf++;
if (sum & 0x80000000){
sum = (sum & 0xFFFF) + (sum >> 16);
}
len -= 2;
}
if(len & 1){
// Add the padding if the packet lenght is odd
sum += *((uint8_t *)buf);
}
// Add the pseudo-header
for(int i = 0; i < 8; i++){
sum += *ip_src;
ip_src++;
}
for(int i = 0; i < 8; i++){
sum += *ip_dst;
ip_dst++;
}
sum += htons(IPPROTO_TCP);
sum += htons(length);
// Add the carries
while(sum >> 16){
sum = (sum & 0xFFFF) + (sum >> 16);
}
// Return the one's complement of sum
return ((uint16_t)(~sum));
}
uint16_t kni_tcp_checksum(const void *_buf, size_t len, in_addr_t src_addr, in_addr_t dest_addr){
const uint16_t *buf = (u_int16_t *)_buf;
uint16_t *ip_src=(uint16_t *)&src_addr, *ip_dst=(uint16_t *)&dest_addr;
@@ -255,4 +304,82 @@ MESA_htable_handle kni_create_htable(const char *profile, const char *section, v
return NULL;
}
return htable;
}
char* kni_ipv4_errmsg_get(int _errno){
switch(_errno){
case KNI_IPV4HDR_PARSE_ERROR_NULL_PACKET:
return (char*)"null packet";
default:
return (char*)"unknown error";
}
}
char* kni_ipv6_errmsg_get(int _errno){
switch(_errno){
case KNI_IPV6HDR_PARSE_ERROR_NULL_PACKET:
return (char*)"null packet";
case KNI_IPV6HDR_PARSE_ERROR_NO_TCPHDR:
return (char*)"no tcp header";
case KNI_IPV6HDR_PARSE_ERROR_INVALID_TYPE:
return (char*)"invalid header type";
default:
return (char*)"unknown error";
}
}
int kni_ipv4_header_parse(const void *a_packet, struct pkt_info *pktinfo){
if(a_packet == NULL){
return KNI_IPV4HDR_PARSE_ERROR_NULL_PACKET;
}
pktinfo->iphdr.v4 = (struct iphdr*)a_packet;
pktinfo->iphdr_len = pktinfo->iphdr.v4->ihl * 4;
pktinfo->ip_totlen = ntohs(pktinfo->iphdr.v4->tot_len);
pktinfo->tcphdr = (struct tcphdr*)((char*)pktinfo->iphdr.v4 + pktinfo->iphdr_len);
pktinfo->tcphdr_len = pktinfo->tcphdr->doff * 4;
pktinfo->data = (char*)pktinfo->tcphdr + pktinfo->tcphdr_len;
pktinfo->data_len = pktinfo->ip_totlen - pktinfo->iphdr_len - pktinfo->tcphdr_len;
return 0;
}
int kni_ipv6_header_parse(const void *a_packet, struct pkt_info *pktinfo){
if(a_packet == NULL){
return KNI_IPV6HDR_PARSE_ERROR_NULL_PACKET;
}
pktinfo->iphdr.v6 = (struct ip6_hdr*)a_packet;
pktinfo->ip_totlen = ntohs(pktinfo->iphdr.v6->ip6_ctlun.ip6_un1.ip6_un1_plen) + sizeof(struct ip6_hdr);
uint8_t next_hdr_type = pktinfo->iphdr.v6->ip6_ctlun.ip6_un1.ip6_un1_nxt;
char *next_hdr_ptr = (char*)pktinfo->iphdr.v6 + sizeof(struct ip6_hdr);
int skip_len = 0;
int ret = 0;
while(true){
switch(next_hdr_type)
{
case IPPROTO_TCP:
//parse tcphdr
pktinfo->iphdr_len = next_hdr_ptr - (char*)a_packet;
pktinfo->tcphdr = (struct tcphdr*)next_hdr_ptr;
pktinfo->tcphdr_len = pktinfo->tcphdr->doff * 4;
pktinfo->data = (char*)pktinfo->tcphdr + pktinfo->tcphdr_len;
pktinfo->data_len = pktinfo->ip_totlen - pktinfo->iphdr_len - pktinfo->tcphdr_len;
return 0;
case IPPROTO_HOPOPTS:
case IPPROTO_ROUTING:
case IPPROTO_AH:
case IPPROTO_DSTOPTS:
skip_len = (*(next_hdr_ptr + 1)) * 8 + 8;
next_hdr_type = *next_hdr_ptr;
next_hdr_ptr += skip_len;
break;
case IPPROTO_NONE:
ret = KNI_IPV6HDR_PARSE_ERROR_NO_TCPHDR;
goto error_out;
default:
ret = KNI_IPV6HDR_PARSE_ERROR_INVALID_TYPE;
goto error_out;
}
}
error_out:
return ret;
}