DTS Application Library  0.2.3
Application library containing referenced objects and interfaces to common libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups Pages

Implementation of RFC6296. More...

Files

file  rfc6296.c
 Implementation of RFC6296.
 

Data Structures

struct  natmap
 RFC6296 Nat map. More...
 

Typedefs

typedef struct natmap natmap
 Forward decleration of structure. More...
 

Functions

void rfc6296_map (struct natmap *map, struct in6_addr *ipaddr, int out)
 Lookup and process a NAT transform as per RFC 6296. More...
 
int rfc6296_map_add (char *intaddr, char *extaddr)
 Calculate and add a NAT map. More...
 
void rfc6296_test (blist_cb callback, struct in6_addr *internal)
 Quick test function. More...
 

Detailed Description

Implementation of RFC6296.

Typedef Documentation

typedef struct natmap natmap

Forward decleration of structure.

Definition at line 189 of file dtsapp.h.

Function Documentation

void rfc6296_map ( struct natmap map,
struct in6_addr *  ipaddr,
int  out 
)

Lookup and process a NAT transform as per RFC 6296.

Parameters
mapNat map structure to procees against.
ipaddrAddress to transform.
outSet to non zero if ipaddr is internal and must be transformed to external.

Definition at line 62 of file rfc6296.c.

References natmap::adji, natmap::adjo, natmap::epre, natmap::ipre, and natmap::mask.

62  {
63  uint16_t *addr_16 = (uint16_t *)&ipaddr->s6_addr;
64  uint32_t calc;
65  uint8_t cnt, *prefix, bitlen, bytelen;
66  uint16_t adj;
67 
68  prefix = (out) ? map->epre : map->ipre;
69  adj = (out) ? map->adjo : map->adji;
70 
71  if ((bitlen = map->mask % 8)) {
72  bytelen = (map->mask - bitlen) / 8;
73  bytelen++;
74  } else {
75  bytelen = map->mask / 8;
76  }
77 
78  /*as per RFC we handle /48 and longer /48 changes are reflected in SN*/
79  if ((bytelen == 6) && (~addr_16[3]) && (!bitlen)) {
80  memcpy(&ipaddr->s6_addr, prefix, bytelen);
81  calc = ntohs(addr_16[3]) + adj;
82  addr_16[3] = htons((calc & 0xFFFF) + (calc >> 16));
83  if (! ~addr_16[3]) {
84  addr_16[3] = 0;
85  }
86  } else if ((bytelen > 6) && (bytelen < 15)) {
87  /* find first non 0xFFFF word in lower 64 bits*/
88  for(cnt = ((bytelen-1) >> 1) + 1; cnt < 8; cnt++) {
89  if (! ~addr_16[cnt]) {
90  continue;
91  }
92  if (bitlen) {
93  ipaddr->s6_addr[bytelen-1] = prefix[bytelen-1] | (ipaddr->s6_addr[bytelen-1] & ((1 << (8 - bitlen)) -1));
94  } else {
95  ipaddr->s6_addr[bytelen-1] = prefix[bytelen-1];
96  }
97  memcpy(&ipaddr->s6_addr, prefix, bytelen - 1);
98  calc = ntohs(addr_16[cnt]) + adj;
99  addr_16[cnt] = htons((calc & 0xFFFF) + (calc >> 16));
100  if (! ~addr_16[cnt]) {
101  addr_16[cnt] = 0;
102  }
103  break;
104  }
105  }
106 }
uint8_t epre[16]
External prefix.
Definition: rfc6296.c:43
uint16_t mask
The greater of internal or external subnet mask.
Definition: rfc6296.c:35
uint16_t adjo
Outbound adjustment.
Definition: rfc6296.c:37
uint16_t adji
Inbound adjustment.
Definition: rfc6296.c:39
uint8_t ipre[16]
Internal prefix.
Definition: rfc6296.c:41
int rfc6296_map_add ( char *  intaddr,
char *  extaddr 
)

Calculate and add a NAT map.

Parameters
intaddrInternal prefix/subnet.
extaddrExternal prefix/subnet.

Definition at line 111 of file rfc6296.c.

References addtobucket(), natmap::adji, natmap::adjo, checksum(), create_bucketlist(), natmap::epre, natmap::ipre, natmap::mask, objalloc(), and objunref().

