Compare commits

...

32 Commits

Author SHA1 Message Date
likewise
a552a9993e Fixed the variable types in inet_ntoa() to comply with API change. 2004-04-26 13:15:26 +00:00
likewise
a74a801f35 Removed the forward declaration of netif. 2004-04-26 13:03:36 +00:00
likewise
7eae414a2f Prepare for 0.7.2 release. Mention 0.7.2 in the Changelog before tagging STABLE-0_7_2. 2004-04-26 10:56:23 +00:00
likewise
84be06c4da Mention the merged fixed from HEAD. 2004-04-23 16:51:13 +00:00
likewise
0912877fd7 Several fixed from HEAD merged in. 2004-04-23 16:16:48 +00:00
likewise
52dd00b217 Removed ip_lookup() like in HEAD. 2004-04-23 15:49:42 +00:00
likewise
2eab21d3cf Set point-to-point flag on SLIP (merged from HEAD). 2004-04-23 15:46:29 +00:00
likewise
a5ce8ca555 Important fix from HEAD merged. 2004-04-23 15:45:53 +00:00
likewise
2c02689d5c Updated with current API (merged from HEAD). 2004-04-23 15:45:15 +00:00
likewise
a52d3548a0 Merged listen_pcb union fix from HEAD. 2004-04-23 15:43:44 +00:00
likewise
3cf8dfa55e Indentation white space fix from HEAD. 2004-04-23 15:42:21 +00:00
likewise
0be1bad42f Merged stats_display_*() fucntions from HEAD. 2004-04-23 15:41:22 +00:00
likewise
d995bc01b3 Removed ip_lookup() like in HEAD. 2004-04-23 15:40:25 +00:00
likewise
d95256817e Merged several cast fixes from HEAD. 2004-04-23 15:38:42 +00:00
likewise
d7c6590b8f Merged udp_sendto() from HEAD. 2004-04-23 15:36:17 +00:00
likewise
70128cf2b9 Mentioned the merge from HEAD. 2004-04-23 15:24:08 +00:00
likewise
a94db2ed71 Merged updated documentation from HEAD. 2004-04-23 15:18:49 +00:00
likewise
a0f45e9d27 Fixed documentation. Updated copyright years. 2004-04-23 15:12:25 +00:00
likewise
31c58725ce Fixed cast in memp_alloc(). Updated copyright years. 2004-04-23 15:11:53 +00:00
likewise
95ac72a0f2 #if LWIP_DHCP fix. 2004-04-23 15:09:24 +00:00
likewise
13386978a1 Updated copyright years. 2004-04-23 15:08:12 +00:00
likewise
95e738a955 #ifdef SO_REUSE to #if SO_REUSE. Updated copyright years. 2004-04-23 14:53:18 +00:00
likewise
3efda64604 Mentioned SO_REUSE #if fix. 2004-03-23 00:40:15 +00:00
likewise
98f546664e Made #ifdef's into #if's for SO_REUSE. 2004-03-23 00:32:36 +00:00
likewise
4e44c2b993 Added missing #if LWIP_DHCP #endif pair. 2004-03-11 19:23:07 +00:00
likewise
30fde02666 Mentioned another ARP fix and named this 0.7.1 for release. 2004-02-05 19:15:24 +00:00
likewise
100eaa9855 Removed updating ARP cache using destination address (which is wrong for requests and replies are unicast anyway). 2004-02-05 19:13:33 +00:00
likewise
3d287a950f Mention ARP fix. 2004-02-05 18:31:57 +00:00
likewise
3aa6a385da Was updating ARP cache from a re-cycled ARP reply pbuf in some cases. Fixed.
Reported on lwip-users by Stephen Chen on february 4th 2004.
2004-02-05 18:29:08 +00:00
likewise
79e66ac841 Savannah now does anonymous CVS access using empty-password SSH. 2004-01-20 13:51:54 +00:00
likewise
1b96391cdf Merged from DEVEL to main. Two TCP fixes and two NULL reference fixes. 2004-01-20 13:23:52 +00:00
uid67528
eed8ea5bc1 Merged from DEVEL. etharp prepared for queueing feature. DHCP fix. 2003-12-28 02:38:51 +00:00
69 changed files with 774 additions and 632 deletions

View File

@@ -1,12 +1,63 @@
TODO
FUTURE
* TODO: Fix unaligned 16-bit access in checksum routine.
* TODO: Fix assumptions on storage sizes wherever we cast.
* TODO: The lwIP source code makes some invalid assumptions on processor
word-length, storage sizes and alignment. See the mailing lists for
problems with exoteric architectures showing these problems.
Neat fixes are needed.
HISTORY
(STABLE-0_7 branch)
(STABLE-0_7_2)
++ Bug fixes:
2004-04-23 Leon Woestenberg <leon.woestenberg@gmx.net>
* memp.c: Fixed cast in mem_malloc().
* sockets.c, tcp_in.c, udp.c: #ifdef SO_REUSE now #if SO_REUSE.
* dhcp.c: #if LWIP_DHCP fixed.
* etharp.c: Fixed the case where the packet that initiates the ARP request
is not queued, and gets lost. Fixed the case where the packets destination
address is already known; we now always queue the packet and perform an ARP
request.
2004-03-23 Leon Woestenberg <leon.woestenberg@gmx.net>
* tcp.c: #ifdef SO_REUSE now #if SO_REUSE.
2004-03-11 Leon Woestenberg <leon.woestenberg@gmx.net>
* dhcp.c: Added missing #if LWIP_DHCP #endif pair.
(STABLE-0_7_1)
++ Bug fixes:
* Fixed updating the ARP cache from a request pbuf that was recycled earlier for reply.
* Removed updating ARP cache using destination address (which is wrong for requests and
does not work for replies as those are unicast anyway).
(STABLE-0_7_0)
++ Bug fixes:
* Fixed TCP bug for SYN_SENT to ESTABLISHED state transition.
* Fixed TCP bug in dequeueing of FIN from out of order segment queue.
* Fixed two possible NULL references in rare cases.
(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)
++ Bug fixes:
* Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic.
* Packets sent from ARP queue had invalid source hardware address.

View File

@@ -272,6 +272,11 @@ level of complexity of UDP, the interface is significantly simpler.
Sets the remote end of the pcb. This function does not generate any
network traffic, but only set the remote address of the pcb.
- err_t udp_disconnect(struct udp_pcb *pcb)
Remove the remote end of the pcb. This function does not generate
any network traffic, but only removes the remote address of the pcb.
- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p)
Sends the pbuf p. The pbuf is not deallocated.

View File

