mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-07-04 20:08:57 +00:00
Merged from DEVEL. etharp prepared for queueing feature. DHCP fix.
This commit is contained in:
parent
a646b5374f
commit
eed8ea5bc1
12
CHANGELOG
12
CHANGELOG
|
@ -5,8 +5,20 @@ TODO
|
||||||
|
|
||||||
HISTORY
|
HISTORY
|
||||||
|
|
||||||
|
(STABLE-0_6_6)
|
||||||
|
|
||||||
|
++ Bug fixes:
|
||||||
|
|
||||||
|
* Fixed DHCP which did not include the IP address in DECLINE messages.
|
||||||
|
|
||||||
|
++ Changes:
|
||||||
|
|
||||||
|
* etharp.c has been hauled over a bit.
|
||||||
|
|
||||||
(STABLE-0_6_5)
|
(STABLE-0_6_5)
|
||||||
|
|
||||||
|
++ Bug fixes:
|
||||||
|
|
||||||
* Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic.
|
* Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic.
|
||||||
* Packets sent from ARP queue had invalid source hardware address.
|
* Packets sent from ARP queue had invalid source hardware address.
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,7 @@ static void dhcp_handle_offer(struct netif *netif)
|
||||||
/* remember offered address */
|
/* remember offered address */
|
||||||
ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr);
|
ip_addr_set(&dhcp->offered_ip_addr, (struct ip_addr *)&dhcp->msg_in->yiaddr);
|
||||||
LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08lx\n", dhcp->offered_ip_addr.addr));
|
LWIP_DEBUGF(DHCP_DEBUG | DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08lx\n", dhcp->offered_ip_addr.addr));
|
||||||
|
|
||||||
dhcp_select(netif);
|
dhcp_select(netif);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -646,6 +647,9 @@ static err_t dhcp_decline(struct netif *netif)
|
||||||
dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
|
dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN);
|
||||||
dhcp_option_short(dhcp, 576);
|
dhcp_option_short(dhcp, 576);
|
||||||
|
|
||||||
|
dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4);
|
||||||
|
dhcp_option_long(dhcp, ntohl(dhcp->offered_ip_addr.addr));
|
||||||
|
|
||||||
dhcp_option_trailer(dhcp);
|
dhcp_option_trailer(dhcp);
|
||||||
/* resize pbuf to reflect true size of options */
|
/* resize pbuf to reflect true size of options */
|
||||||
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
|
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
|
||||||
|
|
|
@ -220,8 +220,6 @@ memp_malloc(memp_t type)
|
||||||
((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
|
((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
|
||||||
|
|
||||||
mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
|
mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
|
||||||
/* initialize memp memory with zeroes */
|
|
||||||
memset(mem, 0, memp_sizes[type]);
|
|
||||||
return mem;
|
return mem;
|
||||||
} else {
|
} else {
|
||||||
LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %d\n", type));
|
LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %d\n", type));
|
||||||
|
|
|
@ -39,7 +39,6 @@
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
|
|
||||||
#include "lwip/def.h"
|
#include "lwip/def.h"
|
||||||
#include "lwip/mem.h"
|
|
||||||
#include "lwip/netif.h"
|
#include "lwip/netif.h"
|
||||||
#include "lwip/ip_addr.h"
|
#include "lwip/ip_addr.h"
|
||||||
#include "lwip/tcp.h"
|
#include "lwip/tcp.h"
|
||||||
|
@ -61,22 +60,15 @@ struct netif *netif_default = NULL;
|
||||||
* @return netif, or NULL if failed.
|
* @return netif, or NULL if failed.
|
||||||
*/
|
*/
|
||||||
struct netif *
|
struct netif *
|
||||||
netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
|
netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
|
||||||
struct ip_addr *gw,
|
struct ip_addr *gw,
|
||||||
void *state,
|
void *state,
|
||||||
err_t (* init)(struct netif *netif),
|
err_t (* init)(struct netif *netif),
|
||||||
err_t (* input)(struct pbuf *p, struct netif *netif))
|
err_t (* input)(struct pbuf *p, struct netif *netif))
|
||||||
{
|
{
|
||||||
struct netif *netif;
|
|
||||||
static int netifnum = 0;
|
static int netifnum = 0;
|
||||||
|
|
||||||
/* allocate netif structure */
|
|
||||||
netif = mem_malloc(sizeof(struct netif));
|
|
||||||
|
|
||||||
if (netif == NULL) {
|
|
||||||
LWIP_DEBUGF(NETIF_DEBUG, ("netif_add(): out of memory for netif\n"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#if LWIP_DHCP
|
#if LWIP_DHCP
|
||||||
/* netif not under DHCP control by default */
|
/* netif not under DHCP control by default */
|
||||||
netif->dhcp = NULL;
|
netif->dhcp = NULL;
|
||||||
|
@ -90,7 +82,6 @@ netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
|
||||||
|
|
||||||
/* call user specified initialization function for netif */
|
/* call user specified initialization function for netif */
|
||||||
if (init(netif) != ERR_OK) {
|
if (init(netif) != ERR_OK) {
|
||||||
mem_free(netif);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +133,6 @@ void netif_remove(struct netif * netif)
|
||||||
/* reset default netif */
|
/* reset default netif */
|
||||||
netif_default = NULL;
|
netif_default = NULL;
|
||||||
LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
|
LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
|
||||||
mem_free( netif );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct netif *
|
struct netif *
|
||||||
|
|
|
@ -504,29 +504,33 @@ pbuf_header(struct pbuf *p, s16_t header_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a pbuf (chain) from usage, de-allocate non-used head of chain.
|
* Dereference a pbuf (chain) and deallocate any no-longer-used
|
||||||
|
* pbufs at the head of this chain.
|
||||||
*
|
*
|
||||||
* Decrements the pbuf reference count. If it reaches
|
* Decrements the pbuf reference count. If it reaches
|
||||||
* zero, the pbuf is deallocated.
|
* zero, the pbuf is deallocated.
|
||||||
*
|
*
|
||||||
* For a pbuf chain, this is repeated for each pbuf in the chain, up to the
|
* For a pbuf chain, this is repeated for each pbuf in the chain,
|
||||||
* pbuf which has a non-zero reference count after decrementing.
|
* up to a pbuf which has a non-zero reference count after
|
||||||
* (This might be the whole chain.)
|
* decrementing. (This might de-allocate the whole chain.)
|
||||||
*
|
*
|
||||||
* @param pbuf pbuf (chain) to be freed from one user.
|
* @param pbuf The pbuf (chain) to be dereferenced.
|
||||||
*
|
*
|
||||||
* @return the number of unreferenced pbufs that were de-allocated
|
* @return the number of pbufs that were de-allocated
|
||||||
* from the head of the chain.
|
* from the head of the chain.
|
||||||
*
|
*
|
||||||
* @note May not be called on a packet queue.
|
* @note MUST NOT be called on a packet queue.
|
||||||
* @note the reference counter of a pbuf equals the number of pointers
|
* @note the reference counter of a pbuf equals the number of pointers
|
||||||
* that refer to the pbuf (or into the pbuf).
|
* that refer to the pbuf (or into the pbuf).
|
||||||
*
|
*
|
||||||
* @internal examples:
|
* @internal examples:
|
||||||
*
|
*
|
||||||
|
* Assuming existing chains a->b->c with the following reference
|
||||||
|
* counts, calling pbuf_free(a) results in:
|
||||||
|
*
|
||||||
* 1->2->3 becomes ...1->3
|
* 1->2->3 becomes ...1->3
|
||||||
* 3->3->3 becomes 2->3->3
|
* 3->3->3 becomes 2->3->3
|
||||||
* 1->1->2 becomes ....->1
|
* 1->1->2 becomes ......1
|
||||||
* 2->1->1 becomes 1->1->1
|
* 2->1->1 becomes 1->1->1
|
||||||
* 1->1->1 becomes .......
|
* 1->1->1 becomes .......
|
||||||
*
|
*
|
||||||
|
@ -636,9 +640,10 @@ pbuf_ref(struct pbuf *p)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concatenate two pbufs (each may be a pbuf chain) and take over
|
* Concatenate two pbufs (each may be a pbuf chain) and take over
|
||||||
* the reference of the tail pbuf.
|
* the caller's reference of the tail pbuf.
|
||||||
*
|
*
|
||||||
* @note The caller MAY NOT reference the tail pbuf afterwards.
|
* @note The caller MAY NOT reference the tail pbuf afterwards.
|
||||||
|
* Use pbuf_chain() for that purpose.
|
||||||
*
|
*
|
||||||
* @see pbuf_chain()
|
* @see pbuf_chain()
|
||||||
*/
|
*/
|
||||||
|
@ -650,16 +655,14 @@ pbuf_cat(struct pbuf *h, struct pbuf *t)
|
||||||
|
|
||||||
LWIP_ASSERT("h != NULL", h != NULL);
|
LWIP_ASSERT("h != NULL", h != NULL);
|
||||||
LWIP_ASSERT("t != NULL", t != NULL);
|
LWIP_ASSERT("t != NULL", t != NULL);
|
||||||
|
if ((h == NULL) || (t == NULL)) return;
|
||||||
if (t == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* proceed to last pbuf of chain */
|
/* proceed to last pbuf of chain */
|
||||||
for (p = h; p->next != NULL; p = p->next) {
|
for (p = h; p->next != NULL; p = p->next) {
|
||||||
/* add total length of second chain to all totals of first chain */
|
/* add total length of second chain to all totals of first chain */
|
||||||
p->tot_len += t->tot_len;
|
p->tot_len += t->tot_len;
|
||||||
}
|
}
|
||||||
/* p is last pbuf of first h chain */
|
/* { p is last pbuf of first h chain, p->next == NULL } */
|
||||||
LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
|
LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len);
|
||||||
/* add total length of second chain to last pbuf total of first chain */
|
/* add total length of second chain to last pbuf total of first chain */
|
||||||
p->tot_len += t->tot_len;
|
p->tot_len += t->tot_len;
|
||||||
|
@ -668,13 +671,15 @@ pbuf_cat(struct pbuf *h, struct pbuf *t)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chain two pbufs (or pbuf chains) together. They must belong to the same packet.
|
* Chain two pbufs (or pbuf chains) together.
|
||||||
* It's the same as pbuf_cat with the addition that it increases the reference count
|
*
|
||||||
* of the tail.
|
* The caller MUST call pbuf_free(t) once it has stopped
|
||||||
|
* using it. Use pbuf_cat() instead if you no longer use t.
|
||||||
*
|
*
|
||||||
* @param h head pbuf (chain)
|
* @param h head pbuf (chain)
|
||||||
* @param t tail pbuf (chain)
|
* @param t tail pbuf (chain)
|
||||||
* @note May not be called on a packet queue.
|
* @note The pbufs MUST belong to the same packet.
|
||||||
|
* @note MAY NOT be called on a packet queue.
|
||||||
*
|
*
|
||||||
* The ->tot_len fields of all pbufs of the head chain are adjusted.
|
* The ->tot_len fields of all pbufs of the head chain are adjusted.
|
||||||
* The ->next field of the last pbuf of the head chain is adjusted.
|
* The ->next field of the last pbuf of the head chain is adjusted.
|
||||||
|
@ -685,7 +690,7 @@ void
|
||||||
pbuf_chain(struct pbuf *h, struct pbuf *t)
|
pbuf_chain(struct pbuf *h, struct pbuf *t)
|
||||||
{
|
{
|
||||||
pbuf_cat(h, t);
|
pbuf_cat(h, t);
|
||||||
/* t is now referenced to one more time */
|
/* t is now referenced by h */
|
||||||
pbuf_ref(t);
|
pbuf_ref(t);
|
||||||
LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
|
LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
||||||
pcb->unsent != NULL);
|
pcb->unsent != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
seg = NULL;
|
seg = useg = NULL;
|
||||||
seglen = 0;
|
seglen = 0;
|
||||||
|
|
||||||
/* First, break up the data into segments and tuck them together in
|
/* First, break up the data into segments and tuck them together in
|
||||||
|
@ -158,6 +158,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Attach the segment to the end of the queued segments. */
|
/* Attach the segment to the end of the queued segments. */
|
||||||
|
LWIP_ASSERT("useg != NULL", useg != NULL);
|
||||||
useg->next = seg;
|
useg->next = seg;
|
||||||
useg = seg;
|
useg = seg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,10 +191,10 @@ void dhcp_fine_tmr(void);
|
||||||
#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
|
#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
|
||||||
|
|
||||||
|
|
||||||
#define DHCP_OPTION_SERVER_ID 54 /* RFC 2131 9.7, server IP address */
|
#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
|
||||||
#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2131 9.8, requested option types */
|
#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */
|
||||||
|
|
||||||
#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2131 9.10, message size accepted >= 576 */
|
#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */
|
||||||
#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2
|
#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2
|
||||||
|
|
||||||
#define DHCP_OPTION_T1 58 /* T1 renewal time */
|
#define DHCP_OPTION_T1 58 /* T1 renewal time */
|
||||||
|
|
|
@ -115,7 +115,7 @@ extern struct netif *netif_default;
|
||||||
/* netif_init() must be called first. */
|
/* netif_init() must be called first. */
|
||||||
void netif_init(void);
|
void netif_init(void);
|
||||||
|
|
||||||
struct netif *netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
|
struct netif *netif_add(struct netif *netif, struct ip_addr *ipaddr, struct ip_addr *netmask,
|
||||||
struct ip_addr *gw,
|
struct ip_addr *gw,
|
||||||
void *state,
|
void *state,
|
||||||
err_t (* init)(struct netif *netif),
|
err_t (* init)(struct netif *netif),
|
||||||
|
|
|
@ -42,6 +42,13 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO:
|
||||||
|
* - pbufs should be sent from the queue once an ARP entry state
|
||||||
|
* goes from PENDING to STABLE.
|
||||||
|
* - Non-PENDING entries MUST NOT have queued packets.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO:
|
* TODO:
|
||||||
*
|
*
|
||||||
|
@ -113,6 +120,9 @@ struct etharp_entry {
|
||||||
struct eth_addr ethaddr;
|
struct eth_addr ethaddr;
|
||||||
enum etharp_state state;
|
enum etharp_state state;
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
|
/**
|
||||||
|
* Pointer to queue of pending outgoing packets on this ARP entry.
|
||||||
|
* Must be at most a single packet for now. */
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
#endif
|
#endif
|
||||||
u8_t ctime;
|
u8_t ctime;
|
||||||
|
@ -121,22 +131,27 @@ struct etharp_entry {
|
||||||
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
|
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
|
||||||
static struct etharp_entry arp_table[ARP_TABLE_SIZE];
|
static struct etharp_entry arp_table[ARP_TABLE_SIZE];
|
||||||
|
|
||||||
static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
|
static s8_t find_arp_entry(void);
|
||||||
#define ARP_INSERT_FLAG 1
|
#define ARP_INSERT_FLAG 1
|
||||||
|
static struct pbuf *update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags);
|
||||||
|
#if ARP_QUEUEING
|
||||||
|
static struct pbuf *etharp_enqueue(s8_t i, struct pbuf *q);
|
||||||
|
static u8_t etharp_dequeue(s8_t i);
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* Initializes ARP module.
|
* Initializes ARP module.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
etharp_init(void)
|
etharp_init(void)
|
||||||
{
|
{
|
||||||
u8_t i;
|
s8_t i;
|
||||||
/* clear ARP entries */
|
/* clear ARP entries */
|
||||||
for(i = 0; i < ARP_TABLE_SIZE; ++i) {
|
for(i = 0; i < ARP_TABLE_SIZE; ++i) {
|
||||||
arp_table[i].state = ETHARP_STATE_EMPTY;
|
arp_table[i].state = ETHARP_STATE_EMPTY;
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
arp_table[i].p = NULL;
|
arp_table[i].p = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
arp_table[i].ctime = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,22 +164,28 @@ etharp_init(void)
|
||||||
void
|
void
|
||||||
etharp_tmr(void)
|
etharp_tmr(void)
|
||||||
{
|
{
|
||||||
u8_t i;
|
s8_t i;
|
||||||
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
|
||||||
/* remove expired entries from the ARP table */
|
/* remove expired entries from the ARP table */
|
||||||
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
||||||
arp_table[i].ctime++;
|
arp_table[i].ctime++;
|
||||||
|
/* a resolved/stable entry? */
|
||||||
if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
|
if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
|
||||||
|
/* entry has become old? */
|
||||||
(arp_table[i].ctime >= ARP_MAXAGE)) {
|
(arp_table[i].ctime >= ARP_MAXAGE)) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));
|
||||||
goto empty;
|
goto empty;
|
||||||
|
/* an unresolved/pending entry? */
|
||||||
} else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&
|
} else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&
|
||||||
|
/* entry unresolved/pending for too long? */
|
||||||
(arp_table[i].ctime >= ARP_MAXPENDING)) {
|
(arp_table[i].ctime >= ARP_MAXPENDING)) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));
|
||||||
empty:
|
empty:
|
||||||
|
/* empty old entry */
|
||||||
arp_table[i].state = ETHARP_STATE_EMPTY;
|
arp_table[i].state = ETHARP_STATE_EMPTY;
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
|
/* and empty packet queue */
|
||||||
if (arp_table[i].p != NULL) {
|
if (arp_table[i].p != NULL) {
|
||||||
/* remove any queued packet */
|
/* remove any queued packet */
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %u, packet queue %p.\n", i, (void *)(arp_table[i].p)));
|
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: freeing entry %u, packet queue %p.\n", i, (void *)(arp_table[i].p)));
|
||||||
|
@ -177,55 +198,125 @@ etharp_tmr(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an empty ARP entry or, if the table is full, ARP_TABLE_SIZE if all
|
* Return an empty ARP entry (possibly recycling the oldest stable entry).
|
||||||
* entries are pending, otherwise the oldest entry.
|
|
||||||
*
|
*
|
||||||
* @return The ARP entry index that is available, ARP_TABLE_SIZE if no usable
|
* @return The ARP entry index that is available, ERR_MEM if no usable
|
||||||
* entry is found.
|
* entry is found.
|
||||||
*/
|
*/
|
||||||
static u8_t
|
static s8_t
|
||||||
find_arp_entry(void)
|
find_arp_entry(void)
|
||||||
{
|
{
|
||||||
u8_t i, j, maxtime;
|
s8_t i, j;
|
||||||
|
u8_t maxtime = 0;
|
||||||
|
|
||||||
/* Try to find an unused entry in the ARP table. */
|
|
||||||
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
|
||||||
if (arp_table[i].state == ETHARP_STATE_EMPTY) {
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found empty entry %u\n", i));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If no unused entry is found, we try to find the oldest entry and
|
|
||||||
throw it away. If all entries are new and have 0 ctime drop one */
|
|
||||||
if (i == ARP_TABLE_SIZE) {
|
|
||||||
maxtime = 0;
|
|
||||||
j = ARP_TABLE_SIZE;
|
j = ARP_TABLE_SIZE;
|
||||||
|
/* search ARP table for an unused or old entry */
|
||||||
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
|
||||||
/* remember entry with oldest stable entry in j*/
|
/* empty entry? */
|
||||||
if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
|
if (arp_table[i].state == ETHARP_STATE_EMPTY) {
|
||||||
#if ARP_QUEUEING /* do not want to re-use an entry with queued packets */
|
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning empty entry %u\n", i));
|
||||||
(arp_table[i].p == NULL) &&
|
return i;
|
||||||
#endif
|
/* stable entry? */
|
||||||
(arp_table[i].ctime >= maxtime)) {
|
} else if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
||||||
maxtime = arp_table[i].ctime;
|
/* remember entry with oldest stable entry in j */
|
||||||
j = i;
|
if (arp_table[i].ctime >= maxtime) maxtime = arp_table[j = i].ctime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j != ARP_TABLE_SIZE) {
|
/* no empty entry found? */
|
||||||
|
if (i == ARP_TABLE_SIZE) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j));
|
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j));
|
||||||
} else {
|
/* fall-back to oldest stable */
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: no replacable entry could be found\n"));
|
|
||||||
}
|
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u, state %u\n", i, arp_table[i].state));
|
/* no available entry found? */
|
||||||
|
if (i == ARP_TABLE_SIZE) {
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: no replacable entry could be found\n"));
|
||||||
|
/* return failure */
|
||||||
|
return ERR_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up the recycled stable entry */
|
||||||
|
if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
||||||
|
#if ARP_QUEUEING
|
||||||
|
/* free packets on queue */
|
||||||
|
etharp_dequeue(i);
|
||||||
|
#endif
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("find_arp_entry: recycling oldest stable entry %u\n", i));
|
||||||
|
arp_table[i].state = ETHARP_STATE_EMPTY;
|
||||||
|
arp_table[i].ctime = 0;
|
||||||
|
}
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u\n", i));
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ARP_QUEUEING
|
||||||
|
/*
|
||||||
|
* Enqueues a pbuf (chain) on an ARP entry.
|
||||||
|
*
|
||||||
|
* Places the pbuf (chain) on the queue (if space allows). The
|
||||||
|
* caller may safely free the pbuf (chain) afterwards, as the
|
||||||
|
* pbufs will be referenced by the queue and copies are made of
|
||||||
|
* pbufs referencing external payloads.
|
||||||
|
*
|
||||||
|
* @ i the ARP entry index
|
||||||
|
* @arg q the pbuf (chain) to be queued on the ARP entry
|
||||||
|
*
|
||||||
|
* @return Returns the new head of queue of the ARP entry.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static struct pbuf *
|
||||||
|
etharp_enqueue(s8_t i, struct pbuf *q)
|
||||||
|
{
|
||||||
|
/* any pbuf to queue? */
|
||||||
|
if (q != NULL) {
|
||||||
|
/* queue later packet over earliers? TODO: Implement multiple pbuf queue */
|
||||||
|
#if ARP_QUEUE_FIRST == 0
|
||||||
|
/* remove any pbufs on queue */
|
||||||
|
u8_t deq = etharp_dequeue(i);
|
||||||
|
if (deq > 0) LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dequeued %u pbufs from ARP entry %u. Should not occur.\n", deq, i));
|
||||||
|
#endif
|
||||||
|
/* packet can be queued? TODO: Implement multiple pbuf queue */
|
||||||
|
if (arp_table[i].p == NULL) {
|
||||||
|
/* copy any PBUF_REF referenced payloads into PBUF_RAM */
|
||||||
|
q = pbuf_take(q);
|
||||||
|
/* add pbuf to queue */
|
||||||
|
arp_table[i].p = q;
|
||||||
|
/* pbuf (chain) now queued, increase the reference count */
|
||||||
|
pbuf_ref(q);
|
||||||
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arp_table[i].p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dequeues any pbufs queued on an ARP entry
|
||||||
|
*
|
||||||
|
* @return number of pbufs removed from the queue
|
||||||
|
*
|
||||||
|
* TODO: decide what is a sensible return value?
|
||||||
|
*/
|
||||||
|
static u8_t
|
||||||
|
etharp_dequeue(s8_t i)
|
||||||
|
{
|
||||||
|
/* queued packets on a stable entry (work in progress) */
|
||||||
|
if (arp_table[i].p != NULL) {
|
||||||
|
/* queue no longer references pbuf */
|
||||||
|
pbuf_free(arp_table[i].p);
|
||||||
|
arp_table[i].p = NULL;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update (or insert) a IP/MAC address pair in the ARP cache.
|
* Update (or insert) a IP/MAC address pair in the ARP cache.
|
||||||
*
|
*
|
||||||
|
* If a pending entry is resolved, any queued packets will be sent
|
||||||
|
* at this point.
|
||||||
|
*
|
||||||
* @param ipaddr IP address of the inserted ARP entry.
|
* @param ipaddr IP address of the inserted ARP entry.
|
||||||
* @param ethaddr Ethernet address of the inserted ARP entry.
|
* @param ethaddr Ethernet address of the inserted ARP entry.
|
||||||
* @param flags Defines behaviour:
|
* @param flags Defines behaviour:
|
||||||
|
@ -240,7 +331,7 @@ find_arp_entry(void)
|
||||||
static struct pbuf *
|
static struct pbuf *
|
||||||
update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
|
update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *ethaddr, u8_t flags)
|
||||||
{
|
{
|
||||||
u8_t i, k;
|
s8_t i, k;
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("update_arp_entry()\n"));
|
||||||
LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);
|
LWIP_ASSERT("netif->hwaddr_len != 0", netif->hwaddr_len != 0);
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr),
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: %u.%u.%u.%u - %02x:%02x:%02x:%02x:%02x:%02x\n", ip4_addr1(ipaddr), ip4_addr2(ipaddr), ip4_addr3(ipaddr), ip4_addr4(ipaddr),
|
||||||
|
@ -264,7 +355,7 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
||||||
arp_table[i].state = ETHARP_STATE_STABLE;
|
arp_table[i].state = ETHARP_STATE_STABLE;
|
||||||
/* fall-through to next if */
|
/* fall-through to next if */
|
||||||
}
|
}
|
||||||
/* stable entry? (possible just marked to become stable) */
|
/* stable entry? (possibly just marked to become stable) */
|
||||||
if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
struct pbuf *p;
|
struct pbuf *p;
|
||||||
|
@ -277,12 +368,25 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
||||||
}
|
}
|
||||||
/* reset time stamp */
|
/* reset time stamp */
|
||||||
arp_table[i].ctime = 0;
|
arp_table[i].ctime = 0;
|
||||||
|
/* this is where we will send out queued packets! */
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
|
/* get the first packet on the queue (if any) */
|
||||||
p = arp_table[i].p;
|
p = arp_table[i].p;
|
||||||
/* queued packet present? */
|
/* queued packet present? */
|
||||||
if (p != NULL) {
|
while (p != NULL) {
|
||||||
/* NULL attached buffer immediately */
|
struct pbuf *q, *n;
|
||||||
arp_table[i].p = NULL;
|
/* search for second packet on queue (n) */
|
||||||
|
q = p;
|
||||||
|
while (q->tot_len > q->len) {
|
||||||
|
/* proceed to next pbuf of this packet */
|
||||||
|
LWIP_ASSERT("q->next ! NULL", q->next != NULL);
|
||||||
|
q = q->next;
|
||||||
|
}
|
||||||
|
/* { q = last pbuf of first packet, q->tot_len = q->len } */
|
||||||
|
n = q->next;
|
||||||
|
/* { n = first pbuf of 2nd packet, or NULL if no 2nd packet } */
|
||||||
|
/* terminate the first packet pbuf chain */
|
||||||
|
q->next = NULL;
|
||||||
/* fill-in Ethernet header */
|
/* fill-in Ethernet header */
|
||||||
ethhdr = p->payload;
|
ethhdr = p->payload;
|
||||||
for (k = 0; k < netif->hwaddr_len; ++k) {
|
for (k = 0; k < netif->hwaddr_len; ++k) {
|
||||||
|
@ -290,12 +394,16 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
||||||
ethhdr->src.addr[k] = netif->hwaddr[k];
|
ethhdr->src.addr[k] = netif->hwaddr[k];
|
||||||
}
|
}
|
||||||
ethhdr->type = htons(ETHTYPE_IP);
|
ethhdr->type = htons(ETHTYPE_IP);
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet.\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: sending queued IP packet %p.\n",(void *)p));
|
||||||
/* send the queued IP packet */
|
/* send the queued IP packet */
|
||||||
netif->linkoutput(netif, p);
|
netif->linkoutput(netif, p);
|
||||||
/* free the queued IP packet */
|
/* free the queued IP packet */
|
||||||
pbuf_free(p);
|
pbuf_free(p);
|
||||||
|
/* proceed to next packet on queue */
|
||||||
|
p = n;
|
||||||
}
|
}
|
||||||
|
/* NULL attached buffer*/
|
||||||
|
arp_table[i].p = NULL;
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -312,21 +420,10 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: adding entry to table\n"));
|
||||||
/* find an empty or old entry. */
|
/* find an empty or old entry. */
|
||||||
i = find_arp_entry();
|
i = find_arp_entry();
|
||||||
if (i == ARP_TABLE_SIZE) {
|
if (i == ERR_MEM) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no available entry found\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: no available entry found\n"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* see if find_arp_entry() gave us an old stable, or empty entry to re-use */
|
|
||||||
if (arp_table[i].state == ETHARP_STATE_STABLE) {
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("update_arp_entry: overwriting old stable entry %u\n", i));
|
|
||||||
/* stable entries should have no queued packets (TODO: allow later) */
|
|
||||||
#if ARP_QUEUEING
|
|
||||||
LWIP_ASSERT("update_arp_entry: arp_table[i].p == NULL", arp_table[i].p == NULL);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("update_arp_entry: filling empty entry %u with state %u\n", i, arp_table[i].state));
|
|
||||||
LWIP_ASSERT("update_arp_entry: arp_table[i].state == ETHARP_STATE_EMPTY", arp_table[i].state == ETHARP_STATE_EMPTY);
|
|
||||||
}
|
|
||||||
/* set IP address */
|
/* set IP address */
|
||||||
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
|
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
|
||||||
/* set Ethernet hardware address */
|
/* set Ethernet hardware address */
|
||||||
|
@ -350,7 +447,7 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the ARP table using the given packet.
|
* Updates the ARP table using the given IP packet.
|
||||||
*
|
*
|
||||||
* Uses the incoming IP packet's source address to update the
|
* Uses the incoming IP packet's source address to update the
|
||||||
* ARP cache for the local network. The function does not alter
|
* ARP cache for the local network. The function does not alter
|
||||||
|
@ -512,10 +609,10 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
||||||
* This ARP request is returned as a pbuf, which should be sent by
|
* This ARP request is returned as a pbuf, which should be sent by
|
||||||
* the caller.
|
* the caller.
|
||||||
*
|
*
|
||||||
* If ARP failed to allocate resources, NULL is returned.
|
|
||||||
*
|
|
||||||
* A returned non-NULL packet should be sent by the caller.
|
* A returned non-NULL packet should be sent by the caller.
|
||||||
*
|
*
|
||||||
|
* If ARP failed to allocate resources, NULL is returned.
|
||||||
|
*
|
||||||
* @param netif The lwIP network interface which the IP packet will be sent on.
|
* @param netif The lwIP network interface which the IP packet will be sent on.
|
||||||
* @param ipaddr The IP address of the packet destination.
|
* @param ipaddr The IP address of the packet destination.
|
||||||
* @param pbuf The pbuf(s) containing the IP packet to be sent.
|
* @param pbuf The pbuf(s) containing the IP packet to be sent.
|
||||||
|
@ -528,9 +625,9 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
{
|
{
|
||||||
struct eth_addr *dest, *srcaddr, mcastaddr;
|
struct eth_addr *dest, *srcaddr, mcastaddr;
|
||||||
struct eth_hdr *ethhdr;
|
struct eth_hdr *ethhdr;
|
||||||
u8_t i;
|
s8_t i;
|
||||||
|
|
||||||
/* Make room for Ethernet header. */
|
/* make room for Ethernet header */
|
||||||
if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
|
if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
|
||||||
/* The pbuf_header() call shouldn't fail, and we'll just bail
|
/* The pbuf_header() call shouldn't fail, and we'll just bail
|
||||||
out if it does.. */
|
out if it does.. */
|
||||||
|
@ -539,9 +636,6 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* obtain source Ethernet address of the given interface */
|
|
||||||
srcaddr = (struct eth_addr *)netif->hwaddr;
|
|
||||||
|
|
||||||
/* assume unresolved Ethernet address */
|
/* assume unresolved Ethernet address */
|
||||||
dest = NULL;
|
dest = NULL;
|
||||||
/* Construct Ethernet header. Start with looking up deciding which
|
/* Construct Ethernet header. Start with looking up deciding which
|
||||||
|
@ -569,19 +663,20 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
}
|
}
|
||||||
/* destination IP address is an IP unicast address */
|
/* destination IP address is an IP unicast address */
|
||||||
else {
|
else {
|
||||||
/* destination IP network address not on local network? */
|
/* destination IP network address not on local network?
|
||||||
/* this occurs if the packet is routed to the default gateway on this interface */
|
* IP layer wants us to forward to the default gateway */
|
||||||
if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
|
if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
|
||||||
/* gateway available? */
|
/* interface has default gateway? */
|
||||||
if (netif->gw.addr != 0)
|
if (netif->gw.addr != 0)
|
||||||
{
|
{
|
||||||
/* use the gateway IP address */
|
/* route to default gateway IP address */
|
||||||
ipaddr = &(netif->gw);
|
ipaddr = &(netif->gw);
|
||||||
}
|
}
|
||||||
/* no gateway available? */
|
/* no gateway available? */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* IP destination address outside local network, but no gateway available */
|
/* IP destination address outside local network, but no gateway available */
|
||||||
|
/* { packet is discarded } */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -600,6 +695,7 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
/* ARP query for the IP address, submit this IP packet for queueing */
|
/* ARP query for the IP address, submit this IP packet for queueing */
|
||||||
/* TODO: How do we handle netif->ipaddr == ipaddr? */
|
/* TODO: How do we handle netif->ipaddr == ipaddr? */
|
||||||
etharp_query(netif, ipaddr, q);
|
etharp_query(netif, ipaddr, q);
|
||||||
|
/* { packet was queued (ERR_OK), or discarded } */
|
||||||
/* return nothing */
|
/* return nothing */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -612,8 +708,11 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
|
|
||||||
/* destination Ethernet address known */
|
/* destination Ethernet address known */
|
||||||
if (dest != NULL) {
|
if (dest != NULL) {
|
||||||
/* A valid IP->MAC address mapping was found, so we construct the
|
/* obtain source Ethernet address of the given interface */
|
||||||
Ethernet header for the outgoing packet. */
|
srcaddr = (struct eth_addr *)netif->hwaddr;
|
||||||
|
|
||||||
|
/* A valid IP->MAC address mapping was found, fill in the
|
||||||
|
* Ethernet header for the outgoing packet */
|
||||||
ethhdr = q->payload;
|
ethhdr = q->payload;
|
||||||
|
|
||||||
for(i = 0; i < netif->hwaddr_len; i++) {
|
for(i = 0; i < netif->hwaddr_len; i++) {
|
||||||
|
@ -654,9 +753,8 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
{
|
{
|
||||||
struct eth_addr *srcaddr;
|
struct eth_addr *srcaddr;
|
||||||
struct etharp_hdr *hdr;
|
struct etharp_hdr *hdr;
|
||||||
struct pbuf *p;
|
|
||||||
err_t result = ERR_OK;
|
err_t result = ERR_OK;
|
||||||
u8_t i;
|
s8_t i;
|
||||||
u8_t perform_arp_request = 1;
|
u8_t perform_arp_request = 1;
|
||||||
/* prevent 'unused argument' warning if ARP_QUEUEING == 0 */
|
/* prevent 'unused argument' warning if ARP_QUEUEING == 0 */
|
||||||
(void)q;
|
(void)q;
|
||||||
|
@ -666,7 +764,7 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
|
if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
|
||||||
if (arp_table[i].state == ETHARP_STATE_PENDING) {
|
if (arp_table[i].state == ETHARP_STATE_PENDING) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already pending as entry %u\n", i));
|
||||||
/* break out of for-loop, user may wish to queue a packet on a stable entry */
|
/* break out of for-loop, user may wish to queue a packet on a pending entry */
|
||||||
/* TODO: we will issue a new ARP request, which should not occur too often */
|
/* TODO: we will issue a new ARP request, which should not occur too often */
|
||||||
/* we might want to run a faster timer on ARP to limit this */
|
/* we might want to run a faster timer on ARP to limit this */
|
||||||
break;
|
break;
|
||||||
|
@ -683,56 +781,26 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
|
||||||
/* queried address not yet in ARP table? */
|
/* queried address not yet in ARP table? */
|
||||||
if (i == ARP_TABLE_SIZE) {
|
if (i == ARP_TABLE_SIZE) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: IP address not found in ARP table\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: IP address not found in ARP table\n"));
|
||||||
/* find an available entry */
|
/* find an available (unused or old) entry */
|
||||||
i = find_arp_entry();
|
i = find_arp_entry();
|
||||||
/* bail out if no ARP entries are available */
|
/* bail out if no ARP entries are available */
|
||||||
if (i == ARP_TABLE_SIZE) {
|
if (i == ERR_MEM) {
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n"));
|
LWIP_DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available. Should seldom occur.\n"));
|
||||||
return ERR_MEM;
|
return ERR_MEM;
|
||||||
}
|
}
|
||||||
/* we will now recycle entry i */
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_query: created ARP table entry %u.\n", i));
|
|
||||||
/* i is available, create ARP entry */
|
/* i is available, create ARP entry */
|
||||||
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
|
|
||||||
arp_table[i].ctime = 0;
|
|
||||||
arp_table[i].state = ETHARP_STATE_PENDING;
|
arp_table[i].state = ETHARP_STATE_PENDING;
|
||||||
|
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
|
||||||
|
/* queried address was already in ARP table */
|
||||||
|
} else {
|
||||||
#if ARP_QUEUEING
|
#if ARP_QUEUEING
|
||||||
/* free queued packet, as entry is now invalidated */
|
etharp_enqueue(i, q);
|
||||||
if (arp_table[i].p != NULL) {
|
|
||||||
pbuf_free(arp_table[i].p);
|
|
||||||
arp_table[i].p = NULL;
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet on ARP queue. Should not occur.\n"));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if ARP_QUEUEING
|
|
||||||
/* any pbuf to queue and queue is empty? */
|
|
||||||
if (q != NULL) {
|
|
||||||
/* yield later packets over older packets? */
|
|
||||||
#if ARP_QUEUE_FIRST == 0
|
|
||||||
/* earlier queued packet on this entry? */
|
|
||||||
if (arp_table[i].p != NULL) {
|
|
||||||
pbuf_free(arp_table[i].p);
|
|
||||||
arp_table[i].p = NULL;
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 3, ("etharp_query: dropped packet on ARP queue. Should not occur.\n"));
|
|
||||||
/* fall-through into next if */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* packet can be queued? */
|
|
||||||
if (arp_table[i].p == NULL) {
|
|
||||||
/* copy PBUF_REF referenced payloads into PBUF_RAM */
|
|
||||||
q = pbuf_take(q);
|
|
||||||
/* remember pbuf to queue, if any */
|
|
||||||
arp_table[i].p = q;
|
|
||||||
/* pbufs are queued, increase the reference count */
|
|
||||||
pbuf_ref(q);
|
|
||||||
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: queued packet %p on ARP entry %u.\n", (void *)q, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* ARP request? */
|
/* ARP request? */
|
||||||
if (perform_arp_request)
|
if (perform_arp_request)
|
||||||
{
|
{
|
||||||
|
struct pbuf *p;
|
||||||
/* allocate a pbuf for the outgoing ARP request packet */
|
/* allocate a pbuf for the outgoing ARP request packet */
|
||||||
p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
|
p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
|
||||||
/* could allocate pbuf? */
|
/* could allocate pbuf? */
|
||||||
|
|
|
@ -153,7 +153,7 @@ typedef struct PPPControl_s {
|
||||||
struct vjcompress vjComp; /* Van Jabobsen compression header. */
|
struct vjcompress vjComp; /* Van Jabobsen compression header. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct netif *netif;
|
struct netif netif;
|
||||||
|
|
||||||
struct ppp_addrs addrs;
|
struct ppp_addrs addrs;
|
||||||
|
|
||||||
|
@ -296,7 +296,6 @@ void pppInit(void)
|
||||||
|
|
||||||
for (i = 0; i < NUM_PPP; i++) {
|
for (i = 0; i < NUM_PPP; i++) {
|
||||||
pppControl[i].openFlag = 0;
|
pppControl[i].openFlag = 0;
|
||||||
pppControl[i].netif = NULL;
|
|
||||||
|
|
||||||
subnetMask = htonl(0xffffff00);
|
subnetMask = htonl(0xffffff00);
|
||||||
|
|
||||||
|
@ -1003,10 +1002,8 @@ int sifup(int pd)
|
||||||
st = 0;
|
st = 0;
|
||||||
PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
|
PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
|
||||||
} else {
|
} else {
|
||||||
if(pc->netif)
|
netif_remove(&pc->netif);
|
||||||
netif_remove(pc->netif);
|
if (netif_add(&pc->netif, &pc->addrs.our_ipaddr, &pc->addrs.netmask, &pc->addrs.his_ipaddr, (void *)pd, pppifNetifInit, ip_input)) {
|
||||||
pc->netif = netif_add(&pc->addrs.our_ipaddr, &pc->addrs.netmask, &pc->addrs.his_ipaddr, (void *)pd, pppifNetifInit, ip_input);
|
|
||||||
if(pc->netif) {
|
|
||||||
pc->if_up = 1;
|
pc->if_up = 1;
|
||||||
pc->errCode = PPPERR_NONE;
|
pc->errCode = PPPERR_NONE;
|
||||||
|
|
||||||
|
@ -1046,9 +1043,7 @@ int sifdown(int pd)
|
||||||
PPPDEBUG((LOG_WARNING, "sifdown[%d]: bad parms\n", pd));
|
PPPDEBUG((LOG_WARNING, "sifdown[%d]: bad parms\n", pd));
|
||||||
} else {
|
} else {
|
||||||
pc->if_up = 0;
|
pc->if_up = 0;
|
||||||
if(pc->netif)
|
netif_remove(&pc->netif);
|
||||||
netif_remove(pc->netif);
|
|
||||||
pc->netif = NULL;
|
|
||||||
PPPDEBUG((LOG_DEBUG, "sifdown: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
|
PPPDEBUG((LOG_DEBUG, "sifdown: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
|
||||||
if(pc->linkStatusCB)
|
if(pc->linkStatusCB)
|
||||||
pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);
|
pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);
|
||||||
|
@ -1126,7 +1121,7 @@ int sifdefaultroute(int pd, u32_t l, u32_t g)
|
||||||
st = 0;
|
st = 0;
|
||||||
PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
|
PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
|
||||||
} else {
|
} else {
|
||||||
netif_set_default(pc->netif);
|
netif_set_default(&pc->netif);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */
|
/* TODO: check how PPP handled the netMask, previously not set by ipSetDefault */
|
||||||
|
@ -1324,7 +1319,7 @@ static void pppInput(void *arg)
|
||||||
* pass the result to IP.
|
* pass the result to IP.
|
||||||
*/
|
*/
|
||||||
if (vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) {
|
if (vj_uncompress_tcp(&nb, &pppControl[pd].vjComp) >= 0) {
|
||||||
pppControl[pd].netif->input(nb, pppControl[pd].netif);
|
pppControl[pd].netif.input(nb, &pppControl[pd].netif);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Something's wrong so drop it. */
|
/* Something's wrong so drop it. */
|
||||||
|
@ -1342,7 +1337,7 @@ static void pppInput(void *arg)
|
||||||
* the packet to IP.
|
* the packet to IP.
|
||||||
*/
|
*/
|
||||||
if (vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) {
|
if (vj_uncompress_uncomp(nb, &pppControl[pd].vjComp) >= 0) {
|
||||||
pppControl[pd].netif->input(nb, pppControl[pd].netif);
|
pppControl[pd].netif.input(nb, &pppControl[pd].netif);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Something's wrong so drop it. */
|
/* Something's wrong so drop it. */
|
||||||
|
@ -1356,7 +1351,7 @@ static void pppInput(void *arg)
|
||||||
break;
|
break;
|
||||||
case PPP_IP: /* Internet Protocol */
|
case PPP_IP: /* Internet Protocol */
|
||||||
PPPDEBUG((LOG_INFO, "pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len));
|
PPPDEBUG((LOG_INFO, "pppInput[%d]: ip in pbuf len=%d\n", pd, nb->len));
|
||||||
pppControl[pd].netif->input(nb, pppControl[pd].netif);
|
pppControl[pd].netif.input(nb, &pppControl[pd].netif);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user