Commit 7f242751 authored by Stig Venaas's avatar Stig Venaas
Browse files

initial IPv6 support in topx. Now supports TOPX_IP with TOS, LENGTH, TTL (hop...

initial IPv6 support in topx. Now supports TOPX_IP with TOS, LENGTH, TTL (hop limit), CHECKSUM (no checksum for IPv6, set to 0) fields. Now always returns length field value in host order, was network order. Many other parameters should probably change from network to host order as well

git-svn-id: file:///home/svn/mapi/trunk@807 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent c391b408
......@@ -16,6 +16,7 @@
#include "protocols.h"
#include "mapi_errors.h"
#include <netinet/in.h>
#include <netinet/ip6.h>
#ifndef CHDLC_HDRLEN
#define CHDLC_HDRLEN 4
......@@ -25,6 +26,7 @@ struct topx_field {
void *pointer;
char needs_reverse;
unsigned int len;
unsigned short value; /* used when cannot pass pointer directly into packet data */
};
static int topx_reset(mapidflib_function_instance_t *instance)
......@@ -72,6 +74,9 @@ void extract_field(unsigned int link_type, struct topx_field *field, unsigned ch
ether_header* eth = NULL;
ip_header* ip = NULL;
struct ip6_hdr *ip6;
uint8_t ip_ver;
tcp_header* tcp = NULL;
udp_header* udp = NULL;
......@@ -86,19 +91,41 @@ void extract_field(unsigned int link_type, struct topx_field *field, unsigned ch
assert(0);
}
field->len = 0;
ip = (ip_header*)(dev_pkt + ether_len);
ip_ver = ip->ver_ihl >> 4;
if (ip_ver == 4)
ip_len = (ip->ver_ihl & 0xf) * 4;
else if (ip_ver == 6)
ip6 = (struct ip6_hdr *)ip;
else
return; /* Only support versions 4 and 6 */
field->needs_reverse=0;
switch(protocol) {
case TOPX_IP:
switch(pfield) {
case TOPX_IP_TOS:
field->pointer=&(ip->tos);
field->len=1;
if (ip_ver == 4) {
field->pointer = &ip->tos;
field->len = 1;
} else { /* For IPv6, extract bit 5-12 */
unsigned char *flowbytes = (unsigned char *)&ip6->ip6_flow;
field->value = (flowbytes[0] & 0xf) * 16 + (flowbytes[1] >> 4);
field->pointer = &field->value;
field->len = 2;
}
break;
case TOPX_IP_LENGTH:
field->pointer=&(ip->tlen);
if (ip_ver == 4) {
field->pointer = &ip->tlen;
field->needs_reverse = 1;
} else { /* For IPv6, total length = 40 + payload length */
field->value = 40 + ntohs(ip6->ip6_plen);
field->pointer = &field->value;
}
field->len=2;
break;
case TOPX_IP_ID:
......@@ -110,7 +137,7 @@ void extract_field(unsigned int link_type, struct topx_field *field, unsigned ch
field->len=2;
break;
case TOPX_IP_TTL:
field->pointer=&(ip->ttl);
field->pointer = (ip_ver == 4) ? &ip->ttl : &ip6->ip6_hlim;
field->len=1;
break;
case TOPX_IP_PROTOCOL:
......@@ -118,7 +145,12 @@ void extract_field(unsigned int link_type, struct topx_field *field, unsigned ch
field->len=1;
break;
case TOPX_IP_CHECKSUM:
field->pointer=&(ip->sum);
if (ip_ver == 4)
field->pointer = &ip->sum;
else { /* No checksum in IPv6 header */
field->value = 0;
field->pointer = &field->value;
}
field->len=2;
break;
case TOPX_IP_SRCIP:
......@@ -132,10 +164,8 @@ void extract_field(unsigned int link_type, struct topx_field *field, unsigned ch
}
break;
case TOPX_TCP:
if (ip->ptcl != IPPROTO_TCP) { // no TCP packet
field->len=0;
if (ip->ptcl != IPPROTO_TCP) /* no TCP packet */
return;
}
tcp = (tcp_header*)(dev_pkt + ether_len + ip_len);
//tcp_len = tcp->off * 4;
switch(pfield) {
......@@ -176,10 +206,8 @@ void extract_field(unsigned int link_type, struct topx_field *field, unsigned ch
}
break;
case TOPX_UDP:
if (ip->ptcl != IPPROTO_UDP) { // no UDP packet
field->len=0;
if (ip->ptcl != IPPROTO_UDP) /* no UDP packet */
return;
}
udp = (udp_header *)(dev_pkt + ether_len + ip_len);
switch(pfield) {
case TOPX_UDP_SRCPORT:
......@@ -339,7 +367,6 @@ static int topx_process(mapidflib_function_instance_t *instance,
struct topx_result *result;
// struct timeval ts;
unsigned int cur_secs = 0;
static unsigned int last_reset = 0;
struct timeval tv;
extract_field(instance->hwinfo->link_type,&field,packet,data->protocol,data->field);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment