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 picotcp@tass.be
Date:
Wed Apr 09 14:31:41 2014 +0200
Revision:
149:5f4cb161cec3
Parent:
131:4758606c9316
Child:
152:a3d286bf94e5
Update from git masterbranch

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 .
tass 68:0847e35d08a6 6
TASS Belgium NV 131:4758606c9316 7 Authors: Daniele Lacamera
TASS Belgium NV 131:4758606c9316 8 *********************************************************************/
tass 68:0847e35d08a6 9
tass 68:0847e35d08a6 10
tass 68:0847e35d08a6 11 #include "pico_icmp4.h"
tass 68:0847e35d08a6 12 #include "pico_config.h"
tass 68:0847e35d08a6 13 #include "pico_ipv4.h"
tass 68:0847e35d08a6 14 #include "pico_eth.h"
tass 68:0847e35d08a6 15 #include "pico_device.h"
tass 68:0847e35d08a6 16 #include "pico_stack.h"
tass 68:0847e35d08a6 17 #include "pico_tree.h"
tass 68:0847e35d08a6 18
tass 68:0847e35d08a6 19 /* Queues */
TASS Belgium NV 131:4758606c9316 20 static struct pico_queue icmp_in = {
TASS Belgium NV 131:4758606c9316 21 0
TASS Belgium NV 131:4758606c9316 22 };
TASS Belgium NV 131:4758606c9316 23 static struct pico_queue icmp_out = {
TASS Belgium NV 131:4758606c9316 24 0
TASS Belgium NV 131:4758606c9316 25 };
tass 68:0847e35d08a6 26
tass 68:0847e35d08a6 27
tass 68:0847e35d08a6 28 /* Functions */
tass 68:0847e35d08a6 29
tass 68:0847e35d08a6 30 static int pico_icmp4_checksum(struct pico_frame *f)
tass 68:0847e35d08a6 31 {
TASS Belgium NV 131:4758606c9316 32 struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
TASS Belgium NV 131:4758606c9316 33 if (!hdr) {
TASS Belgium NV 131:4758606c9316 34 pico_err = PICO_ERR_EINVAL;
TASS Belgium NV 131:4758606c9316 35 return -1;
TASS Belgium NV 131:4758606c9316 36 }
TASS Belgium NV 131:4758606c9316 37
TASS Belgium NV 131:4758606c9316 38 hdr->crc = 0;
TASS Belgium NV 131:4758606c9316 39 hdr->crc = short_be(pico_checksum(hdr, f->transport_len));
TASS Belgium NV 131:4758606c9316 40 return 0;
tass 68:0847e35d08a6 41 }
tass 68:0847e35d08a6 42
tass 68:0847e35d08a6 43 #ifdef PICO_SUPPORT_PING
tass 68:0847e35d08a6 44 static void ping_recv_reply(struct pico_frame *f);
tass 68:0847e35d08a6 45 #endif
tass 68:0847e35d08a6 46
tass 68:0847e35d08a6 47 static int pico_icmp4_process_in(struct pico_protocol *self, struct pico_frame *f)
tass 68:0847e35d08a6 48 {
TASS Belgium NV 131:4758606c9316 49 struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
TASS Belgium NV 131:4758606c9316 50 IGNORE_PARAMETER(self);
TASS Belgium NV 131:4758606c9316 51
TASS Belgium NV 131:4758606c9316 52 if (hdr->type == PICO_ICMP_ECHO) {
TASS Belgium NV 131:4758606c9316 53 hdr->type = PICO_ICMP_ECHOREPLY;
TASS Belgium NV 131:4758606c9316 54 /* outgoing frames require a f->len without the ethernet header len */
tass picotcp@tass.be 149:5f4cb161cec3 55 if (f->dev && f->dev->eth)
TASS Belgium NV 131:4758606c9316 56 f->len -= PICO_SIZE_ETHHDR;
tass 68:0847e35d08a6 57
TASS Belgium NV 131:4758606c9316 58 pico_icmp4_checksum(f);
TASS Belgium NV 131:4758606c9316 59 pico_ipv4_rebound(f);
TASS Belgium NV 131:4758606c9316 60 } else if (hdr->type == PICO_ICMP_UNREACH) {
TASS Belgium NV 131:4758606c9316 61 f->net_hdr = f->transport_hdr + PICO_ICMPHDR_UN_SIZE;
TASS Belgium NV 131:4758606c9316 62 pico_ipv4_unreachable(f, hdr->code);
TASS Belgium NV 131:4758606c9316 63 } else if (hdr->type == PICO_ICMP_ECHOREPLY) {
tass 68:0847e35d08a6 64 #ifdef PICO_SUPPORT_PING
TASS Belgium NV 131:4758606c9316 65 ping_recv_reply(f);
tass 68:0847e35d08a6 66 #endif
TASS Belgium NV 131:4758606c9316 67 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 68 } else {
TASS Belgium NV 131:4758606c9316 69 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 70 }
TASS Belgium NV 131:4758606c9316 71
TASS Belgium NV 131:4758606c9316 72 return 0;
tass 68:0847e35d08a6 73 }
tass 68:0847e35d08a6 74
tass 68:0847e35d08a6 75 static int pico_icmp4_process_out(struct pico_protocol *self, struct pico_frame *f)
tass 68:0847e35d08a6 76 {
TASS Belgium NV 131:4758606c9316 77 IGNORE_PARAMETER(self);
TASS Belgium NV 131:4758606c9316 78 IGNORE_PARAMETER(f);
TASS Belgium NV 131:4758606c9316 79 dbg("Called %s\n", __FUNCTION__);
TASS Belgium NV 131:4758606c9316 80 return 0;
tass 68:0847e35d08a6 81 }
tass 68:0847e35d08a6 82
tass 68:0847e35d08a6 83 /* Interface: protocol definition */
tass 68:0847e35d08a6 84 struct pico_protocol pico_proto_icmp4 = {
TASS Belgium NV 131:4758606c9316 85 .name = "icmp4",
TASS Belgium NV 131:4758606c9316 86 .proto_number = PICO_PROTO_ICMP4,
TASS Belgium NV 131:4758606c9316 87 .layer = PICO_LAYER_TRANSPORT,
TASS Belgium NV 131:4758606c9316 88 .process_in = pico_icmp4_process_in,
TASS Belgium NV 131:4758606c9316 89 .process_out = pico_icmp4_process_out,
TASS Belgium NV 131:4758606c9316 90 .q_in = &icmp_in,
TASS Belgium NV 131:4758606c9316 91 .q_out = &icmp_out,
tass 68:0847e35d08a6 92 };
tass 68:0847e35d08a6 93
tass 68:0847e35d08a6 94 static int pico_icmp4_notify(struct pico_frame *f, uint8_t type, uint8_t code)
tass 68:0847e35d08a6 95 {
TASS Belgium NV 131:4758606c9316 96 struct pico_frame *reply;
TASS Belgium NV 131:4758606c9316 97 struct pico_icmp4_hdr *hdr;
TASS Belgium NV 131:4758606c9316 98 struct pico_ipv4_hdr *info;
TASS Belgium NV 131:4758606c9316 99 if (f == NULL) {
TASS Belgium NV 131:4758606c9316 100 pico_err = PICO_ERR_EINVAL;
TASS Belgium NV 131:4758606c9316 101 return -1;
TASS Belgium NV 131:4758606c9316 102 }
TASS Belgium NV 131:4758606c9316 103
TASS Belgium NV 131:4758606c9316 104 reply = pico_proto_ipv4.alloc(&pico_proto_ipv4, 8 + sizeof(struct pico_ipv4_hdr) + PICO_ICMPHDR_UN_SIZE);
TASS Belgium NV 131:4758606c9316 105 info = (struct pico_ipv4_hdr*)(f->net_hdr);
TASS Belgium NV 131:4758606c9316 106 hdr = (struct pico_icmp4_hdr *) reply->transport_hdr;
TASS Belgium NV 131:4758606c9316 107 hdr->type = type;
TASS Belgium NV 131:4758606c9316 108 hdr->code = code;
TASS Belgium NV 131:4758606c9316 109 hdr->hun.ih_pmtu.ipm_nmtu = short_be(1500);
TASS Belgium NV 131:4758606c9316 110 hdr->hun.ih_pmtu.ipm_void = 0;
TASS Belgium NV 131:4758606c9316 111 reply->transport_len = 8 + sizeof(struct pico_ipv4_hdr) + PICO_ICMPHDR_UN_SIZE;
TASS Belgium NV 131:4758606c9316 112 reply->payload = reply->transport_hdr + PICO_ICMPHDR_UN_SIZE;
TASS Belgium NV 131:4758606c9316 113 memcpy(reply->payload, f->net_hdr, 8 + sizeof(struct pico_ipv4_hdr));
TASS Belgium NV 131:4758606c9316 114 pico_icmp4_checksum(reply);
TASS Belgium NV 131:4758606c9316 115 pico_ipv4_frame_push(reply, &info->src, PICO_PROTO_ICMP4);
TASS Belgium NV 131:4758606c9316 116 return 0;
tass 68:0847e35d08a6 117 }
tass 68:0847e35d08a6 118
tass 68:0847e35d08a6 119 int pico_icmp4_port_unreachable(struct pico_frame *f)
tass 68:0847e35d08a6 120 {
TASS Belgium NV 131:4758606c9316 121 /*Parameter check executed in pico_icmp4_notify*/
TASS Belgium NV 131:4758606c9316 122 return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_PORT);
tass 68:0847e35d08a6 123 }
tass 68:0847e35d08a6 124
tass 68:0847e35d08a6 125 int pico_icmp4_proto_unreachable(struct pico_frame *f)
tass 68:0847e35d08a6 126 {
TASS Belgium NV 131:4758606c9316 127 /*Parameter check executed in pico_icmp4_notify*/
TASS Belgium NV 131:4758606c9316 128 return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_PROTOCOL);
tass 68:0847e35d08a6 129 }
tass 68:0847e35d08a6 130
tass 68:0847e35d08a6 131 int pico_icmp4_dest_unreachable(struct pico_frame *f)
tass 68:0847e35d08a6 132 {
TASS Belgium NV 131:4758606c9316 133 /*Parameter check executed in pico_icmp4_notify*/
TASS Belgium NV 131:4758606c9316 134 return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_HOST);
tass 68:0847e35d08a6 135 }
tass 68:0847e35d08a6 136
tass 68:0847e35d08a6 137 int pico_icmp4_ttl_expired(struct pico_frame *f)
tass 68:0847e35d08a6 138 {
TASS Belgium NV 131:4758606c9316 139 /*Parameter check executed in pico_icmp4_notify*/
TASS Belgium NV 131:4758606c9316 140 return pico_icmp4_notify(f, PICO_ICMP_TIME_EXCEEDED, PICO_ICMP_TIMXCEED_INTRANS);
tass 68:0847e35d08a6 141 }
tass 68:0847e35d08a6 142
tass picotcp@tass.be 149:5f4cb161cec3 143 int pico_icmp4_mtu_exceeded(struct pico_frame *f)
tass picotcp@tass.be 149:5f4cb161cec3 144 {
tass picotcp@tass.be 149:5f4cb161cec3 145 /*Parameter check executed in pico_icmp4_notify*/
tass picotcp@tass.be 149:5f4cb161cec3 146 return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_NEEDFRAG);
tass picotcp@tass.be 149:5f4cb161cec3 147 }
tass picotcp@tass.be 149:5f4cb161cec3 148
tass 68:0847e35d08a6 149 int pico_icmp4_packet_filtered(struct pico_frame *f)
tass 68:0847e35d08a6 150 {
TASS Belgium NV 131:4758606c9316 151 /*Parameter check executed in pico_icmp4_notify*/
TASS Belgium NV 131:4758606c9316 152 /*Packet Filtered: type 3, code 13 (Communication Administratively Prohibited)*/
TASS Belgium NV 131:4758606c9316 153 return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_FILTER_PROHIB);
tass 68:0847e35d08a6 154 }
tass 68:0847e35d08a6 155
tass 68:0847e35d08a6 156 /***********************/
tass 68:0847e35d08a6 157 /* Ping implementation */
tass 68:0847e35d08a6 158 /***********************/
tass 68:0847e35d08a6 159 /***********************/
tass 68:0847e35d08a6 160 /***********************/
tass 68:0847e35d08a6 161 /***********************/
tass 68:0847e35d08a6 162
tass 68:0847e35d08a6 163
tass 68:0847e35d08a6 164 #ifdef PICO_SUPPORT_PING
tass 68:0847e35d08a6 165
tass 68:0847e35d08a6 166
tass 68:0847e35d08a6 167 struct pico_icmp4_ping_cookie
tass 68:0847e35d08a6 168 {
TASS Belgium NV 131:4758606c9316 169 struct pico_ip4 dst;
TASS Belgium NV 131:4758606c9316 170 uint16_t err;
TASS Belgium NV 131:4758606c9316 171 uint16_t id;
TASS Belgium NV 131:4758606c9316 172 uint16_t seq;
TASS Belgium NV 131:4758606c9316 173 uint16_t size;
TASS Belgium NV 131:4758606c9316 174 int count;
TASS Belgium NV 131:4758606c9316 175 pico_time timestamp;
TASS Belgium NV 131:4758606c9316 176 int interval;
TASS Belgium NV 131:4758606c9316 177 int timeout;
TASS Belgium NV 131:4758606c9316 178 void (*cb)(struct pico_icmp4_stats*);
tass 68:0847e35d08a6 179
tass 68:0847e35d08a6 180 };
tass 68:0847e35d08a6 181
tass 68:0847e35d08a6 182 static int cookie_compare(void *ka, void *kb)
tass 68:0847e35d08a6 183 {
TASS Belgium NV 131:4758606c9316 184 struct pico_icmp4_ping_cookie *a = ka, *b = kb;
TASS Belgium NV 131:4758606c9316 185 if (a->id < b->id)
TASS Belgium NV 131:4758606c9316 186 return -1;
TASS Belgium NV 131:4758606c9316 187
TASS Belgium NV 131:4758606c9316 188 if (a->id > b->id)
TASS Belgium NV 131:4758606c9316 189 return 1;
TASS Belgium NV 131:4758606c9316 190
TASS Belgium NV 131:4758606c9316 191 return (a->seq - b->seq);
tass 68:0847e35d08a6 192 }
tass 68:0847e35d08a6 193
TASS Belgium NV 131:4758606c9316 194 PICO_TREE_DECLARE(Pings, cookie_compare);
tass 68:0847e35d08a6 195
tass picotcp@tass.be 149:5f4cb161cec3 196 static int8_t pico_icmp4_send_echo(struct pico_icmp4_ping_cookie *cookie)
tass 68:0847e35d08a6 197 {
TASS Belgium NV 131:4758606c9316 198 struct pico_frame *echo = pico_proto_ipv4.alloc(&pico_proto_ipv4, (uint16_t)(PICO_ICMPHDR_UN_SIZE + cookie->size));
TASS Belgium NV 131:4758606c9316 199 struct pico_icmp4_hdr *hdr;
tass picotcp@tass.be 149:5f4cb161cec3 200 if (!echo) {
tass picotcp@tass.be 149:5f4cb161cec3 201 return -1;
tass picotcp@tass.be 149:5f4cb161cec3 202 }
tass 68:0847e35d08a6 203
TASS Belgium NV 131:4758606c9316 204 hdr = (struct pico_icmp4_hdr *) echo->transport_hdr;
tass 68:0847e35d08a6 205
TASS Belgium NV 131:4758606c9316 206 hdr->type = PICO_ICMP_ECHO;
TASS Belgium NV 131:4758606c9316 207 hdr->code = 0;
TASS Belgium NV 131:4758606c9316 208 hdr->hun.ih_idseq.idseq_id = short_be(cookie->id);
TASS Belgium NV 131:4758606c9316 209 hdr->hun.ih_idseq.idseq_seq = short_be(cookie->seq);
TASS Belgium NV 131:4758606c9316 210 echo->transport_len = (uint16_t)(PICO_ICMPHDR_UN_SIZE + cookie->size);
TASS Belgium NV 131:4758606c9316 211 echo->payload = echo->transport_hdr + PICO_ICMPHDR_UN_SIZE;
TASS Belgium NV 131:4758606c9316 212 echo->payload_len = cookie->size;
TASS Belgium NV 131:4758606c9316 213 /* XXX: Fill payload */
TASS Belgium NV 131:4758606c9316 214 pico_icmp4_checksum(echo);
TASS Belgium NV 131:4758606c9316 215 pico_ipv4_frame_push(echo, &cookie->dst, PICO_PROTO_ICMP4);
TASS Belgium NV 131:4758606c9316 216 return 0;
tass 68:0847e35d08a6 217 }
tass 68:0847e35d08a6 218
tass 68:0847e35d08a6 219
tass 128:ae39e6e81531 220 static void ping_timeout(pico_time now, void *arg)
tass 68:0847e35d08a6 221 {
TASS Belgium NV 131:4758606c9316 222 struct pico_icmp4_ping_cookie *cookie = (struct pico_icmp4_ping_cookie *)arg;
TASS Belgium NV 131:4758606c9316 223 IGNORE_PARAMETER(now);
tass 68:0847e35d08a6 224
TASS Belgium NV 131:4758606c9316 225 if(pico_tree_findKey(&Pings, cookie)) {
TASS Belgium NV 131:4758606c9316 226 if (cookie->err == PICO_PING_ERR_PENDING) {
TASS Belgium NV 131:4758606c9316 227 struct pico_icmp4_stats stats;
TASS Belgium NV 131:4758606c9316 228 stats.dst = cookie->dst;
TASS Belgium NV 131:4758606c9316 229 stats.seq = cookie->seq;
TASS Belgium NV 131:4758606c9316 230 stats.time = 0;
TASS Belgium NV 131:4758606c9316 231 stats.size = cookie->size;
TASS Belgium NV 131:4758606c9316 232 stats.err = PICO_PING_ERR_TIMEOUT;
TASS Belgium NV 131:4758606c9316 233 dbg(" ---- Ping timeout!!!\n");
TASS Belgium NV 131:4758606c9316 234 cookie->cb(&stats);
TASS Belgium NV 131:4758606c9316 235 }
TASS Belgium NV 131:4758606c9316 236
TASS Belgium NV 131:4758606c9316 237 pico_tree_delete(&Pings, cookie);
tass picotcp@tass.be 149:5f4cb161cec3 238 PICO_FREE(cookie);
tass 68:0847e35d08a6 239 }
tass 68:0847e35d08a6 240 }
tass 68:0847e35d08a6 241
tass 128:ae39e6e81531 242 static void next_ping(pico_time now, void *arg);
tass 68:0847e35d08a6 243 static inline void send_ping(struct pico_icmp4_ping_cookie *cookie)
tass 68:0847e35d08a6 244 {
TASS Belgium NV 131:4758606c9316 245 pico_icmp4_send_echo(cookie);
TASS Belgium NV 131:4758606c9316 246 cookie->timestamp = pico_tick;
TASS Belgium NV 131:4758606c9316 247 pico_timer_add((uint32_t)cookie->timeout, ping_timeout, cookie);
tass picotcp@tass.be 149:5f4cb161cec3 248 if (cookie->seq < (uint16_t)cookie->count)
TASS Belgium NV 131:4758606c9316 249 pico_timer_add((uint32_t)cookie->interval, next_ping, cookie);
tass 68:0847e35d08a6 250 }
tass 68:0847e35d08a6 251
tass 128:ae39e6e81531 252 static void next_ping(pico_time now, void *arg)
tass 68:0847e35d08a6 253 {
TASS Belgium NV 131:4758606c9316 254 struct pico_icmp4_ping_cookie *newcookie, *cookie = (struct pico_icmp4_ping_cookie *)arg;
TASS Belgium NV 131:4758606c9316 255 IGNORE_PARAMETER(now);
tass 68:0847e35d08a6 256
TASS Belgium NV 131:4758606c9316 257 if(pico_tree_findKey(&Pings, cookie)) {
tass picotcp@tass.be 149:5f4cb161cec3 258 if (cookie->seq < (uint16_t)cookie->count) {
tass picotcp@tass.be 149:5f4cb161cec3 259 newcookie = PICO_ZALLOC(sizeof(struct pico_icmp4_ping_cookie));
TASS Belgium NV 131:4758606c9316 260 if (!newcookie)
TASS Belgium NV 131:4758606c9316 261 return;
tass 68:0847e35d08a6 262
TASS Belgium NV 131:4758606c9316 263 memcpy(newcookie, cookie, sizeof(struct pico_icmp4_ping_cookie));
TASS Belgium NV 131:4758606c9316 264 newcookie->seq++;
TASS Belgium NV 131:4758606c9316 265
TASS Belgium NV 131:4758606c9316 266 pico_tree_insert(&Pings, newcookie);
TASS Belgium NV 131:4758606c9316 267 send_ping(newcookie);
TASS Belgium NV 131:4758606c9316 268 }
tass 68:0847e35d08a6 269 }
tass 68:0847e35d08a6 270 }
tass 68:0847e35d08a6 271
tass 68:0847e35d08a6 272
tass 68:0847e35d08a6 273 static void ping_recv_reply(struct pico_frame *f)
tass 68:0847e35d08a6 274 {
TASS Belgium NV 131:4758606c9316 275 struct pico_icmp4_ping_cookie test, *cookie;
TASS Belgium NV 131:4758606c9316 276 struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
TASS Belgium NV 131:4758606c9316 277 test.id = short_be(hdr->hun.ih_idseq.idseq_id );
TASS Belgium NV 131:4758606c9316 278 test.seq = short_be(hdr->hun.ih_idseq.idseq_seq);
tass 68:0847e35d08a6 279
TASS Belgium NV 131:4758606c9316 280 cookie = pico_tree_findKey(&Pings, &test);
TASS Belgium NV 131:4758606c9316 281 if (cookie) {
TASS Belgium NV 131:4758606c9316 282 struct pico_icmp4_stats stats;
TASS Belgium NV 131:4758606c9316 283 cookie->err = PICO_PING_ERR_REPLIED;
tass picotcp@tass.be 149:5f4cb161cec3 284 stats.dst = ((struct pico_ipv4_hdr *)f->net_hdr)->src;
TASS Belgium NV 131:4758606c9316 285 stats.seq = cookie->seq;
TASS Belgium NV 131:4758606c9316 286 stats.size = cookie->size;
TASS Belgium NV 131:4758606c9316 287 stats.time = pico_tick - cookie->timestamp;
TASS Belgium NV 131:4758606c9316 288 stats.err = cookie->err;
TASS Belgium NV 131:4758606c9316 289 stats.ttl = ((struct pico_ipv4_hdr *)f->net_hdr)->ttl;
TASS Belgium NV 131:4758606c9316 290 if(cookie->cb != NULL)
TASS Belgium NV 131:4758606c9316 291 cookie->cb(&stats);
TASS Belgium NV 131:4758606c9316 292 } else {
TASS Belgium NV 131:4758606c9316 293 dbg("Reply for seq=%d, not found.\n", test.seq);
TASS Belgium NV 131:4758606c9316 294 }
tass 68:0847e35d08a6 295 }
tass 68:0847e35d08a6 296
tass 68:0847e35d08a6 297 int pico_icmp4_ping(char *dst, int count, int interval, int timeout, int size, void (*cb)(struct pico_icmp4_stats *))
tass 68:0847e35d08a6 298 {
TASS Belgium NV 131:4758606c9316 299 static uint16_t next_id = 0x91c0;
TASS Belgium NV 131:4758606c9316 300 struct pico_icmp4_ping_cookie *cookie;
tass 68:0847e35d08a6 301
TASS Belgium NV 131:4758606c9316 302 if((dst == NULL) || (interval == 0) || (timeout == 0) || (count == 0)) {
TASS Belgium NV 131:4758606c9316 303 pico_err = PICO_ERR_EINVAL;
TASS Belgium NV 131:4758606c9316 304 return -1;
TASS Belgium NV 131:4758606c9316 305 }
tass 68:0847e35d08a6 306
tass picotcp@tass.be 149:5f4cb161cec3 307 cookie = PICO_ZALLOC(sizeof(struct pico_icmp4_ping_cookie));
TASS Belgium NV 131:4758606c9316 308 if (!cookie) {
TASS Belgium NV 131:4758606c9316 309 pico_err = PICO_ERR_ENOMEM;
TASS Belgium NV 131:4758606c9316 310 return -1;
TASS Belgium NV 131:4758606c9316 311 }
tass 68:0847e35d08a6 312
tass picotcp@tass.be 149:5f4cb161cec3 313 if (pico_string_to_ipv4(dst, (uint32_t *)&cookie->dst.addr) < 0) {
TASS Belgium NV 131:4758606c9316 314 pico_err = PICO_ERR_EINVAL;
tass picotcp@tass.be 149:5f4cb161cec3 315 PICO_FREE(cookie);
TASS Belgium NV 131:4758606c9316 316 return -1;
TASS Belgium NV 131:4758606c9316 317 }
tass 68:0847e35d08a6 318
TASS Belgium NV 131:4758606c9316 319 cookie->seq = 1;
TASS Belgium NV 131:4758606c9316 320 cookie->id = next_id++;
TASS Belgium NV 131:4758606c9316 321 cookie->err = PICO_PING_ERR_PENDING;
TASS Belgium NV 131:4758606c9316 322 cookie->size = (uint16_t)size;
TASS Belgium NV 131:4758606c9316 323 cookie->interval = interval;
TASS Belgium NV 131:4758606c9316 324 cookie->timeout = timeout;
TASS Belgium NV 131:4758606c9316 325 cookie->cb = cb;
TASS Belgium NV 131:4758606c9316 326 cookie->count = count;
tass 68:0847e35d08a6 327
TASS Belgium NV 131:4758606c9316 328 pico_tree_insert(&Pings, cookie);
TASS Belgium NV 131:4758606c9316 329 send_ping(cookie);
TASS Belgium NV 131:4758606c9316 330
TASS Belgium NV 131:4758606c9316 331 return 0;
tass 68:0847e35d08a6 332
tass 68:0847e35d08a6 333 }
tass 68:0847e35d08a6 334
tass 68:0847e35d08a6 335 #endif