增加ipv6支持
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user