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 .
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 Belgium NV 131:4758606c9316 55 if (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 68:0847e35d08a6 143 int pico_icmp4_packet_filtered(struct pico_frame *f)
tass 68:0847e35d08a6 144 {
TASS Belgium NV 131:4758606c9316 145 /*Parameter check executed in pico_icmp4_notify*/
TASS Belgium NV 131:4758606c9316 146 /*Packet Filtered: type 3, code 13 (Communication Administratively Prohibited)*/
TASS Belgium NV 131:4758606c9316 147 return pico_icmp4_notify(f, PICO_ICMP_UNREACH, PICO_ICMP_UNREACH_FILTER_PROHIB);
tass 68:0847e35d08a6 148 }
tass 68:0847e35d08a6 149
tass 68:0847e35d08a6 150 /***********************/
tass 68:0847e35d08a6 151 /* Ping implementation */
tass 68:0847e35d08a6 152 /***********************/
tass 68:0847e35d08a6 153 /***********************/
tass 68:0847e35d08a6 154 /***********************/
tass 68:0847e35d08a6 155 /***********************/
tass 68:0847e35d08a6 156
tass 68:0847e35d08a6 157
tass 68:0847e35d08a6 158 #ifdef PICO_SUPPORT_PING
tass 68:0847e35d08a6 159
tass 68:0847e35d08a6 160
tass 68:0847e35d08a6 161 struct pico_icmp4_ping_cookie
tass 68:0847e35d08a6 162 {
TASS Belgium NV 131:4758606c9316 163 struct pico_ip4 dst;
TASS Belgium NV 131:4758606c9316 164 uint16_t err;
TASS Belgium NV 131:4758606c9316 165 uint16_t id;
TASS Belgium NV 131:4758606c9316 166 uint16_t seq;
TASS Belgium NV 131:4758606c9316 167 uint16_t size;
TASS Belgium NV 131:4758606c9316 168 int count;
TASS Belgium NV 131:4758606c9316 169 pico_time timestamp;
TASS Belgium NV 131:4758606c9316 170 int interval;
TASS Belgium NV 131:4758606c9316 171 int timeout;
TASS Belgium NV 131:4758606c9316 172 void (*cb)(struct pico_icmp4_stats*);
tass 68:0847e35d08a6 173
tass 68:0847e35d08a6 174 };
tass 68:0847e35d08a6 175
tass 68:0847e35d08a6 176 static int cookie_compare(void *ka, void *kb)
tass 68:0847e35d08a6 177 {
TASS Belgium NV 131:4758606c9316 178 struct pico_icmp4_ping_cookie *a = ka, *b = kb;
TASS Belgium NV 131:4758606c9316 179 if (a->id < b->id)
TASS Belgium NV 131:4758606c9316 180 return -1;
TASS Belgium NV 131:4758606c9316 181
TASS Belgium NV 131:4758606c9316 182 if (a->id > b->id)
TASS Belgium NV 131:4758606c9316 183 return 1;
TASS Belgium NV 131:4758606c9316 184
TASS Belgium NV 131:4758606c9316 185 return (a->seq - b->seq);
tass 68:0847e35d08a6 186 }
tass 68:0847e35d08a6 187
TASS Belgium NV 131:4758606c9316 188 PICO_TREE_DECLARE(Pings, cookie_compare);
tass 68:0847e35d08a6 189
tass 70:cd218dd180e5 190 static uint8_t pico_icmp4_send_echo(struct pico_icmp4_ping_cookie *cookie)
tass 68:0847e35d08a6 191 {
TASS Belgium NV 131:4758606c9316 192 struct pico_frame *echo = pico_proto_ipv4.alloc(&pico_proto_ipv4, (uint16_t)(PICO_ICMPHDR_UN_SIZE + cookie->size));
TASS Belgium NV 131:4758606c9316 193 struct pico_icmp4_hdr *hdr;
tass 68:0847e35d08a6 194
TASS Belgium NV 131:4758606c9316 195 hdr = (struct pico_icmp4_hdr *) echo->transport_hdr;
tass 68:0847e35d08a6 196
TASS Belgium NV 131:4758606c9316 197 hdr->type = PICO_ICMP_ECHO;
TASS Belgium NV 131:4758606c9316 198 hdr->code = 0;
TASS Belgium NV 131:4758606c9316 199 hdr->hun.ih_idseq.idseq_id = short_be(cookie->id);
TASS Belgium NV 131:4758606c9316 200 hdr->hun.ih_idseq.idseq_seq = short_be(cookie->seq);
TASS Belgium NV 131:4758606c9316 201 echo->transport_len = (uint16_t)(PICO_ICMPHDR_UN_SIZE + cookie->size);
TASS Belgium NV 131:4758606c9316 202 echo->payload = echo->transport_hdr + PICO_ICMPHDR_UN_SIZE;
TASS Belgium NV 131:4758606c9316 203 echo->payload_len = cookie->size;
TASS Belgium NV 131:4758606c9316 204 /* XXX: Fill payload */
TASS Belgium NV 131:4758606c9316 205 pico_icmp4_checksum(echo);
TASS Belgium NV 131:4758606c9316 206 pico_ipv4_frame_push(echo, &cookie->dst, PICO_PROTO_ICMP4);
TASS Belgium NV 131:4758606c9316 207 return 0;
tass 68:0847e35d08a6 208 }
tass 68:0847e35d08a6 209
tass 68:0847e35d08a6 210
tass 128:ae39e6e81531 211 static void ping_timeout(pico_time now, void *arg)
tass 68:0847e35d08a6 212 {
TASS Belgium NV 131:4758606c9316 213 struct pico_icmp4_ping_cookie *cookie = (struct pico_icmp4_ping_cookie *)arg;
TASS Belgium NV 131:4758606c9316 214 IGNORE_PARAMETER(now);
tass 68:0847e35d08a6 215
TASS Belgium NV 131:4758606c9316 216 if(pico_tree_findKey(&Pings, cookie)) {
TASS Belgium NV 131:4758606c9316 217 if (cookie->err == PICO_PING_ERR_PENDING) {
TASS Belgium NV 131:4758606c9316 218 struct pico_icmp4_stats stats;
TASS Belgium NV 131:4758606c9316 219 stats.dst = cookie->dst;
TASS Belgium NV 131:4758606c9316 220 stats.seq = cookie->seq;
TASS Belgium NV 131:4758606c9316 221 stats.time = 0;
TASS Belgium NV 131:4758606c9316 222 stats.size = cookie->size;
TASS Belgium NV 131:4758606c9316 223 stats.err = PICO_PING_ERR_TIMEOUT;
TASS Belgium NV 131:4758606c9316 224 dbg(" ---- Ping timeout!!!\n");
TASS Belgium NV 131:4758606c9316 225 cookie->cb(&stats);
TASS Belgium NV 131:4758606c9316 226 }
TASS Belgium NV 131:4758606c9316 227
TASS Belgium NV 131:4758606c9316 228 pico_tree_delete(&Pings, cookie);
TASS Belgium NV 131:4758606c9316 229 pico_free(cookie);
tass 68:0847e35d08a6 230 }
tass 68:0847e35d08a6 231 }
tass 68:0847e35d08a6 232
tass 128:ae39e6e81531 233 static void next_ping(pico_time now, void *arg);
tass 68:0847e35d08a6 234 static inline void send_ping(struct pico_icmp4_ping_cookie *cookie)
tass 68:0847e35d08a6 235 {
TASS Belgium NV 131:4758606c9316 236 pico_icmp4_send_echo(cookie);
TASS Belgium NV 131:4758606c9316 237 cookie->timestamp = pico_tick;
TASS Belgium NV 131:4758606c9316 238 pico_timer_add((uint32_t)cookie->timeout, ping_timeout, cookie);
TASS Belgium NV 131:4758606c9316 239 if (cookie->seq < cookie->count)
TASS Belgium NV 131:4758606c9316 240 pico_timer_add((uint32_t)cookie->interval, next_ping, cookie);
tass 68:0847e35d08a6 241 }
tass 68:0847e35d08a6 242
tass 128:ae39e6e81531 243 static void next_ping(pico_time now, void *arg)
tass 68:0847e35d08a6 244 {
TASS Belgium NV 131:4758606c9316 245 struct pico_icmp4_ping_cookie *newcookie, *cookie = (struct pico_icmp4_ping_cookie *)arg;
TASS Belgium NV 131:4758606c9316 246 IGNORE_PARAMETER(now);
tass 68:0847e35d08a6 247
TASS Belgium NV 131:4758606c9316 248 if(pico_tree_findKey(&Pings, cookie)) {
TASS Belgium NV 131:4758606c9316 249 if (cookie->seq < cookie->count) {
TASS Belgium NV 131:4758606c9316 250 newcookie = pico_zalloc(sizeof(struct pico_icmp4_ping_cookie));
TASS Belgium NV 131:4758606c9316 251 if (!newcookie)
TASS Belgium NV 131:4758606c9316 252 return;
tass 68:0847e35d08a6 253
TASS Belgium NV 131:4758606c9316 254 memcpy(newcookie, cookie, sizeof(struct pico_icmp4_ping_cookie));
TASS Belgium NV 131:4758606c9316 255 newcookie->seq++;
TASS Belgium NV 131:4758606c9316 256
TASS Belgium NV 131:4758606c9316 257 pico_tree_insert(&Pings, newcookie);
TASS Belgium NV 131:4758606c9316 258 send_ping(newcookie);
TASS Belgium NV 131:4758606c9316 259 }
tass 68:0847e35d08a6 260 }
tass 68:0847e35d08a6 261 }
tass 68:0847e35d08a6 262
tass 68:0847e35d08a6 263
tass 68:0847e35d08a6 264 static void ping_recv_reply(struct pico_frame *f)
tass 68:0847e35d08a6 265 {
TASS Belgium NV 131:4758606c9316 266 struct pico_icmp4_ping_cookie test, *cookie;
TASS Belgium NV 131:4758606c9316 267 struct pico_icmp4_hdr *hdr = (struct pico_icmp4_hdr *) f->transport_hdr;
TASS Belgium NV 131:4758606c9316 268 test.id = short_be(hdr->hun.ih_idseq.idseq_id );
TASS Belgium NV 131:4758606c9316 269 test.seq = short_be(hdr->hun.ih_idseq.idseq_seq);
tass 68:0847e35d08a6 270
TASS Belgium NV 131:4758606c9316 271 cookie = pico_tree_findKey(&Pings, &test);
TASS Belgium NV 131:4758606c9316 272 if (cookie) {
TASS Belgium NV 131:4758606c9316 273 struct pico_icmp4_stats stats;
TASS Belgium NV 131:4758606c9316 274 cookie->err = PICO_PING_ERR_REPLIED;
TASS Belgium NV 131:4758606c9316 275 stats.dst = cookie->dst;
TASS Belgium NV 131:4758606c9316 276 stats.seq = cookie->seq;
TASS Belgium NV 131:4758606c9316 277 stats.size = cookie->size;
TASS Belgium NV 131:4758606c9316 278 stats.time = pico_tick - cookie->timestamp;
TASS Belgium NV 131:4758606c9316 279 stats.err = cookie->err;
TASS Belgium NV 131:4758606c9316 280 stats.ttl = ((struct pico_ipv4_hdr *)f->net_hdr)->ttl;
TASS Belgium NV 131:4758606c9316 281 if(cookie->cb != NULL)
TASS Belgium NV 131:4758606c9316 282 cookie->cb(&stats);
TASS Belgium NV 131:4758606c9316 283 } else {
TASS Belgium NV 131:4758606c9316 284 dbg("Reply for seq=%d, not found.\n", test.seq);
TASS Belgium NV 131:4758606c9316 285 }
tass 68:0847e35d08a6 286 }
tass 68:0847e35d08a6 287
tass 68:0847e35d08a6 288 int pico_icmp4_ping(char *dst, int count, int interval, int timeout, int size, void (*cb)(struct pico_icmp4_stats *))
tass 68:0847e35d08a6 289 {
TASS Belgium NV 131:4758606c9316 290 static uint16_t next_id = 0x91c0;
TASS Belgium NV 131:4758606c9316 291 struct pico_icmp4_ping_cookie *cookie;
tass 68:0847e35d08a6 292
TASS Belgium NV 131:4758606c9316 293 if((dst == NULL) || (interval == 0) || (timeout == 0) || (count == 0)) {
TASS Belgium NV 131:4758606c9316 294 pico_err = PICO_ERR_EINVAL;
TASS Belgium NV 131:4758606c9316 295 return -1;
TASS Belgium NV 131:4758606c9316 296 }
tass 68:0847e35d08a6 297
TASS Belgium NV 131:4758606c9316 298 cookie = pico_zalloc(sizeof(struct pico_icmp4_ping_cookie));
TASS Belgium NV 131:4758606c9316 299 if (!cookie) {
TASS Belgium NV 131:4758606c9316 300 pico_err = PICO_ERR_ENOMEM;
TASS Belgium NV 131:4758606c9316 301 return -1;
TASS Belgium NV 131:4758606c9316 302 }
tass 68:0847e35d08a6 303
TASS Belgium NV 131:4758606c9316 304 if (pico_string_to_ipv4(dst, &cookie->dst.addr) < 0) {
TASS Belgium NV 131:4758606c9316 305 pico_err = PICO_ERR_EINVAL;
TASS Belgium NV 131:4758606c9316 306 pico_free(cookie);
TASS Belgium NV 131:4758606c9316 307 return -1;
TASS Belgium NV 131:4758606c9316 308 }
tass 68:0847e35d08a6 309
TASS Belgium NV 131:4758606c9316 310 cookie->seq = 1;
TASS Belgium NV 131:4758606c9316 311 cookie->id = next_id++;
TASS Belgium NV 131:4758606c9316 312 cookie->err = PICO_PING_ERR_PENDING;
TASS Belgium NV 131:4758606c9316 313 cookie->size = (uint16_t)size;
TASS Belgium NV 131:4758606c9316 314 cookie->interval = interval;
TASS Belgium NV 131:4758606c9316 315 cookie->timeout = timeout;
TASS Belgium NV 131:4758606c9316 316 cookie->cb = cb;
TASS Belgium NV 131:4758606c9316 317 cookie->count = count;
tass 68:0847e35d08a6 318
TASS Belgium NV 131:4758606c9316 319 pico_tree_insert(&Pings, cookie);
TASS Belgium NV 131:4758606c9316 320 send_ping(cookie);
TASS Belgium NV 131:4758606c9316 321
TASS Belgium NV 131:4758606c9316 322 return 0;
tass 68:0847e35d08a6 323
tass 68:0847e35d08a6 324 }
tass 68:0847e35d08a6 325
tass 68:0847e35d08a6 326 #endif