@@ -2,33 +2,70 @@ Daily Use Guide for using Savannah for lwIP
Table of Contents:
1 - Anonymous CVS checkouts and updates (to be elaborated)
1 - Obtaining lwIP from the CVS repository
2 - Committers/developers CVS access using SSH (to be written)
3 - Merging from DEVEL branch to main trunk (stable branch)
4 - How to release lwIP
1 Anonymous CVS checkouts and updates
-------------------------------------
Obtain lwIP from the CVS main trunk (stable)
1 Obtaining lwIP from the CVS repository
----------------------------------------
cvs -d:pserver:anoncvs@subversions.gnu.org:/cvsroot/lwip login
cvs -d:pserver:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout lwip
To perform an anonymous CVS checkout of the main trunk (this is where
bug fixes and incremental enhancements occur), do this:
Or, obtain a specific release as follows:
export CVS_RSH=ssh
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout lwip
cvs -d:pserver:anoncvs@subversions.gnu.org:/cvsroot/lwip login
cvs -d:pserver:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r STABLE-0_6_3 -d lwip-0.6.3 lwip
(If SSH asks about authenticity of the host, you can check the key
fingerprint against http://savannah.nongnu.org/cvs/?group=lwip)
Or, obtain a development branch as follows:
Or, obtain a stable branch (updated with bug fixes only) as follows:
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r STABLE-0_7 -d lwip-0.7 lwip
cvs -d:pserver:anoncvs@subversions.gnu.org:/cvsroot/lwip login
cvs -d:pserver:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r DEVEL -d lwip-DEVEL lwip
Or, obtain a specific (fixed) release as follows:
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r STABLE-0_7_0 -d lwip-0.7.0 lwip
Or, obtain a development branch (considered unstable!) as follows:
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip checkout -r DEVEL -d lwip-DEVEL lwip
3 Committers/developers CVS access using SSH
--------------------------------------------
The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption.
As such, CVS commits to the server occur through a SSH tunnel for project members.
To create a SSH2 key pair in UNIX-like environments, do this:
ssh-keygen -t dsa
Under Windows, a recommended SSH client is "PuTTY", freely available with good
documentation and a graphic user interface. Use its key generator.
Now paste the id_dsa.pub contents into your Savannah account public key list. Wait
a while so that Savannah can update its configuration (This can take minutes).
Try to login using SSH:
ssh -v your_login@subversions.gnu.org
If it tells you:
Authenticating with public key "your_key_name"...
Server refused to allocate pty
then you could login; Savannah refuses to give you a shell - which is OK, as we
are allowed to use SSH for CVS only. Now, you should be able to do this:
export CVS_RSH=ssh
cvs -d:ext:your_login@subversions.gnu.org:/cvsroot/lwip checkout lwip
after which you can edit your local files with bug fixes or new features and
commit them. Make sure you know what you are doing when using CVS to make
changes on the repository. If in doubt, ask on the lwip-members mailing list.
3 Merging from DEVEL branch to main trunk (stable)
---------------------------------------------------------
--------------------------------------------------
Merging is a delicate process in CVS and requires the
following disciplined steps in order to prevent conflicts
@@ -51,6 +88,9 @@ cvs update -P -jmerged_from_DEVEL_to_main -jDEVEL
(This will apply the changes between 'merged_from_DEVEL_to_main'
and 'DEVEL' to your work set of files)
We can now commit the merge result.
cvs commit -R -m "Merged from DEVEL to main."
If this worked out OK, we now move the tag in the DEVEL branch
to this merge point, so we can use this point for future merges:
@@ -66,8 +106,8 @@ Login CVS using pserver authentication, then export a clean copy of the
tagged tree. Export is similar to a checkout, except that the CVS metadata
is not created locally.
cvs -d:pserver:anoncvs@subversions.gnu.org:/cvsroot/lwip login
cvs -d:pserver:anoncvs@subversions.gnu.org:/cvsroot/lwip export -r STABLE-0_6_3 -d lwip-0.6.3 lwip
export CVS_RSH=ssh
cvs -d:ext:anoncvs@subversions.gnu.org:/cvsroot/lwip export -r STABLE-0_6_3 -d lwip-0.6.3 lwip
Archive this directory using tar, gzip'd, bzip2'd and zip'd.

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -993,7 +993,7 @@ int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *opt
/* UNIMPL case SO_SNDBUF: */
/* UNIMPL case SO_RCVLOWAT: */
/* UNIMPL case SO_SNDLOWAT: */
#ifdef SO_REUSE
#if SO_REUSE
case SO_REUSEADDR:
case SO_REUSEPORT:
#endif /* SO_REUSE */
@@ -1079,7 +1079,7 @@ int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *opt
/* UNIMPL case SO_DONTROUTE: */
case SO_KEEPALIVE:
/* UNIMPL case SO_OOBINCLUDE: */
#ifdef SO_REUSE
#if SO_REUSE
case SO_REUSEADDR:
case SO_REUSEPORT:
#endif /* SO_REUSE */
@@ -1182,7 +1182,7 @@ int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_
/* UNIMPL case SO_SNDBUF: */
/* UNIMPL case SO_RCVLOWAT: */
/* UNIMPL case SO_SNDLOWAT: */
#ifdef SO_REUSE
#if SO_REUSE
case SO_REUSEADDR:
case SO_REUSEPORT:
#endif /* SO_REUSE */
@@ -1264,7 +1264,7 @@ int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_
/* UNIMPL case SO_DONTROUTE: */
case SO_KEEPALIVE:
/* UNIMPL case SO_OOBINCLUDE: */
#ifdef SO_REUSE
#if SO_REUSE
case SO_REUSEADDR:
case SO_REUSEPORT:
#endif /* SO_REUSE */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -6,8 +6,8 @@
/*
*
* Copyright (c) 2001-2003 Leon Woestenberg <leon.woestenberg@gmx.net>
* Copyright (c) 2001-2003 Axon Digital Design B.V., The Netherlands.
* Copyright (c) 2001-2004 Leon Woestenberg <leon.woestenberg@gmx.net>
* Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -70,15 +70,17 @@
#include "lwip/stats.h"
#include "lwip/mem.h"
#include "lwip/udp.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/inet.h"
#include "lwip/ip_addr.h"
#include "netif/etharp.h"
#include "lwip/sys.h"
#include "lwip/opt.h"
#include "lwip/dhcp.h"
#if LWIP_DHCP /* don't build if not configured for use in lwipopt.h */
/** global transaction identifier, must be
* unique for each DHCP request. */
static u32_t xid = 0xABCD0000;
@@ -192,6 +194,7 @@ static void dhcp_handle_offer(struct netif *netif)
/* remember offered address */
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));
dhcp_select(netif);
}
}
@@ -646,6 +649,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_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);
/* resize pbuf to reflect true size of options */
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
@@ -702,15 +708,9 @@ static err_t dhcp_discover(struct netif *netif)
/* set receive callback function with netif as user data */
udp_recv(dhcp->pcb, dhcp_recv, netif);
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: send()ing\n"));
udp_send(dhcp->pcb, dhcp->p_out);
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: bind()ing\n"));
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: connect()ing\n"));
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n"));
udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE, ("dhcp_discover: deleting()ing\n"));
dhcp_delete_request(netif);
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_discover: SELECTING\n"));
@@ -877,10 +877,11 @@ static err_t dhcp_rebind(struct netif *netif)
pbuf_realloc(dhcp->p_out, sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len);
/* set remote IP association to any DHCP server */
udp_bind(dhcp->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
udp_connect(dhcp->pcb, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
udp_send(dhcp->pcb, dhcp->p_out);
udp_connect(dhcp->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
/* broadcast to server */
udp_sendto(dhcp->pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT);
dhcp_delete_request(netif);
LWIP_DEBUGF(DHCP_DEBUG | DBG_TRACE | DBG_STATE, ("dhcp_rebind: REBINDING\n"));
} else {
@@ -1414,3 +1415,5 @@ static u32_t dhcp_get_option_long(u8_t *ptr)
LWIP_DEBUGF(DHCP_DEBUG, ("option long value=%lu\n", value));
return value;
}
#endif /* LWIP_DHCP */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -300,18 +300,19 @@ inet_chksum_pbuf(struct pbuf *p)
/* Convert numeric IP address into decimal dotted ASCII representation.
* returns ptr to static buffer; not reentrant!
*/
u8_t *inet_ntoa(u32_t addr)
char *inet_ntoa(struct in_addr addr)
{
static u8_t str[16];
u8_t inv[3];
u8_t *rp;
u8_t *ap;
static char str[16];
u32_t s_addr = addr.s_addr;
char inv[3];
char *rp;
char *ap;
u8_t rem;
u8_t n;
u8_t i;
rp = str;
ap = (u8_t *)&addr;
ap = (u8_t *)&s_addr;
for(n = 0; n < 4; n++) {
i = 0;
do {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -80,7 +80,6 @@ icmp_input(struct pbuf *p, struct netif *inp)
return;
}
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n"));
LWIP_DEBUGF(DEMO_DEBUG, ("Pong!\n"));
if (p->tot_len < sizeof(struct icmp_echo_hdr)) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n"));
pbuf_free(p);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -73,57 +73,6 @@ ip_init(void)
{
}
/* ip_lookup:
*
* An experimental feature that will be changed in future versions. Do
* not depend on it yet...
*/
#ifdef LWIP_DEBUG
u8_t
ip_lookup(void *header, struct netif *inp)
{
struct ip_hdr *iphdr;
iphdr = header;
/* not IP v4? */
if (IPH_V(iphdr) != 4) {
return 0;
}
/* Immediately accept/decline packets that are fragments or has
options. */
#if IP_REASSEMBLY == 0
/* if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) {
return 0;
}*/
#endif /* IP_REASSEMBLY == 0 */
#if IP_OPTIONS == 0
if (IPH_HL(iphdr) != 5) {
return 0;
}
#endif /* IP_OPTIONS == 0 */
switch (IPH_PROTO(iphdr)) {
#if LWIP_UDP
case IP_PROTO_UDP:
case IP_PROTO_UDPLITE:
return udp_lookup(iphdr, inp);
#endif /* LWIP_UDP */
#if LWIP_TCP
case IP_PROTO_TCP:
return 1;
#endif /* LWIP_TCP */
case IP_PROTO_ICMP:
return 1;
default:
return 0;
}
}
#endif /* LWIP_DEBUG */
/* ip_route:
*
* Finds the appropriate network interface for a given IP address. It

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -54,6 +54,8 @@ struct mem {
u16_t used;
#elif MEM_ALIGNMENT == 4
u32_t used;
#elif MEM_ALIGNMENT == 8
u64_t used;
#else
#error "unhandled MEM_ALIGNMENT size"
#endif /* MEM_ALIGNMENT */
@@ -292,7 +294,7 @@ mem_malloc(mem_size_t size)
}
sys_sem_signal(mem_sem);
LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.",
(u32_t)mem + SIZEOF_STRUCT_MEM + size <= (u32_t)ram_end);
(mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end);
LWIP_ASSERT("mem_malloc: allocated memory properly aligned.",
(unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0);
return (u8_t *)mem + SIZEOF_STRUCT_MEM;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -120,7 +120,7 @@ static u8_t memp_memory[(MEMP_NUM_PBUF *
static sys_sem_t mutex;
#endif
#ifndef LWIP_NOASSERT
#if MEMP_SANITY_CHECK
static int
memp_sanity(void)
{
@@ -140,7 +140,7 @@ memp_sanity(void)
}
return 1;
}
#endif /* LWIP_DEBUG */
#endif /* MEMP_SANITY_CHECK*/
void
memp_init(void)
@@ -217,11 +217,9 @@ memp_malloc(memp_t type)
sys_sem_signal(mutex);
#endif /* SYS_LIGHTWEIGHT_PROT */
LWIP_ASSERT("memp_malloc: memp properly aligned",
((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
((mem_ptr_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
/* initialize memp memory with zeroes */
memset(mem, 0, memp_sizes[type]);
return mem;
} else {
LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %d\n", type));
@@ -263,7 +261,9 @@ memp_free(memp_t type, void *mem)
memp->next = memp_tab[type];
memp_tab[type] = memp;
#if MEMP_SANITY_CHECK
LWIP_ASSERT("memp sanity", memp_sanity());
#endif
#if SYS_LIGHTWEIGHT_PROT
SYS_ARCH_UNPROTECT(old_level);

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -39,44 +39,37 @@
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/netif.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/tcp.h"
struct netif *netif_list = NULL;
struct netif *netif_default = NULL;
/**
* Add a network interface to the list of lwIP netifs.
*
* @param netif a pre-allocated netif structure
* @param ipaddr IP address for the new netif
* @param netmask network mask for the new netif
* @param gw default gateway IP address for the new netif
* @param state opaque data passed to the new netif
* @param init callback function that initializes the interface
* @param input callback function that...
* @param input callback function that is called to pass
* ingress packets up in the protocol layer stack.
*
* @return netif, or NULL if failed.
*/
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,
void *state,
err_t (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, struct netif *netif))
{
struct netif *netif;
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
/* netif not under DHCP control by default */
netif->dhcp = NULL;
@@ -90,7 +83,6 @@ netif_add(struct ip_addr *ipaddr, struct ip_addr *netmask,
/* call user specified initialization function for netif */
if (init(netif) != ERR_OK) {
mem_free(netif);
return NULL;
}
@@ -142,7 +134,6 @@ void netif_remove(struct netif * netif)
/* reset default netif */
netif_default = NULL;
LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") );
mem_free( netif );
}
struct netif *
@@ -181,7 +172,7 @@ netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
/* address is actually being changed? */
if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
{
extern struct tcp_pcb *tcp_active_pcbs;
/* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));
pcb = tcp_active_pcbs;
while (pcb != NULL) {
@@ -196,7 +187,7 @@ netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
pcb = pcb->next;
}
}
for (lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
/* PCB bound to current local interface address? */
if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {
/* The PCB is listening to the old ipaddr and

View File

@@ -28,7 +28,7 @@
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -100,7 +100,7 @@ pbuf_init(void)
u16_t i;
pbuf_pool = (struct pbuf *)&pbuf_pool_memory[0];
LWIP_ASSERT("pbuf_init: pool aligned", (long)pbuf_pool % MEM_ALIGNMENT == 0);
LWIP_ASSERT("pbuf_init: pool aligned", (mem_ptr_t)pbuf_pool % MEM_ALIGNMENT == 0);
#if PBUF_STATS
lwip_stats.pbuf.avail = PBUF_POOL_SIZE;
@@ -254,7 +254,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
/* make the payload pointer point 'offset' bytes into pbuf data memory */
p->payload = MEM_ALIGN((void *)((u8_t *)p + (sizeof(struct pbuf) + offset)));
LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned",
((u32_t)p->payload % MEM_ALIGNMENT) == 0);
((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
/* the total length of the pbuf chain is the requested size */
p->tot_len = length;
/* set the length of the first pbuf in the chain */
@@ -290,7 +290,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
q->len = rem_len > PBUF_POOL_BUFSIZE? PBUF_POOL_BUFSIZE: rem_len;
q->payload = (void *)((u8_t *)q + sizeof(struct pbuf));
LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned",
((u32_t)q->payload % MEM_ALIGNMENT) == 0);
((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0);
q->ref = 1;
/* calculate remaining length to be allocated */
rem_len -= q->len;
@@ -314,7 +314,7 @@ pbuf_alloc(pbuf_layer l, u16_t length, pbuf_flag flag)
p->flags = PBUF_FLAG_RAM;
LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned",
((u32_t)p->payload % MEM_ALIGNMENT) == 0);
((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0);
break;
/* pbuf references existing (static constant) ROM payload? */
case PBUF_ROM:
@@ -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
* zero, the pbuf is deallocated.
*
* For a pbuf chain, this is repeated for each pbuf in the chain, up to the
* pbuf which has a non-zero reference count after decrementing.
* (This might be the whole chain.)
* For a pbuf chain, this is repeated for each pbuf in the chain,
* up to a pbuf which has a non-zero reference count after
* 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.
*
* @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
* that refer to the pbuf (or into the pbuf).
*
* @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
* 3->3->3 becomes 2->3->3
* 1->1->2 becomes ....->1
* 1->1->2 becomes ......1
* 2->1->1 becomes 1->1->1
* 1->1->1 becomes .......
*
@@ -636,11 +640,12 @@ pbuf_ref(struct pbuf *p)
/**
* 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()
*/
void
@@ -650,16 +655,14 @@ pbuf_cat(struct pbuf *h, struct pbuf *t)
LWIP_ASSERT("h != NULL", h != NULL);
LWIP_ASSERT("t != NULL", t != NULL);
if (t == NULL)
return;
if ((h == NULL) || (t == NULL)) return;
/* proceed to last pbuf of chain */
for (p = h; p->next != NULL; p = p->next) {
/* add total length of second chain to all totals of first chain */
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);
/* add total length of second chain to last pbuf total of first chain */
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.
* It's the same as pbuf_cat with the addition that it increases the reference count
* of the tail.
* Chain two pbufs (or pbuf chains) together.
*
* 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 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 ->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_cat(h, t);
/* t is now referenced to one more time */
/* t is now referenced by h */
pbuf_ref(t);
LWIP_DEBUGF(PBUF_DEBUG | DBG_FRESH | 2, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t));
}

View File

@@ -4,7 +4,7 @@
*
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -47,8 +47,8 @@
#include "lwip/def.h"
#include "lwip/memp.h"
#include "lwip/inet.h"
#include "lwip/netif.h"
#include "lwip/ip_addr.h"
#include "lwip/netif.h"
#include "lwip/raw.h"
#include "lwip/stats.h"

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -47,5 +47,68 @@ stats_init(void)
{
memset(&lwip_stats, 0, sizeof(struct stats_));
}
#if LWIP_STATS_DISPLAY
void
stats_display_proto(struct stats_proto *proto, char *name)
{
LWIP_PLATFORM_DIAG(("\n%s\n\t", name));
LWIP_PLATFORM_DIAG(("xmit: %d\n\t", proto->xmit));
LWIP_PLATFORM_DIAG(("rexmit: %d\n\t", proto->rexmit));
LWIP_PLATFORM_DIAG(("recv: %d\n\t", proto->recv));
LWIP_PLATFORM_DIAG(("fw: %d\n\t", proto->fw));
LWIP_PLATFORM_DIAG(("drop: %d\n\t", proto->drop));
LWIP_PLATFORM_DIAG(("chkerr: %d\n\t", proto->chkerr));
LWIP_PLATFORM_DIAG(("lenerr: %d\n\t", proto->lenerr));
LWIP_PLATFORM_DIAG(("memerr: %d\n\t", proto->memerr));
LWIP_PLATFORM_DIAG(("rterr: %d\n\t", proto->rterr));
LWIP_PLATFORM_DIAG(("proterr: %d\n\t", proto->proterr));
LWIP_PLATFORM_DIAG(("opterr: %d\n\t", proto->opterr));
LWIP_PLATFORM_DIAG(("err: %d\n\t", proto->err));
LWIP_PLATFORM_DIAG(("cachehit: %d\n", proto->cachehit));
}
void
stats_display_pbuf(struct stats_pbuf *pbuf)
{
LWIP_PLATFORM_DIAG(("\nPBUF\n\t"));
LWIP_PLATFORM_DIAG(("avail: %d\n\t", pbuf->avail));
LWIP_PLATFORM_DIAG(("used: %d\n\t", pbuf->used));
LWIP_PLATFORM_DIAG(("max: %d\n\t", pbuf->max));
LWIP_PLATFORM_DIAG(("err: %d\n\t", pbuf->err));
LWIP_PLATFORM_DIAG(("alloc_locked: %d\n\t", pbuf->alloc_locked));
LWIP_PLATFORM_DIAG(("refresh_locked: %d\n", pbuf->refresh_locked));
}
void
stats_display_mem(struct stats_mem *mem, char *name)
{
LWIP_PLATFORM_DIAG(("\n MEM %s\n\t", name));
LWIP_PLATFORM_DIAG(("avail: %d\n\t", mem->avail));
LWIP_PLATFORM_DIAG(("used: %d\n\t", mem->used));
LWIP_PLATFORM_DIAG(("max: %d\n\t", mem->max));
LWIP_PLATFORM_DIAG(("err: %d\n", mem->err));
}
void
stats_display(void)
{
int i;
char * memp_names[] = {"PBUF", "RAW_PCB", "UDP_PCB", "TCP_PCB", "TCP_PCB_LISTEN",
"TCP_SEG", "NETBUF", "NETCONN", "API_MSG", "TCP_MSG", "TIMEOUT"};
stats_display_proto(&lwip_stats.link, "LINK");
stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG");
stats_display_proto(&lwip_stats.ip, "IP");
stats_display_proto(&lwip_stats.icmp, "ICMP");
stats_display_proto(&lwip_stats.udp, "UDP");
stats_display_proto(&lwip_stats.tcp, "TCP");
stats_display_pbuf(&lwip_stats.pbuf);
stats_display_mem(&lwip_stats.mem, "HEAP");
for (i = 0; i < MEMP_MAX; i++) {
stats_display_mem(&lwip_stats.memp[i], memp_names[i]);
}
}
#endif /* LWIP_STATS_DISPLAY */
#endif /* LWIP_STATS */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -174,6 +174,7 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
(void *)timeout, msecs, (void *)h, (void *)arg));
LWIP_ASSERT("sys_timeout: timeouts != NULL", timeouts != NULL);
if (timeouts->next == NULL) {
timeouts->next = timeout;
return;
@@ -186,14 +187,13 @@ sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
} else {
for(t = timeouts->next; t != NULL; t = t->next) {
timeout->time -= t->time;
if (t->next == NULL ||
t->next->time > timeout->time) {
if (t->next != NULL) {
t->next->time -= timeout->time;
}
timeout->next = t->next;
t->next = timeout;
break;
if (t->next == NULL || t->next->time > timeout->time) {
if (t->next != NULL) {
t->next->time -= timeout->time;
}
timeout->next = t->next;
t->next = timeout;
break;
}
}
}

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -62,7 +62,9 @@ const u8_t tcp_backoff[13] =
{ 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7};
/* The TCP PCB lists. */
struct tcp_pcb_listen *tcp_listen_pcbs; /* List of all TCP PCBs in LISTEN state. */
/* List of all TCP PCBs in LISTEN state. */
union tcp_listen_pcbs_t tcp_listen_pcbs;
struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
state in which they accept or send
data. */
@@ -85,7 +87,7 @@ void
tcp_init(void)
{
/* Clear globals. */
tcp_listen_pcbs = NULL;
tcp_listen_pcbs.listen_pcbs = NULL;
tcp_active_pcbs = NULL;
tcp_tw_pcbs = NULL;
tcp_tmp_pcb = NULL;
@@ -136,7 +138,7 @@ tcp_close(struct tcp_pcb *pcb)
switch (pcb->state) {
case LISTEN:
err = ERR_OK;
tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs, pcb);
tcp_pcb_remove((struct tcp_pcb **)&tcp_listen_pcbs.pcbs, pcb);
memp_free(MEMP_TCP_PCB_LISTEN, pcb);
pcb = NULL;
break;
@@ -147,11 +149,6 @@ tcp_close(struct tcp_pcb *pcb)
pcb = NULL;
break;
case SYN_RCVD:
err = tcp_send_ctrl(pcb, TCP_FIN);
if (err == ERR_OK) {
pcb->state = FIN_WAIT_1;
}
break;
case ESTABLISHED:
err = tcp_send_ctrl(pcb, TCP_FIN);
if (err == ERR_OK) {
@@ -247,16 +244,16 @@ err_t
tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
{
struct tcp_pcb *cpcb;
#ifdef SO_REUSE
#if SO_REUSE
int reuse_port_all_set = 1;
#endif /* SO_REUSE */
if (port == 0) {
port = tcp_new_port();
}
#ifndef SO_REUSE
#if SO_REUSE == 0
/* Check if the address already is in use. */
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs;
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs;
cpcb != NULL; cpcb = cpcb->next) {
if (cpcb->local_port == port) {
if (ip_addr_isany(&(cpcb->local_ip)) ||
@@ -289,7 +286,7 @@ tcp_bind(struct tcp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
When the two options aren't set and specified port is already bound, ERR_USE is returned saying that
address is already in use. */
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs; cpcb != NULL; cpcb = cpcb->next) {
for(cpcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; cpcb != NULL; cpcb = cpcb->next) {
if(cpcb->local_port == port) {
if(ip_addr_cmp(&(cpcb->local_ip), ipaddr)) {
if(pcb->so_options & SOF_REUSEPORT) {
@@ -426,7 +423,7 @@ tcp_listen(struct tcp_pcb *pcb)
#if LWIP_CALLBACK_API
lpcb->accept = tcp_accept_null;
#endif /* LWIP_CALLBACK_API */
TCP_REG(&tcp_listen_pcbs, lpcb);
TCP_REG(&tcp_listen_pcbs.listen_pcbs, lpcb);
return (struct tcp_pcb *)lpcb;
}
@@ -449,6 +446,16 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
}
if (!(pcb->flags & TF_ACK_DELAY) &&
!(pcb->flags & TF_ACK_NOW)) {
/*
* We send an ACK here (if one is not already pending, hence
* the above tests) as tcp_recved() implies that the application
* has processed some data, and so we can open the receiver's
* window to allow more to be transmitted. This could result in
* two ACKs being sent for each received packet in some limited cases
* (where the application is only receiving data, and is slow to
* process it) but it is necessary to guarantee that the sender can
* continue to transmit.
*/
tcp_ack(pcb);
}
@@ -488,7 +495,7 @@ tcp_new_port(void)
goto again;
}
}
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs; pcb != NULL; pcb = pcb->next) {
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
if (pcb->local_port == port) {
goto again;
}
@@ -1082,7 +1089,6 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n"));
#if TCP_DEBUG
if (pcb->unsent != NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n"));
}
@@ -1093,18 +1099,13 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
if (pcb->ooseq != NULL) {
LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n"));
}
#endif
#endif /* TCP_DEBUG */
tcp_segs_free(pcb->unsent);
#if TCP_QUEUE_OOSEQ
tcp_segs_free(pcb->ooseq);
pcb->ooseq = NULL;
#endif /* TCP_QUEUE_OOSEQ */
tcp_segs_free(pcb->unsent);
tcp_segs_free(pcb->unacked);
pcb->unacked = pcb->unsent =
#if TCP_QUEUE_OOSEQ
pcb->ooseq =
#endif /* TCP_QUEUE_OOSEQ */
NULL;
pcb->unacked = pcb->unsent = NULL;
}
}
@@ -1264,7 +1265,7 @@ tcp_debug_print_pcbs(void)
tcp_debug_print_state(pcb->state);
}
LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n"));
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs; pcb != NULL; pcb = pcb->next) {
for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) {
LWIP_DEBUGF(TCP_DEBUG, ("Local port %u, foreign port %u snd_nxt %lu rcv_nxt %lu ",
pcb->local_port, pcb->remote_port,
pcb->snd_nxt, pcb->rcv_nxt));

View File

@@ -5,7 +5,7 @@
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -102,7 +102,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
u8_t hdrlen;
err_t err;
#ifdef SO_REUSE
#if SO_REUSE
struct tcp_pcb *pcb_temp;
int reuse = 0;
int reuse_port = 0;
@@ -153,7 +153,6 @@ tcp_input(struct pbuf *p, struct netif *inp)
return;
}
/* Move the payload pointer in the pbuf so that it points to the
TCP data instead of the TCP header. */
hdrlen = TCPH_HDRLEN(tcphdr);
@@ -173,7 +172,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
for an active connection. */
prev = NULL;
#ifdef SO_REUSE
#if SO_REUSE
pcb_temp = tcp_active_pcbs;
again_1:
@@ -191,7 +190,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src)) &&
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest))) {
#ifdef SO_REUSE
#if SO_REUSE
if(pcb->so_options & SOF_REUSEPORT) {
if(reuse) {
/* We processed one PCB already */
@@ -255,7 +254,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
/* Finally, if we still did not get a match, we check all PCBs that
are LISTENing for incoming connections. */
prev = NULL;
for(lpcb = tcp_listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
if ((ip_addr_isany(&(lpcb->local_ip)) ||
ip_addr_cmp(&(lpcb->local_ip), &(iphdr->dest))) &&
lpcb->local_port == tcphdr->dest) {
@@ -265,9 +264,9 @@ tcp_input(struct pbuf *p, struct netif *inp)
if (prev != NULL) {
((struct tcp_pcb_listen *)prev)->next = lpcb->next;
/* our successor is the remainder of the listening list */
lpcb->next = tcp_listen_pcbs;
lpcb->next = tcp_listen_pcbs.listen_pcbs;
/* put this listening pcb at the head of the listening list */
tcp_listen_pcbs = lpcb;
tcp_listen_pcbs.listen_pcbs = lpcb;
}
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n"));
@@ -361,7 +360,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
tcp_debug_print_state(pcb->state);
#endif /* TCP_DEBUG */
#endif /* TCP_INPUT_DEBUG */
#ifdef SO_REUSE
#if SO_REUSE
/* First socket should receive now */
if(reuse_port) {
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: searching next PCB.\n"));
@@ -373,7 +372,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
#endif /* SO_REUSE */
} else {
#ifdef SO_REUSE
#if SO_REUSE
if(reuse) {
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: freeing PBUF with reference counter set to %i\n", p->ref));
pbuf_free(p);
@@ -392,7 +391,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
}
pbuf_free(p);
}
#ifdef SO_REUSE
#if SO_REUSE
end:
#endif /* SO_REUSE */
LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane());
@@ -421,7 +420,7 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
&(iphdr->dest), &(iphdr->src),
tcphdr->dest, tcphdr->src);
} else if (flags & TCP_SYN) {
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection request %u -> %u.\n", tcphdr->src, tcphdr->dest));
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %u -> %u.\n", tcphdr->src, tcphdr->dest));
npcb = tcp_alloc(pcb->prio);
/* If a new PCB could not be created (probably due to lack of memory),
we don't do anything, but rely on the sender will retransmit the
@@ -540,8 +539,8 @@ tcp_process(struct tcp_pcb *pcb)
case SYN_SENT:
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %lu pcb->snd_nxt %lu unacked %lu\n", ackno,
pcb->snd_nxt, ntohl(pcb->unacked->tcphdr->seqno)));
if (flags & (TCP_ACK | TCP_SYN) &&
ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
if ((flags & TCP_ACK) && (flags & TCP_SYN)
&& ackno == ntohl(pcb->unacked->tcphdr->seqno) + 1) {
pcb->rcv_nxt = seqno + 1;
pcb->lastack = ackno;
pcb->snd_wnd = tcphdr->wnd;
@@ -569,7 +568,7 @@ tcp_process(struct tcp_pcb *pcb)
if (TCP_SEQ_LT(pcb->lastack, ackno) &&
TCP_SEQ_LEQ(ackno, pcb->snd_nxt)) {
pcb->state = ESTABLISHED;
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
#if LWIP_CALLBACK_API
LWIP_ASSERT("pcb->accept != NULL", pcb->accept != NULL);
#endif
@@ -601,7 +600,7 @@ tcp_process(struct tcp_pcb *pcb)
tcp_receive(pcb);
if (flags & TCP_FIN) {
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
LWIP_DEBUGF(DEMO_DEBUG,
LWIP_DEBUGF(TCP_DEBUG,
("TCP connection closed %d -> %d.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
tcp_ack_now(pcb);
tcp_pcb_purge(pcb);
@@ -619,7 +618,7 @@ tcp_process(struct tcp_pcb *pcb)
case FIN_WAIT_2:
tcp_receive(pcb);
if (flags & TCP_FIN) {
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
tcp_ack_now(pcb);
tcp_pcb_purge(pcb);
TCP_RMV(&tcp_active_pcbs, pcb);
@@ -630,7 +629,7 @@ tcp_process(struct tcp_pcb *pcb)
case CLOSING:
tcp_receive(pcb);
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
tcp_ack_now(pcb);
tcp_pcb_purge(pcb);
TCP_RMV(&tcp_active_pcbs, pcb);
@@ -641,7 +640,7 @@ tcp_process(struct tcp_pcb *pcb)
case LAST_ACK:
tcp_receive(pcb);
if (flags & TCP_ACK && ackno == pcb->snd_nxt) {
LWIP_DEBUGF(DEMO_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed %u -> %u.\n", inseg.tcphdr->src, inseg.tcphdr->dest));
pcb->state = CLOSED;
recv_flags = TF_CLOSED;
}
@@ -1021,7 +1020,7 @@ tcp_receive(struct tcp_pcb *pcb)
}
cseg->p = NULL;
}
if (flags & TCP_FIN) {
if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) {
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n"));
recv_flags = TF_GOT_FIN;
}

View File

@@ -4,7 +4,7 @@
* Transmission Control Protocol, outgoing traffic
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -63,8 +63,6 @@
/* Forward declarations.*/
static void tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb);
err_t
tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
{
@@ -72,6 +70,14 @@ tcp_send_ctrl(struct tcp_pcb *pcb, u8_t flags)
}
/*
* NB. tcp_write() enqueues data for sending, but does not send it
* straight away. It waits in the expectation of more data being sent
* soon (as it can send them more efficiently by combining them
* together). To prompt the system to send data now, call
* tcp_output() after calling tcp_write().
*/
err_t
tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t copy)
{
@@ -133,7 +139,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
pcb->unsent != NULL);
}
seg = NULL;
seg = useg = NULL;
seglen = 0;
/* First, break up the data into segments and tuck them together in
@@ -158,6 +164,7 @@ tcp_enqueue(struct tcp_pcb *pcb, void *arg, u16_t len,
}
else {
/* Attach the segment to the end of the queued segments. */
LWIP_ASSERT("useg != NULL", useg != NULL);
useg->next = seg;
useg = seg;
}
@@ -402,7 +409,6 @@ tcp_output(struct tcp_pcb *pcb)
tcphdr->chksum = inet_chksum_pseudo(p, &(pcb->local_ip), &(pcb->remote_ip),
IP_PROTO_TCP, p->tot_len);
ip_output(p, &(pcb->local_ip), &(pcb->remote_ip), pcb->ttl, pcb->tos,
IP_PROTO_TCP);
pbuf_free(p);

View File

@@ -4,7 +4,7 @@
*
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -71,76 +71,6 @@ udp_init(void)
udp_pcbs = pcb_cache = NULL;
}
/* udp_lookup:
*
* An experimental feature that will be changed in future versions. Do
* not depend on it yet...
*/
#ifdef LWIP_DEBUG
u8_t
udp_lookup(struct ip_hdr *iphdr, struct netif *inp)
{
struct udp_pcb *pcb;
struct udp_hdr *udphdr;
u16_t src, dest;
PERF_START;
(void)inp;
udphdr = (struct udp_hdr *)(u8_t *)iphdr + IPH_HL(iphdr) * 4;
src = ntohs(udphdr->src);
dest = ntohs(udphdr->dest);
pcb = pcb_cache;
if (pcb != NULL &&
pcb->remote_port == src &&
pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
return 1;
}
else {
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
if (pcb->remote_port == src &&
pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
pcb_cache = pcb;
break;
}
}
if (pcb == NULL) {
for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) {
if (pcb->remote_port == 0 &&
pcb->local_port == dest &&
(ip_addr_isany(&pcb->remote_ip) ||
ip_addr_cmp(&(pcb->remote_ip), &(iphdr->src))) &&
(ip_addr_isany(&pcb->local_ip) ||
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
break;
}
}
}
}
PERF_STOP("udp_lookup");
if (pcb != NULL) {
return 1;
}
else {
return 1;
}
}
#endif /* LWIP_DEBUG */
/**
* Process an incoming UDP datagram.
*
@@ -159,7 +89,7 @@ udp_input(struct pbuf *p, struct netif *inp)
struct ip_hdr *iphdr;
u16_t src, dest;
#ifdef SO_REUSE
#if SO_REUSE
struct udp_pcb *pcb_temp;
int reuse = 0;
int reuse_port_1 = 0;
@@ -198,7 +128,7 @@ udp_input(struct pbuf *p, struct netif *inp)
ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src), ntohs(udphdr->src)));
#ifdef SO_REUSE
#if SO_REUSE
pcb_temp = udp_pcbs;
again_1:
@@ -228,7 +158,7 @@ udp_input(struct pbuf *p, struct netif *inp)
(ip_addr_isany(&pcb->local_ip) ||
/* PCB local IP address matches UDP destination IP address? */
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
#ifdef SO_REUSE
#if SO_REUSE
if(pcb->so_options & SOF_REUSEPORT) {
if(reuse) {
/* We processed one PCB already */
@@ -257,7 +187,7 @@ udp_input(struct pbuf *p, struct netif *inp)
/* Iterate through the UDP PCB list for a pcb that matches
the local address. */
#ifdef SO_REUSE
#if SO_REUSE
pcb_temp = udp_pcbs;
again_2:
@@ -279,7 +209,7 @@ udp_input(struct pbuf *p, struct netif *inp)
(ip_addr_isany(&pcb->local_ip) ||
/* ...matching interface address? */
ip_addr_cmp(&(pcb->local_ip), &(iphdr->dest)))) {
#ifdef SO_REUSE
#if SO_REUSE
if(pcb->so_options & SOF_REUSEPORT) {
if(reuse) {
/* We processed one PCB already */
@@ -345,7 +275,7 @@ udp_input(struct pbuf *p, struct netif *inp)
if (pcb != NULL) {
snmp_inc_udpindatagrams();
pcb->recv(pcb->recv_arg, pcb, p, &(iphdr->src), src);
#ifdef SO_REUSE
#if SO_REUSE
/* First socket should receive now */
if(reuse_port_1 || reuse_port_2) {
/* We want to search on next socket after receiving */
@@ -365,7 +295,7 @@ udp_input(struct pbuf *p, struct netif *inp)
}
#endif /* SO_REUSE */
} else {
#ifdef SO_REUSE
#if SO_REUSE
if(reuse) {
LWIP_DEBUGF(UDP_DEBUG, ("udp_input: freeing PBUF with reference counter set to %i\n", p->ref));
pbuf_free(p);
@@ -375,7 +305,7 @@ udp_input(struct pbuf *p, struct netif *inp)
LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE, ("udp_input: not for us.\n"));
/* No match was found, send ICMP destination port unreachable unless
destination address was broadcast/multicast. */
destination address was broadcast/multicast. */
if (!ip_addr_isbroadcast(&iphdr->dest, &inp->netmask) &&
!ip_addr_ismulticast(&iphdr->dest)) {
@@ -396,6 +326,46 @@ udp_input(struct pbuf *p, struct netif *inp)
PERF_STOP("udp_input");
}
/**
* Send data to a specified address using UDP.
*
* @param pcb UDP PCB used to send the data.
* @param pbuf chain of pbuf's to be sent.
* @param dst_ip Destination IP address.
* @param dst_port Destination UDP port.
*
* If the PCB already has a remote address association, it will
* be restored after the data is sent.
*
* @return lwIP error code.
* - ERR_OK. Successful. No error occured.
* - ERR_MEM. Out of memory.
* - ERR_RTE. Could not find route to destination address.
*
* @see udp_disconnect() udp_send()
*/
err_t
udp_sendto(struct udp_pcb *pcb, struct pbuf *p,
struct ip_addr *dst_ip, u16_t dst_port)
{
err_t err;
struct ip_addr pcb_remote_ip;
u16_t pcb_remote_port;
/* remember remote peer address of PCB */
pcb_remote_ip.addr = pcb->remote_ip.addr;
pcb_remote_port = pcb->remote_port;
/* copy packet destination address to PCB remote peer address */
pcb->remote_ip.addr = dst_ip->addr;
pcb->remote_port = dst_port;
/* send to the packet destination address */
err = udp_send(pcb, p);
/* reset PCB remote peer address */
pcb->remote_ip.addr = pcb_remote_ip.addr;
pcb->remote_port = pcb_remote_port;
return err;
}
/**
* Send data using UDP.
*
@@ -405,10 +375,9 @@ udp_input(struct pbuf *p, struct netif *inp)
* @return lwIP error code.
* - ERR_OK. Successful. No error occured.
* - ERR_MEM. Out of memory.
* - ERR_USE. The specified ipaddr and port are already bound to by
* another UDP PCB.
* - ERR_RTE. Could not find route to destination address.
*
* @see udp_disconnect()
* @see udp_disconnect() udp_sendto()
*/
err_t
udp_send(struct udp_pcb *pcb, struct pbuf *p)
@@ -433,7 +402,7 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
/* not enough space to add an UDP header to first pbuf in given p chain? */
if (pbuf_header(p, UDP_HLEN)) {
/* allocate header in new pbuf */
/* allocate header in a seperate new pbuf */
q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM);
/* new header pbuf could not be allocated? */
if (q == NULL) {
@@ -445,23 +414,25 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
/* { first pbuf q points to header pbuf } */
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
/* adding a header within p succeeded */
} else {
} else {
/* first pbuf q equals given pbuf */
q = p;
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p));
}
/* { q now represents the packet to be sent */
/* { q now represents the packet to be sent } */
udphdr = q->payload;
udphdr->src = htons(pcb->local_port);
udphdr->dest = htons(pcb->remote_port);
udphdr->chksum = 0x0000;
/* in UDP, 0 checksum means 'no checksum' */
udphdr->chksum = 0x0000;
/* find the outgoing network interface for this packet */
if ((netif = ip_route(&(pcb->remote_ip))) == NULL) {
LWIP_DEBUGF(UDP_DEBUG | 1, ("udp_send: No route to 0x%lx\n", pcb->remote_ip.addr));
UDP_STATS_INC(udp.rterr);
return ERR_RTE;
}
/* using IP_ANY_ADDR? */
/* PCB local address is IP_ANY_ADDR? */
if (ip_addr_isany(&pcb->local_ip)) {
/* use outgoing network interface IP address as source address */
src_ip = &(netif->ip_addr);
@@ -483,8 +454,9 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
/* chksum zero must become 0xffff, as zero means 'no checksum' */
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
/* output to IP */
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDPLITE,)\n"));
err = ip_output_if (q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDPLITE, netif);
snmp_inc_udpoutdatagrams();
/* UDP */
} else {
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %u\n", q->tot_len));
udphdr->len = htons(q->tot_len);
@@ -495,17 +467,18 @@ udp_send(struct udp_pcb *pcb, struct pbuf *p)
if (udphdr->chksum == 0x0000) udphdr->chksum = 0xffff;
}
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04x\n", udphdr->chksum));
snmp_inc_udpoutdatagrams();
LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,IP_PROTO_UDP,)\n"));
/* output to IP */
err = ip_output_if(q, src_ip, &pcb->remote_ip, pcb->ttl, pcb->tos, IP_PROTO_UDP, netif);
}
/* TODO: must this be increased even if error occured? */
snmp_inc_udpoutdatagrams();
/* did we chain a header earlier? */
/* did we chain a seperate header pbuf earlier? */
if (q != p) {
/* free the header */
/* p is also still referenced by the caller, and will live on */
pbuf_free(q);
/* free the header pbuf */
pbuf_free(q); q = NULL;
/* { p is still referenced by the caller, and will live on } */
}
UDP_STATS_INC(udp.xmit);
@@ -532,7 +505,7 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
{
struct udp_pcb *ipcb;
u8_t rebind;
#ifdef SO_REUSE
#if SO_REUSE
int reuse_port_all_set = 1;
#endif /* SO_REUSE */
LWIP_DEBUGF(UDP_DEBUG | DBG_TRACE | 3, ("udp_bind(ipaddr = "));
@@ -550,7 +523,7 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
rebind = 1;
}
#ifndef SO_REUSE
#if SO_REUSE == 0
/* this code does not allow upper layer to share a UDP port for
listening to broadcast or multicast traffic (See SO_REUSE_ADDR and
SO_REUSE_PORT under *BSD). TODO: See where it fits instead, OR
@@ -604,7 +577,7 @@ udp_bind(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
}
#ifdef SO_REUSE
#if SO_REUSE
/* If SOF_REUSEPORT isn't set in all PCB's bound to specified port and local address specified then
{IP, port} can't be reused. */
if(!reuse_port_all_set) {
@@ -717,6 +690,10 @@ udp_connect(struct udp_pcb *pcb, struct ip_addr *ipaddr, u16_t port)
void
udp_disconnect(struct udp_pcb *pcb)
{
/* reset remote address association */
ip_addr_set(&pcb->remote_ip, IP_ADDR_ANY);
pcb->remote_port = 0;
/* mark PCB as unconnected */
pcb->flags &= ~UDP_FLAGS_CONNECTED;
}
@@ -772,9 +749,9 @@ udp_new(void) {
if (pcb != NULL) {
/* initialize PCB to all zeroes */
memset(pcb, 0, sizeof(struct udp_pcb));
pcb->ttl = UDP_TTL;
}
pcb->ttl = UDP_TTL;
return pcb;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -46,7 +46,7 @@ u16_t inet_chksum_pseudo(struct pbuf *p,
u32_t inet_addr(const char *cp);
int inet_aton(const char *cp, struct in_addr *addr);
u8_t *inet_ntoa(u32_t addr); /* returns ptr to static buffer; not reentrant! */
char *inet_ntoa(struct in_addr addr); /* returns ptr to static buffer; not reentrant! */
#ifdef htons
#undef htons

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -43,7 +43,6 @@
struct netif;
void ip_init(void);
u8_t ip_lookup(void *header, struct netif *inp);
struct netif *ip_route(struct ip_addr *dest);
err_t ip_input(struct pbuf *p, struct netif *inp);
err_t ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -34,6 +34,26 @@
#include "lwip/arch.h"
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip_addr {
PACK_STRUCT_FIELD(u32_t addr);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/* For compatibility with BSD code */
struct in_addr {
u32_t s_addr;
};
extern const struct ip_addr ip_addr_any;
extern const struct ip_addr ip_addr_broadcast;
/** IP_ADDR_ can be used as a fixed IP address
* for the wildcard and the broadcast address
*/
@@ -76,25 +96,6 @@
#define IN_LOOPBACKNET 127 /* official! */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct ip_addr {
PACK_STRUCT_FIELD(u32_t addr);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/* For compatibility with BSD code */
struct in_addr {
u32_t s_addr;
};
extern const struct ip_addr ip_addr_any;
extern const struct ip_addr ip_addr_broadcast;
#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = htonl(((u32_t)(a & 0xff) << 24) | ((u32_t)(b & 0xff) << 16) | \
((u32_t)(c & 0xff) << 8) | (u32_t)(d & 0xff))

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -191,10 +191,10 @@ void dhcp_fine_tmr(void);
#define DHCP_OPTION_MESSAGE_TYPE_LEN 1
#define DHCP_OPTION_SERVER_ID 54 /* RFC 2131 9.7, server IP address */
#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2131 9.8, requested option types */
#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */
#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_T1 58 /* T1 renewal time */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -59,6 +59,7 @@ typedef s8_t err_t;
#define ERR_USE -10 /* Address in use. */
#define ERR_IF -11 /* Low-level netif error */
#define ERR_ISCONN -12 /* Already connected. */
#ifdef LWIP_DEBUG

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -40,7 +40,9 @@
#include "lwip/inet.h"
#include "lwip/pbuf.h"
#include "lwip/dhcp.h"
#if LWIP_DHCP
# include "lwip/dhcp.h"
#endif
/** must be the maximum of all used hardware address lengths
across all types of interfaces in use */
@@ -115,7 +117,7 @@ extern struct netif *netif_default;
/* netif_init() must be called first. */
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,
void *state,
err_t (* init)(struct netif *netif),

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -67,6 +67,10 @@ a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE 1600
#endif
#ifndef MEMP_SANITY_CHECK
#define MEMP_SANITY_CHECK 0
#endif
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
@@ -218,6 +222,10 @@ a lot of data that needs to be copied, this should be set high. */
/* ---------- RAW options ---------- */
#ifndef LWIP_RAW
#define LWIP_RAW 1
#endif
#ifndef RAW_TTL
#define RAW_TTL 255
#endif
@@ -348,6 +356,10 @@ a lot of data that needs to be copied, this should be set high. */
#if LWIP_STATS
#ifndef LWIP_STATS_DISPLAY
#define LWIP_STATS_DISPLAY 0
#endif
#ifndef LINK_STATS
#define LINK_STATS 1
#endif
@@ -405,6 +417,7 @@ a lot of data that needs to be copied, this should be set high. */
#define PBUF_STATS 0
#define SYS_STATS 0
#define RAW_STATS 0
#define LWIP_STATS_DISPLAY 0
#endif /* LWIP_STATS */
@@ -502,10 +515,6 @@ a lot of data that needs to be copied, this should be set high. */
#define DBG_TYPES_ON 0
#endif
#ifndef DEMO_DEBUG
#define DEMO_DEBUG DBG_OFF
#endif
#ifndef ETHARP_DEBUG
#define ETHARP_DEBUG DBG_OFF
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -144,6 +144,13 @@ void stats_init(void);
#define LINK_STATS_INC(x)
#endif
/* Display of statistics */
#if LWIP_STATS_DISPLAY
void stats_display(void);
#else
#define stats_display()
#endif
#endif /* __LWIP_STATS_H__ */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -40,8 +40,6 @@
#include "lwip/ip.h"
#include "lwip/icmp.h"
#include "lwip/sys.h"
#include "lwip/err.h"
struct tcp_pcb;
@@ -457,7 +455,11 @@ void tcp_timer_needed(void);
#endif
/* The TCP PCB lists. */
extern struct tcp_pcb_listen *tcp_listen_pcbs; /* List of all TCP PCBs in LISTEN state. */
union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */
struct tcp_pcb_listen *listen_pcbs;
struct tcp_pcb *pcbs;
};
extern union tcp_listen_pcbs_t tcp_listen_pcbs;
extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a
state in which they accept or send
data. */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -84,14 +84,13 @@ void udp_recv (struct udp_pcb *pcb,
struct ip_addr *addr,
u16_t port),
void *recv_arg);
err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *dst_ip, u16_t dst_port);
err_t udp_send (struct udp_pcb *pcb, struct pbuf *p);
#define udp_flags(pcb) ((pcb)->flags)
#define udp_setflags(pcb, f) ((pcb)->flags = (f))
/* The following functions are the lower layer interface to UDP. */
u8_t udp_lookup (struct ip_hdr *iphdr, struct netif *inp);
void udp_input (struct pbuf *p, struct netif *inp);
void udp_init (void);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -11,7 +11,7 @@
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -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:
*
@@ -113,6 +120,9 @@ struct etharp_entry {
struct eth_addr ethaddr;
enum etharp_state state;
#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;
#endif
u8_t ctime;
@@ -121,22 +131,27 @@ struct etharp_entry {
static const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}};
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
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.
*/
void
etharp_init(void)
{
u8_t i;
s8_t i;
/* clear ARP entries */
for(i = 0; i < ARP_TABLE_SIZE; ++i) {
arp_table[i].state = ETHARP_STATE_EMPTY;
#if ARP_QUEUEING
arp_table[i].p = NULL;
#endif
arp_table[i].ctime = 0;
}
}
@@ -149,22 +164,28 @@ etharp_init(void)
void
etharp_tmr(void)
{
u8_t i;
s8_t i;
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n"));
/* remove expired entries from the ARP table */
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
arp_table[i].ctime++;
/* a resolved/stable entry? */
if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
/* entry has become old? */
(arp_table[i].ctime >= ARP_MAXAGE)) {
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired stable entry %u.\n", i));
goto empty;
/* an unresolved/pending entry? */
} else if ((arp_table[i].state == ETHARP_STATE_PENDING) &&
/* entry unresolved/pending for too long? */
(arp_table[i].ctime >= ARP_MAXPENDING)) {
LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired pending entry %u.\n", i));
empty:
empty:
/* empty old entry */
arp_table[i].state = ETHARP_STATE_EMPTY;
#if ARP_QUEUEING
/* and empty packet queue */
if (arp_table[i].p != NULL) {
/* remove any queued packet */
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
* entries are pending, otherwise the oldest entry.
* Return an empty ARP entry (possibly recycling the oldest stable 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.
*/
static u8_t
static s8_t
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. */
j = ARP_TABLE_SIZE;
/* search ARP table for an unused or old entry */
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
/* empty entry? */
if (arp_table[i].state == ETHARP_STATE_EMPTY) {
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found empty entry %u\n", i));
break;
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning empty entry %u\n", i));
return i;
/* stable entry? */
} else if (arp_table[i].state == ETHARP_STATE_STABLE) {
/* remember entry with oldest stable entry in j */
if (arp_table[i].ctime >= maxtime) maxtime = arp_table[j = i].ctime;
}
}
/* no empty entry found? */
if (i == ARP_TABLE_SIZE) {
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j));
/* fall-back to oldest stable */
i = j;
}
/* 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;
}
/* 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;
for (i = 0; i < ARP_TABLE_SIZE; ++i) {
/* remember entry with oldest stable entry in j*/
if ((arp_table[i].state == ETHARP_STATE_STABLE) &&
#if ARP_QUEUEING /* do not want to re-use an entry with queued packets */
(arp_table[i].p == NULL) &&
/* 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
(arp_table[i].ctime >= maxtime)) {
maxtime = arp_table[i].ctime;
j = i;
}
}
if (j != ARP_TABLE_SIZE) {
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: found oldest stable entry %u\n", j));
} else {
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: no replacable entry could be found\n"));
}
i = j;
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, state %u\n", i, arp_table[i].state));
LWIP_DEBUGF(ETHARP_DEBUG, ("find_arp_entry: returning %u\n", 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.
*
* 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 ethaddr Ethernet address of the inserted ARP entry.
* @param flags Defines behaviour:
@@ -240,7 +331,7 @@ find_arp_entry(void)
static struct pbuf *
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_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),
@@ -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;
/* 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_QUEUEING
struct pbuf *p;
@@ -277,12 +368,27 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
}
/* reset time stamp */
arp_table[i].ctime = 0;
/* this is where we will send out queued packets! */
#if ARP_QUEUEING
/* get the first packet on the queue (if any) */
p = arp_table[i].p;
/* queued packet present? */
if (p != NULL) {
/* NULL attached buffer immediately */
arp_table[i].p = NULL;
/* (another) queued packet present? */
while (p != NULL) {
struct pbuf *q, *n;
/* search for second packet on queue (n) */
q = p;
while (q->tot_len > q->len) {
LWIP_ASSERT("q->next != NULL (while q->tot_len > q->len)", q->next != NULL);
/* proceed to next pbuf of this packet */
q = q->next;
}
/* { q = last pbuf of this packet, q->tot_len == q->len } */
LWIP_ASSERT("q->tot_len == q->len", q->tot_len == q->len);
/* remember next packet on queue */
n = q->next;
/* { n = first pbuf of next packet, or NULL if no next packet } */
/* terminate this packet pbuf chain */
q->next = NULL;
/* fill-in Ethernet header */
ethhdr = p->payload;
for (k = 0; k < netif->hwaddr_len; ++k) {
@@ -290,17 +396,22 @@ update_arp_entry(struct netif *netif, struct ip_addr *ipaddr, struct eth_addr *e
ethhdr->src.addr[k] = netif->hwaddr[k];
}
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 */
netif->linkoutput(netif, p);
/* free the queued IP packet */
pbuf_free(p);
/* proceed to next packet on queue */
p = n;
}
/* NULL attached buffer*/
arp_table[i].p = NULL;
#endif
/* IP addresses should only occur once in the ARP entry, we are done */
return NULL;
}
} /* if */
} /* for */
} /* if STABLE */
} /* for all ARP entries */
/* no matching ARP entry was found */
LWIP_ASSERT("update_arp_entry: i == ARP_TABLE_SIZE", i == ARP_TABLE_SIZE);
@@ -312,21 +423,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"));
/* find an empty or old 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"));
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 */
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
/* set Ethernet hardware address */
@@ -350,7 +450,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
* ARP cache for the local network. The function does not alter
@@ -424,6 +524,17 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
for_us = ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr));
}
/* add or update entries in the ARP cache */
if (for_us) {
/* insert IP address in ARP cache (assume requester wants to talk to us)
* we might even send out a queued packet to this host */
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG);
/* request was not directed to us, but snoop anyway */
} else {
/* update the source IP address in the cache */
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
}
switch (htons(hdr->opcode)) {
/* ARP request? */
case ARP_REQUEST:
@@ -474,7 +585,7 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
/* ARP reply. We insert or update the ARP table later. */
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
/* DHCP needs to know about ARP replies to our address */
/* DHCP wants to know about ARP replies to our wanna-have-address */
if (for_us) dhcp_arp_reply(netif, &hdr->sipaddr);
#endif
break;
@@ -482,18 +593,6 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
break;
}
/* add or update entries in the ARP cache */
if (for_us) {
/* insert IP address in ARP cache (assume requester wants to talk to us)
* we might even send out a queued packet to this host */
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG);
/* request was not directed to us, but snoop anyway */
} else {
/* update or insert the source IP address in the cache */
update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
/* update or insert the destination IP address pair in the cache */
update_arp_entry(netif, &(hdr->dipaddr), &(hdr->dhwaddr), 0);
}
/* free ARP packet */
pbuf_free(p);
p = NULL;
@@ -512,10 +611,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
* the caller.
*
* If ARP failed to allocate resources, NULL is returned.
*
* 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 ipaddr The IP address of the packet destination.
* @param pbuf The pbuf(s) containing the IP packet to be sent.
@@ -528,9 +627,9 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{
struct eth_addr *dest, *srcaddr, mcastaddr;
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) {
/* The pbuf_header() call shouldn't fail, and we'll just bail
out if it does.. */
@@ -539,9 +638,6 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
return NULL;
}
/* obtain source Ethernet address of the given interface */
srcaddr = (struct eth_addr *)netif->hwaddr;
/* assume unresolved Ethernet address */
dest = NULL;
/* Construct Ethernet header. Start with looking up deciding which
@@ -569,19 +665,20 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
}
/* destination IP address is an IP unicast address */
else {
/* destination IP network address not on local network? */
/* this occurs if the packet is routed to the default gateway on this interface */
/* destination IP network address not on local network?
* IP layer wants us to forward to the default gateway */
if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
/* gateway available? */
/* interface has default gateway? */
if (netif->gw.addr != 0)
{
/* use the gateway IP address */
/* route to default gateway IP address */
ipaddr = &(netif->gw);
}
/* no gateway available? */
else
{
/* IP destination address outside local network, but no gateway available */
/* { packet is discarded } */
return NULL;
}
}
@@ -600,6 +697,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 */
/* TODO: How do we handle netif->ipaddr == ipaddr? */
etharp_query(netif, ipaddr, q);
/* { packet was queued (ERR_OK), or discarded } */
/* return nothing */
return NULL;
}
@@ -612,8 +710,11 @@ etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
/* destination Ethernet address known */
if (dest != NULL) {
/* A valid IP->MAC address mapping was found, so we construct the
Ethernet header for the outgoing packet. */
/* obtain source Ethernet address of the given interface */
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;
for(i = 0; i < netif->hwaddr_len; i++) {
@@ -654,9 +755,8 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{
struct eth_addr *srcaddr;
struct etharp_hdr *hdr;
struct pbuf *p;
err_t result = ERR_OK;
u8_t i;
s8_t i;
u8_t perform_arp_request = 1;
/* prevent 'unused argument' warning if ARP_QUEUEING == 0 */
(void)q;
@@ -666,16 +766,21 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
if (ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
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));
/* 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 */
/* we might want to run a faster timer on ARP to limit this */
break;
}
else if (arp_table[i].state == ETHARP_STATE_STABLE) {
LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | DBG_STATE, ("etharp_query: requested IP already stable as entry %u\n", i));
/* user may wish to queue a packet on a stable entry, so we proceed without ARP requesting */
/* TODO: even if the ARP entry is stable, we might do an ARP request anyway */
perform_arp_request = 0;
/* User wishes to queue a packet on a stable entry (or does she want to send
* out the packet immediately, we will not know), so we force an ARP request.
* Upon response we will send out the queued packet in etharp_update().
*
* Alternatively, we could accept the stable entry, and just send out the packet
* immediately. I chose to implement the former approach.
*/
perform_arp_request = (q?1:0);
break;
}
}
@@ -683,56 +788,25 @@ err_t etharp_query(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
/* queried address not yet in ARP table? */
if (i == ARP_TABLE_SIZE) {
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();
/* bail out if no ARP entries are available */
if (i == ARP_TABLE_SIZE) {
LWIP_DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available.\n"));
if (i == ERR_MEM) {
LWIP_DEBUGF(ETHARP_DEBUG | 2, ("etharp_query: no more ARP entries available. Should seldom occur.\n"));
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 */
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
arp_table[i].ctime = 0;
arp_table[i].state = ETHARP_STATE_PENDING;
#if ARP_QUEUEING
/* free queued packet, as entry is now invalidated */
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
}
#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));
}
ip_addr_set(&arp_table[i].ipaddr, ipaddr);
}
/* { i is now valid } */
#if ARP_QUEUEING /* queue packet (even on a stable entry, see above) */
etharp_enqueue(i, q);
#endif
/* ARP request? */
if (perform_arp_request)
{
struct pbuf *p;
/* allocate a pbuf for the outgoing ARP request packet */
p = pbuf_alloc(PBUF_LINK, sizeof(struct etharp_hdr), PBUF_RAM);
/* could allocate pbuf? */

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
@@ -35,8 +35,6 @@
* drivers for lwIP. Add code to the low_level functions and do a
* search-and-replace for the word "ethernetif" to replace it with
* something that better describes your network interface.
*
* THIS CODE NEEDS TO BE FIXED - IT IS NOT In SYNC WITH CURRENT ETHARP API
*/
#include "lwip/opt.h"
@@ -45,11 +43,11 @@
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "netif/arp.h"
#include "netif/etharp.h"
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 't'
#define IFNAME1 'n'
struct ethernetif {
struct eth_addr *ethaddr;
@@ -77,7 +75,7 @@ low_level_init(struct netif *netif)
/* set MAC hardware address */
netif->hwaddr[0] = ;
...
netif->hwaddr[6] = ;
netif->hwaddr[5] = ;
/* maximum transfer unit */
netif->mtu = 1500;
@@ -171,7 +169,7 @@ low_level_input(struct ethernetif *ethernetif)
*
* This function is called by the TCP/IP stack when an IP packet
* should be sent. It calls the function called low_level_output() to
* do the actuall transmission of the packet.
* do the actual transmission of the packet.
*
*/
@@ -189,78 +187,18 @@ ethernetif_output(struct netif *netif, struct pbuf *p,
ethernetif = netif->state;
/* Make room for Ethernet header. */
if (pbuf_header(p, 14) != 0) {
/* The pbuf_header() call shouldn't fail, but we allocate an extra
pbuf just in case. */
q = pbuf_alloc(PBUF_LINK, 14, PBUF_RAM);
if (q == NULL) {
#ifdef LINK_STATS
lwip_stats.link.drop++;
lwip_stats.link.memerr++;
#endif /* LINK_STATS */
return ERR_MEM;
}
pbuf_chain(q, p);
p = q;
}
/* Construct Ethernet header. Start with looking up deciding which
MAC address to use as a destination address. Broadcasts and
multicasts are special, all other addresses are looked up in the
ARP table. */
queryaddr = ipaddr;
if (ip_addr_isany(ipaddr) ||
ip_addr_isbroadcast(ipaddr, &(netif->netmask))) {
dest = (struct eth_addr *)&ethbroadcast;
} else if (ip_addr_ismulticast(ipaddr)) {
/* Hash IP multicast address to MAC address. */
mcastaddr.addr[0] = 0x01;
mcastaddr.addr[1] = 0x0;
mcastaddr.addr[2] = 0x5e;
mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
mcastaddr.addr[4] = ip4_addr3(ipaddr);
mcastaddr.addr[5] = ip4_addr4(ipaddr);
dest = &mcastaddr;
} else {
if (ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
/* Use destination IP address if the destination is on the same
subnet as we are. */
queryaddr = ipaddr;
} else {
/* Otherwise we use the default router as the address to send
the Ethernet frame to. */
queryaddr = &(netif->gw);
}
dest = arp_lookup(queryaddr);
}
/* If the arp_lookup() didn't find an address, we send out an ARP
query for the IP address. */
if (dest == NULL) {
q = arp_query(netif, ethernetif->ethaddr, queryaddr);
if (q != NULL) {
err = low_level_output(ethernetif, q);
pbuf_free(q);
return err;
}
#ifdef LINK_STATS
lwip_stats.link.drop++;
lwip_stats.link.memerr++;
#endif /* LINK_STATS */
return ERR_MEM;
}
ethhdr = p->payload;
for(i = 0; i < 6; i++) {
ethhdr->dest.addr[i] = dest->addr[i];
ethhdr->src.addr[i] = ethernetif->ethaddr->addr[i];
}
ethhdr->type = htons(ETHTYPE_IP);
/* resolve the link destination hardware address */
p = etharp_output(netif, ipaddr, p);
/* network hardware address obtained? */
if (p == NULL)
{
/* we cannot tell if the packet was sent: the packet could */
/* have been queued on an ARP entry that was already pending. */
return ERR_OK;
}
/* send out the packet */
return low_level_output(ethernetif, p);
}
@@ -280,45 +218,48 @@ ethernetif_input(struct netif *netif)
{
struct ethernetif *ethernetif;
struct eth_hdr *ethhdr;
struct pbuf *p;
struct pbuf *p, *q;
ethernetif = netif->state;
p = low_level_input(ethernetif);
if (p != NULL) {
if (p != NULL)
return;
#ifdef LINK_STATS
lwip_stats.link.recv++;
lwip_stats.link.recv++;
#endif /* LINK_STATS */
ethhdr = p->payload;
ethhdr = p->payload;
q = NULL;
switch (htons(ethhdr->type)) {
switch (htons(ethhdr->type)) {
case ETHTYPE_IP:
arp_ip_input(netif, p);
q = etharp_ip_input(netif, p);
pbuf_header(p, -14);
netif->input(p, netif);
break;
case ETHTYPE_ARP:
p = arp_arp_input(netif, ethernetif->ethaddr, p);
if (p != NULL) {
low_level_output(ethernetif, p);
pbuf_free(p);
}
q = etharp_arp_input(netif, ethernetif->ethaddr, p);
break;
default:
pbuf_free(p);
p = NULL;
break;
}
}
if (q != NULL) {
low_level_output(ethernetif, q);
pbuf_free(q);
q = NULL;
}
}
static void
arp_timer(void *arg)
{
arp_tmr();
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
}
@@ -337,6 +278,13 @@ ethernetif_init(struct netif *netif)
struct ethernetif *ethernetif;
ethernetif = mem_malloc(sizeof(struct ethernetif));
if (ethernetif == NULL)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
return ERR_MEM;
}
netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
@@ -346,7 +294,8 @@ ethernetif_init(struct netif *netif)
ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
low_level_init(netif);
arp_init();
etharp_init();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,

View File

@@ -610,7 +610,7 @@ int get_secret(
addrs = NULL;
if(!client || !client[0] && strcmp(client, ppp_settings.user)) {
if(!client || !client[0] || strcmp(client, ppp_settings.user)) {
return 0;
}

View File

@@ -51,7 +51,6 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: chpms.h,v 1.2 2003/11/14 14:56:31 likewise Exp $
*/
#ifndef CHPMS_H

View File

@@ -178,6 +178,20 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
/*** LOCAL FUNCTION DEFINITIONS ***/
/**********************************/
/*
* Non-standard inet_ntoa left here for compat with original ppp
* sources. Assumes u32_t instead of struct in_addr.
*/
char * _inet_ntoa(u32_t n)
{
struct in_addr ia;
ia.s_addr = n;
return inet_ntoa(ia);
}
#define inet_ntoa _inet_ntoa
/*
* ipcp_init - Initialize IPCP.
*/

View File

@@ -153,7 +153,7 @@ typedef struct PPPControl_s {
struct vjcompress vjComp; /* Van Jabobsen compression header. */
#endif
struct netif *netif;
struct netif netif;
struct ppp_addrs addrs;
@@ -296,7 +296,6 @@ void pppInit(void)
for (i = 0; i < NUM_PPP; i++) {
pppControl[i].openFlag = 0;
pppControl[i].netif = NULL;
subnetMask = htonl(0xffffff00);
@@ -537,14 +536,14 @@ static struct pbuf *pppAppend(u_char c, struct pbuf *nb, ext_accm *outACCM)
/* Send a packet on the given connection. */
static err_t pppifOutput(struct netif *netif, struct pbuf *pb, struct ip_addr *ipaddr)
{
int pd = (int)netif->state;
u_short protocol = PPP_IP;
int pd = (int)netif->state;
u_short protocol = PPP_IP;
PPPControl *pc = &pppControl[pd];
u_int fcsOut = PPP_INITFCS;
struct pbuf *headMB = NULL, *tailMB = NULL, *p;
u_char c;
(void)ipaddr;
(void)ipaddr;
/* Validate parameters. */
/* We let any protocol value go through - it can't hurt us
@@ -1003,12 +1002,10 @@ int sifup(int pd)
st = 0;
PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
} else {
if(pc->netif)
netif_remove(pc->netif);
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->errCode = PPPERR_NONE;
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->if_up = 1;
pc->errCode = PPPERR_NONE;
PPPDEBUG((LOG_DEBUG, "sifup: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
if(pc->linkStatusCB)
@@ -1046,12 +1043,10 @@ int sifdown(int pd)
PPPDEBUG((LOG_WARNING, "sifdown[%d]: bad parms\n", pd));
} else {
pc->if_up = 0;
if(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));
if(pc->linkStatusCB)
pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);
netif_remove(&pc->netif);
PPPDEBUG((LOG_DEBUG, "sifdown: unit %d: linkStatusCB=%lx errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
if(pc->linkStatusCB)
pc->linkStatusCB(pc->linkStatusCtx, PPPERR_CONNECT, NULL);
}
return st;
}
@@ -1126,7 +1121,7 @@ int sifdefaultroute(int pd, u32_t l, u32_t g)
st = 0;
PPPDEBUG((LOG_WARNING, "sifup[%d]: bad parms\n", pd));
} else {
netif_set_default(pc->netif);
netif_set_default(&pc->netif);
}
/* 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.
*/
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;
}
/* Something's wrong so drop it. */
@@ -1342,7 +1337,7 @@ static void pppInput(void *arg)
* the packet to IP.
*/
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;
}
/* Something's wrong so drop it. */
@@ -1356,7 +1351,7 @@ static void pppInput(void *arg)
break;
case PPP_IP: /* Internet Protocol */
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;
default:
{

View File

@@ -1,8 +1,6 @@
/*
* Definitions for tcp compression routines.
*
* $Id: vj.h,v 1.3 2003/11/14 14:56:31 likewise Exp $
*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -199,6 +199,7 @@ slipif_init(struct netif *netif)
netif->name[1] = 'l';
netif->output = slipif_output;
netif->mtu = 1500;
netif->flags = NETIF_FLAG_POINTTOPOINT;
netif->state = sio_open(netif->num);
if (!netif->state)