Free (GPLv2) TCP/IP stack developed by TASS Belgium
Dependents: lpc1768-picotcp-demo ZeroMQ_PicoTCP_Publisher_demo TCPSocket_HelloWorld_PicoTCP Pico_TCP_UDP_Test ... more
PicoTCP. Copyright (c) 2013 TASS Belgium NV.
Released under the GNU General Public License, version 2.
Different licensing models may exist, at the sole discretion of the Copyright holders.
Official homepage: http://www.picotcp.com
Bug tracker: https://github.com/tass-belgium/picotcp/issues
Development steps:
initial integration with mbed RTOSgeneric mbed Ethernet driverhigh performance NXP LPC1768 specific Ethernet driverMulti-threading support for mbed RTOSBerkeley sockets and integration with the New Socket APIFork of the apps running on top of the New Socket APIScheduling optimizations- Debugging/benchmarking/testing
Demo application (measuring TCP sender performance):
Import programlpc1768-picotcp-demo
A PicoTCP demo app testing the ethernet throughput on the lpc1768 mbed board.
modules/pico_nat.c@155:a70f34550c34, 2016-01-28 (annotated)
- Committer:
- tass
- Date:
- Thu Jan 28 15:12:00 2016 +0100
- Revision:
- 155:a70f34550c34
- Parent:
- 152:a3d286bf94e5
Adding TCP flag for FIN.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tass | 68:0847e35d08a6 | 1 | /********************************************************************* |
tass | 152:a3d286bf94e5 | 2 | PicoTCP. Copyright (c) 2012-2015 Altran Intelligent Systems. Some rights reserved. |
TASS Belgium NV |
131:4758606c9316 | 3 | See LICENSE and COPYING for usage. |
tass | 68:0847e35d08a6 | 4 | |
TASS Belgium NV |
131:4758606c9316 | 5 | . |
tass | 68:0847e35d08a6 | 6 | |
TASS Belgium NV |
131:4758606c9316 | 7 | Authors: Kristof Roelants, Brecht Van Cauwenberghe, |
tass | 68:0847e35d08a6 | 8 | Simon Maes, Philippe Mariman |
TASS Belgium NV |
131:4758606c9316 | 9 | *********************************************************************/ |
tass | 68:0847e35d08a6 | 10 | |
tass | 68:0847e35d08a6 | 11 | #include "pico_stack.h" |
tass | 68:0847e35d08a6 | 12 | #include "pico_frame.h" |
tass | 68:0847e35d08a6 | 13 | #include "pico_tcp.h" |
tass | 68:0847e35d08a6 | 14 | #include "pico_udp.h" |
tass | 68:0847e35d08a6 | 15 | #include "pico_ipv4.h" |
tass | 68:0847e35d08a6 | 16 | #include "pico_addressing.h" |
tass | 68:0847e35d08a6 | 17 | #include "pico_nat.h" |
tass | 68:0847e35d08a6 | 18 | |
tass | 68:0847e35d08a6 | 19 | #ifdef PICO_SUPPORT_IPV4 |
tass | 68:0847e35d08a6 | 20 | #ifdef PICO_SUPPORT_NAT |
tass | 68:0847e35d08a6 | 21 | |
TASS Belgium NV |
131:4758606c9316 | 22 | #define nat_dbg(...) do {} while(0) |
TASS Belgium NV |
131:4758606c9316 | 23 | /* #define nat_dbg dbg */ |
tass | 68:0847e35d08a6 | 24 | #define PICO_NAT_TIMEWAIT 240000 /* msec (4 mins) */ |
tass | 68:0847e35d08a6 | 25 | |
tass | 68:0847e35d08a6 | 26 | #define PICO_NAT_INBOUND 0 |
tass | 68:0847e35d08a6 | 27 | #define PICO_NAT_OUTBOUND 1 |
tass | 68:0847e35d08a6 | 28 | |
tass | 68:0847e35d08a6 | 29 | struct pico_nat_tuple { |
TASS Belgium NV |
131:4758606c9316 | 30 | uint8_t proto; |
TASS Belgium NV |
131:4758606c9316 | 31 | uint16_t conn_active : 11; |
TASS Belgium NV |
131:4758606c9316 | 32 | uint16_t portforward : 1; |
TASS Belgium NV |
131:4758606c9316 | 33 | uint16_t rst : 1; |
TASS Belgium NV |
131:4758606c9316 | 34 | uint16_t syn : 1; |
TASS Belgium NV |
131:4758606c9316 | 35 | uint16_t fin_in : 1; |
TASS Belgium NV |
131:4758606c9316 | 36 | uint16_t fin_out : 1; |
TASS Belgium NV |
131:4758606c9316 | 37 | uint16_t src_port; |
TASS Belgium NV |
131:4758606c9316 | 38 | uint16_t dst_port; |
TASS Belgium NV |
131:4758606c9316 | 39 | uint16_t nat_port; |
TASS Belgium NV |
131:4758606c9316 | 40 | struct pico_ip4 src_addr; |
TASS Belgium NV |
131:4758606c9316 | 41 | struct pico_ip4 dst_addr; |
TASS Belgium NV |
131:4758606c9316 | 42 | struct pico_ip4 nat_addr; |
tass | 68:0847e35d08a6 | 43 | }; |
tass | 68:0847e35d08a6 | 44 | |
tass | 68:0847e35d08a6 | 45 | static struct pico_ipv4_link *nat_link = NULL; |
tass | 68:0847e35d08a6 | 46 | |
tass | 152:a3d286bf94e5 | 47 | static int nat_cmp_natport(struct pico_nat_tuple *a, struct pico_nat_tuple *b) |
tass | 68:0847e35d08a6 | 48 | { |
TASS Belgium NV |
131:4758606c9316 | 49 | |
TASS Belgium NV |
131:4758606c9316 | 50 | if (a->nat_port < b->nat_port) |
TASS Belgium NV |
131:4758606c9316 | 51 | return -1; |
tass | 68:0847e35d08a6 | 52 | |
TASS Belgium NV |
131:4758606c9316 | 53 | if (a->nat_port > b->nat_port) |
tass | 152:a3d286bf94e5 | 54 | |
TASS Belgium NV |
131:4758606c9316 | 55 | return 1; |
TASS Belgium NV |
131:4758606c9316 | 56 | |
tass | 152:a3d286bf94e5 | 57 | return 0; |
tass | 152:a3d286bf94e5 | 58 | |
tass | 152:a3d286bf94e5 | 59 | } |
tass | 152:a3d286bf94e5 | 60 | |
tass | 152:a3d286bf94e5 | 61 | static int nat_cmp_srcport(struct pico_nat_tuple *a, struct pico_nat_tuple *b) |
tass | 152:a3d286bf94e5 | 62 | { |
tass | 152:a3d286bf94e5 | 63 | |
tass | 152:a3d286bf94e5 | 64 | if (a->src_port < b->src_port) |
tass | 152:a3d286bf94e5 | 65 | return -1; |
tass | 152:a3d286bf94e5 | 66 | |
tass | 152:a3d286bf94e5 | 67 | if (a->src_port > b->src_port) |
tass | 152:a3d286bf94e5 | 68 | |
tass | 152:a3d286bf94e5 | 69 | return 1; |
tass | 152:a3d286bf94e5 | 70 | |
tass | 152:a3d286bf94e5 | 71 | return 0; |
tass | 152:a3d286bf94e5 | 72 | |
tass | 152:a3d286bf94e5 | 73 | } |
tass | 152:a3d286bf94e5 | 74 | |
tass | 152:a3d286bf94e5 | 75 | static int nat_cmp_proto(struct pico_nat_tuple *a, struct pico_nat_tuple *b) |
tass | 152:a3d286bf94e5 | 76 | { |
TASS Belgium NV |
131:4758606c9316 | 77 | if (a->proto < b->proto) |
TASS Belgium NV |
131:4758606c9316 | 78 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 79 | |
TASS Belgium NV |
131:4758606c9316 | 80 | if (a->proto > b->proto) |
TASS Belgium NV |
131:4758606c9316 | 81 | return 1; |
TASS Belgium NV |
131:4758606c9316 | 82 | |
tass | 152:a3d286bf94e5 | 83 | return 0; |
tass | 152:a3d286bf94e5 | 84 | } |
tass | 152:a3d286bf94e5 | 85 | |
tass | 152:a3d286bf94e5 | 86 | static int nat_cmp_address(struct pico_nat_tuple *a, struct pico_nat_tuple *b) |
tass | 152:a3d286bf94e5 | 87 | { |
tass | 152:a3d286bf94e5 | 88 | return pico_ipv4_compare(&a->src_addr, &b->src_addr); |
tass | 68:0847e35d08a6 | 89 | } |
tass | 68:0847e35d08a6 | 90 | |
tass | 152:a3d286bf94e5 | 91 | static int nat_cmp_inbound(void *ka, void *kb) |
tass | 152:a3d286bf94e5 | 92 | { |
tass | 152:a3d286bf94e5 | 93 | struct pico_nat_tuple *a = ka, *b = kb; |
tass | 152:a3d286bf94e5 | 94 | int cport = nat_cmp_natport(a, b); |
tass | 152:a3d286bf94e5 | 95 | if (cport) |
tass | 152:a3d286bf94e5 | 96 | return cport; |
tass | 152:a3d286bf94e5 | 97 | |
tass | 152:a3d286bf94e5 | 98 | return nat_cmp_proto(a, b); |
tass | 152:a3d286bf94e5 | 99 | } |
tass | 152:a3d286bf94e5 | 100 | |
tass | 152:a3d286bf94e5 | 101 | |
TASS Belgium NV |
131:4758606c9316 | 102 | static int nat_cmp_outbound(void *ka, void *kb) |
tass | 68:0847e35d08a6 | 103 | { |
TASS Belgium NV |
131:4758606c9316 | 104 | struct pico_nat_tuple *a = ka, *b = kb; |
tass | 152:a3d286bf94e5 | 105 | int caddr, cport; |
TASS Belgium NV |
131:4758606c9316 | 106 | |
tass | 152:a3d286bf94e5 | 107 | caddr = nat_cmp_address(a, b); |
tass | 152:a3d286bf94e5 | 108 | if (caddr) |
tass | 152:a3d286bf94e5 | 109 | return caddr; |
TASS Belgium NV |
131:4758606c9316 | 110 | |
tass | 152:a3d286bf94e5 | 111 | cport = nat_cmp_srcport(a, b); |
TASS Belgium NV |
131:4758606c9316 | 112 | |
tass | 152:a3d286bf94e5 | 113 | if (cport) |
tass | 152:a3d286bf94e5 | 114 | return cport; |
TASS Belgium NV |
131:4758606c9316 | 115 | |
tass | 152:a3d286bf94e5 | 116 | return nat_cmp_proto(a, b); |
tass | 68:0847e35d08a6 | 117 | } |
tass | 68:0847e35d08a6 | 118 | |
tass | 68:0847e35d08a6 | 119 | PICO_TREE_DECLARE(NATOutbound, nat_cmp_outbound); |
tass | 68:0847e35d08a6 | 120 | PICO_TREE_DECLARE(NATInbound, nat_cmp_inbound); |
tass | 68:0847e35d08a6 | 121 | |
tass | 68:0847e35d08a6 | 122 | void pico_ipv4_nat_print_table(void) |
tass | 68:0847e35d08a6 | 123 | { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 124 | struct pico_nat_tuple *t = NULL; |
TASS Belgium NV |
131:4758606c9316 | 125 | struct pico_tree_node *index = NULL; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 126 | (void)t; |
tass | 68:0847e35d08a6 | 127 | |
TASS Belgium NV |
131:4758606c9316 | 128 | nat_dbg("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); |
TASS Belgium NV |
131:4758606c9316 | 129 | nat_dbg("+ NAT table +\n"); |
TASS Belgium NV |
131:4758606c9316 | 130 | nat_dbg("+------------------------------------------------------------------------------------------------------------------------+\n"); |
TASS Belgium NV |
131:4758606c9316 | 131 | nat_dbg("+ src_addr | src_port | dst_addr | dst_port | nat_addr | nat_port | proto | conn active | FIN1 | FIN2 | SYN | RST | FORW +\n"); |
TASS Belgium NV |
131:4758606c9316 | 132 | nat_dbg("+------------------------------------------------------------------------------------------------------------------------+\n"); |
tass | 68:0847e35d08a6 | 133 | |
TASS Belgium NV |
131:4758606c9316 | 134 | pico_tree_foreach(index, &NATOutbound) |
TASS Belgium NV |
131:4758606c9316 | 135 | { |
TASS Belgium NV |
131:4758606c9316 | 136 | t = index->keyValue; |
TASS Belgium NV |
131:4758606c9316 | 137 | nat_dbg("+ %08X | %05u | %08X | %05u | %08X | %05u | %03u | %03u | %u | %u | %u | %u | %u +\n", |
TASS Belgium NV |
131:4758606c9316 | 138 | long_be(t->src_addr.addr), t->src_port, long_be(t->dst_addr.addr), t->dst_port, long_be(t->nat_addr.addr), t->nat_port, |
TASS Belgium NV |
131:4758606c9316 | 139 | t->proto, t->conn_active, t->fin_in, t->fin_out, t->syn, t->rst, t->portforward); |
TASS Belgium NV |
131:4758606c9316 | 140 | } |
TASS Belgium NV |
131:4758606c9316 | 141 | nat_dbg("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); |
tass | 68:0847e35d08a6 | 142 | } |
tass | 68:0847e35d08a6 | 143 | |
TASS Belgium NV |
131:4758606c9316 | 144 | /* |
TASS Belgium NV |
131:4758606c9316 | 145 | 2 options: |
tass | 68:0847e35d08a6 | 146 | find on nat_port and proto |
TASS Belgium NV |
131:4758606c9316 | 147 | find on src_addr, src_port and proto |
TASS Belgium NV |
131:4758606c9316 | 148 | zero the unused parameters |
TASS Belgium NV |
131:4758606c9316 | 149 | */ |
tass | 68:0847e35d08a6 | 150 | static struct pico_nat_tuple *pico_ipv4_nat_find_tuple(uint16_t nat_port, struct pico_ip4 *src_addr, uint16_t src_port, uint8_t proto) |
tass | 68:0847e35d08a6 | 151 | { |
TASS Belgium NV |
131:4758606c9316 | 152 | struct pico_nat_tuple *found = NULL, test = { |
TASS Belgium NV |
131:4758606c9316 | 153 | 0 |
TASS Belgium NV |
131:4758606c9316 | 154 | }; |
tass | 68:0847e35d08a6 | 155 | |
TASS Belgium NV |
131:4758606c9316 | 156 | test.nat_port = nat_port; |
TASS Belgium NV |
131:4758606c9316 | 157 | test.src_port = src_port; |
TASS Belgium NV |
131:4758606c9316 | 158 | test.proto = proto; |
TASS Belgium NV |
131:4758606c9316 | 159 | if (src_addr) |
TASS Belgium NV |
131:4758606c9316 | 160 | test.src_addr = *src_addr; |
tass | 68:0847e35d08a6 | 161 | |
TASS Belgium NV |
131:4758606c9316 | 162 | if (nat_port) |
TASS Belgium NV |
131:4758606c9316 | 163 | found = pico_tree_findKey(&NATInbound, &test); |
TASS Belgium NV |
131:4758606c9316 | 164 | else |
TASS Belgium NV |
131:4758606c9316 | 165 | found = pico_tree_findKey(&NATOutbound, &test); |
tass | 68:0847e35d08a6 | 166 | |
TASS Belgium NV |
131:4758606c9316 | 167 | if (found) |
TASS Belgium NV |
131:4758606c9316 | 168 | return found; |
TASS Belgium NV |
131:4758606c9316 | 169 | else |
TASS Belgium NV |
131:4758606c9316 | 170 | return NULL; |
tass | 68:0847e35d08a6 | 171 | } |
tass | 68:0847e35d08a6 | 172 | |
tass | 68:0847e35d08a6 | 173 | int pico_ipv4_nat_find(uint16_t nat_port, struct pico_ip4 *src_addr, uint16_t src_port, uint8_t proto) |
tass | 68:0847e35d08a6 | 174 | { |
TASS Belgium NV |
131:4758606c9316 | 175 | struct pico_nat_tuple *t = NULL; |
tass | 68:0847e35d08a6 | 176 | |
TASS Belgium NV |
131:4758606c9316 | 177 | t = pico_ipv4_nat_find_tuple(nat_port, src_addr, src_port, proto); |
TASS Belgium NV |
131:4758606c9316 | 178 | if (t) |
TASS Belgium NV |
131:4758606c9316 | 179 | return 1; |
TASS Belgium NV |
131:4758606c9316 | 180 | else |
TASS Belgium NV |
131:4758606c9316 | 181 | return 0; |
tass | 68:0847e35d08a6 | 182 | } |
tass | 68:0847e35d08a6 | 183 | |
TASS Belgium NV |
131:4758606c9316 | 184 | static struct pico_nat_tuple *pico_ipv4_nat_add(struct pico_ip4 dst_addr, uint16_t dst_port, struct pico_ip4 src_addr, uint16_t src_port, |
tass | 68:0847e35d08a6 | 185 | struct pico_ip4 nat_addr, uint16_t nat_port, uint8_t proto) |
tass | 68:0847e35d08a6 | 186 | { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 187 | struct pico_nat_tuple *t = PICO_ZALLOC(sizeof(struct pico_nat_tuple)); |
TASS Belgium NV |
131:4758606c9316 | 188 | if (!t) { |
TASS Belgium NV |
131:4758606c9316 | 189 | pico_err = PICO_ERR_ENOMEM; |
TASS Belgium NV |
131:4758606c9316 | 190 | return NULL; |
TASS Belgium NV |
131:4758606c9316 | 191 | } |
tass | 68:0847e35d08a6 | 192 | |
TASS Belgium NV |
131:4758606c9316 | 193 | t->dst_addr = dst_addr; |
TASS Belgium NV |
131:4758606c9316 | 194 | t->dst_port = dst_port; |
TASS Belgium NV |
131:4758606c9316 | 195 | t->src_addr = src_addr; |
TASS Belgium NV |
131:4758606c9316 | 196 | t->src_port = src_port; |
TASS Belgium NV |
131:4758606c9316 | 197 | t->nat_addr = nat_addr; |
TASS Belgium NV |
131:4758606c9316 | 198 | t->nat_port = nat_port; |
TASS Belgium NV |
131:4758606c9316 | 199 | t->proto = proto; |
TASS Belgium NV |
131:4758606c9316 | 200 | t->conn_active = 1; |
TASS Belgium NV |
131:4758606c9316 | 201 | t->portforward = 0; |
TASS Belgium NV |
131:4758606c9316 | 202 | t->rst = 0; |
TASS Belgium NV |
131:4758606c9316 | 203 | t->syn = 0; |
TASS Belgium NV |
131:4758606c9316 | 204 | t->fin_in = 0; |
TASS Belgium NV |
131:4758606c9316 | 205 | t->fin_out = 0; |
tass | 68:0847e35d08a6 | 206 | |
TASS Belgium NV |
131:4758606c9316 | 207 | if (pico_tree_insert(&NATOutbound, t)) { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 208 | PICO_FREE(t); |
TASS Belgium NV |
131:4758606c9316 | 209 | return NULL; |
TASS Belgium NV |
131:4758606c9316 | 210 | } |
tass | 68:0847e35d08a6 | 211 | |
TASS Belgium NV |
131:4758606c9316 | 212 | if (pico_tree_insert(&NATInbound, t)) { |
TASS Belgium NV |
131:4758606c9316 | 213 | pico_tree_delete(&NATOutbound, t); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 214 | PICO_FREE(t); |
TASS Belgium NV |
131:4758606c9316 | 215 | return NULL; |
TASS Belgium NV |
131:4758606c9316 | 216 | } |
TASS Belgium NV |
131:4758606c9316 | 217 | |
TASS Belgium NV |
131:4758606c9316 | 218 | return t; |
tass | 68:0847e35d08a6 | 219 | } |
tass | 68:0847e35d08a6 | 220 | |
tass | 68:0847e35d08a6 | 221 | static int pico_ipv4_nat_del(uint16_t nat_port, uint8_t proto) |
tass | 68:0847e35d08a6 | 222 | { |
TASS Belgium NV |
131:4758606c9316 | 223 | struct pico_nat_tuple *t = NULL; |
TASS Belgium NV |
131:4758606c9316 | 224 | t = pico_ipv4_nat_find_tuple(nat_port, NULL, 0, proto); |
TASS Belgium NV |
131:4758606c9316 | 225 | if (t) { |
TASS Belgium NV |
131:4758606c9316 | 226 | pico_tree_delete(&NATOutbound, t); |
TASS Belgium NV |
131:4758606c9316 | 227 | pico_tree_delete(&NATInbound, t); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 228 | PICO_FREE(t); |
TASS Belgium NV |
131:4758606c9316 | 229 | } |
TASS Belgium NV |
131:4758606c9316 | 230 | |
TASS Belgium NV |
131:4758606c9316 | 231 | return 0; |
tass | 68:0847e35d08a6 | 232 | } |
tass | 68:0847e35d08a6 | 233 | |
tass | 152:a3d286bf94e5 | 234 | static struct pico_trans *pico_nat_generate_tuple_trans(struct pico_ipv4_hdr *net, struct pico_frame *f) |
tass | 152:a3d286bf94e5 | 235 | { |
tass | 152:a3d286bf94e5 | 236 | struct pico_trans *trans = NULL; |
tass | 152:a3d286bf94e5 | 237 | switch (net->proto) { |
tass | 152:a3d286bf94e5 | 238 | case PICO_PROTO_TCP: |
tass | 152:a3d286bf94e5 | 239 | { |
tass | 152:a3d286bf94e5 | 240 | struct pico_tcp_hdr *tcp = (struct pico_tcp_hdr *)f->transport_hdr; |
tass | 152:a3d286bf94e5 | 241 | trans = (struct pico_trans *)&tcp->trans; |
tass | 152:a3d286bf94e5 | 242 | break; |
tass | 152:a3d286bf94e5 | 243 | } |
tass | 152:a3d286bf94e5 | 244 | case PICO_PROTO_UDP: |
tass | 152:a3d286bf94e5 | 245 | { |
tass | 152:a3d286bf94e5 | 246 | struct pico_udp_hdr *udp = (struct pico_udp_hdr *)f->transport_hdr; |
tass | 152:a3d286bf94e5 | 247 | trans = (struct pico_trans *)&udp->trans; |
tass | 152:a3d286bf94e5 | 248 | break; |
tass | 152:a3d286bf94e5 | 249 | } |
tass | 152:a3d286bf94e5 | 250 | case PICO_PROTO_ICMP4: |
tass | 152:a3d286bf94e5 | 251 | /* XXX: implement */ |
tass | 152:a3d286bf94e5 | 252 | break; |
tass | 152:a3d286bf94e5 | 253 | } |
tass | 152:a3d286bf94e5 | 254 | return trans; |
tass | 152:a3d286bf94e5 | 255 | } |
tass | 152:a3d286bf94e5 | 256 | |
tass | 68:0847e35d08a6 | 257 | static struct pico_nat_tuple *pico_ipv4_nat_generate_tuple(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 258 | { |
TASS Belgium NV |
131:4758606c9316 | 259 | struct pico_trans *trans = NULL; |
TASS Belgium NV |
131:4758606c9316 | 260 | struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr; |
TASS Belgium NV |
131:4758606c9316 | 261 | uint16_t nport = 0; |
TASS Belgium NV |
131:4758606c9316 | 262 | uint8_t retry = 32; |
tass | 68:0847e35d08a6 | 263 | |
TASS Belgium NV |
131:4758606c9316 | 264 | /* generate NAT port */ |
TASS Belgium NV |
131:4758606c9316 | 265 | do { |
TASS Belgium NV |
131:4758606c9316 | 266 | uint32_t rand = pico_rand(); |
TASS Belgium NV |
131:4758606c9316 | 267 | nport = (uint16_t) (rand & 0xFFFFU); |
TASS Belgium NV |
131:4758606c9316 | 268 | nport = (uint16_t)((nport % (65535 - 1024)) + 1024U); |
TASS Belgium NV |
131:4758606c9316 | 269 | nport = short_be(nport); |
tass | 68:0847e35d08a6 | 270 | |
TASS Belgium NV |
131:4758606c9316 | 271 | if (pico_is_port_free(net->proto, nport, NULL, &pico_proto_ipv4)) |
TASS Belgium NV |
131:4758606c9316 | 272 | break; |
TASS Belgium NV |
131:4758606c9316 | 273 | } while (--retry); |
tass | 68:0847e35d08a6 | 274 | |
TASS Belgium NV |
131:4758606c9316 | 275 | if (!retry) |
TASS Belgium NV |
131:4758606c9316 | 276 | return NULL; |
TASS Belgium NV |
131:4758606c9316 | 277 | |
tass | 152:a3d286bf94e5 | 278 | trans = pico_nat_generate_tuple_trans(net, f); |
tass | 152:a3d286bf94e5 | 279 | if(!trans) |
TASS Belgium NV |
131:4758606c9316 | 280 | return NULL; |
tass | 68:0847e35d08a6 | 281 | |
TASS Belgium NV |
131:4758606c9316 | 282 | return pico_ipv4_nat_add(net->dst, trans->dport, net->src, trans->sport, nat_link->address, nport, net->proto); |
TASS Belgium NV |
131:4758606c9316 | 283 | /* XXX return pico_ipv4_nat_add(nat_link->address, port, net->src, trans->sport, net->proto); */ |
tass | 68:0847e35d08a6 | 284 | } |
tass | 68:0847e35d08a6 | 285 | |
tass | 152:a3d286bf94e5 | 286 | static inline void pico_ipv4_nat_set_tcp_flags(struct pico_nat_tuple *t, struct pico_frame *f, uint8_t direction) |
tass | 152:a3d286bf94e5 | 287 | { |
tass | 152:a3d286bf94e5 | 288 | struct pico_tcp_hdr *tcp = (struct pico_tcp_hdr *)f->transport_hdr; |
tass | 152:a3d286bf94e5 | 289 | if (tcp->flags & PICO_TCP_SYN) |
tass | 152:a3d286bf94e5 | 290 | t->syn = 1; |
tass | 152:a3d286bf94e5 | 291 | |
tass | 152:a3d286bf94e5 | 292 | if (tcp->flags & PICO_TCP_RST) |
tass | 152:a3d286bf94e5 | 293 | t->rst = 1; |
tass | 152:a3d286bf94e5 | 294 | |
tass | 152:a3d286bf94e5 | 295 | if ((tcp->flags & PICO_TCP_FIN) && (direction == PICO_NAT_INBOUND)) |
tass | 152:a3d286bf94e5 | 296 | t->fin_in = 1; |
tass | 152:a3d286bf94e5 | 297 | |
tass | 152:a3d286bf94e5 | 298 | if ((tcp->flags & PICO_TCP_FIN) && (direction == PICO_NAT_OUTBOUND)) |
tass | 152:a3d286bf94e5 | 299 | t->fin_out = 1; |
tass | 152:a3d286bf94e5 | 300 | } |
tass | 152:a3d286bf94e5 | 301 | |
tass | 152:a3d286bf94e5 | 302 | static int pico_ipv4_nat_sniff_session(struct pico_nat_tuple *t, struct pico_frame *f, uint8_t direction) |
tass | 68:0847e35d08a6 | 303 | { |
TASS Belgium NV |
131:4758606c9316 | 304 | struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr; |
TASS Belgium NV |
131:4758606c9316 | 305 | |
TASS Belgium NV |
131:4758606c9316 | 306 | switch (net->proto) { |
tass | 68:0847e35d08a6 | 307 | case PICO_PROTO_TCP: |
tass | 68:0847e35d08a6 | 308 | { |
tass | 152:a3d286bf94e5 | 309 | pico_ipv4_nat_set_tcp_flags(t, f, direction); |
TASS Belgium NV |
131:4758606c9316 | 310 | break; |
tass | 68:0847e35d08a6 | 311 | } |
tass | 68:0847e35d08a6 | 312 | |
tass | 68:0847e35d08a6 | 313 | case PICO_PROTO_UDP: |
TASS Belgium NV |
131:4758606c9316 | 314 | t->conn_active = 1; |
TASS Belgium NV |
131:4758606c9316 | 315 | break; |
tass | 68:0847e35d08a6 | 316 | |
tass | 68:0847e35d08a6 | 317 | case PICO_PROTO_ICMP4: |
TASS Belgium NV |
131:4758606c9316 | 318 | /* XXX: implement */ |
TASS Belgium NV |
131:4758606c9316 | 319 | break; |
tass | 68:0847e35d08a6 | 320 | |
tass | 68:0847e35d08a6 | 321 | default: |
TASS Belgium NV |
131:4758606c9316 | 322 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 323 | } |
tass | 68:0847e35d08a6 | 324 | |
TASS Belgium NV |
131:4758606c9316 | 325 | return 0; |
tass | 68:0847e35d08a6 | 326 | } |
tass | 68:0847e35d08a6 | 327 | |
tass | 128:ae39e6e81531 | 328 | static void pico_ipv4_nat_table_cleanup(pico_time now, void *_unused) |
tass | 68:0847e35d08a6 | 329 | { |
TASS Belgium NV |
131:4758606c9316 | 330 | struct pico_tree_node *index = NULL, *_tmp = NULL; |
TASS Belgium NV |
131:4758606c9316 | 331 | struct pico_nat_tuple *t = NULL; |
TASS Belgium NV |
131:4758606c9316 | 332 | IGNORE_PARAMETER(now); |
TASS Belgium NV |
131:4758606c9316 | 333 | IGNORE_PARAMETER(_unused); |
TASS Belgium NV |
131:4758606c9316 | 334 | nat_dbg("NAT: before table cleanup:\n"); |
TASS Belgium NV |
131:4758606c9316 | 335 | pico_ipv4_nat_print_table(); |
tass | 68:0847e35d08a6 | 336 | |
TASS Belgium NV |
131:4758606c9316 | 337 | pico_tree_foreach_reverse_safe(index, &NATOutbound, _tmp) |
tass | 68:0847e35d08a6 | 338 | { |
TASS Belgium NV |
131:4758606c9316 | 339 | t = index->keyValue; |
TASS Belgium NV |
131:4758606c9316 | 340 | switch (t->proto) |
TASS Belgium NV |
131:4758606c9316 | 341 | { |
TASS Belgium NV |
131:4758606c9316 | 342 | case PICO_PROTO_TCP: |
TASS Belgium NV |
131:4758606c9316 | 343 | if (t->portforward) |
TASS Belgium NV |
131:4758606c9316 | 344 | break; |
TASS Belgium NV |
131:4758606c9316 | 345 | else if (t->conn_active == 0 || t->conn_active > 360) /* conn active for > 24 hours */ |
TASS Belgium NV |
131:4758606c9316 | 346 | pico_ipv4_nat_del(t->nat_port, t->proto); |
TASS Belgium NV |
131:4758606c9316 | 347 | else if (t->rst || (t->fin_in && t->fin_out)) |
TASS Belgium NV |
131:4758606c9316 | 348 | t->conn_active = 0; |
TASS Belgium NV |
131:4758606c9316 | 349 | else |
TASS Belgium NV |
131:4758606c9316 | 350 | t->conn_active++; |
TASS Belgium NV |
131:4758606c9316 | 351 | |
TASS Belgium NV |
131:4758606c9316 | 352 | break; |
tass | 68:0847e35d08a6 | 353 | |
TASS Belgium NV |
131:4758606c9316 | 354 | case PICO_PROTO_UDP: |
TASS Belgium NV |
131:4758606c9316 | 355 | if (t->portforward) |
TASS Belgium NV |
131:4758606c9316 | 356 | break; |
TASS Belgium NV |
131:4758606c9316 | 357 | else if (t->conn_active > 1) |
TASS Belgium NV |
131:4758606c9316 | 358 | pico_ipv4_nat_del(t->nat_port, t->proto); |
TASS Belgium NV |
131:4758606c9316 | 359 | else |
TASS Belgium NV |
131:4758606c9316 | 360 | t->conn_active++; |
TASS Belgium NV |
131:4758606c9316 | 361 | |
TASS Belgium NV |
131:4758606c9316 | 362 | break; |
tass | 68:0847e35d08a6 | 363 | |
TASS Belgium NV |
131:4758606c9316 | 364 | case PICO_PROTO_ICMP4: |
TASS Belgium NV |
131:4758606c9316 | 365 | if (t->conn_active > 1) |
TASS Belgium NV |
131:4758606c9316 | 366 | pico_ipv4_nat_del(t->nat_port, t->proto); |
TASS Belgium NV |
131:4758606c9316 | 367 | else |
TASS Belgium NV |
131:4758606c9316 | 368 | t->conn_active++; |
tass | 68:0847e35d08a6 | 369 | |
TASS Belgium NV |
131:4758606c9316 | 370 | default: |
TASS Belgium NV |
131:4758606c9316 | 371 | /* unknown protocol in NAT table, delete when it has existed NAT_TIMEWAIT */ |
TASS Belgium NV |
131:4758606c9316 | 372 | if (t->conn_active > 1) |
TASS Belgium NV |
131:4758606c9316 | 373 | pico_ipv4_nat_del(t->nat_port, t->proto); |
TASS Belgium NV |
131:4758606c9316 | 374 | else |
TASS Belgium NV |
131:4758606c9316 | 375 | t->conn_active++; |
TASS Belgium NV |
131:4758606c9316 | 376 | } |
tass | 68:0847e35d08a6 | 377 | } |
tass | 68:0847e35d08a6 | 378 | |
TASS Belgium NV |
131:4758606c9316 | 379 | nat_dbg("NAT: after table cleanup:\n"); |
TASS Belgium NV |
131:4758606c9316 | 380 | pico_ipv4_nat_print_table(); |
TASS Belgium NV |
131:4758606c9316 | 381 | pico_timer_add(PICO_NAT_TIMEWAIT, pico_ipv4_nat_table_cleanup, NULL); |
tass | 68:0847e35d08a6 | 382 | } |
tass | 68:0847e35d08a6 | 383 | |
tass | 68:0847e35d08a6 | 384 | int pico_ipv4_port_forward(struct pico_ip4 nat_addr, uint16_t nat_port, struct pico_ip4 src_addr, uint16_t src_port, uint8_t proto, uint8_t flag) |
tass | 68:0847e35d08a6 | 385 | { |
TASS Belgium NV |
131:4758606c9316 | 386 | struct pico_nat_tuple *t = NULL; |
TASS Belgium NV |
131:4758606c9316 | 387 | struct pico_ip4 any_addr = { |
TASS Belgium NV |
131:4758606c9316 | 388 | 0 |
TASS Belgium NV |
131:4758606c9316 | 389 | }; |
TASS Belgium NV |
131:4758606c9316 | 390 | uint16_t any_port = 0; |
tass | 68:0847e35d08a6 | 391 | |
TASS Belgium NV |
131:4758606c9316 | 392 | switch (flag) |
TASS Belgium NV |
131:4758606c9316 | 393 | { |
tass | 68:0847e35d08a6 | 394 | case PICO_NAT_PORT_FORWARD_ADD: |
TASS Belgium NV |
131:4758606c9316 | 395 | t = pico_ipv4_nat_add(any_addr, any_port, src_addr, src_port, nat_addr, nat_port, proto); |
TASS Belgium NV |
131:4758606c9316 | 396 | if (!t) { |
TASS Belgium NV |
131:4758606c9316 | 397 | pico_err = PICO_ERR_EAGAIN; |
TASS Belgium NV |
131:4758606c9316 | 398 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 399 | } |
TASS Belgium NV |
131:4758606c9316 | 400 | |
TASS Belgium NV |
131:4758606c9316 | 401 | t->portforward = 1; |
TASS Belgium NV |
131:4758606c9316 | 402 | break; |
tass | 68:0847e35d08a6 | 403 | |
tass | 68:0847e35d08a6 | 404 | case PICO_NAT_PORT_FORWARD_DEL: |
TASS Belgium NV |
131:4758606c9316 | 405 | return pico_ipv4_nat_del(nat_port, proto); |
tass | 68:0847e35d08a6 | 406 | |
tass | 68:0847e35d08a6 | 407 | default: |
TASS Belgium NV |
131:4758606c9316 | 408 | pico_err = PICO_ERR_EINVAL; |
TASS Belgium NV |
131:4758606c9316 | 409 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 410 | } |
tass | 68:0847e35d08a6 | 411 | |
TASS Belgium NV |
131:4758606c9316 | 412 | pico_ipv4_nat_print_table(); |
TASS Belgium NV |
131:4758606c9316 | 413 | return 0; |
tass | 68:0847e35d08a6 | 414 | } |
tass | 68:0847e35d08a6 | 415 | |
tass | 68:0847e35d08a6 | 416 | int pico_ipv4_nat_inbound(struct pico_frame *f, struct pico_ip4 *link_addr) |
tass | 68:0847e35d08a6 | 417 | { |
TASS Belgium NV |
131:4758606c9316 | 418 | struct pico_nat_tuple *tuple = NULL; |
TASS Belgium NV |
131:4758606c9316 | 419 | struct pico_trans *trans = NULL; |
TASS Belgium NV |
131:4758606c9316 | 420 | struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr; |
tass | 68:0847e35d08a6 | 421 | |
TASS Belgium NV |
131:4758606c9316 | 422 | if (!pico_ipv4_nat_is_enabled(link_addr)) |
TASS Belgium NV |
131:4758606c9316 | 423 | return -1; |
tass | 68:0847e35d08a6 | 424 | |
TASS Belgium NV |
131:4758606c9316 | 425 | switch (net->proto) { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 426 | #ifdef PICO_SUPPORT_TCP |
tass | 68:0847e35d08a6 | 427 | case PICO_PROTO_TCP: |
tass | 68:0847e35d08a6 | 428 | { |
TASS Belgium NV |
131:4758606c9316 | 429 | struct pico_tcp_hdr *tcp = (struct pico_tcp_hdr *)f->transport_hdr; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 430 | trans = (struct pico_trans *)&tcp->trans; |
TASS Belgium NV |
131:4758606c9316 | 431 | tuple = pico_ipv4_nat_find_tuple(trans->dport, 0, 0, net->proto); |
TASS Belgium NV |
131:4758606c9316 | 432 | if (!tuple) |
TASS Belgium NV |
131:4758606c9316 | 433 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 434 | |
TASS Belgium NV |
131:4758606c9316 | 435 | /* replace dst IP and dst PORT */ |
TASS Belgium NV |
131:4758606c9316 | 436 | net->dst = tuple->src_addr; |
TASS Belgium NV |
131:4758606c9316 | 437 | trans->dport = tuple->src_port; |
TASS Belgium NV |
131:4758606c9316 | 438 | /* recalculate CRC */ |
TASS Belgium NV |
131:4758606c9316 | 439 | tcp->crc = 0; |
TASS Belgium NV |
131:4758606c9316 | 440 | tcp->crc = short_be(pico_tcp_checksum_ipv4(f)); |
TASS Belgium NV |
131:4758606c9316 | 441 | break; |
tass | 68:0847e35d08a6 | 442 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 443 | #endif |
tass picotcp@tass.be | 149:5f4cb161cec3 | 444 | #ifdef PICO_SUPPORT_UDP |
tass | 68:0847e35d08a6 | 445 | case PICO_PROTO_UDP: |
tass | 68:0847e35d08a6 | 446 | { |
TASS Belgium NV |
131:4758606c9316 | 447 | struct pico_udp_hdr *udp = (struct pico_udp_hdr *)f->transport_hdr; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 448 | trans = (struct pico_trans *)&udp->trans; |
TASS Belgium NV |
131:4758606c9316 | 449 | tuple = pico_ipv4_nat_find_tuple(trans->dport, 0, 0, net->proto); |
TASS Belgium NV |
131:4758606c9316 | 450 | if (!tuple) |
TASS Belgium NV |
131:4758606c9316 | 451 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 452 | |
TASS Belgium NV |
131:4758606c9316 | 453 | /* replace dst IP and dst PORT */ |
TASS Belgium NV |
131:4758606c9316 | 454 | net->dst = tuple->src_addr; |
TASS Belgium NV |
131:4758606c9316 | 455 | trans->dport = tuple->src_port; |
TASS Belgium NV |
131:4758606c9316 | 456 | /* recalculate CRC */ |
TASS Belgium NV |
131:4758606c9316 | 457 | udp->crc = 0; |
TASS Belgium NV |
131:4758606c9316 | 458 | udp->crc = short_be(pico_udp_checksum_ipv4(f)); |
TASS Belgium NV |
131:4758606c9316 | 459 | break; |
tass | 68:0847e35d08a6 | 460 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 461 | #endif |
tass | 68:0847e35d08a6 | 462 | case PICO_PROTO_ICMP4: |
TASS Belgium NV |
131:4758606c9316 | 463 | /* XXX reimplement */ |
TASS Belgium NV |
131:4758606c9316 | 464 | break; |
tass | 68:0847e35d08a6 | 465 | |
tass | 68:0847e35d08a6 | 466 | default: |
TASS Belgium NV |
131:4758606c9316 | 467 | nat_dbg("NAT ERROR: inbound NAT on erroneous protocol\n"); |
TASS Belgium NV |
131:4758606c9316 | 468 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 469 | } |
tass | 68:0847e35d08a6 | 470 | |
tass | 152:a3d286bf94e5 | 471 | pico_ipv4_nat_sniff_session(tuple, f, PICO_NAT_INBOUND); |
TASS Belgium NV |
131:4758606c9316 | 472 | net->crc = 0; |
TASS Belgium NV |
131:4758606c9316 | 473 | net->crc = short_be(pico_checksum(net, f->net_len)); |
tass | 68:0847e35d08a6 | 474 | |
TASS Belgium NV |
131:4758606c9316 | 475 | nat_dbg("NAT: inbound translation {dst.addr, dport}: {%08X,%u} -> {%08X,%u}\n", |
tass | 68:0847e35d08a6 | 476 | tuple->nat_addr.addr, short_be(tuple->nat_port), tuple->src_addr.addr, short_be(tuple->src_port)); |
tass | 68:0847e35d08a6 | 477 | |
TASS Belgium NV |
131:4758606c9316 | 478 | return 0; |
tass | 68:0847e35d08a6 | 479 | } |
tass | 68:0847e35d08a6 | 480 | |
tass | 68:0847e35d08a6 | 481 | int pico_ipv4_nat_outbound(struct pico_frame *f, struct pico_ip4 *link_addr) |
tass | 68:0847e35d08a6 | 482 | { |
TASS Belgium NV |
131:4758606c9316 | 483 | struct pico_nat_tuple *tuple = NULL; |
TASS Belgium NV |
131:4758606c9316 | 484 | struct pico_trans *trans = NULL; |
TASS Belgium NV |
131:4758606c9316 | 485 | struct pico_ipv4_hdr *net = (struct pico_ipv4_hdr *)f->net_hdr; |
tass | 68:0847e35d08a6 | 486 | |
TASS Belgium NV |
131:4758606c9316 | 487 | if (!pico_ipv4_nat_is_enabled(link_addr)) |
TASS Belgium NV |
131:4758606c9316 | 488 | return -1; |
tass | 68:0847e35d08a6 | 489 | |
TASS Belgium NV |
131:4758606c9316 | 490 | switch (net->proto) { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 491 | #ifdef PICO_SUPPORT_TCP |
tass | 68:0847e35d08a6 | 492 | case PICO_PROTO_TCP: |
tass | 68:0847e35d08a6 | 493 | { |
TASS Belgium NV |
131:4758606c9316 | 494 | struct pico_tcp_hdr *tcp = (struct pico_tcp_hdr *)f->transport_hdr; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 495 | trans = (struct pico_trans *)&tcp->trans; |
TASS Belgium NV |
131:4758606c9316 | 496 | tuple = pico_ipv4_nat_find_tuple(0, &net->src, trans->sport, net->proto); |
TASS Belgium NV |
131:4758606c9316 | 497 | if (!tuple) |
TASS Belgium NV |
131:4758606c9316 | 498 | tuple = pico_ipv4_nat_generate_tuple(f); |
TASS Belgium NV |
131:4758606c9316 | 499 | |
TASS Belgium NV |
131:4758606c9316 | 500 | /* replace src IP and src PORT */ |
TASS Belgium NV |
131:4758606c9316 | 501 | net->src = tuple->nat_addr; |
TASS Belgium NV |
131:4758606c9316 | 502 | trans->sport = tuple->nat_port; |
TASS Belgium NV |
131:4758606c9316 | 503 | /* recalculate CRC */ |
TASS Belgium NV |
131:4758606c9316 | 504 | tcp->crc = 0; |
TASS Belgium NV |
131:4758606c9316 | 505 | tcp->crc = short_be(pico_tcp_checksum_ipv4(f)); |
TASS Belgium NV |
131:4758606c9316 | 506 | break; |
tass | 68:0847e35d08a6 | 507 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 508 | #endif |
tass picotcp@tass.be | 149:5f4cb161cec3 | 509 | #ifdef PICO_SUPPORT_UDP |
tass | 68:0847e35d08a6 | 510 | case PICO_PROTO_UDP: |
tass | 68:0847e35d08a6 | 511 | { |
TASS Belgium NV |
131:4758606c9316 | 512 | struct pico_udp_hdr *udp = (struct pico_udp_hdr *)f->transport_hdr; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 513 | trans = (struct pico_trans *)&udp->trans; |
TASS Belgium NV |
131:4758606c9316 | 514 | tuple = pico_ipv4_nat_find_tuple(0, &net->src, trans->sport, net->proto); |
TASS Belgium NV |
131:4758606c9316 | 515 | if (!tuple) |
TASS Belgium NV |
131:4758606c9316 | 516 | tuple = pico_ipv4_nat_generate_tuple(f); |
TASS Belgium NV |
131:4758606c9316 | 517 | |
TASS Belgium NV |
131:4758606c9316 | 518 | /* replace src IP and src PORT */ |
TASS Belgium NV |
131:4758606c9316 | 519 | net->src = tuple->nat_addr; |
TASS Belgium NV |
131:4758606c9316 | 520 | trans->sport = tuple->nat_port; |
TASS Belgium NV |
131:4758606c9316 | 521 | /* recalculate CRC */ |
TASS Belgium NV |
131:4758606c9316 | 522 | udp->crc = 0; |
TASS Belgium NV |
131:4758606c9316 | 523 | udp->crc = short_be(pico_udp_checksum_ipv4(f)); |
TASS Belgium NV |
131:4758606c9316 | 524 | break; |
tass | 68:0847e35d08a6 | 525 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 526 | #endif |
tass | 68:0847e35d08a6 | 527 | case PICO_PROTO_ICMP4: |
TASS Belgium NV |
131:4758606c9316 | 528 | /* XXX reimplement */ |
TASS Belgium NV |
131:4758606c9316 | 529 | break; |
tass | 68:0847e35d08a6 | 530 | |
tass | 68:0847e35d08a6 | 531 | default: |
TASS Belgium NV |
131:4758606c9316 | 532 | nat_dbg("NAT ERROR: outbound NAT on erroneous protocol\n"); |
TASS Belgium NV |
131:4758606c9316 | 533 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 534 | } |
tass | 68:0847e35d08a6 | 535 | |
tass | 152:a3d286bf94e5 | 536 | pico_ipv4_nat_sniff_session(tuple, f, PICO_NAT_OUTBOUND); |
TASS Belgium NV |
131:4758606c9316 | 537 | net->crc = 0; |
TASS Belgium NV |
131:4758606c9316 | 538 | net->crc = short_be(pico_checksum(net, f->net_len)); |
tass | 68:0847e35d08a6 | 539 | |
TASS Belgium NV |
131:4758606c9316 | 540 | nat_dbg("NAT: outbound translation {src.addr, sport}: {%08X,%u} -> {%08X,%u}\n", |
tass | 68:0847e35d08a6 | 541 | tuple->src_addr.addr, short_be(tuple->src_port), tuple->nat_addr.addr, short_be(tuple->nat_port)); |
tass | 68:0847e35d08a6 | 542 | |
TASS Belgium NV |
131:4758606c9316 | 543 | return 0; |
tass | 68:0847e35d08a6 | 544 | } |
tass | 68:0847e35d08a6 | 545 | |
tass | 68:0847e35d08a6 | 546 | int pico_ipv4_nat_enable(struct pico_ipv4_link *link) |
tass | 68:0847e35d08a6 | 547 | { |
TASS Belgium NV |
131:4758606c9316 | 548 | if (link == NULL) { |
TASS Belgium NV |
131:4758606c9316 | 549 | pico_err = PICO_ERR_EINVAL; |
TASS Belgium NV |
131:4758606c9316 | 550 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 551 | } |
tass | 68:0847e35d08a6 | 552 | |
TASS Belgium NV |
131:4758606c9316 | 553 | nat_link = link; |
TASS Belgium NV |
131:4758606c9316 | 554 | pico_timer_add(PICO_NAT_TIMEWAIT, pico_ipv4_nat_table_cleanup, NULL); |
TASS Belgium NV |
131:4758606c9316 | 555 | return 0; |
tass | 68:0847e35d08a6 | 556 | } |
TASS Belgium NV |
131:4758606c9316 | 557 | |
tass | 68:0847e35d08a6 | 558 | int pico_ipv4_nat_disable(void) |
tass | 68:0847e35d08a6 | 559 | { |
TASS Belgium NV |
131:4758606c9316 | 560 | nat_link = NULL; |
TASS Belgium NV |
131:4758606c9316 | 561 | return 0; |
tass | 68:0847e35d08a6 | 562 | } |
tass | 68:0847e35d08a6 | 563 | |
tass | 68:0847e35d08a6 | 564 | int pico_ipv4_nat_is_enabled(struct pico_ip4 *link_addr) |
tass | 68:0847e35d08a6 | 565 | { |
TASS Belgium NV |
131:4758606c9316 | 566 | if (!nat_link) |
TASS Belgium NV |
131:4758606c9316 | 567 | return 0; |
TASS Belgium NV |
131:4758606c9316 | 568 | |
TASS Belgium NV |
131:4758606c9316 | 569 | if (nat_link->address.addr != link_addr->addr) |
TASS Belgium NV |
131:4758606c9316 | 570 | return 0; |
TASS Belgium NV |
131:4758606c9316 | 571 | |
TASS Belgium NV |
131:4758606c9316 | 572 | return 1; |
tass | 68:0847e35d08a6 | 573 | } |
tass | 68:0847e35d08a6 | 574 | |
tass | 68:0847e35d08a6 | 575 | #endif |
tass | 68:0847e35d08a6 | 576 | #endif |