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 RTOS
  • generic mbed Ethernet driver
  • high performance NXP LPC1768 specific Ethernet driver
  • Multi-threading support for mbed RTOS
  • Berkeley sockets and integration with the New Socket API
  • Fork of the apps running on top of the New Socket API
  • Scheduling 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.

Committer:
tass
Date:
Thu Jan 28 15:12:00 2016 +0100
Revision:
155:a70f34550c34
Parent:
154:6c0e92a80c4a
Adding TCP flag for FIN.

Who changed what in which revision?

UserRevisionLine numberNew 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 Authors: Andrei Carp
TASS Belgium NV 131:4758606c9316 6 Simon Maes
TASS Belgium NV 131:4758606c9316 7 *********************************************************************/
tass 68:0847e35d08a6 8
tass 68:0847e35d08a6 9 #include "pico_ipv4.h"
tass 68:0847e35d08a6 10 #include "pico_config.h"
tass 68:0847e35d08a6 11 #include "pico_icmp4.h"
tass 68:0847e35d08a6 12 #include "pico_stack.h"
tass 68:0847e35d08a6 13 #include "pico_eth.h"
tass 68:0847e35d08a6 14 #include "pico_socket.h"
tass 68:0847e35d08a6 15 #include "pico_device.h"
tass 68:0847e35d08a6 16 #include "pico_ipfilter.h"
tass 68:0847e35d08a6 17 #include "pico_tcp.h"
tass 68:0847e35d08a6 18 #include "pico_udp.h"
tass 125:96003ae6f1d8 19 #include "pico_tree.h"
tass 68:0847e35d08a6 20
tass 125:96003ae6f1d8 21 /**************** LOCAL MACROS ****************/
TASS Belgium NV 131:4758606c9316 22 #define MAX_PRIORITY (10)
TASS Belgium NV 131:4758606c9316 23 #define MIN_PRIORITY (-10)
tass 125:96003ae6f1d8 24
TASS Belgium NV 131:4758606c9316 25 #define ipf_dbg(...) do {} while(0)
tass 68:0847e35d08a6 26
tass 125:96003ae6f1d8 27 /**************** LOCAL DECLARATIONS ****************/
tass 68:0847e35d08a6 28 struct filter_node;
tass 125:96003ae6f1d8 29 static int filter_compare(void *filterA, void *filterB);
tass 125:96003ae6f1d8 30
tass 125:96003ae6f1d8 31 /**************** FILTER TREE ****************/
tass 68:0847e35d08a6 32
tass 68:0847e35d08a6 33 struct filter_node {
TASS Belgium NV 131:4758606c9316 34 struct pico_device *fdev;
TASS Belgium NV 131:4758606c9316 35 /* output address */
TASS Belgium NV 131:4758606c9316 36 uint32_t out_addr;
TASS Belgium NV 131:4758606c9316 37 uint32_t out_addr_netmask;
TASS Belgium NV 131:4758606c9316 38 /* input address */
TASS Belgium NV 131:4758606c9316 39 uint32_t in_addr;
TASS Belgium NV 131:4758606c9316 40 uint32_t in_addr_netmask;
TASS Belgium NV 131:4758606c9316 41 /* transport */
TASS Belgium NV 131:4758606c9316 42 uint16_t out_port;
TASS Belgium NV 131:4758606c9316 43 uint16_t in_port;
TASS Belgium NV 131:4758606c9316 44 /* filter details */
TASS Belgium NV 131:4758606c9316 45 uint8_t proto;
TASS Belgium NV 131:4758606c9316 46 int8_t priority;
TASS Belgium NV 131:4758606c9316 47 uint8_t tos;
tass 152:a3d286bf94e5 48 uint32_t filter_id;
TASS Belgium NV 131:4758606c9316 49 int (*function_ptr)(struct filter_node *filter, struct pico_frame *f);
tass 68:0847e35d08a6 50 };
tass 68:0847e35d08a6 51
TASS Belgium NV 131:4758606c9316 52 PICO_TREE_DECLARE(filter_tree, &filter_compare);
tass 125:96003ae6f1d8 53
tass 152:a3d286bf94e5 54 static inline int ipfilter_uint32_cmp(uint32_t a, uint32_t b)
tass 152:a3d286bf94e5 55 {
tass 152:a3d286bf94e5 56 if (a < b)
tass 152:a3d286bf94e5 57 return -1;
tass 152:a3d286bf94e5 58
tass 152:a3d286bf94e5 59 if (b < a)
tass 152:a3d286bf94e5 60 return 1;
tass 152:a3d286bf94e5 61
tass 152:a3d286bf94e5 62 return 0;
tass 152:a3d286bf94e5 63 }
tass 152:a3d286bf94e5 64
tass 152:a3d286bf94e5 65 static inline int ipfilter_uint16_cmp(uint16_t a, uint16_t b)
tass 152:a3d286bf94e5 66 {
tass 152:a3d286bf94e5 67 if (a < b)
tass 152:a3d286bf94e5 68 return -1;
tass 152:a3d286bf94e5 69
tass 152:a3d286bf94e5 70 if (b < a)
tass 152:a3d286bf94e5 71 return 1;
tass 152:a3d286bf94e5 72
tass 152:a3d286bf94e5 73 return 0;
tass 152:a3d286bf94e5 74 }
tass 152:a3d286bf94e5 75
tass 152:a3d286bf94e5 76 static inline int ipfilter_uint8_cmp(uint8_t a, uint8_t b)
tass 152:a3d286bf94e5 77 {
tass 152:a3d286bf94e5 78 if (a < b)
tass 152:a3d286bf94e5 79 return -1;
tass 152:a3d286bf94e5 80
tass 152:a3d286bf94e5 81 if (b < a)
tass 152:a3d286bf94e5 82 return 1;
tass 152:a3d286bf94e5 83
tass 152:a3d286bf94e5 84 return 0;
tass 152:a3d286bf94e5 85 }
tass 152:a3d286bf94e5 86
tass 152:a3d286bf94e5 87 static inline int ipfilter_ptr_cmp(void *a, void *b)
tass 152:a3d286bf94e5 88 {
tass 152:a3d286bf94e5 89 if (a < b)
tass 152:a3d286bf94e5 90 return -1;
tass 152:a3d286bf94e5 91
tass 152:a3d286bf94e5 92 if (b < a)
tass 152:a3d286bf94e5 93 return 1;
tass 152:a3d286bf94e5 94
tass 152:a3d286bf94e5 95 return 0;
tass 152:a3d286bf94e5 96 }
tass 152:a3d286bf94e5 97
tass 152:a3d286bf94e5 98
tass 152:a3d286bf94e5 99
tass 152:a3d286bf94e5 100 static inline int filter_compare_ports(struct filter_node *a, struct filter_node *b)
tass 152:a3d286bf94e5 101 {
tass 152:a3d286bf94e5 102 int cmp;
tass 152:a3d286bf94e5 103 cmp = ipfilter_uint16_cmp(a->in_port, b->in_port);
tass 152:a3d286bf94e5 104 if (cmp)
tass 152:a3d286bf94e5 105 return cmp;
tass 152:a3d286bf94e5 106
tass 152:a3d286bf94e5 107 cmp = ipfilter_uint16_cmp(a->out_port, b->out_port);
tass 152:a3d286bf94e5 108 return cmp;
tass 152:a3d286bf94e5 109 }
tass 152:a3d286bf94e5 110
tass 152:a3d286bf94e5 111 static inline int filter_compare_addresses(struct filter_node *a, struct filter_node *b)
tass 152:a3d286bf94e5 112 {
tass 152:a3d286bf94e5 113 int cmp;
tass 152:a3d286bf94e5 114 /* Compare source address */
tass 152:a3d286bf94e5 115 cmp = ipfilter_uint32_cmp((a->in_addr & a->in_addr_netmask), (b->in_addr & b->in_addr_netmask));
tass 152:a3d286bf94e5 116 if (cmp)
tass 152:a3d286bf94e5 117 return cmp;
tass 152:a3d286bf94e5 118
tass 152:a3d286bf94e5 119 /* Compare destination address */
tass 152:a3d286bf94e5 120 cmp = ipfilter_uint32_cmp((a->out_addr & a->out_addr_netmask), (b->out_addr & b->out_addr_netmask));
tass 152:a3d286bf94e5 121 return cmp;
tass 152:a3d286bf94e5 122 }
tass 152:a3d286bf94e5 123
tass 152:a3d286bf94e5 124 static inline int filter_compare_proto(struct filter_node *a, struct filter_node *b)
tass 152:a3d286bf94e5 125 {
tass 152:a3d286bf94e5 126 return ipfilter_uint8_cmp(a->proto, b->proto);
tass 152:a3d286bf94e5 127 }
tass 152:a3d286bf94e5 128
tass 152:a3d286bf94e5 129 static inline int filter_compare_address_port(struct filter_node *a, struct filter_node *b)
tass 152:a3d286bf94e5 130 {
tass 152:a3d286bf94e5 131 int cmp;
tass 152:a3d286bf94e5 132 cmp = filter_compare_addresses(a, b);
tass 152:a3d286bf94e5 133 if (cmp)
tass 152:a3d286bf94e5 134 return cmp;
tass 152:a3d286bf94e5 135
tass 152:a3d286bf94e5 136 return filter_compare_ports(a, b);
tass 152:a3d286bf94e5 137 }
tass 152:a3d286bf94e5 138
tass 152:a3d286bf94e5 139 static inline int filter_match_packet_dev(struct filter_node *a, struct filter_node *b, struct filter_node *rule)
tass 152:a3d286bf94e5 140 {
tass 152:a3d286bf94e5 141 int cmp;
tass 152:a3d286bf94e5 142 /* 1. Compare devices */
tass 152:a3d286bf94e5 143 if (rule->fdev) {
tass 152:a3d286bf94e5 144 cmp = ipfilter_ptr_cmp(a->fdev, b->fdev);
tass 152:a3d286bf94e5 145 if (cmp)
tass 152:a3d286bf94e5 146 return cmp;
tass 152:a3d286bf94e5 147 }
tass 152:a3d286bf94e5 148
tass 152:a3d286bf94e5 149 return 0;
tass 152:a3d286bf94e5 150
tass 152:a3d286bf94e5 151 }
tass 152:a3d286bf94e5 152
tass 152:a3d286bf94e5 153 static inline int filter_match_packet_proto(struct filter_node *a, struct filter_node *b, struct filter_node *rule)
tass 152:a3d286bf94e5 154 {
tass 152:a3d286bf94e5 155 int cmp;
tass 152:a3d286bf94e5 156 /* 2. Compare protocol */
tass 152:a3d286bf94e5 157 if (rule->proto) {
tass 152:a3d286bf94e5 158 cmp = filter_compare_proto(a, b);
tass 152:a3d286bf94e5 159 if (cmp)
tass 152:a3d286bf94e5 160 return cmp;
tass 152:a3d286bf94e5 161 }
tass 152:a3d286bf94e5 162
tass 152:a3d286bf94e5 163 return 0;
tass 152:a3d286bf94e5 164
tass 152:a3d286bf94e5 165 }
tass 152:a3d286bf94e5 166 static inline int filter_match_packet_addr_in(struct filter_node *a, struct filter_node *b, struct filter_node *rule)
tass 152:a3d286bf94e5 167 {
tass 152:a3d286bf94e5 168 int cmp;
tass 152:a3d286bf94e5 169 /* 3. Compare addresses order: in, out */
tass 152:a3d286bf94e5 170 if (rule->in_addr_netmask) {
tass 152:a3d286bf94e5 171 cmp = ipfilter_uint32_cmp(a->in_addr & rule->in_addr_netmask, b->in_addr & rule->in_addr_netmask);
tass 152:a3d286bf94e5 172 if (cmp)
tass 152:a3d286bf94e5 173 return cmp;
tass 152:a3d286bf94e5 174 }
tass 152:a3d286bf94e5 175
tass 152:a3d286bf94e5 176 return 0;
tass 152:a3d286bf94e5 177 }
tass 152:a3d286bf94e5 178 static inline int filter_match_packet_addr_out(struct filter_node *a, struct filter_node *b, struct filter_node *rule)
tass 152:a3d286bf94e5 179 {
tass 152:a3d286bf94e5 180 int cmp;
tass 152:a3d286bf94e5 181 if (rule->out_addr_netmask) {
tass 152:a3d286bf94e5 182 cmp = ipfilter_uint32_cmp(a->out_addr & rule->out_addr_netmask, b->out_addr & rule->out_addr_netmask);
tass 152:a3d286bf94e5 183 if (cmp) {
tass 152:a3d286bf94e5 184 return cmp;
tass 152:a3d286bf94e5 185 }
tass 152:a3d286bf94e5 186 }
tass 152:a3d286bf94e5 187
tass 152:a3d286bf94e5 188 return 0;
tass 152:a3d286bf94e5 189 }
tass 152:a3d286bf94e5 190 static inline int filter_match_packet_port_in(struct filter_node *a, struct filter_node *b, struct filter_node *rule)
tass 152:a3d286bf94e5 191 {
tass 152:a3d286bf94e5 192 int cmp;
tass 152:a3d286bf94e5 193 /* 4. Compare ports order: in, out */
tass 152:a3d286bf94e5 194 if (rule->in_port) {
tass 152:a3d286bf94e5 195 cmp = ipfilter_uint16_cmp(a->in_port, b->in_port);
tass 152:a3d286bf94e5 196 if (cmp)
tass 152:a3d286bf94e5 197 return cmp;
tass 152:a3d286bf94e5 198 }
tass 152:a3d286bf94e5 199
tass 152:a3d286bf94e5 200 return 0;
tass 152:a3d286bf94e5 201 }
tass 152:a3d286bf94e5 202 static inline int filter_match_packet_port_out(struct filter_node *a, struct filter_node *b, struct filter_node *rule)
tass 152:a3d286bf94e5 203 {
tass 152:a3d286bf94e5 204 int cmp;
tass 152:a3d286bf94e5 205 if (rule->out_port) {
tass 152:a3d286bf94e5 206 cmp = ipfilter_uint16_cmp(a->out_port, b->out_port);
tass 152:a3d286bf94e5 207 if (cmp)
tass 152:a3d286bf94e5 208 return cmp;
tass 152:a3d286bf94e5 209 }
tass 152:a3d286bf94e5 210
tass 152:a3d286bf94e5 211 return 0;
tass 152:a3d286bf94e5 212 }
tass 152:a3d286bf94e5 213
tass 152:a3d286bf94e5 214 static inline int filter_match_packet_dev_and_proto(struct filter_node *a, struct filter_node *b, struct filter_node *rule)
tass 152:a3d286bf94e5 215 {
tass 152:a3d286bf94e5 216 int cmp = filter_match_packet_dev(a, b, rule);
tass 152:a3d286bf94e5 217 if (cmp)
tass 152:a3d286bf94e5 218 return cmp;
tass 152:a3d286bf94e5 219
tass 152:a3d286bf94e5 220 return filter_match_packet_proto(a, b, rule);
tass 152:a3d286bf94e5 221 }
tass 152:a3d286bf94e5 222
tass 152:a3d286bf94e5 223 static inline int filter_match_packet_addr(struct filter_node *a, struct filter_node *b, struct filter_node *rule)
tass 152:a3d286bf94e5 224 {
tass 152:a3d286bf94e5 225 int cmp = filter_match_packet_addr_in(a, b, rule);
tass 152:a3d286bf94e5 226 if (cmp)
tass 152:a3d286bf94e5 227 return cmp;
tass 152:a3d286bf94e5 228
tass 152:a3d286bf94e5 229 return filter_match_packet_addr_out(a, b, rule);
tass 152:a3d286bf94e5 230
tass 152:a3d286bf94e5 231 }
tass 152:a3d286bf94e5 232
tass 152:a3d286bf94e5 233 static inline int filter_match_packet_port(struct filter_node *a, struct filter_node *b, struct filter_node *rule)
tass 152:a3d286bf94e5 234 {
tass 152:a3d286bf94e5 235 int cmp = filter_match_packet_port_in(a, b, rule);
tass 152:a3d286bf94e5 236 if (cmp)
tass 152:a3d286bf94e5 237 return cmp;
tass 152:a3d286bf94e5 238
tass 152:a3d286bf94e5 239 return filter_match_packet_port_out(a, b, rule);
tass 152:a3d286bf94e5 240 }
tass 152:a3d286bf94e5 241
tass 152:a3d286bf94e5 242 static inline struct filter_node *filter_match_packet_find_rule(struct filter_node *a, struct filter_node *b)
tass 152:a3d286bf94e5 243 {
tass 152:a3d286bf94e5 244 if (!a->filter_id)
tass 152:a3d286bf94e5 245 return b;
tass 152:a3d286bf94e5 246
tass 152:a3d286bf94e5 247 return a;
tass 152:a3d286bf94e5 248 }
tass 152:a3d286bf94e5 249
tass 152:a3d286bf94e5 250 static inline int filter_match_packet(struct filter_node *a, struct filter_node *b)
tass 152:a3d286bf94e5 251 {
tass 152:a3d286bf94e5 252 struct filter_node *rule;
tass 152:a3d286bf94e5 253 int cmp = 0;
tass 152:a3d286bf94e5 254 rule = filter_match_packet_find_rule(a, b);
tass 152:a3d286bf94e5 255
tass 152:a3d286bf94e5 256 cmp = filter_match_packet_dev_and_proto(a, b, rule);
tass 152:a3d286bf94e5 257 if (cmp)
tass 152:a3d286bf94e5 258 return cmp;
tass 152:a3d286bf94e5 259
tass 152:a3d286bf94e5 260 cmp = filter_match_packet_addr(a, b, rule);
tass 152:a3d286bf94e5 261 if (cmp)
tass 152:a3d286bf94e5 262 return cmp;
tass 152:a3d286bf94e5 263
tass 152:a3d286bf94e5 264 cmp = filter_match_packet_port(a, b, rule);
tass 152:a3d286bf94e5 265 if (cmp)
tass 152:a3d286bf94e5 266 return cmp;
tass 152:a3d286bf94e5 267
tass 152:a3d286bf94e5 268 return 0;
tass 152:a3d286bf94e5 269 }
tass 125:96003ae6f1d8 270
tass 68:0847e35d08a6 271
tass 125:96003ae6f1d8 272 int filter_compare(void *filterA, void *filterB)
tass 125:96003ae6f1d8 273 {
tass 152:a3d286bf94e5 274
tass 152:a3d286bf94e5 275 struct filter_node *a = (struct filter_node *)filterA;
tass 152:a3d286bf94e5 276 struct filter_node *b = (struct filter_node *)filterB;
tass 152:a3d286bf94e5 277 int cmp = 0;
tass 152:a3d286bf94e5 278 if (a->filter_id == 0 || b->filter_id == 0) {
tass 152:a3d286bf94e5 279 return filter_match_packet(a, b);
tass 152:a3d286bf94e5 280 }
tass 125:96003ae6f1d8 281
TASS Belgium NV 131:4758606c9316 282 /* improve the search */
tass 152:a3d286bf94e5 283 if(a->filter_id == b->filter_id)
TASS Belgium NV 131:4758606c9316 284 return 0;
tass 68:0847e35d08a6 285
tass 152:a3d286bf94e5 286 /* 1. Compare devices */
tass 152:a3d286bf94e5 287 cmp = ipfilter_ptr_cmp(a->fdev, a->fdev);
tass 152:a3d286bf94e5 288 if (cmp)
tass 152:a3d286bf94e5 289 return cmp;
tass 125:96003ae6f1d8 290
tass 152:a3d286bf94e5 291 /* 2. Compare protocol */
tass 152:a3d286bf94e5 292 cmp = filter_compare_proto(a, b);
tass 152:a3d286bf94e5 293 if(cmp)
tass 152:a3d286bf94e5 294 return cmp;
tass 152:a3d286bf94e5 295
tass 152:a3d286bf94e5 296 /* 3. Compare addresses order: in, out */
tass 152:a3d286bf94e5 297 /* 4. Compare ports order: in, out */
tass 152:a3d286bf94e5 298 cmp = filter_compare_address_port(a, b);
tass 152:a3d286bf94e5 299
tass 152:a3d286bf94e5 300 return cmp;
tass 68:0847e35d08a6 301 }
tass 68:0847e35d08a6 302
tass 125:96003ae6f1d8 303 /**************** FILTER CALLBACKS ****************/
tass 125:96003ae6f1d8 304
TASS Belgium NV 131:4758606c9316 305 static int fp_priority(struct filter_node *filter, struct pico_frame *f)
TASS Belgium NV 131:4758606c9316 306 {
TASS Belgium NV 131:4758606c9316 307 /* TODO do priority-stuff */
TASS Belgium NV 131:4758606c9316 308 IGNORE_PARAMETER(filter);
TASS Belgium NV 131:4758606c9316 309 IGNORE_PARAMETER(f);
TASS Belgium NV 131:4758606c9316 310 return 0;
tass 68:0847e35d08a6 311 }
tass 68:0847e35d08a6 312
TASS Belgium NV 131:4758606c9316 313 static int fp_reject(struct filter_node *filter, struct pico_frame *f)
TASS Belgium NV 131:4758606c9316 314 {
TASS Belgium NV 131:4758606c9316 315 /* TODO check first if sender is pico itself or not */
TASS Belgium NV 131:4758606c9316 316 IGNORE_PARAMETER(filter);
TASS Belgium NV 131:4758606c9316 317 ipf_dbg("ipfilter> reject\n");
tass 152:a3d286bf94e5 318 (void)pico_icmp4_packet_filtered(f);
TASS Belgium NV 131:4758606c9316 319 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 320 return 1;
tass 68:0847e35d08a6 321 }
tass 68:0847e35d08a6 322
TASS Belgium NV 131:4758606c9316 323 static int fp_drop(struct filter_node *filter, struct pico_frame *f)
TASS Belgium NV 131:4758606c9316 324 {
TASS Belgium NV 131:4758606c9316 325 IGNORE_PARAMETER(filter);
TASS Belgium NV 131:4758606c9316 326 ipf_dbg("ipfilter> drop\n");
TASS Belgium NV 131:4758606c9316 327 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 328 return 1;
tass 68:0847e35d08a6 329 }
tass 68:0847e35d08a6 330
tass 152:a3d286bf94e5 331 struct fp_function {
tass 152:a3d286bf94e5 332 int (*fn)(struct filter_node *filter, struct pico_frame *f);
tass 152:a3d286bf94e5 333 };
tass 152:a3d286bf94e5 334
tass 152:a3d286bf94e5 335
tass 152:a3d286bf94e5 336 static const struct fp_function fp_function[FILTER_COUNT] =
tass 68:0847e35d08a6 337 {
tass 152:a3d286bf94e5 338 {&fp_priority},
tass 152:a3d286bf94e5 339 {&fp_reject},
tass 152:a3d286bf94e5 340 {&fp_drop}
tass 152:a3d286bf94e5 341 };
tass 68:0847e35d08a6 342
tass 152:a3d286bf94e5 343 static int pico_ipv4_filter_add_validate(int8_t priority, enum filter_action action)
tass 152:a3d286bf94e5 344 {
tass 152:a3d286bf94e5 345 if ( priority > MAX_PRIORITY || priority < MIN_PRIORITY) {
tass 152:a3d286bf94e5 346 return -1;
tass 152:a3d286bf94e5 347 }
tass 152:a3d286bf94e5 348
tass 152:a3d286bf94e5 349 if (action >= FILTER_COUNT) {
TASS Belgium NV 131:4758606c9316 350 return -1;
TASS Belgium NV 131:4758606c9316 351 }
TASS Belgium NV 131:4758606c9316 352
tass 152:a3d286bf94e5 353 return 0;
tass 152:a3d286bf94e5 354 }
tass 152:a3d286bf94e5 355
tass 152:a3d286bf94e5 356
tass 152:a3d286bf94e5 357 /**************** FILTER API's ****************/
tass 152:a3d286bf94e5 358 uint32_t pico_ipv4_filter_add(struct pico_device *dev, uint8_t proto,
tass 152:a3d286bf94e5 359 struct pico_ip4 *out_addr, struct pico_ip4 *out_addr_netmask,
tass 152:a3d286bf94e5 360 struct pico_ip4 *in_addr, struct pico_ip4 *in_addr_netmask,
tass 152:a3d286bf94e5 361 uint16_t out_port, uint16_t in_port, int8_t priority,
tass 152:a3d286bf94e5 362 uint8_t tos, enum filter_action action)
tass 152:a3d286bf94e5 363 {
tass 152:a3d286bf94e5 364 static uint32_t filter_id = 1u; /* 0 is a special value used in the binary-tree search for packets being processed */
tass 152:a3d286bf94e5 365 struct filter_node *new_filter;
tass 152:a3d286bf94e5 366
tass 152:a3d286bf94e5 367 if (pico_ipv4_filter_add_validate(priority, action) < 0) {
TASS Belgium NV 131:4758606c9316 368 pico_err = PICO_ERR_EINVAL;
tass 152:a3d286bf94e5 369 return 0;
TASS Belgium NV 131:4758606c9316 370 }
tass 125:96003ae6f1d8 371
tass picotcp@tass.be 149:5f4cb161cec3 372 new_filter = PICO_ZALLOC(sizeof(struct filter_node));
tass picotcp@tass.be 149:5f4cb161cec3 373 if (!new_filter) {
tass picotcp@tass.be 149:5f4cb161cec3 374 pico_err = PICO_ERR_ENOMEM;
tass 152:a3d286bf94e5 375 return 0;
tass picotcp@tass.be 149:5f4cb161cec3 376 }
tass 68:0847e35d08a6 377
TASS Belgium NV 131:4758606c9316 378 new_filter->fdev = dev;
TASS Belgium NV 131:4758606c9316 379 new_filter->proto = proto;
tass picotcp@tass.be 149:5f4cb161cec3 380 new_filter->out_addr = (!out_addr) ? (0U) : (out_addr->addr);
tass picotcp@tass.be 149:5f4cb161cec3 381 new_filter->out_addr_netmask = (!out_addr_netmask) ? (0U) : (out_addr_netmask->addr);
tass picotcp@tass.be 149:5f4cb161cec3 382 new_filter->in_addr = (!in_addr) ? (0U) : (in_addr->addr);
tass picotcp@tass.be 149:5f4cb161cec3 383 new_filter->in_addr_netmask = (!in_addr_netmask) ? (0U) : (in_addr_netmask->addr);
TASS Belgium NV 131:4758606c9316 384 new_filter->out_port = out_port;
TASS Belgium NV 131:4758606c9316 385 new_filter->in_port = in_port;
TASS Belgium NV 131:4758606c9316 386 new_filter->priority = priority;
TASS Belgium NV 131:4758606c9316 387 new_filter->tos = tos;
TASS Belgium NV 131:4758606c9316 388 new_filter->filter_id = filter_id++;
tass 152:a3d286bf94e5 389 new_filter->function_ptr = fp_function[action].fn;
tass 68:0847e35d08a6 390
TASS Belgium NV 131:4758606c9316 391 if(pico_tree_insert(&filter_tree, new_filter))
TASS Belgium NV 131:4758606c9316 392 {
tass picotcp@tass.be 149:5f4cb161cec3 393 PICO_FREE(new_filter);
tass 152:a3d286bf94e5 394 filter_id--;
tass 152:a3d286bf94e5 395 return 0;
TASS Belgium NV 131:4758606c9316 396 }
tass 125:96003ae6f1d8 397
TASS Belgium NV 131:4758606c9316 398 return new_filter->filter_id;
tass 68:0847e35d08a6 399 }
tass 68:0847e35d08a6 400
tass 152:a3d286bf94e5 401 int pico_ipv4_filter_del(uint32_t filter_id)
tass 68:0847e35d08a6 402 {
TASS Belgium NV 131:4758606c9316 403 struct filter_node *node = NULL;
tass 154:6c0e92a80c4a 404 struct filter_node dummy = { 0 };
tass 154:6c0e92a80c4a 405
tass 154:6c0e92a80c4a 406 dummy.filter_id = filter_id;
TASS Belgium NV 131:4758606c9316 407 if((node = pico_tree_delete(&filter_tree, &dummy)) == NULL)
TASS Belgium NV 131:4758606c9316 408 {
TASS Belgium NV 131:4758606c9316 409 ipf_dbg("ipfilter> failed to delete filter :%d\n", filter_id);
TASS Belgium NV 131:4758606c9316 410 return -1;
TASS Belgium NV 131:4758606c9316 411 }
tass 68:0847e35d08a6 412
tass picotcp@tass.be 149:5f4cb161cec3 413 PICO_FREE(node);
TASS Belgium NV 131:4758606c9316 414 return 0;
tass 68:0847e35d08a6 415 }
tass 68:0847e35d08a6 416
tass 152:a3d286bf94e5 417 static int ipfilter_apply_filter(struct pico_frame *f, struct filter_node *pkt)
tass 152:a3d286bf94e5 418 {
tass 152:a3d286bf94e5 419 struct filter_node *filter_frame = NULL;
tass 152:a3d286bf94e5 420 filter_frame = pico_tree_findKey(&filter_tree, pkt);
tass 152:a3d286bf94e5 421 if(filter_frame)
tass 152:a3d286bf94e5 422 {
tass 152:a3d286bf94e5 423 filter_frame->function_ptr(filter_frame, f);
tass 152:a3d286bf94e5 424 return 1;
tass 152:a3d286bf94e5 425 }
tass 152:a3d286bf94e5 426
tass 152:a3d286bf94e5 427 return 0;
tass 152:a3d286bf94e5 428 }
tass 152:a3d286bf94e5 429
tass 125:96003ae6f1d8 430 int ipfilter(struct pico_frame *f)
tass 68:0847e35d08a6 431 {
TASS Belgium NV 131:4758606c9316 432 struct filter_node temp;
TASS Belgium NV 131:4758606c9316 433 struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *) f->net_hdr;
tass 152:a3d286bf94e5 434 struct pico_trans *trans;
TASS Belgium NV 131:4758606c9316 435 struct pico_icmp4_hdr *icmp_hdr;
tass 68:0847e35d08a6 436
TASS Belgium NV 131:4758606c9316 437 memset(&temp, 0u, sizeof(struct filter_node));
tass 68:0847e35d08a6 438
TASS Belgium NV 131:4758606c9316 439 temp.fdev = f->dev;
TASS Belgium NV 131:4758606c9316 440 temp.out_addr = ipv4_hdr->dst.addr;
TASS Belgium NV 131:4758606c9316 441 temp.in_addr = ipv4_hdr->src.addr;
tass 152:a3d286bf94e5 442 if ((ipv4_hdr->proto == PICO_PROTO_TCP) || (ipv4_hdr->proto == PICO_PROTO_UDP)) {
tass 152:a3d286bf94e5 443 trans = (struct pico_trans *) f->transport_hdr;
tass 152:a3d286bf94e5 444 temp.out_port = short_be(trans->dport);
tass 152:a3d286bf94e5 445 temp.in_port = short_be(trans->sport);
TASS Belgium NV 131:4758606c9316 446 }
tass 152:a3d286bf94e5 447 else if(ipv4_hdr->proto == PICO_PROTO_ICMP4) {
tass 152:a3d286bf94e5 448 icmp_hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
tass 152:a3d286bf94e5 449 if(icmp_hdr->type == PICO_ICMP_UNREACH && icmp_hdr->type == PICO_ICMP_UNREACH_FILTER_PROHIB)
tass 152:a3d286bf94e5 450 return 0;
TASS Belgium NV 131:4758606c9316 451 }
TASS Belgium NV 131:4758606c9316 452
TASS Belgium NV 131:4758606c9316 453 temp.proto = ipv4_hdr->proto;
TASS Belgium NV 131:4758606c9316 454 temp.priority = f->priority;
TASS Belgium NV 131:4758606c9316 455 temp.tos = ipv4_hdr->tos;
tass 152:a3d286bf94e5 456 return ipfilter_apply_filter(f, &temp);
tass 68:0847e35d08a6 457 }
tass 68:0847e35d08a6 458