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 Belgium NV
Date:
Mon Dec 16 11:25:54 2013 +0100
Revision:
131:4758606c9316
Parent:
128:ae39e6e81531
Child:
149:5f4cb161cec3
Syncronized with master branch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 68:0847e35d08a6 1 /*********************************************************************
TASS Belgium NV 131:4758606c9316 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. 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 Belgium NV 131:4758606c9316 48 uint8_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 Belgium NV 131:4758606c9316 54 #define CHECK_AND_RETURN(a, b) do { \
TASS Belgium NV 131:4758606c9316 55 if((a) && ((a) != (b))) \
TASS Belgium NV 131:4758606c9316 56 { \
TASS Belgium NV 131:4758606c9316 57 if((a) > (b)) return 1; \
TASS Belgium NV 131:4758606c9316 58 else return -1; \
TASS Belgium NV 131:4758606c9316 59 } \
TASS Belgium NV 131:4758606c9316 60 } while(0) \
tass 125:96003ae6f1d8 61
tass 68:0847e35d08a6 62
tass 125:96003ae6f1d8 63 int filter_compare(void *filterA, void *filterB)
tass 125:96003ae6f1d8 64 {
TASS Belgium NV 131:4758606c9316 65 struct filter_node *filter = (struct filter_node *)filterA,
TASS Belgium NV 131:4758606c9316 66 *temp = (struct filter_node *)filterB;
tass 125:96003ae6f1d8 67
TASS Belgium NV 131:4758606c9316 68 /* improve the search */
TASS Belgium NV 131:4758606c9316 69 if(temp->filter_id && filter->filter_id == temp->filter_id)
TASS Belgium NV 131:4758606c9316 70 return 0;
tass 68:0847e35d08a6 71
TASS Belgium NV 131:4758606c9316 72 ipf_dbg("\nfilter ->> %x %x %x %x %d %d %d\n", filter->in_addr, filter->in_addr_netmask, filter->out_addr, filter->out_addr_netmask, filter->in_port, filter->out_port, filter->proto);
TASS Belgium NV 131:4758606c9316 73 ipf_dbg("\ntemp ->> %x %x %x %x %d %d %d\n", temp->in_addr, temp->in_addr_netmask, temp->out_addr, temp->out_addr_netmask, temp->in_port, temp->out_port, filter->proto);
TASS Belgium NV 131:4758606c9316 74 CHECK_AND_RETURN(filter->fdev, temp->fdev);
TASS Belgium NV 131:4758606c9316 75 CHECK_AND_RETURN((filter->in_addr & filter->in_addr_netmask), (temp->in_addr & filter->in_addr_netmask));
TASS Belgium NV 131:4758606c9316 76 CHECK_AND_RETURN((filter->out_addr & filter->out_addr_netmask), (temp->out_addr & filter->out_addr_netmask));
TASS Belgium NV 131:4758606c9316 77 CHECK_AND_RETURN(filter->in_port, temp->in_port);
TASS Belgium NV 131:4758606c9316 78 CHECK_AND_RETURN(filter->out_port, temp->out_port);
TASS Belgium NV 131:4758606c9316 79 CHECK_AND_RETURN(filter->priority, temp->priority);
TASS Belgium NV 131:4758606c9316 80 CHECK_AND_RETURN(filter->proto, temp->proto);
tass 125:96003ae6f1d8 81
TASS Belgium NV 131:4758606c9316 82 return 0;
tass 68:0847e35d08a6 83 }
tass 68:0847e35d08a6 84
tass 125:96003ae6f1d8 85 /**************** FILTER CALLBACKS ****************/
tass 125:96003ae6f1d8 86
TASS Belgium NV 131:4758606c9316 87 static int fp_priority(struct filter_node *filter, struct pico_frame *f)
TASS Belgium NV 131:4758606c9316 88 {
TASS Belgium NV 131:4758606c9316 89 /* TODO do priority-stuff */
TASS Belgium NV 131:4758606c9316 90 IGNORE_PARAMETER(filter);
TASS Belgium NV 131:4758606c9316 91 IGNORE_PARAMETER(f);
TASS Belgium NV 131:4758606c9316 92 return 0;
tass 68:0847e35d08a6 93 }
tass 68:0847e35d08a6 94
TASS Belgium NV 131:4758606c9316 95 static int fp_reject(struct filter_node *filter, struct pico_frame *f)
TASS Belgium NV 131:4758606c9316 96 {
TASS Belgium NV 131:4758606c9316 97 /* TODO check first if sender is pico itself or not */
TASS Belgium NV 131:4758606c9316 98 IGNORE_PARAMETER(filter);
TASS Belgium NV 131:4758606c9316 99 ipf_dbg("ipfilter> reject\n");
TASS Belgium NV 131:4758606c9316 100 pico_icmp4_packet_filtered(f);
TASS Belgium NV 131:4758606c9316 101 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 102 return 1;
tass 68:0847e35d08a6 103 }
tass 68:0847e35d08a6 104
TASS Belgium NV 131:4758606c9316 105 static int fp_drop(struct filter_node *filter, struct pico_frame *f)
TASS Belgium NV 131:4758606c9316 106 {
TASS Belgium NV 131:4758606c9316 107 IGNORE_PARAMETER(filter);
TASS Belgium NV 131:4758606c9316 108 ipf_dbg("ipfilter> drop\n");
TASS Belgium NV 131:4758606c9316 109 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 110 return 1;
tass 68:0847e35d08a6 111 }
tass 68:0847e35d08a6 112
tass 125:96003ae6f1d8 113 /**************** FILTER API's ****************/
tass 68:0847e35d08a6 114 int pico_ipv4_filter_add(struct pico_device *dev, uint8_t proto, struct pico_ip4 *out_addr, struct pico_ip4 *out_addr_netmask, struct pico_ip4 *in_addr, struct pico_ip4 *in_addr_netmask, uint16_t out_port, uint16_t in_port, int8_t priority, uint8_t tos, enum filter_action action)
tass 68:0847e35d08a6 115 {
TASS Belgium NV 131:4758606c9316 116 static uint8_t filter_id = 0;
TASS Belgium NV 131:4758606c9316 117 struct filter_node *new_filter;
tass 68:0847e35d08a6 118
TASS Belgium NV 131:4758606c9316 119 if (proto != PICO_PROTO_IPV4 || tos != 0 )
TASS Belgium NV 131:4758606c9316 120 {
TASS Belgium NV 131:4758606c9316 121 pico_err = PICO_ERR_EINVAL;
TASS Belgium NV 131:4758606c9316 122 return -1;
TASS Belgium NV 131:4758606c9316 123 }
TASS Belgium NV 131:4758606c9316 124
TASS Belgium NV 131:4758606c9316 125 if ( priority > MAX_PRIORITY || priority < MIN_PRIORITY) {
TASS Belgium NV 131:4758606c9316 126 pico_err = PICO_ERR_EINVAL;
TASS Belgium NV 131:4758606c9316 127 return -1;
TASS Belgium NV 131:4758606c9316 128 }
tass 125:96003ae6f1d8 129
TASS Belgium NV 131:4758606c9316 130 if (action > FILTER_COUNT) {
TASS Belgium NV 131:4758606c9316 131 pico_err = PICO_ERR_EINVAL;
TASS Belgium NV 131:4758606c9316 132 return -1;
TASS Belgium NV 131:4758606c9316 133 }
TASS Belgium NV 131:4758606c9316 134
TASS Belgium NV 131:4758606c9316 135 ipf_dbg("ipfilter> adding filter\n");
tass 68:0847e35d08a6 136
TASS Belgium NV 131:4758606c9316 137 new_filter = pico_zalloc(sizeof(struct filter_node));
tass 68:0847e35d08a6 138
TASS Belgium NV 131:4758606c9316 139 new_filter->fdev = dev;
TASS Belgium NV 131:4758606c9316 140 new_filter->proto = proto;
tass 68:0847e35d08a6 141
TASS Belgium NV 131:4758606c9316 142 new_filter->out_addr = (!out_addr) ? 0U : out_addr->addr;
TASS Belgium NV 131:4758606c9316 143 new_filter->out_addr_netmask = (!out_addr_netmask) ? 0U : out_addr_netmask->addr;
TASS Belgium NV 131:4758606c9316 144 new_filter->in_addr = (!in_addr) ? 0U : in_addr->addr;
TASS Belgium NV 131:4758606c9316 145 new_filter->in_addr_netmask = (!in_addr_netmask) ? 0U : in_addr_netmask->addr;
tass 68:0847e35d08a6 146
TASS Belgium NV 131:4758606c9316 147 new_filter->out_port = out_port;
TASS Belgium NV 131:4758606c9316 148 new_filter->in_port = in_port;
TASS Belgium NV 131:4758606c9316 149 new_filter->priority = priority;
TASS Belgium NV 131:4758606c9316 150 new_filter->tos = tos;
tass 125:96003ae6f1d8 151
TASS Belgium NV 131:4758606c9316 152 if(filter_id == 0)
TASS Belgium NV 131:4758606c9316 153 filter_id = 1;
tass 125:96003ae6f1d8 154
TASS Belgium NV 131:4758606c9316 155 new_filter->filter_id = filter_id++;
tass 68:0847e35d08a6 156
TASS Belgium NV 131:4758606c9316 157 /*Define filterType_functionPointer here instead of in ipfilter-function, to prevent running multiple times through switch*/
TASS Belgium NV 131:4758606c9316 158 switch (action) {
tass 68:0847e35d08a6 159 case FILTER_PRIORITY:
TASS Belgium NV 131:4758606c9316 160 new_filter->function_ptr = fp_priority;
TASS Belgium NV 131:4758606c9316 161 break;
tass 68:0847e35d08a6 162 case FILTER_REJECT:
TASS Belgium NV 131:4758606c9316 163 new_filter->function_ptr = fp_reject;
TASS Belgium NV 131:4758606c9316 164 break;
tass 68:0847e35d08a6 165 case FILTER_DROP:
TASS Belgium NV 131:4758606c9316 166 new_filter->function_ptr = fp_drop;
TASS Belgium NV 131:4758606c9316 167 break;
tass 68:0847e35d08a6 168 default:
TASS Belgium NV 131:4758606c9316 169 ipf_dbg("ipfilter> unknown filter action\n");
TASS Belgium NV 131:4758606c9316 170 break;
TASS Belgium NV 131:4758606c9316 171 }
TASS Belgium NV 131:4758606c9316 172 if(pico_tree_insert(&filter_tree, new_filter))
TASS Belgium NV 131:4758606c9316 173 {
TASS Belgium NV 131:4758606c9316 174 pico_free(new_filter);
TASS Belgium NV 131:4758606c9316 175 ipf_dbg("ipfilter> failed adding filter to tree.\n");
TASS Belgium NV 131:4758606c9316 176 return -1;
TASS Belgium NV 131:4758606c9316 177 }
tass 125:96003ae6f1d8 178
TASS Belgium NV 131:4758606c9316 179 return new_filter->filter_id;
tass 68:0847e35d08a6 180 }
tass 68:0847e35d08a6 181
tass 68:0847e35d08a6 182 int pico_ipv4_filter_del(uint8_t filter_id)
tass 68:0847e35d08a6 183 {
TASS Belgium NV 131:4758606c9316 184 struct filter_node *node = NULL;
TASS Belgium NV 131:4758606c9316 185 struct filter_node dummy = {
TASS Belgium NV 131:4758606c9316 186 .filter_id = filter_id
TASS Belgium NV 131:4758606c9316 187 };
TASS Belgium NV 131:4758606c9316 188 if((node = pico_tree_delete(&filter_tree, &dummy)) == NULL)
TASS Belgium NV 131:4758606c9316 189 {
TASS Belgium NV 131:4758606c9316 190 ipf_dbg("ipfilter> failed to delete filter :%d\n", filter_id);
TASS Belgium NV 131:4758606c9316 191 return -1;
TASS Belgium NV 131:4758606c9316 192 }
tass 68:0847e35d08a6 193
TASS Belgium NV 131:4758606c9316 194 pico_free(node);
TASS Belgium NV 131:4758606c9316 195 return 0;
tass 68:0847e35d08a6 196 }
tass 68:0847e35d08a6 197
tass 125:96003ae6f1d8 198 int ipfilter(struct pico_frame *f)
tass 68:0847e35d08a6 199 {
TASS Belgium NV 131:4758606c9316 200 struct filter_node temp;
TASS Belgium NV 131:4758606c9316 201 struct filter_node *filter_frame = NULL;
TASS Belgium NV 131:4758606c9316 202 struct pico_ipv4_hdr *ipv4_hdr = (struct pico_ipv4_hdr *) f->net_hdr;
TASS Belgium NV 131:4758606c9316 203 struct pico_tcp_hdr *tcp_hdr;
TASS Belgium NV 131:4758606c9316 204 struct pico_udp_hdr *udp_hdr;
TASS Belgium NV 131:4758606c9316 205 struct pico_icmp4_hdr *icmp_hdr;
tass 68:0847e35d08a6 206
TASS Belgium NV 131:4758606c9316 207 memset(&temp, 0u, sizeof(struct filter_node));
tass 68:0847e35d08a6 208
TASS Belgium NV 131:4758606c9316 209 temp.fdev = f->dev;
TASS Belgium NV 131:4758606c9316 210 temp.out_addr = ipv4_hdr->dst.addr;
TASS Belgium NV 131:4758606c9316 211 temp.in_addr = ipv4_hdr->src.addr;
tass 128:ae39e6e81531 212
TASS Belgium NV 131:4758606c9316 213 if (ipv4_hdr->proto == PICO_PROTO_TCP ) {
TASS Belgium NV 131:4758606c9316 214 tcp_hdr = (struct pico_tcp_hdr *) f->transport_hdr;
TASS Belgium NV 131:4758606c9316 215 temp.out_port = short_be(tcp_hdr->trans.dport);
TASS Belgium NV 131:4758606c9316 216 temp.in_port = short_be(tcp_hdr->trans.sport);
TASS Belgium NV 131:4758606c9316 217 }else if (ipv4_hdr->proto == PICO_PROTO_UDP ) {
TASS Belgium NV 131:4758606c9316 218 udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
TASS Belgium NV 131:4758606c9316 219 temp.out_port = short_be(udp_hdr->trans.dport);
TASS Belgium NV 131:4758606c9316 220 temp.in_port = short_be(udp_hdr->trans.sport);
TASS Belgium NV 131:4758606c9316 221 }
TASS Belgium NV 131:4758606c9316 222 else
TASS Belgium NV 131:4758606c9316 223 {
TASS Belgium NV 131:4758606c9316 224 if(ipv4_hdr->proto == PICO_PROTO_ICMP4)
TASS Belgium NV 131:4758606c9316 225 {
TASS Belgium NV 131:4758606c9316 226 icmp_hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
TASS Belgium NV 131:4758606c9316 227 if(icmp_hdr->type == PICO_ICMP_UNREACH && icmp_hdr->type == PICO_ICMP_UNREACH_FILTER_PROHIB)
TASS Belgium NV 131:4758606c9316 228 return 0;
TASS Belgium NV 131:4758606c9316 229 }
tass 125:96003ae6f1d8 230
TASS Belgium NV 131:4758606c9316 231 temp.out_port = temp.in_port = 0;
TASS Belgium NV 131:4758606c9316 232 }
TASS Belgium NV 131:4758606c9316 233
TASS Belgium NV 131:4758606c9316 234 temp.proto = ipv4_hdr->proto;
TASS Belgium NV 131:4758606c9316 235 temp.priority = f->priority;
TASS Belgium NV 131:4758606c9316 236 temp.tos = ipv4_hdr->tos;
tass 68:0847e35d08a6 237
TASS Belgium NV 131:4758606c9316 238 filter_frame = pico_tree_findKey(&filter_tree, &temp);
TASS Belgium NV 131:4758606c9316 239 if(filter_frame)
TASS Belgium NV 131:4758606c9316 240 {
TASS Belgium NV 131:4758606c9316 241 ipf_dbg("Filtering frame %p with filter %p\n", f, filter_frame);
TASS Belgium NV 131:4758606c9316 242 filter_frame->function_ptr(filter_frame, f);
TASS Belgium NV 131:4758606c9316 243 return 1;
TASS Belgium NV 131:4758606c9316 244 }
tass 68:0847e35d08a6 245
TASS Belgium NV 131:4758606c9316 246 return 0;
tass 68:0847e35d08a6 247 }
tass 68:0847e35d08a6 248