111  {
112  struct natmap *map;
113  uint16_t emask, imask, isum, esum, bytelen, bitlen;
114  char inip[43], exip[43], *tmp2;
115  struct in6_addr i6addr;
116  uint32_t adj;
117 
118  strncpy(inip, intaddr, 43);
119  if ((tmp2 = rindex(inip, '/'))) {
120  tmp2[0] = '\0';
121  tmp2++;
122  imask = atoi(tmp2);
123  } else {
124  return (-1);
125  }
126 
127  strncpy(exip, extaddr, 43);
128  if ((tmp2 = rindex(exip, '/'))) {
129  tmp2[0] = '\0';
130  tmp2++;
131  emask = atoi(tmp2);
132  } else {
133  return (-1);
134  }
135 
136  map = objalloc(sizeof(*map), NULL);
137  map->mask = (emask > imask) ? emask : imask;
138 
139  /*rfc says we must zero extend this is what we do here looking at each supplied len*/
140  /*external range*/
141  inet_pton(AF_INET6, exip, &i6addr);
142  if ((bitlen = emask % 8)) {
143  bytelen = (emask - bitlen) / 8;
144  i6addr.s6_addr[bytelen] &= ~((1 << (8 - bitlen)) - 1);
145  bytelen++;
146  } else {
147  bytelen = emask / 8;
148  }
149  memcpy(map->epre, &i6addr.s6_addr, bytelen);
150 
151  /*internal range*/
152  inet_pton(AF_INET6, inip, &i6addr);
153  if ((bitlen = imask % 8)) {
154  bytelen = (imask - bitlen) / 8;
155  i6addr.s6_addr[bytelen] &= ~((1 << (8 - bitlen)) - 1);
156  bytelen++;
157  } else {
158  bytelen = imask / 8;
159  }
160  memcpy(map->ipre, &i6addr.s6_addr, bytelen);
161 
162  /*calculate the adjustments from checksums of prefixes*/
163  if ((bitlen = map->mask % 8)) {
164  bytelen = (map->mask - bitlen) / 8;
165  bytelen++;
166  } else {
167  bytelen = map->mask / 8;
168  }
169  esum = ntohs(checksum(map->epre, bytelen));
170  isum = ntohs(checksum(map->ipre, bytelen));
171 
172  /*outgoing transform*/
173  adj = esum - isum;
174  adj = (adj & 0xFFFF) + (adj >> 16);
175  map->adjo = (uint16_t)adj;
176 
177  /*incoming transform*/
178  adj = isum - esum;
179  adj = (adj & 0xFFFF) + (adj >> 16);
180  map->adji = (uint16_t)adj;
181 
182  if (!nptv6tbl && (!(nptv6tbl = create_bucketlist(5, nptv6_hash)))) {
183  objunref(map);
184  return (-1);
185  }
186  addtobucket(nptv6tbl, map);
187  objunref(map);
188 
189  return (0);
190 }
uint16_t checksum(const void *data, int len)
Obtain the checksum for a buffer.
Definition: util.c:452
void * create_bucketlist(int bitmask, blisthash hash_function)
Definition: refobj.c:356
uint8_t epre[16]
External prefix.
Definition: rfc6296.c:43
uint16_t mask
The greater of internal or external subnet mask.
Definition: rfc6296.c:35
void * objalloc(int size, objdestroy)
Allocate a referenced lockable object.
Definition: refobj.c:129
uint16_t adjo
Outbound adjustment.
Definition: rfc6296.c:37
uint16_t adji
Inbound adjustment.
Definition: rfc6296.c:39
uint8_t ipre[16]
Internal prefix.
Definition: rfc6296.c:41
RFC6296 Nat map.
Definition: rfc6296.c:33
int addtobucket(struct bucket_list *blist, void *data)
Add a reference to the bucketlist.
Definition: refobj.c:428
int objunref(void *data)
Drop reference held.
Definition: refobj.c:184
void rfc6296_test ( blist_cb  callback,
struct in6_addr *  internal 
)

Quick test function.

Run a callback against each entry in the table with the internal address as data.

Parameters
callbackBucket list callback.
internalIp addr passed as data to the callback.

Definition at line 197 of file rfc6296.c.

References bucketlist_callback(), and objunref().

197  {
198  /*find and run map*/
199  bucketlist_callback(nptv6tbl, callback, internal);
200 
201  objunref(nptv6tbl);
202 }
void bucketlist_callback(struct bucket_list *blist, blist_cb callback, void *data2)
Run a callback function on all items in the list.
Definition: refobj.c:613
int objunref(void *data)
Drop reference held.
Definition: refobj.c:184