CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2
Fork of USB_Ethernet by
pico_nat.c
00001 /********************************************************************* 00002 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved. 00003 See LICENSE and COPYING for usage. 00004 00005 . 00006 00007 Authors: Kristof Roelants, Brecht Van Cauwenberghe, 00008 Simon Maes, Philippe Mariman 00009 *********************************************************************/ 00010 00011 #include "pico_stack.h" 00012 #include "pico_frame.h" 00013 #include "pico_tcp.h" 00014 #include "pico_udp.h" 00015 #include "pico_ipv4.h" 00016 #include "pico_addressing.h" 00017 #include "pico_nat.h" 00018 00019 00020 #ifdef PICO_SUPPORT_IPV4 00021 #ifdef PICO_SUPPORT_NAT 00022 00023 #define nat_dbg(...) do{}while(0) 00024 //#define nat_dbg dbg 00025 #define NAT_TCP_TIMEWAIT 240000 /* 4mins (in msec) */ 00026 //#define NAT_TCP_TIMEWAIT 10000 /* 10 sec (in msec) - for testing purposes only*/ 00027 00028 00029 struct pico_nat_key { 00030 struct pico_ip4 pub_addr; 00031 uint16_t pub_port; 00032 struct pico_ip4 priv_addr; 00033 uint16_t priv_port; 00034 uint8_t proto; 00035 /* 00036 del_flags: 00037 1 0 00038 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 00039 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00040 |F|B|S|R|P|~| CONNECTION ACTIVE | 00041 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 00042 00043 F: FIN from Forwarding packet 00044 B: FIN from Backwarding packet 00045 S: SYN 00046 R: RST 00047 P: Persistant 00048 00049 */ 00050 uint16_t del_flags; 00051 /* Connector for trees */ 00052 }; 00053 00054 static struct pico_ipv4_link pub_link; 00055 static uint8_t enable_nat_flag = 0; 00056 00057 static int nat_cmp_backward(void * ka, void * kb) 00058 { 00059 struct pico_nat_key *a = ka, *b = kb; 00060 if (a->pub_port < b->pub_port) { 00061 return -1; 00062 } 00063 else if (a->pub_port > b->pub_port) { 00064 return 1; 00065 } 00066 else { 00067 if (a->proto < b->proto) { 00068 return -1; 00069 } 00070 else if (a->proto > b->proto) { 00071 return 1; 00072 } 00073 else { 00074 /* a and b are identical */ 00075 return 0; 00076 } 00077 } 00078 } 00079 00080 static int nat_cmp_forward(void * ka, void * kb) 00081 { 00082 struct pico_nat_key *a =ka, *b = kb; 00083 if (a->priv_addr.addr < b->priv_addr.addr) { 00084 return -1; 00085 } 00086 else if (a->priv_addr.addr > b->priv_addr.addr) { 00087 return 1; 00088 } 00089 else { 00090 if (a->priv_port < b->priv_port) { 00091 return -1; 00092 } 00093 else if (a->priv_port > b->priv_port) { 00094 return 1; 00095 } 00096 else { 00097 if (a->proto < b->proto) { 00098 return -1; 00099 } 00100 else if (a->proto > b->proto) { 00101 return 1; 00102 } 00103 else { 00104 /* a and b are identical */ 00105 return 0; 00106 } 00107 } 00108 } 00109 } 00110 00111 PICO_TREE_DECLARE(KEYTable_forward,nat_cmp_forward); 00112 PICO_TREE_DECLARE(KEYTable_backward,nat_cmp_backward); 00113 00114 /* 00115 2 options: 00116 find on proto and pub_port 00117 find on priv_addr, priv_port and proto 00118 zero the unused parameters 00119 */ 00120 static struct pico_nat_key *pico_ipv4_nat_find_key(uint16_t pub_port, struct pico_ip4 *priv_addr, uint16_t priv_port, uint8_t proto) 00121 { 00122 struct pico_nat_key test; 00123 test.pub_port = pub_port; 00124 test.priv_port = priv_port; 00125 test.proto = proto; 00126 if (priv_addr) 00127 test.priv_addr = *priv_addr; 00128 else 00129 test.priv_addr.addr = 0; 00130 00131 /* returns NULL if test can not be found */ 00132 if (!pub_port) 00133 return pico_tree_findKey(&KEYTable_forward,&test); 00134 else 00135 return pico_tree_findKey(&KEYTable_backward, &test); 00136 } 00137 00138 int pico_ipv4_nat_find(uint16_t pub_port, struct pico_ip4 *priv_addr, uint16_t priv_port, uint8_t proto) 00139 { 00140 struct pico_nat_key *k = NULL; 00141 00142 k = pico_ipv4_nat_find_key(pub_port, priv_addr, priv_port, proto); 00143 if (k) 00144 return 0; 00145 else 00146 return -1; 00147 } 00148 00149 int pico_ipv4_nat_snif_forward(struct pico_nat_key *nk, struct pico_frame *f) 00150 { 00151 uint8_t proto; 00152 struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr; 00153 struct pico_tcp_hdr *tcp_hdr; 00154 00155 if (!ipv4_hdr) 00156 return -1; 00157 proto = ipv4_hdr->proto; 00158 00159 if (proto == PICO_PROTO_TCP) { 00160 tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr; 00161 if (!tcp_hdr) 00162 return -1; 00163 if (tcp_hdr->flags & PICO_TCP_FIN) { 00164 nk->del_flags |= PICO_DEL_FLAGS_FIN_FORWARD; //FIN from forwarding packet 00165 } 00166 if (tcp_hdr->flags & PICO_TCP_SYN) { 00167 nk->del_flags |= PICO_DEL_FLAGS_SYN; 00168 } 00169 if (tcp_hdr->flags & PICO_TCP_RST) { 00170 nk->del_flags |= PICO_DEL_FLAGS_RST; 00171 } 00172 } else if (proto == PICO_PROTO_UDP) { 00173 /* set conn active to 1 */ 00174 nk->del_flags &= 0xFE00; 00175 nk->del_flags++; 00176 } 00177 return 0; 00178 } 00179 00180 00181 int pico_ipv4_nat_snif_backward(struct pico_nat_key *nk, struct pico_frame *f) 00182 { 00183 uint8_t proto; 00184 struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr; 00185 struct pico_tcp_hdr *tcp_hdr; 00186 00187 if (!ipv4_hdr) 00188 return -1; 00189 proto = ipv4_hdr->proto; 00190 00191 if (proto == PICO_PROTO_TCP) { 00192 tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr; 00193 if (!tcp_hdr) 00194 return -1; 00195 if (tcp_hdr->flags & PICO_TCP_FIN) { 00196 nk->del_flags |= PICO_DEL_FLAGS_FIN_BACKWARD; //FIN from backwarding packet 00197 } 00198 if (tcp_hdr->flags & PICO_TCP_SYN) { 00199 nk->del_flags |= PICO_DEL_FLAGS_SYN; 00200 } 00201 if (tcp_hdr->flags & PICO_TCP_RST) { 00202 nk->del_flags |= PICO_DEL_FLAGS_RST; 00203 } 00204 } else if (proto == PICO_PROTO_UDP) { 00205 /* set conn active to 1 */ 00206 nk->del_flags &= 0xFE00; 00207 nk->del_flags++; 00208 } 00209 return 0; 00210 } 00211 00212 void pico_ipv4_nat_table_cleanup(unsigned long now, void *_unused) 00213 { 00214 struct pico_tree_node * idx, * safe; 00215 struct pico_nat_key *k = NULL; 00216 nat_dbg("NAT: before table cleanup:\n"); 00217 pico_ipv4_nat_print_table(); 00218 00219 //struct pico_nat_key *tmp; 00220 pico_tree_foreach_reverse_safe(idx,&KEYTable_forward,safe){ 00221 k = idx->keyValue; 00222 switch (k->proto) 00223 { 00224 case PICO_PROTO_TCP: 00225 if ((k->del_flags & 0x0800) >> 11) { 00226 /* entry is persistant */ 00227 break; 00228 } 00229 else if ((k->del_flags & 0x01FF) == 0) { 00230 /* conn active is zero, delete entry */ 00231 pico_ipv4_nat_del(k->pub_port, k->proto); 00232 } 00233 else if ((k->del_flags & 0x1000) >> 12) { 00234 /* RST flag set, set conn active to zero */ 00235 k->del_flags &= 0xFE00; 00236 } 00237 else if (((k->del_flags & 0x8000) >> 15) && ((k->del_flags & 0x4000) >> 14)) { 00238 /* FIN1 and FIN2 set, set conn active to zero */ 00239 k->del_flags &= 0xFE00; 00240 } 00241 else if ((k->del_flags & 0x01FF) > 360) { 00242 /* conn is active for 24 hours, delete entry */ 00243 pico_ipv4_nat_del(k->pub_port, k->proto); 00244 } 00245 else { 00246 k->del_flags++; 00247 } 00248 break; 00249 00250 case PICO_PROTO_UDP: 00251 if ((k->del_flags & 0x0800) >> 11) { 00252 /* entry is persistant */ 00253 break; 00254 } 00255 else if ((k->del_flags & 0x01FF) > 1) { 00256 /* Delete entry when it has existed NAT_TCP_TIMEWAIT */ 00257 pico_ipv4_nat_del(k->pub_port, k->proto); 00258 } 00259 else { 00260 k->del_flags++; 00261 } 00262 break; 00263 00264 default: 00265 /* Unknown protocol in NAT table, delete when it has existed NAT_TCP_TIMEWAIT */ 00266 if ((k->del_flags & 0x01FF) > 1) { 00267 pico_ipv4_nat_del(k->pub_port, k->proto); 00268 } 00269 else { 00270 k->del_flags++; 00271 } 00272 } 00273 } 00274 00275 nat_dbg("NAT: after table cleanup:\n"); 00276 pico_ipv4_nat_print_table(); 00277 pico_timer_add(NAT_TCP_TIMEWAIT, pico_ipv4_nat_table_cleanup, NULL); 00278 } 00279 00280 int pico_ipv4_nat_add(struct pico_ip4 pub_addr, uint16_t pub_port, struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto) 00281 { 00282 struct pico_nat_key *key = pico_zalloc(sizeof(struct pico_nat_key)); 00283 if (!key) { 00284 pico_err = PICO_ERR_ENOMEM; 00285 return -1; 00286 } 00287 00288 key->pub_addr = pub_addr; 00289 key->pub_port = pub_port; 00290 key->priv_addr = priv_addr; 00291 key->priv_port = priv_port; 00292 key->proto = proto; 00293 key->del_flags = 0x0001; /* set conn active to 1, other flags to 0 */ 00294 00295 /* RB_INSERT returns NULL when element added, pointer to the element if already in tree */ 00296 if(!pico_tree_insert(&KEYTable_forward, key) && !pico_tree_insert(&KEYTable_backward, key)){ 00297 return 0; /* New element added */ 00298 } 00299 else { 00300 pico_free(key); 00301 pico_err = PICO_ERR_EINVAL; 00302 return -1; /* Element key already exists */ 00303 } 00304 } 00305 00306 00307 int pico_ipv4_nat_del(uint16_t pub_port, uint8_t proto) 00308 { 00309 struct pico_nat_key *key = NULL; 00310 key = pico_ipv4_nat_find_key(pub_port, NULL, 0, proto); 00311 if (!key) { 00312 nat_dbg("NAT: key to delete not found: proto %u | pub_port %u\n", proto, pub_port); 00313 return -1; 00314 } 00315 else { 00316 nat_dbg("NAT: key to delete found: proto %u | pub_port %u\n", proto, pub_port); 00317 /* RB_REMOVE returns pointer to removed element, NULL to indicate error */ 00318 if(pico_tree_delete(&KEYTable_forward, key) && pico_tree_delete(&KEYTable_backward, key)) 00319 pico_free(key); 00320 else 00321 return -1; /* Error on removing element, do not free! */ 00322 } 00323 return 0; 00324 } 00325 00326 int pico_ipv4_port_forward(struct pico_ip4 pub_addr, uint16_t pub_port, struct pico_ip4 priv_addr, uint16_t priv_port, uint8_t proto, uint8_t persistant) 00327 { 00328 struct pico_nat_key *key = NULL; 00329 00330 switch (persistant) 00331 { 00332 case PICO_IPV4_FORWARD_ADD: 00333 if (pico_ipv4_nat_add(pub_addr, pub_port, priv_addr, priv_port, proto) != 0) 00334 return -1; /* pico_err set in nat_add */ 00335 key = pico_ipv4_nat_find_key(pub_port, &priv_addr, priv_port, proto); 00336 if (!key) { 00337 pico_err = PICO_ERR_EAGAIN; 00338 return -1; 00339 } 00340 key->del_flags = (key->del_flags & ~(0x1 << 11)) | (persistant << 11); 00341 break; 00342 00343 case PICO_IPV4_FORWARD_DEL: 00344 return pico_ipv4_nat_del(pub_port, proto); 00345 00346 default: 00347 pico_err = PICO_ERR_EINVAL; 00348 return -1; 00349 } 00350 pico_ipv4_nat_print_table(); 00351 return 0; 00352 } 00353 00354 00355 void pico_ipv4_nat_print_table(void) 00356 { 00357 struct pico_nat_key __attribute__((unused)) *k = NULL ; 00358 struct pico_tree_node * index; 00359 uint16_t i = 0; 00360 00361 nat_dbg("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 00362 nat_dbg("+ NAT table +\n"); 00363 nat_dbg("+-----------------------------------------------------------------------------------------------------------------------+\n"); 00364 nat_dbg("+ pointer | private_addr | private_port | proto | pub_addr | pub_port | conn active | FIN1 | FIN2 | SYN | RST | PERS +\n"); 00365 nat_dbg("+-----------------------------------------------------------------------------------------------------------------------+\n"); 00366 00367 pico_tree_foreach(index,&KEYTable_forward){ 00368 k = index->keyValue; 00369 nat_dbg("+ %10p | %08X | %05u | %04u | %08X | %05u | %03u | %u | %u | %u | %u | %u +\n", 00370 k, k->priv_addr.addr, k->priv_port, k->proto, k->pub_addr.addr, k->pub_port, (k->del_flags)&0x01FF, ((k->del_flags)&0x8000)>>15, 00371 ((k->del_flags)&0x4000)>>14, ((k->del_flags)&0x2000)>>13, ((k->del_flags)&0x1000)>>12, ((k->del_flags)&0x0800)>>11); 00372 i++; 00373 } 00374 nat_dbg("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); 00375 } 00376 00377 int pico_ipv4_nat_generate_key(struct pico_nat_key* nk, struct pico_frame* f, struct pico_ip4 pub_addr) 00378 { 00379 uint16_t pub_port = 0; 00380 uint8_t proto; 00381 struct pico_tcp_hdr *tcp_hdr = NULL; /* forced to use pico_trans */ 00382 struct pico_udp_hdr *udp_hdr = NULL; /* forced to use pico_trans */ 00383 struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr; 00384 if (!ipv4_hdr) 00385 return -1; 00386 proto = ipv4_hdr->proto; 00387 do { 00388 /* 1. generate valid new NAT port entry */ 00389 uint32_t rand = pico_rand(); 00390 pub_port = (uint16_t) (rand & 0xFFFFU); 00391 pub_port = (uint16_t)(pub_port % (65535 - 1024)) + 1024U; 00392 pub_port = short_be(pub_port); 00393 00394 /* 2. check if already in table, if no exit */ 00395 nat_dbg("NAT: check if generated port %u is free\n", short_be(pub_port)); 00396 if (pico_is_port_free(proto, pub_port, NULL, &pico_proto_ipv4)) 00397 break; 00398 00399 } while (1); 00400 nat_dbg("NAT: port %u is free\n", short_be(pub_port)); 00401 00402 if (proto == PICO_PROTO_TCP) { 00403 tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr; 00404 if (!tcp_hdr) 00405 return -1; 00406 nk->priv_port = tcp_hdr->trans.sport; 00407 } else if (proto == PICO_PROTO_UDP) { 00408 udp_hdr = (struct pico_udp_hdr *) f->transport_hdr; 00409 if (!udp_hdr) 00410 return -1; 00411 nk->priv_port = udp_hdr->trans.sport; 00412 } else if (proto == PICO_PROTO_ICMP4) { 00413 nk->priv_port = (uint16_t)(ipv4_hdr->src.addr & 0x00FF); 00414 pub_port = (uint16_t)(ipv4_hdr->dst.addr & 0x00FF); 00415 if (!pico_is_port_free(proto, pub_port, NULL, &pico_proto_ipv4)) 00416 return -1; 00417 } 00418 00419 nk->pub_addr = pub_addr; /* get public ip address from device */ 00420 nk->pub_port = pub_port; 00421 nk->priv_addr = ipv4_hdr->src; 00422 nk->proto = ipv4_hdr->proto; 00423 nk->del_flags = 0x0001; /* set conn active to 1 */ 00424 if (pico_ipv4_nat_add(nk->pub_addr, nk->pub_port, nk->priv_addr, nk->priv_port, nk->proto) < 0) { 00425 return -1; 00426 } else { 00427 return 0; 00428 } 00429 } 00430 00431 00432 static int pico_nat_tcp_checksum(struct pico_frame *f) 00433 { 00434 struct pico_tcp_hdr *trans_hdr = (struct pico_tcp_hdr *) f->transport_hdr; 00435 struct pico_ipv4_hdr *net_hdr = (struct pico_ipv4_hdr *) f->net_hdr; 00436 00437 struct tcp_pseudo_hdr_ipv4 pseudo; 00438 if (!trans_hdr || !net_hdr) 00439 return -1; 00440 00441 pseudo.src.addr = net_hdr->src.addr; 00442 pseudo.dst.addr = net_hdr->dst.addr; 00443 pseudo.res = 0; 00444 pseudo.proto = PICO_PROTO_TCP; 00445 pseudo.tcp_len = short_be(f->transport_len); 00446 00447 trans_hdr->crc = 0; 00448 trans_hdr->crc = pico_dualbuffer_checksum(&pseudo, sizeof(struct tcp_pseudo_hdr_ipv4), trans_hdr, f->transport_len); 00449 trans_hdr->crc = short_be(trans_hdr->crc); 00450 return 0; 00451 } 00452 00453 00454 int pico_ipv4_nat_translate(struct pico_nat_key* nk, struct pico_frame* f) 00455 { 00456 uint8_t proto; 00457 struct pico_tcp_hdr *tcp_hdr = NULL; /* forced to use pico_trans */ 00458 struct pico_udp_hdr *udp_hdr = NULL; /* forced to use pico_trans */ 00459 00460 struct pico_ipv4_hdr* ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr; 00461 if (!ipv4_hdr) 00462 return -1; 00463 proto = ipv4_hdr->proto; 00464 00465 if (proto == PICO_PROTO_TCP) { 00466 tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr; 00467 if (!tcp_hdr) 00468 return -1; 00469 tcp_hdr->trans.sport = nk->pub_port; 00470 } else if (proto == PICO_PROTO_UDP) { 00471 udp_hdr = (struct pico_udp_hdr *) f->transport_hdr; 00472 if (!udp_hdr) 00473 return -1; 00474 udp_hdr->trans.sport = nk->pub_port; 00475 } 00476 00477 //if(f->proto == PICO_PROTO_ICMP){ 00478 //} XXX no action 00479 00480 ipv4_hdr->src = nk->pub_addr; 00481 00482 if (proto == PICO_PROTO_TCP) { 00483 pico_nat_tcp_checksum(f); 00484 } else if (proto == PICO_PROTO_UDP){ 00485 udp_hdr->crc = 0; 00486 udp_hdr->crc = short_be(pico_udp_checksum_ipv4(f)); 00487 } 00488 00489 // pico_ipv4_checksum(f); 00490 ipv4_hdr->crc = 0; 00491 ipv4_hdr->crc = short_be(pico_checksum(ipv4_hdr, f->net_len)); 00492 00493 return 0; 00494 } 00495 00496 00497 int pico_ipv4_nat_port_forward(struct pico_frame* f) 00498 { 00499 struct pico_nat_key *nk = NULL; 00500 struct pico_tcp_hdr *tcp_hdr = NULL; 00501 struct pico_udp_hdr *udp_hdr = NULL; 00502 struct pico_icmp4_hdr *icmp_hdr = NULL; 00503 struct pico_ipv4_hdr* ipv4_hdr; 00504 uint16_t pub_port = 0; 00505 uint8_t proto; 00506 00507 ipv4_hdr = (struct pico_ipv4_hdr *)f->net_hdr; 00508 if (!ipv4_hdr) 00509 return -1; 00510 proto = ipv4_hdr->proto; 00511 00512 if (proto == PICO_PROTO_TCP) { 00513 tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr; 00514 if (!tcp_hdr) 00515 return -1; 00516 pub_port = tcp_hdr->trans.dport; 00517 } else if (proto == PICO_PROTO_UDP) { 00518 udp_hdr = (struct pico_udp_hdr *) f->transport_hdr; 00519 if (!udp_hdr) 00520 return -1; 00521 pub_port = udp_hdr->trans.dport; 00522 } else if (proto == PICO_PROTO_ICMP4) { 00523 icmp_hdr = (struct pico_icmp4_hdr *) f->transport_hdr; 00524 if (!icmp_hdr) 00525 return -1; 00526 /* XXX PRELIMINARY ONLY LAST 16 BITS OF IP */ 00527 pub_port = (uint16_t)(ipv4_hdr->src.addr & 0x00FF); 00528 } 00529 00530 nk = pico_ipv4_nat_find_key(pub_port, 0, 0, proto); 00531 00532 if (!nk) { 00533 nat_dbg("\nNAT: ERROR key not found in table\n"); 00534 return -1; 00535 } else { 00536 pico_ipv4_nat_snif_forward(nk,f); 00537 ipv4_hdr->dst.addr = nk->priv_addr.addr; 00538 00539 if (proto == PICO_PROTO_TCP) { 00540 tcp_hdr->trans.dport = nk->priv_port; 00541 pico_nat_tcp_checksum(f); 00542 } else if (proto == PICO_PROTO_UDP) { 00543 udp_hdr->trans.dport = nk->priv_port; 00544 udp_hdr->crc = 0; 00545 udp_hdr->crc = short_be(pico_udp_checksum_ipv4(f)); 00546 } 00547 } 00548 00549 ipv4_hdr->crc = 0; 00550 ipv4_hdr->crc = short_be(pico_checksum(ipv4_hdr, f->net_len)); 00551 00552 return 0; 00553 } 00554 00555 00556 00557 int pico_ipv4_nat(struct pico_frame *f, struct pico_ip4 pub_addr) 00558 { 00559 /*do nat---------*/ 00560 struct pico_nat_key *nk = NULL; 00561 struct pico_nat_key key; 00562 struct pico_ipv4_hdr *net_hdr = (struct pico_ipv4_hdr *) f->net_hdr; 00563 struct pico_tcp_hdr *tcp_hdr = NULL; 00564 struct pico_udp_hdr *udp_hdr = NULL; 00565 int ret; 00566 uint8_t proto = net_hdr->proto; 00567 uint16_t priv_port = 0; 00568 struct pico_ip4 priv_addr= net_hdr->src; 00569 00570 nk= &key; 00571 00572 /* TODO DELME check if IN */ 00573 if (pub_addr.addr == net_hdr->dst.addr) { 00574 nat_dbg("NAT: backward translation {dst.addr, dport}: {%08X,%u} ->", net_hdr->dst.addr, ((struct pico_trans *)f->transport_hdr)->dport); 00575 ret = pico_ipv4_nat_port_forward(f); /* our IN definition */ 00576 nat_dbg(" {%08X,%u}\n", net_hdr->dst.addr, short_be(((struct pico_trans *)f->transport_hdr)->dport)); 00577 } else { 00578 if (net_hdr->proto == PICO_PROTO_TCP) { 00579 tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr; 00580 priv_port = tcp_hdr->trans.sport; 00581 } else if (net_hdr->proto == PICO_PROTO_UDP) { 00582 udp_hdr = (struct pico_udp_hdr *) f->transport_hdr; 00583 priv_port = udp_hdr->trans.sport; 00584 } else if (net_hdr->proto == PICO_PROTO_ICMP4) { 00585 //udp_hdr = (struct pico_udp_hdr *) f->transport_hdr; 00586 priv_port = (uint16_t)(net_hdr->src.addr & 0x00FF); 00587 } 00588 00589 ret = pico_ipv4_nat_find(0, &priv_addr, priv_port, proto); 00590 if (ret >= 0) { 00591 // Key is available in table 00592 nk = pico_ipv4_nat_find_key(0, &priv_addr, priv_port, proto); 00593 } else { 00594 nat_dbg("NAT: key not found in NAT table -> generate key\n"); 00595 pico_ipv4_nat_generate_key(nk, f, pub_addr); 00596 } 00597 pico_ipv4_nat_snif_backward(nk,f); 00598 nat_dbg("NAT: forward translation {src.addr, sport}: {%08X,%u} ->", net_hdr->src.addr, short_be(((struct pico_trans *)f->transport_hdr)->sport)); 00599 pico_ipv4_nat_translate(nk, f); /* our OUT definition */ 00600 nat_dbg(" {%08X,%u}\n", net_hdr->src.addr, short_be(((struct pico_trans *)f->transport_hdr)->sport)); 00601 } 00602 return 0; 00603 } 00604 00605 00606 int pico_ipv4_nat_enable(struct pico_ipv4_link *link) 00607 { 00608 if (link == NULL) { 00609 pico_err = PICO_ERR_EINVAL; 00610 return -1; 00611 } 00612 00613 pub_link = *link; 00614 pico_timer_add(NAT_TCP_TIMEWAIT, pico_ipv4_nat_table_cleanup, NULL); 00615 enable_nat_flag = 1; 00616 return 0; 00617 } 00618 00619 int pico_ipv4_nat_disable(void) 00620 { 00621 pub_link.address.addr = 0; 00622 enable_nat_flag = 0; 00623 return 0; 00624 } 00625 00626 00627 int pico_ipv4_nat_isenabled_out(struct pico_ipv4_link *link) 00628 { 00629 if (enable_nat_flag) { 00630 // is pub_link = *link 00631 if (pub_link.address.addr == link->address.addr) 00632 return 0; 00633 else 00634 return -1; 00635 } else { 00636 return -1; 00637 } 00638 } 00639 00640 00641 int pico_ipv4_nat_isenabled_in(struct pico_frame *f) 00642 { 00643 if (enable_nat_flag) { 00644 struct pico_tcp_hdr *tcp_hdr = NULL; 00645 struct pico_udp_hdr *udp_hdr = NULL; 00646 uint16_t pub_port = 0; 00647 int ret; 00648 uint8_t proto; 00649 00650 struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *) f->net_hdr; 00651 if (!ipv4_hdr) 00652 return -1; 00653 proto = ipv4_hdr->proto; 00654 00655 if (proto == PICO_PROTO_TCP) { 00656 tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr; 00657 if (!tcp_hdr) 00658 return -1; 00659 pub_port= tcp_hdr->trans.dport; 00660 } else if (proto == PICO_PROTO_UDP) { 00661 udp_hdr = (struct pico_udp_hdr *) f->transport_hdr; 00662 if (!udp_hdr) 00663 return -1; 00664 pub_port= udp_hdr->trans.dport; 00665 } else if (proto == PICO_PROTO_ICMP4) { 00666 //icmp_hdr = (struct pico_icmp4_hdr *) f->transport_hdr; 00667 //if (!icmp_hdr) 00668 // return -1; 00669 /* XXX PRELIMINARY ONLY LAST 16 BITS OF IP */ 00670 pub_port = (uint16_t)(ipv4_hdr->src.addr & 0x00FF); 00671 } 00672 ret = pico_ipv4_nat_find(pub_port, NULL, 0, proto); 00673 if (ret == 0) 00674 return 0; 00675 else 00676 return -1; 00677 } else { 00678 return -1; 00679 } 00680 } 00681 #endif 00682 #endif 00683
Generated on Wed Jul 13 2022 02:20:45 by 1.7.2