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:
Wed Nov 27 10:20:00 2013 +0000
Revision:
123:dd26752a4538
Parent:
74:c146c4e346c4
Child:
128:ae39e6e81531
Update from masterbranch + created stack dummy macros.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 68:0847e35d08a6 1 /*********************************************************************
tass 68:0847e35d08a6 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
tass 68:0847e35d08a6 3 See LICENSE and COPYING for usage.
tass 68:0847e35d08a6 4
tass 68:0847e35d08a6 5 .
tass 68:0847e35d08a6 6
tass 68:0847e35d08a6 7 Authors: Daniele Lacamera
tass 68:0847e35d08a6 8 *********************************************************************/
tass 68:0847e35d08a6 9
tass 68:0847e35d08a6 10
tass 68:0847e35d08a6 11 #include "pico_config.h"
tass 68:0847e35d08a6 12 #include "pico_arp.h"
tass 68:0847e35d08a6 13 #include "pico_tree.h"
tass 68:0847e35d08a6 14 #include "pico_ipv4.h"
tass 68:0847e35d08a6 15 #include "pico_device.h"
tass 68:0847e35d08a6 16 #include "pico_stack.h"
tass 68:0847e35d08a6 17
tass 68:0847e35d08a6 18 const uint8_t PICO_ETHADDR_ALL[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
tass 68:0847e35d08a6 19 #define PICO_ARP_TIMEOUT 600000
tass 68:0847e35d08a6 20 #define PICO_ARP_RETRY 300
tass 68:0847e35d08a6 21
tass 68:0847e35d08a6 22 #ifdef DEBUG_ARP
tass 68:0847e35d08a6 23 #define arp_dbg dbg
tass 68:0847e35d08a6 24 #else
tass 68:0847e35d08a6 25 #define arp_dbg(...) do{}while(0)
tass 68:0847e35d08a6 26 #endif
tass 68:0847e35d08a6 27
tass 68:0847e35d08a6 28 static struct pico_queue pending;
tass 68:0847e35d08a6 29 static int pending_timer_on = 0;
tass 68:0847e35d08a6 30
tass 73:dfb737147f6e 31 void check_pending(uint32_t now, void *_unused)
tass 68:0847e35d08a6 32 {
tass 68:0847e35d08a6 33 struct pico_frame *f = pico_dequeue(&pending);
tass 68:0847e35d08a6 34 IGNORE_PARAMETER(now);
tass 68:0847e35d08a6 35 IGNORE_PARAMETER(_unused);
tass 68:0847e35d08a6 36 if (!f) {
tass 68:0847e35d08a6 37 pending_timer_on = 0;
tass 68:0847e35d08a6 38 return;
tass 68:0847e35d08a6 39 }
tass 68:0847e35d08a6 40 if(pico_ethernet_send(f) > 0)
tass 68:0847e35d08a6 41 pico_frame_discard(f);
tass 68:0847e35d08a6 42 pico_timer_add(PICO_ARP_RETRY, &check_pending, NULL);
tass 68:0847e35d08a6 43 }
tass 68:0847e35d08a6 44
tass 68:0847e35d08a6 45
tass 68:0847e35d08a6 46 struct
tass 68:0847e35d08a6 47 __attribute__ ((__packed__))
tass 68:0847e35d08a6 48 pico_arp_hdr
tass 68:0847e35d08a6 49 {
tass 68:0847e35d08a6 50 uint16_t htype;
tass 68:0847e35d08a6 51 uint16_t ptype;
tass 68:0847e35d08a6 52 uint8_t hsize;
tass 68:0847e35d08a6 53 uint8_t psize;
tass 68:0847e35d08a6 54 uint16_t opcode;
tass 68:0847e35d08a6 55 uint8_t s_mac[PICO_SIZE_ETH];
tass 68:0847e35d08a6 56 struct pico_ip4 src;
tass 68:0847e35d08a6 57 uint8_t d_mac[PICO_SIZE_ETH];
tass 68:0847e35d08a6 58 struct pico_ip4 dst;
tass 68:0847e35d08a6 59 };
tass 68:0847e35d08a6 60
tass 123:dd26752a4538 61 struct arp_service_ipconflict{
tass 123:dd26752a4538 62 struct pico_eth mac;
tass 123:dd26752a4538 63 struct pico_ip4 ip;
tass 123:dd26752a4538 64 void (*conflict)(void);
tass 123:dd26752a4538 65 };
tass 123:dd26752a4538 66
tass 123:dd26752a4538 67 static struct arp_service_ipconflict conflict_ipv4;
tass 68:0847e35d08a6 68
tass 68:0847e35d08a6 69 #define PICO_SIZE_ARPHDR ((sizeof(struct pico_arp_hdr)))
tass 68:0847e35d08a6 70
tass 68:0847e35d08a6 71 /* Arp Entries for the tables. */
tass 68:0847e35d08a6 72 struct pico_arp {
tass 68:0847e35d08a6 73 /* CAREFUL MAN! ARP entry MUST begin with a pico_eth structure,
tass 68:0847e35d08a6 74 * due to in-place casting!!! */
tass 68:0847e35d08a6 75 struct pico_eth eth;
tass 68:0847e35d08a6 76 struct pico_ip4 ipv4;
tass 68:0847e35d08a6 77 int arp_status;
tass 73:dfb737147f6e 78 uint32_t timestamp;
tass 68:0847e35d08a6 79 struct pico_device *dev;
tass 68:0847e35d08a6 80 };
tass 68:0847e35d08a6 81
tass 68:0847e35d08a6 82
tass 68:0847e35d08a6 83
tass 68:0847e35d08a6 84 /*****************/
tass 68:0847e35d08a6 85 /** ARP TREE **/
tass 68:0847e35d08a6 86 /*****************/
tass 68:0847e35d08a6 87
tass 68:0847e35d08a6 88 /* Routing destination */
tass 68:0847e35d08a6 89
tass 68:0847e35d08a6 90 static int arp_compare(void * ka, void * kb)
tass 68:0847e35d08a6 91 {
tass 68:0847e35d08a6 92 struct pico_arp *a = ka, *b = kb;
tass 68:0847e35d08a6 93 if (a->ipv4.addr < b->ipv4.addr)
tass 68:0847e35d08a6 94 return -1;
tass 68:0847e35d08a6 95 else if (a->ipv4.addr > b->ipv4.addr)
tass 68:0847e35d08a6 96 return 1;
tass 68:0847e35d08a6 97 return 0;
tass 68:0847e35d08a6 98 }
tass 68:0847e35d08a6 99
tass 68:0847e35d08a6 100 PICO_TREE_DECLARE(arp_tree, arp_compare);
tass 68:0847e35d08a6 101
tass 68:0847e35d08a6 102 /*********************/
tass 68:0847e35d08a6 103 /** END ARP TREE **/
tass 68:0847e35d08a6 104 /*********************/
tass 68:0847e35d08a6 105
tass 68:0847e35d08a6 106 struct pico_eth *pico_arp_lookup(struct pico_ip4 *dst)
tass 68:0847e35d08a6 107 {
tass 68:0847e35d08a6 108 struct pico_arp search, *found;
tass 68:0847e35d08a6 109 search.ipv4.addr = dst->addr;
tass 68:0847e35d08a6 110 found = pico_tree_findKey(&arp_tree,&search);
tass 68:0847e35d08a6 111 if (found && (found->arp_status != PICO_ARP_STATUS_STALE))
tass 68:0847e35d08a6 112 return &found->eth;
tass 68:0847e35d08a6 113 return NULL;
tass 68:0847e35d08a6 114 }
tass 68:0847e35d08a6 115
tass 68:0847e35d08a6 116 struct pico_ip4 *pico_arp_reverse_lookup(struct pico_eth *dst)
tass 68:0847e35d08a6 117 {
tass 68:0847e35d08a6 118 struct pico_arp* search;
tass 68:0847e35d08a6 119 struct pico_tree_node * index;
tass 68:0847e35d08a6 120 pico_tree_foreach(index,&arp_tree){
tass 68:0847e35d08a6 121 search = index->keyValue;
tass 68:0847e35d08a6 122 if(memcmp(&(search->eth.addr), &dst->addr, 6) == 0)
tass 68:0847e35d08a6 123 return &search->ipv4;
tass 68:0847e35d08a6 124 }
tass 68:0847e35d08a6 125 return NULL;
tass 68:0847e35d08a6 126 }
tass 68:0847e35d08a6 127
tass 68:0847e35d08a6 128 struct pico_eth *pico_arp_get(struct pico_frame *f) {
tass 68:0847e35d08a6 129 struct pico_eth *a4;
tass 68:0847e35d08a6 130 struct pico_ip4 gateway;
tass 68:0847e35d08a6 131 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
tass 68:0847e35d08a6 132 struct pico_ipv4_link *l;
tass 68:0847e35d08a6 133
tass 68:0847e35d08a6 134 l = pico_ipv4_link_get(&hdr->dst);
tass 68:0847e35d08a6 135 if(l){
tass 68:0847e35d08a6 136 //address belongs to ourself
tass 68:0847e35d08a6 137 return &l->dev->eth->mac;
tass 68:0847e35d08a6 138 }
tass 68:0847e35d08a6 139
tass 68:0847e35d08a6 140 gateway = pico_ipv4_route_get_gateway(&hdr->dst);
tass 68:0847e35d08a6 141 /* check if dst is local (gateway = 0), or if to use gateway */
tass 68:0847e35d08a6 142 if (gateway.addr != 0)
tass 68:0847e35d08a6 143 a4 = pico_arp_lookup(&gateway); /* check if gateway ip mac in cache */
tass 68:0847e35d08a6 144 else
tass 68:0847e35d08a6 145 a4 = pico_arp_lookup(&hdr->dst); /* check if local ip mac in cache */
tass 68:0847e35d08a6 146 if (!a4) {
tass 68:0847e35d08a6 147 if (++f->failure_count < 4) {
tass 68:0847e35d08a6 148 dbg ("================= ARP REQUIRED: %d =============\n\n", f->failure_count);
tass 68:0847e35d08a6 149 /* check if dst is local (gateway = 0), or if to use gateway */
tass 68:0847e35d08a6 150 if (gateway.addr != 0)
tass 123:dd26752a4538 151 pico_arp_request(f->dev, &gateway, PICO_ARP_QUERY); /* arp to gateway */
tass 68:0847e35d08a6 152 else
tass 123:dd26752a4538 153 pico_arp_request(f->dev, &hdr->dst, PICO_ARP_QUERY); /* arp to dst */
tass 68:0847e35d08a6 154
tass 68:0847e35d08a6 155 pico_enqueue(&pending, f);
tass 68:0847e35d08a6 156 if (!pending_timer_on) {
tass 68:0847e35d08a6 157 pending_timer_on++;
tass 68:0847e35d08a6 158 pico_timer_add(PICO_ARP_RETRY, &check_pending, NULL);
tass 68:0847e35d08a6 159 }
tass 68:0847e35d08a6 160 } else {
tass 68:0847e35d08a6 161 dbg("ARP: Destination Unreachable\n");
tass 68:0847e35d08a6 162 pico_notify_dest_unreachable(f);
tass 68:0847e35d08a6 163 pico_frame_discard(f);
tass 68:0847e35d08a6 164 }
tass 68:0847e35d08a6 165 }
tass 68:0847e35d08a6 166 return a4;
tass 68:0847e35d08a6 167 }
tass 68:0847e35d08a6 168
tass 68:0847e35d08a6 169 #ifdef DEBUG_ARP
tass 68:0847e35d08a6 170 void dbg_arp(void)
tass 68:0847e35d08a6 171 {
tass 68:0847e35d08a6 172 struct pico_arp *a;
tass 68:0847e35d08a6 173 struct pico_tree_node * index;
tass 68:0847e35d08a6 174
tass 68:0847e35d08a6 175 pico_tree_foreach(index,&arp_tree) {
tass 68:0847e35d08a6 176 a = index->keyValue;
tass 68:0847e35d08a6 177 arp_dbg("ARP to %08x, mac: %02x:%02x:%02x:%02x:%02x:%02x\n", a->ipv4.addr,a->eth.addr[0],a->eth.addr[1],a->eth.addr[2],a->eth.addr[3],a->eth.addr[4],a->eth.addr[5] );
tass 68:0847e35d08a6 178 }
tass 68:0847e35d08a6 179 }
tass 68:0847e35d08a6 180 #endif
tass 68:0847e35d08a6 181
tass 73:dfb737147f6e 182 void arp_expire(uint32_t now, void *_stale)
tass 68:0847e35d08a6 183 {
tass 68:0847e35d08a6 184 struct pico_arp *stale = (struct pico_arp *) _stale;
tass 68:0847e35d08a6 185 IGNORE_PARAMETER(now);
tass 68:0847e35d08a6 186 stale->arp_status = PICO_ARP_STATUS_STALE;
tass 68:0847e35d08a6 187 arp_dbg("ARP: Setting arp_status to STALE\n");
tass 123:dd26752a4538 188 pico_arp_request(stale->dev, &stale->ipv4, PICO_ARP_QUERY);
tass 68:0847e35d08a6 189
tass 68:0847e35d08a6 190 }
tass 68:0847e35d08a6 191
tass 68:0847e35d08a6 192 void pico_arp_add_entry(struct pico_arp *entry)
tass 68:0847e35d08a6 193 {
tass 68:0847e35d08a6 194 entry->arp_status = PICO_ARP_STATUS_REACHABLE;
tass 68:0847e35d08a6 195 entry->timestamp = PICO_TIME();
tass 68:0847e35d08a6 196
tass 68:0847e35d08a6 197 pico_tree_insert(&arp_tree,entry);
tass 68:0847e35d08a6 198 arp_dbg("ARP ## reachable.\n");
tass 68:0847e35d08a6 199 pico_timer_add(PICO_ARP_TIMEOUT, arp_expire, entry);
tass 68:0847e35d08a6 200 }
tass 68:0847e35d08a6 201
tass 68:0847e35d08a6 202 int pico_arp_create_entry(uint8_t* hwaddr, struct pico_ip4 ipv4, struct pico_device* dev)
tass 68:0847e35d08a6 203 {
tass 68:0847e35d08a6 204 struct pico_arp* arp = pico_zalloc(sizeof(struct pico_arp));
tass 68:0847e35d08a6 205 if(!arp){
tass 68:0847e35d08a6 206 pico_err = PICO_ERR_ENOMEM;
tass 68:0847e35d08a6 207 return -1;
tass 68:0847e35d08a6 208 }
tass 68:0847e35d08a6 209 memcpy(arp->eth.addr, hwaddr, 6);
tass 68:0847e35d08a6 210 arp->ipv4.addr = ipv4.addr;
tass 68:0847e35d08a6 211 arp->dev = dev;
tass 68:0847e35d08a6 212
tass 68:0847e35d08a6 213 pico_arp_add_entry(arp);
tass 68:0847e35d08a6 214
tass 68:0847e35d08a6 215 return 0;
tass 68:0847e35d08a6 216 }
tass 68:0847e35d08a6 217
tass 68:0847e35d08a6 218 int pico_arp_receive(struct pico_frame *f)
tass 68:0847e35d08a6 219 {
tass 68:0847e35d08a6 220 struct pico_arp_hdr *hdr;
tass 68:0847e35d08a6 221 struct pico_arp search, *found, *new = NULL;
tass 68:0847e35d08a6 222 int ret = -1;
tass 68:0847e35d08a6 223 hdr = (struct pico_arp_hdr *) f->net_hdr;
tass 68:0847e35d08a6 224
tass 68:0847e35d08a6 225 if (!hdr)
tass 68:0847e35d08a6 226 goto end;
tass 68:0847e35d08a6 227
tass 123:dd26752a4538 228 if (conflict_ipv4.conflict != NULL)
tass 123:dd26752a4538 229 {
tass 123:dd26752a4538 230 if ((conflict_ipv4.ip.addr == hdr->src.addr) && (memcmp(hdr->s_mac,conflict_ipv4.mac.addr,6) != 0))
tass 123:dd26752a4538 231 conflict_ipv4.conflict();
tass 123:dd26752a4538 232 }
tass 68:0847e35d08a6 233
tass 68:0847e35d08a6 234 /* Populate a new arp entry */
tass 68:0847e35d08a6 235 search.ipv4.addr = hdr->src.addr;
tass 68:0847e35d08a6 236 memcpy(search.eth.addr, hdr->s_mac, PICO_SIZE_ETH);
tass 68:0847e35d08a6 237
tass 68:0847e35d08a6 238 /* Search for already existing entry */
tass 68:0847e35d08a6 239
tass 68:0847e35d08a6 240 found = pico_tree_findKey(&arp_tree,&search);
tass 68:0847e35d08a6 241 if (!found) {
tass 68:0847e35d08a6 242 new = pico_zalloc(sizeof(struct pico_arp));
tass 68:0847e35d08a6 243 if (!new)
tass 68:0847e35d08a6 244 goto end;
tass 68:0847e35d08a6 245 new->ipv4.addr = hdr->src.addr;
tass 68:0847e35d08a6 246 }
tass 68:0847e35d08a6 247 else if (found->arp_status == PICO_ARP_STATUS_STALE) {
tass 68:0847e35d08a6 248 /* Replace if stale */
tass 68:0847e35d08a6 249 new = found;
tass 68:0847e35d08a6 250
tass 68:0847e35d08a6 251 pico_tree_delete(&arp_tree,new);
tass 68:0847e35d08a6 252 }
tass 68:0847e35d08a6 253
tass 68:0847e35d08a6 254 ret = 0;
tass 68:0847e35d08a6 255
tass 68:0847e35d08a6 256 if (new) {
tass 68:0847e35d08a6 257 memcpy(new->eth.addr, hdr->s_mac, PICO_SIZE_ETH);
tass 68:0847e35d08a6 258 new->dev = f->dev;
tass 68:0847e35d08a6 259 pico_arp_add_entry(new);
tass 68:0847e35d08a6 260 }
tass 68:0847e35d08a6 261
tass 68:0847e35d08a6 262 if (hdr->opcode == PICO_ARP_REQUEST) {
tass 68:0847e35d08a6 263 struct pico_ip4 me;
tass 68:0847e35d08a6 264 struct pico_eth_hdr *eh = (struct pico_eth_hdr *)f->datalink_hdr;
tass 68:0847e35d08a6 265 struct pico_device *link_dev;
tass 68:0847e35d08a6 266 me.addr = hdr->dst.addr;
tass 68:0847e35d08a6 267
tass 68:0847e35d08a6 268 link_dev = pico_ipv4_link_find(&me);
tass 68:0847e35d08a6 269 if (link_dev != f->dev)
tass 68:0847e35d08a6 270 goto end;
tass 68:0847e35d08a6 271
tass 68:0847e35d08a6 272 hdr->opcode = PICO_ARP_REPLY;
tass 68:0847e35d08a6 273 memcpy(hdr->d_mac, hdr->s_mac, PICO_SIZE_ETH);
tass 68:0847e35d08a6 274 memcpy(hdr->s_mac, f->dev->eth->mac.addr, PICO_SIZE_ETH);
tass 68:0847e35d08a6 275 hdr->dst.addr = hdr->src.addr;
tass 68:0847e35d08a6 276 hdr->src.addr = me.addr;
tass 68:0847e35d08a6 277
tass 68:0847e35d08a6 278 /* Prepare eth header for arp reply */
tass 68:0847e35d08a6 279 memcpy(eh->daddr, eh->saddr, PICO_SIZE_ETH);
tass 68:0847e35d08a6 280 memcpy(eh->saddr, f->dev->eth->mac.addr, PICO_SIZE_ETH);
tass 68:0847e35d08a6 281 f->start = f->datalink_hdr;
tass 68:0847e35d08a6 282 f->len = PICO_SIZE_ETHHDR + PICO_SIZE_ARPHDR;
tass 73:dfb737147f6e 283 f->dev->send(f->dev, f->start, (int)f->len);
tass 68:0847e35d08a6 284 }
tass 68:0847e35d08a6 285
tass 68:0847e35d08a6 286 #ifdef DEBUG_ARG
tass 68:0847e35d08a6 287 dbg_arp();
tass 68:0847e35d08a6 288 #endif
tass 68:0847e35d08a6 289
tass 68:0847e35d08a6 290 end:
tass 68:0847e35d08a6 291 pico_frame_discard(f);
tass 68:0847e35d08a6 292 return ret;
tass 68:0847e35d08a6 293 }
tass 68:0847e35d08a6 294
tass 123:dd26752a4538 295 int32_t pico_arp_request(struct pico_device *dev, struct pico_ip4 *dst, uint8_t type)
tass 68:0847e35d08a6 296 {
tass 68:0847e35d08a6 297 struct pico_frame *q = pico_frame_alloc(PICO_SIZE_ETHHDR + PICO_SIZE_ARPHDR);
tass 68:0847e35d08a6 298 struct pico_eth_hdr *eh;
tass 68:0847e35d08a6 299 struct pico_arp_hdr *ah;
tass 68:0847e35d08a6 300 struct pico_ip4 *src;
tass 73:dfb737147f6e 301 int ret;
tass 68:0847e35d08a6 302
tass 123:dd26752a4538 303 if (type == PICO_ARP_QUERY)
tass 123:dd26752a4538 304 {
tass 123:dd26752a4538 305 src = pico_ipv4_source_find(dst);
tass 123:dd26752a4538 306 if (!src)
tass 123:dd26752a4538 307 return -1;
tass 123:dd26752a4538 308 }
tass 68:0847e35d08a6 309
tass 68:0847e35d08a6 310 arp_dbg("QUERY: %08x\n", dst->addr);
tass 68:0847e35d08a6 311
tass 68:0847e35d08a6 312 if (!q)
tass 68:0847e35d08a6 313 return -1;
tass 68:0847e35d08a6 314 eh = (struct pico_eth_hdr *)q->start;
tass 68:0847e35d08a6 315 ah = (struct pico_arp_hdr *) (q->start + PICO_SIZE_ETHHDR);
tass 68:0847e35d08a6 316
tass 68:0847e35d08a6 317 /* Fill eth header */
tass 68:0847e35d08a6 318 memcpy(eh->saddr, dev->eth->mac.addr, PICO_SIZE_ETH);
tass 68:0847e35d08a6 319 memcpy(eh->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH);
tass 68:0847e35d08a6 320 eh->proto = PICO_IDETH_ARP;
tass 68:0847e35d08a6 321
tass 68:0847e35d08a6 322 /* Fill arp header */
tass 68:0847e35d08a6 323 ah->htype = PICO_ARP_HTYPE_ETH;
tass 68:0847e35d08a6 324 ah->ptype = PICO_IDETH_IPV4;
tass 68:0847e35d08a6 325 ah->hsize = PICO_SIZE_ETH;
tass 68:0847e35d08a6 326 ah->psize = PICO_SIZE_IP4;
tass 68:0847e35d08a6 327 ah->opcode = PICO_ARP_REQUEST;
tass 68:0847e35d08a6 328 memcpy(ah->s_mac, dev->eth->mac.addr, PICO_SIZE_ETH);
tass 123:dd26752a4538 329
tass 123:dd26752a4538 330 switch (type){
tass 123:dd26752a4538 331 case PICO_ARP_ANNOUNCE:
tass 123:dd26752a4538 332 ah->src.addr = dst->addr;
tass 123:dd26752a4538 333 ah->dst.addr = dst->addr;
tass 123:dd26752a4538 334 break;
tass 123:dd26752a4538 335 case PICO_ARP_PROBE:
tass 123:dd26752a4538 336 ah->src.addr = 0;
tass 123:dd26752a4538 337 ah->dst.addr = dst->addr;
tass 123:dd26752a4538 338 break;
tass 123:dd26752a4538 339 default:
tass 123:dd26752a4538 340 ah->src.addr = src->addr;
tass 123:dd26752a4538 341 ah->dst.addr = dst->addr;
tass 123:dd26752a4538 342 }
tass 123:dd26752a4538 343
tass 123:dd26752a4538 344 arp_dbg("Sending arp request.\n");
tass 73:dfb737147f6e 345 ret = dev->send(dev, q->start,(int) q->len);
tass 68:0847e35d08a6 346 pico_frame_discard(q);
tass 73:dfb737147f6e 347 return ret;
tass 68:0847e35d08a6 348 }
tass 74:c146c4e346c4 349
tass 74:c146c4e346c4 350 int pico_arp_get_neighbors(struct pico_device *dev, struct pico_ip4 *neighbors, int maxlen)
tass 74:c146c4e346c4 351 {
tass 74:c146c4e346c4 352 struct pico_arp* search;
tass 74:c146c4e346c4 353 struct pico_tree_node * index;
tass 74:c146c4e346c4 354 int i = 0;
tass 74:c146c4e346c4 355 pico_tree_foreach(index,&arp_tree){
tass 74:c146c4e346c4 356 search = index->keyValue;
tass 74:c146c4e346c4 357 if (search->dev == dev) {
tass 74:c146c4e346c4 358 neighbors[i++].addr = search->ipv4.addr;
tass 74:c146c4e346c4 359 if (i >= maxlen)
tass 74:c146c4e346c4 360 return i;
tass 74:c146c4e346c4 361 }
tass 74:c146c4e346c4 362 }
tass 74:c146c4e346c4 363 return i;
tass 74:c146c4e346c4 364 }
tass 123:dd26752a4538 365
tass 123:dd26752a4538 366 void pico_arp_register_ipconflict(struct pico_ip4 *ip, struct pico_eth *mac, void(*cb)(void))
tass 123:dd26752a4538 367 {
tass 123:dd26752a4538 368 conflict_ipv4.conflict = cb;
tass 123:dd26752a4538 369 conflict_ipv4.ip.addr = ip->addr;
tass 123:dd26752a4538 370 if (mac != NULL)
tass 123:dd26752a4538 371 memcpy(conflict_ipv4.mac.addr, mac, 6);
tass 123:dd26752a4538 372 }