Compare commits
52 Commits
STABLE-1_4
...
STABLE-1_4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a267586f4 | ||
|
|
52271e0366 | ||
|
|
e4739da961 | ||
|
|
80b344e9fc | ||
|
|
036cb26fa3 | ||
|
|
33d6dcec5b | ||
|
|
791505ab6e | ||
|
|
88e1719d8e | ||
|
|
0885555521 | ||
|
|
36c1750b8f | ||
|
|
11b1c9f19f | ||
|
|
b5dd87b184 | ||
|
|
b54c7bedfd | ||
|
|
783404d8d4 | ||
|
|
3bad9f013e | ||
|
|
4495516497 | ||
|
|
3f849848a4 | ||
|
|
7203680146 | ||
|
|
d793ed3b9b | ||
|
|
c6de17d1e5 | ||
|
|
5b084f4b95 | ||
|
|
4e3b2b9f6b | ||
|
|
856ccb5bb7 | ||
|
|
dbf5659cd9 | ||
|
|
fee0c6afe9 | ||
|
|
fb7d3a159a | ||
|
|
dc6b4e65e0 | ||
|
|
17d4ef4053 | ||
|
|
03be8f88fe | ||
|
|
effcb90fdf | ||
|
|
1bd06bee82 | ||
|
|
92cdc1e33f | ||
|
|
377628216e | ||
|
|
f7627929d5 | ||
|
|
b49cf5e7a2 | ||
|
|
231a6cecb4 | ||
|
|
32f02325f9 | ||
|
|
f418782c2c | ||
|
|
e52730d1fb | ||
|
|
d2679e58a6 | ||
|
|
e3817cd549 | ||
|
|
4ace50a7d7 | ||
|
|
fa092c47c8 | ||
|
|
704d90f693 | ||
|
|
93dc36e091 | ||
|
|
4cc36b2284 | ||
|
|
aaa8d2795e | ||
|
|
229137cad1 | ||
|
|
d73262a0e5 | ||
|
|
cd22a8d851 | ||
|
|
7f7df4ae19 | ||
|
|
3c5723e49d |
156
CHANGELOG
156
CHANGELOG
@@ -1,18 +1,29 @@
|
||||
FUTURE
|
||||
|
||||
* 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 (/DSP) architectures showing these problems.
|
||||
We still have to fix some of these issues neatly.
|
||||
|
||||
HISTORY
|
||||
|
||||
(CVS HEAD)
|
||||
|
||||
* [Enter new changes just after this line - do not remove this line]
|
||||
|
||||
++ New features:
|
||||
|
||||
|
||||
++ Bugfixes:
|
||||
|
||||
|
||||
|
||||
|
||||
(STABLE-1.4.0)
|
||||
|
||||
++ New features:
|
||||
|
||||
2011-03-27: Simon Goldschmidt
|
||||
* tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and
|
||||
calculate it in tcp_zero_window_probe (the only place where it was used).
|
||||
|
||||
2010-11-21: Simon Goldschmidt
|
||||
* dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif
|
||||
(fixes bug #31525).
|
||||
|
||||
2010-07-12: Simon Goldschmidt (patch by Stephane Lesage)
|
||||
* ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for
|
||||
IP_MULTICAST_LOOP at socket- and raw-API level.
|
||||
@@ -229,6 +240,137 @@ HISTORY
|
||||
|
||||
++ Bugfixes:
|
||||
|
||||
2011-04-20: Simon Goldschmidt
|
||||
* sys_arch.txt: sys_arch_timeouts() is not needed any more.
|
||||
|
||||
2011-04-13: Simon Goldschmidt
|
||||
* tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by
|
||||
using ports in the IANA private/dynamic range (49152 through 65535).
|
||||
|
||||
2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl:
|
||||
* etharp.h/.c: Fixed broken VLAN support.
|
||||
|
||||
2011-03-27: Simon Goldschmidt
|
||||
* tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp
|
||||
pcbs) by checking if the pcb was bound (local_port != 0).
|
||||
|
||||
2011-03-27: Simon Goldschmidt
|
||||
* ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice)
|
||||
|
||||
2011-03-27: Simon Goldschmidt
|
||||
* sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and
|
||||
raw pcbs with LWIP_TCPIP_CORE_LOCKING==1.
|
||||
|
||||
2011-03-27: Simon Goldschmidt
|
||||
* tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route
|
||||
is present never times out) by starting retransmission timer before checking
|
||||
route.
|
||||
|
||||
2011-03-22: Simon Goldschmidt
|
||||
* ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only
|
||||
calling sio_read_abort() if the file descriptor is valid.
|
||||
|
||||
2011-03-14: Simon Goldschmidt
|
||||
* err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect
|
||||
more than once can render a socket useless) since it mainly involves changing
|
||||
"FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal.
|
||||
|
||||
2011-03-13: Simon Goldschmidt
|
||||
* sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing
|
||||
err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN:
|
||||
use EALRADY instead of -1
|
||||
|
||||
2011-03-13: Simon Goldschmidt
|
||||
* api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the
|
||||
connection has been aborted by err_tcp (since this is not a normal closing
|
||||
procedure).
|
||||
|
||||
2011-03-13: Simon Goldschmidt
|
||||
* tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind
|
||||
with pcb->state != CLOSED
|
||||
|
||||
2011-02-17: Simon Goldschmidt
|
||||
* rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in
|
||||
documentation
|
||||
|
||||
2011-02-17: Simon Goldschmidt
|
||||
* many files: Added missing U/UL modifiers to fix 16-bit-arch portability.
|
||||
|
||||
2011-01-24: Simon Goldschmidt
|
||||
* sockets.c: Fixed bug #31741: lwip_select seems to have threading problems
|
||||
|
||||
2010-12-02: Simon Goldschmidt
|
||||
* err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal.
|
||||
|
||||
2010-11-23: Simon Goldschmidt
|
||||
* api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for
|
||||
LWIP_SO_RCVBUF and ioctl/FIONREAD.
|
||||
|
||||
2010-11-23: Simon Goldschmidt
|
||||
* etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at
|
||||
least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet.
|
||||
|
||||
2010-11-23: Simon Goldschmidt
|
||||
* tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after
|
||||
refusing 'refused_data' again.
|
||||
|
||||
2010-11-22: Simon Goldschmidt
|
||||
* sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS
|
||||
after a successful nonblocking connection.
|
||||
|
||||
2010-11-22: Simon Goldschmidt
|
||||
* etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr
|
||||
must be sent link-local
|
||||
|
||||
2010-11-22: Simon Goldschmidt
|
||||
* timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for
|
||||
LWIP_TIMERS==0
|
||||
|
||||
2010-11-20: Simon Goldschmidt
|
||||
* sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number
|
||||
|
||||
2010-11-20: Simon Goldschmidt
|
||||
* sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to
|
||||
resemble other stacks.
|
||||
|
||||
2010-11-20: Simon Goldschmidt
|
||||
* dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else
|
||||
no-copy TCP writes will never succeed.
|
||||
|
||||
2010-11-20: Simon Goldschmidt
|
||||
* dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does
|
||||
not match documentation: return ERR_ARG instead of ERR_VAL if not
|
||||
initialized or wrong argument.
|
||||
|
||||
2010-10-20: Simon Goldschmidt
|
||||
* sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16
|
||||
|
||||
2010-10-05: Simon Goldschmidt
|
||||
* dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when
|
||||
replugging the network cable after an AutoIP address was assigned.
|
||||
|
||||
2010-08-10: Simon Goldschmidt
|
||||
* tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs
|
||||
|
||||
2010-08-03: Simon Goldschmidt
|
||||
* udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625)
|
||||
|
||||
2010-08-01: Simon Goldschmidt (patch by Greg Renda)
|
||||
* ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big
|
||||
endian architectures)
|
||||
|
||||
2010-07-28: Simon Goldschmidt
|
||||
* api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP
|
||||
disabled.
|
||||
|
||||
2010-07-27: Simon Goldschmidt
|
||||
* tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no
|
||||
harm but never did anything
|
||||
|
||||
2010-07-21: Simon Goldschmidt
|
||||
* ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not
|
||||
add IP options)
|
||||
|
||||
2010-07-16: Kieran Mansley
|
||||
* msg_in.c: Fixed SNMP ASN constant defines to not use ! operator
|
||||
|
||||
|
||||
@@ -111,11 +111,16 @@ with newer versions.
|
||||
* Added const char* name to mem- and memp-stats for easier debugging.
|
||||
|
||||
* Calculate the TCP/UDP checksum while copying to only fetch data once:
|
||||
Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum
|
||||
Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum
|
||||
|
||||
* Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
|
||||
more than one pcb.
|
||||
|
||||
* Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned
|
||||
off any more, if this is set to 0, only one packet (the most recent one) is
|
||||
queued (like demanded by RFC 1122).
|
||||
|
||||
|
||||
++ Major bugfixes/improvements
|
||||
|
||||
* Implemented tcp_shutdown() to only shut down one end of a connection
|
||||
|
||||
@@ -251,8 +251,9 @@ if a call to tcp_write() has failed because memory wasn't available,
|
||||
the application may use the polling functionality to call tcp_write()
|
||||
again when the connection has been idle for a while.
|
||||
|
||||
- void tcp_poll(struct tcp_pcb *pcb, u8_t interval,
|
||||
err_t (* poll)(void *arg, struct tcp_pcb *tpcb))
|
||||
- void tcp_poll(struct tcp_pcb *pcb,
|
||||
err_t (* poll)(void *arg, struct tcp_pcb *tpcb),
|
||||
u8_t interval)
|
||||
|
||||
Specifies the polling interval and the callback function that should
|
||||
be called to poll the application. The interval is specified in
|
||||
|
||||
@@ -123,18 +123,6 @@ The following functions must be implemented by the sys_arch:
|
||||
sys_arch_mbox_fetch(mbox,msg,1)
|
||||
although this would introduce unnecessary delays.
|
||||
|
||||
- struct sys_timeouts *sys_arch_timeouts(void)
|
||||
|
||||
Returns a pointer to the per-thread sys_timeouts structure. In lwIP,
|
||||
each thread has a list of timeouts which is repressented as a linked
|
||||
list of sys_timeout structures. The sys_timeouts structure holds a
|
||||
pointer to a linked list of timeouts. This function is called by
|
||||
the lwIP timeout scheduler and must not return a NULL value.
|
||||
|
||||
In a single thread sys_arch implementation, this function will
|
||||
simply return a pointer to a global sys_timeouts variable stored in
|
||||
the sys_arch module.
|
||||
|
||||
If threads are supported by the underlying operating system and if
|
||||
such functionality is needed in lwIP, the following function will have
|
||||
to be implemented as well:
|
||||
|
||||
@@ -240,6 +240,7 @@ netconn_disconnect(struct netconn *conn)
|
||||
err_t
|
||||
netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
|
||||
{
|
||||
#if LWIP_TCP
|
||||
struct api_msg msg;
|
||||
err_t err;
|
||||
|
||||
@@ -257,6 +258,11 @@ netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
|
||||
|
||||
NETCONN_SET_SAFE_ERR(conn, err);
|
||||
return err;
|
||||
#else /* LWIP_TCP */
|
||||
LWIP_UNUSED_ARG(conn);
|
||||
LWIP_UNUSED_ARG(backlog);
|
||||
return ERR_ARG;
|
||||
#endif /* LWIP_TCP */
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,9 +307,9 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
|
||||
|
||||
if (newconn == NULL) {
|
||||
/* connection has been closed */
|
||||
NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
|
||||
return ERR_CLSD;
|
||||
/* connection has been aborted */
|
||||
NETCONN_SET_SAFE_ERR(conn, ERR_ABRT);
|
||||
return ERR_ABRT;
|
||||
}
|
||||
#if TCP_LISTEN_BACKLOG
|
||||
/* Let the stack know that we have accepted the connection. */
|
||||
@@ -402,7 +408,9 @@ netconn_recv_data(struct netconn *conn, void **new_buf)
|
||||
}
|
||||
#endif /* (LWIP_UDP || LWIP_RAW) */
|
||||
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_DEC(conn->recv_avail, len);
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
|
||||
|
||||
@@ -499,6 +507,7 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
||||
void
|
||||
netconn_recved(struct netconn *conn, u32_t length)
|
||||
{
|
||||
#if LWIP_TCP
|
||||
if ((conn != NULL) && (conn->type == NETCONN_TCP) &&
|
||||
(netconn_get_noautorecved(conn))) {
|
||||
struct api_msg msg;
|
||||
@@ -511,6 +520,10 @@ netconn_recved(struct netconn *conn, u32_t length)
|
||||
/* don't care for the return value of do_recv */
|
||||
TCPIP_APIMSG(&msg);
|
||||
}
|
||||
#else /* LWIP_TCP */
|
||||
LWIP_UNUSED_ARG(conn);
|
||||
LWIP_UNUSED_ARG(length);
|
||||
#endif /* LWIP_TCP */
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -120,7 +120,9 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
||||
netbuf_delete(buf);
|
||||
return 0;
|
||||
} else {
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_INC(conn->recv_avail, len);
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
||||
}
|
||||
@@ -194,7 +196,9 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
||||
netbuf_delete(buf);
|
||||
return;
|
||||
} else {
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_INC(conn->recv_avail, len);
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
||||
}
|
||||
@@ -248,7 +252,9 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
||||
/* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
|
||||
return ERR_MEM;
|
||||
} else {
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_INC(conn->recv_avail, len);
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
|
||||
}
|
||||
@@ -614,7 +620,6 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
||||
conn->socket = -1;
|
||||
#endif /* LWIP_SOCKET */
|
||||
conn->callback = callback;
|
||||
conn->recv_avail = 0;
|
||||
#if LWIP_TCP
|
||||
conn->current_msg = NULL;
|
||||
conn->write_offset = 0;
|
||||
@@ -624,6 +629,7 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
||||
#endif /* LWIP_SO_RCVTIMEO */
|
||||
#if LWIP_SO_RCVBUF
|
||||
conn->recv_bufsize = RECV_BUFSIZE_DEFAULT;
|
||||
conn->recv_avail = 0;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
conn->flags = 0;
|
||||
return conn;
|
||||
@@ -944,12 +950,7 @@ do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
|
||||
conn->current_msg = NULL;
|
||||
conn->state = NETCONN_NONE;
|
||||
if (!was_blocking) {
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (conn->last_err == ERR_INPROGRESS) {
|
||||
conn->last_err = ERR_OK;
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
NETCONN_SET_SAFE_ERR(conn, ERR_OK);
|
||||
}
|
||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||
|
||||
@@ -1040,6 +1041,7 @@ do_disconnect(struct api_msg_msg *msg)
|
||||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
/**
|
||||
* Set a TCP pcb contained in a netconn into listen mode
|
||||
* Called from netconn_listen.
|
||||
@@ -1049,7 +1051,6 @@ do_disconnect(struct api_msg_msg *msg)
|
||||
void
|
||||
do_listen(struct api_msg_msg *msg)
|
||||
{
|
||||
#if LWIP_TCP
|
||||
if (ERR_IS_FATAL(msg->conn->last_err)) {
|
||||
msg->err = msg->conn->last_err;
|
||||
} else {
|
||||
@@ -1091,9 +1092,9 @@ do_listen(struct api_msg_msg *msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
|
||||
/**
|
||||
* Send some data on a RAW or UDP pcb contained in a netconn
|
||||
@@ -1147,6 +1148,7 @@ do_send(struct api_msg_msg *msg)
|
||||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
/**
|
||||
* Indicate data has been received from a TCP pcb contained in a netconn
|
||||
* Called from netconn_recv
|
||||
@@ -1156,7 +1158,6 @@ do_send(struct api_msg_msg *msg)
|
||||
void
|
||||
do_recv(struct api_msg_msg *msg)
|
||||
{
|
||||
#if LWIP_TCP
|
||||
msg->err = ERR_OK;
|
||||
if (msg->conn->pcb.tcp != NULL) {
|
||||
if (msg->conn->type == NETCONN_TCP) {
|
||||
@@ -1175,11 +1176,9 @@ do_recv(struct api_msg_msg *msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_TCP */
|
||||
TCPIP_APIMSG_ACK(msg);
|
||||
}
|
||||
|
||||
#if LWIP_TCP
|
||||
/**
|
||||
* See if more data needs to be written from a previous call to netconn_write.
|
||||
* Called initially from do_write. If the first call can't send all data
|
||||
|
||||
@@ -49,14 +49,14 @@ static const char *err_strerr[] = {
|
||||
"Operation in progress.", /* ERR_INPROGRESS -5 */
|
||||
"Illegal value.", /* ERR_VAL -6 */
|
||||
"Operation would block.", /* ERR_WOULDBLOCK -7 */
|
||||
"Connection aborted.", /* ERR_ABRT -8 */
|
||||
"Connection reset.", /* ERR_RST -9 */
|
||||
"Connection closed.", /* ERR_CLSD -10 */
|
||||
"Not connected.", /* ERR_CONN -11 */
|
||||
"Illegal argument.", /* ERR_ARG -12 */
|
||||
"Address in use.", /* ERR_USE -13 */
|
||||
"Low-level netif error.", /* ERR_IF -14 */
|
||||
"Already connected.", /* ERR_ISCONN -15 */
|
||||
"Address in use.", /* ERR_USE -8 */
|
||||
"Already connected.", /* ERR_ISCONN -9 */
|
||||
"Connection aborted.", /* ERR_ABRT -10 */
|
||||
"Connection reset.", /* ERR_RST -11 */
|
||||
"Connection closed.", /* ERR_CLSD -12 */
|
||||
"Not connected.", /* ERR_CONN -13 */
|
||||
"Illegal argument.", /* ERR_ARG -14 */
|
||||
"Low-level netif error.", /* ERR_IF -15 */
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -105,8 +105,10 @@ struct lwip_select_cb {
|
||||
struct lwip_setgetsockopt_data {
|
||||
/** socket struct for which to change options */
|
||||
struct lwip_sock *sock;
|
||||
#ifdef LWIP_DEBUG
|
||||
/** socket index for which to change options */
|
||||
int s;
|
||||
#endif /* LWIP_DEBUG */
|
||||
/** level of the option to process */
|
||||
int level;
|
||||
/** name of the option to process */
|
||||
@@ -139,14 +141,14 @@ static const int err_to_errno_table[] = {
|
||||
EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */
|
||||
EINVAL, /* ERR_VAL -6 Illegal value. */
|
||||
EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */
|
||||
ECONNABORTED, /* ERR_ABRT -8 Connection aborted. */
|
||||
ECONNRESET, /* ERR_RST -9 Connection reset. */
|
||||
ESHUTDOWN, /* ERR_CLSD -10 Connection closed. */
|
||||
ENOTCONN, /* ERR_CONN -11 Not connected. */
|
||||
EIO, /* ERR_ARG -12 Illegal argument. */
|
||||
EADDRINUSE, /* ERR_USE -13 Address in use. */
|
||||
-1, /* ERR_IF -14 Low-level netif error */
|
||||
-1, /* ERR_ISCONN -15 Already connected. */
|
||||
EADDRINUSE, /* ERR_USE -8 Address in use. */
|
||||
EALREADY, /* ERR_ISCONN -9 Already connected. */
|
||||
ECONNABORTED, /* ERR_ABRT -10 Connection aborted. */
|
||||
ECONNRESET, /* ERR_RST -11 Connection reset. */
|
||||
ENOTCONN, /* ERR_CLSD -12 Connection closed. */
|
||||
ENOTCONN, /* ERR_CONN -13 Not connected. */
|
||||
EIO, /* ERR_ARG -14 Illegal argument. */
|
||||
-1, /* ERR_IF -15 Low-level netif error */
|
||||
};
|
||||
|
||||
#define ERR_TO_ERRNO_TABLE_SIZE \
|
||||
@@ -804,6 +806,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
||||
#if LWIP_TCP
|
||||
return lwip_send(s, data, size, flags);
|
||||
#else /* LWIP_TCP */
|
||||
LWIP_UNUSED_ARG(flags);
|
||||
sock_set_errno(sock, err_to_errno(ERR_ARG));
|
||||
return -1;
|
||||
#endif /* LWIP_TCP */
|
||||
@@ -844,14 +847,19 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
||||
inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr);
|
||||
remote_port = ntohs(to_in->sin_port);
|
||||
} else {
|
||||
remote_addr = IP_ADDR_ANY;
|
||||
remote_port = 0;
|
||||
remote_addr = &sock->conn->pcb.raw->remote_ip;
|
||||
if (sock->conn->type == NETCONN_RAW) {
|
||||
remote_port = 0;
|
||||
} else {
|
||||
remote_port = sock->conn->pcb.udp->remote_port;
|
||||
}
|
||||
}
|
||||
|
||||
LOCK_TCPIP_CORE();
|
||||
if (sock->conn->type == NETCONN_RAW) {
|
||||
err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr);
|
||||
} else {
|
||||
#if LWIP_UDP
|
||||
#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF
|
||||
err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p,
|
||||
remote_addr, remote_port, 1, chksum);
|
||||
@@ -859,6 +867,9 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
||||
err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p,
|
||||
remote_addr, remote_port);
|
||||
#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */
|
||||
#else /* LWIP_UDP */
|
||||
err = ERR_ARG;
|
||||
#endif /* LWIP_UDP */
|
||||
}
|
||||
UNLOCK_TCPIP_CORE();
|
||||
|
||||
@@ -883,7 +894,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
||||
netbuf_fromport(&buf) = 0;
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%d"U16_F", flags=0x%x to=",
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=",
|
||||
s, data, short_size, flags));
|
||||
ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr);
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port));
|
||||
@@ -1181,6 +1192,8 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL);
|
||||
select_cb.prev->next = select_cb.next;
|
||||
}
|
||||
/* Increasing this counter tells even_callback that the list has changed. */
|
||||
select_cb_ctr++;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
sys_sem_free(&select_cb.sem);
|
||||
@@ -1223,6 +1236,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
||||
int s;
|
||||
struct lwip_sock *sock;
|
||||
struct lwip_select_cb *scb;
|
||||
int last_select_cb_ctr;
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
LWIP_UNUSED_ARG(len);
|
||||
@@ -1285,56 +1299,51 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
||||
return;
|
||||
}
|
||||
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
/* Now decide if anyone is waiting for this socket */
|
||||
/* NOTE: This code is written this way to protect the select link list
|
||||
but to avoid a deadlock situation by releasing select_lock before
|
||||
signalling for the select. This means we need to go through the list
|
||||
multiple times ONLY IF a select was actually waiting. We go through
|
||||
the list the number of waiting select calls + 1. This list is
|
||||
expected to be small. */
|
||||
while (1) {
|
||||
int last_select_cb_ctr;
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
for (scb = select_cb_list; scb; scb = scb->next) {
|
||||
/* @todo: unprotect with each loop and check for changes? */
|
||||
if (scb->sem_signalled == 0) {
|
||||
/* Test this select call for our socket */
|
||||
/* NOTE: This code goes through the select_cb_list list multiple times
|
||||
ONLY IF a select was actually waiting. We go through the list the number
|
||||
of waiting select calls + 1. This list is expected to be small. */
|
||||
|
||||
/* At this point, SYS_ARCH is still protected! */
|
||||
again:
|
||||
for (scb = select_cb_list; scb != NULL; scb = scb->next) {
|
||||
if (scb->sem_signalled == 0) {
|
||||
/* semaphore not signalled yet */
|
||||
int do_signal = 0;
|
||||
/* Test this select call for our socket */
|
||||
if (sock->rcvevent > 0) {
|
||||
if (scb->readset && FD_ISSET(s, scb->readset)) {
|
||||
if (sock->rcvevent > 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scb->writeset && FD_ISSET(s, scb->writeset)) {
|
||||
if (sock->sendevent != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (scb->exceptset && FD_ISSET(s, scb->exceptset)) {
|
||||
if (sock->errevent != 0) {
|
||||
break;
|
||||
}
|
||||
do_signal = 1;
|
||||
}
|
||||
}
|
||||
/* unlock interrupts with each step */
|
||||
last_select_cb_ctr = select_cb_ctr;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (last_select_cb_ctr != select_cb_ctr) {
|
||||
/* someone has changed select_cb_list, restart at the beginning */
|
||||
scb = select_cb_list;
|
||||
if (sock->sendevent != 0) {
|
||||
if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) {
|
||||
do_signal = 1;
|
||||
}
|
||||
}
|
||||
if (sock->errevent != 0) {
|
||||
if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) {
|
||||
do_signal = 1;
|
||||
}
|
||||
}
|
||||
if (do_signal) {
|
||||
scb->sem_signalled = 1;
|
||||
/* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might
|
||||
lead to the select thread taking itself off the list, invalidagin the semaphore. */
|
||||
sys_sem_signal(&scb->sem);
|
||||
}
|
||||
}
|
||||
if (scb) {
|
||||
scb->sem_signalled = 1;
|
||||
sys_sem_signal(&scb->sem);
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
} else {
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
break;
|
||||
/* unlock interrupts with each step */
|
||||
last_select_cb_ctr = select_cb_ctr;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
/* this makes sure interrupt protection time is short */
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (last_select_cb_ctr != select_cb_ctr) {
|
||||
/* someone has changed select_cb_list, restart at the beginning */
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1610,6 +1619,9 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
|
||||
/* Now do the actual option processing */
|
||||
data.sock = sock;
|
||||
#ifdef LWIP_DEBUG
|
||||
data.s = s;
|
||||
#endif /* LWIP_DEBUG */
|
||||
data.level = level;
|
||||
data.optname = optname;
|
||||
data.optval = optval;
|
||||
@@ -1691,8 +1703,8 @@ lwip_getsockopt_internal(void *arg)
|
||||
break;
|
||||
|
||||
case SO_ERROR:
|
||||
/* only overwrite if ERR_OK before */
|
||||
if (sock->err == 0) {
|
||||
/* only overwrite ERR_OK or tempoary errors */
|
||||
if ((sock->err == 0) || (sock->err == EINPROGRESS)) {
|
||||
sock_set_errno(sock, err_to_errno(sock->conn->last_err));
|
||||
}
|
||||
*(int *)optval = sock->err;
|
||||
@@ -2017,6 +2029,9 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
|
||||
|
||||
/* Now do the actual option processing */
|
||||
data.sock = sock;
|
||||
#ifdef LWIP_DEBUG
|
||||
data.s = s;
|
||||
#endif /* LWIP_DEBUG */
|
||||
data.level = level;
|
||||
data.optname = optname;
|
||||
data.optval = (void*)optval;
|
||||
@@ -2239,15 +2254,18 @@ int
|
||||
lwip_ioctl(int s, long cmd, void *argp)
|
||||
{
|
||||
struct lwip_sock *sock = get_socket(s);
|
||||
u8_t val;
|
||||
#if LWIP_SO_RCVBUF
|
||||
u16_t buflen = 0;
|
||||
s16_t recv_avail;
|
||||
u8_t val;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
|
||||
if (!sock) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
#if LWIP_SO_RCVBUF
|
||||
case FIONREAD:
|
||||
if (!argp) {
|
||||
sock_set_errno(sock, EINVAL);
|
||||
@@ -2275,6 +2293,7 @@ lwip_ioctl(int s, long cmd, void *argp)
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp)));
|
||||
sock_set_errno(sock, 0);
|
||||
return 0;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
|
||||
case FIONBIO:
|
||||
val = 0;
|
||||
|
||||
@@ -592,6 +592,23 @@ dhcp_set_struct(struct netif *netif, struct dhcp *dhcp)
|
||||
netif->dhcp = dhcp;
|
||||
}
|
||||
|
||||
/** Removes a struct dhcp from a netif.
|
||||
*
|
||||
* ATTENTION: Only use this when not using dhcp_set_struct() to allocate the
|
||||
* struct dhcp since the memory is passed back to the heap.
|
||||
*
|
||||
* @param netif the netif from which to remove the struct dhcp
|
||||
*/
|
||||
void dhcp_cleanup(struct netif *netif)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", netif != NULL);
|
||||
|
||||
if (netif->dhcp != NULL) {
|
||||
mem_free(netif->dhcp);
|
||||
netif->dhcp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start DHCP negotiation for a network interface.
|
||||
*
|
||||
@@ -762,7 +779,10 @@ dhcp_network_changed(struct netif *netif)
|
||||
default:
|
||||
dhcp->tries = 0;
|
||||
#if LWIP_DHCP_AUTOIP_COOP
|
||||
dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
|
||||
if(dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
|
||||
autoip_stop(netif);
|
||||
dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF;
|
||||
}
|
||||
#endif /* LWIP_DHCP_AUTOIP_COOP */
|
||||
dhcp_discover(netif);
|
||||
break;
|
||||
@@ -945,11 +965,11 @@ dhcp_bind(struct netif *netif)
|
||||
/* subnet mask not given, choose a safe subnet mask given the network class */
|
||||
u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr);
|
||||
if (first_octet <= 127) {
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000));
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL));
|
||||
} else if (first_octet >= 192) {
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00));
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL));
|
||||
} else {
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000));
|
||||
ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -959,7 +979,7 @@ dhcp_bind(struct netif *netif)
|
||||
/* copy network address */
|
||||
ip_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask);
|
||||
/* use first host address on network as gateway */
|
||||
ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001));
|
||||
ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL));
|
||||
}
|
||||
|
||||
#if LWIP_DHCP_AUTOIP_COOP
|
||||
|
||||
@@ -922,6 +922,7 @@ dns_enqueue(const char *name, dns_found_callback found, void *callback_arg)
|
||||
* name is already in the local names table.
|
||||
* - ERR_INPROGRESS enqueue a request to be sent to the DNS server
|
||||
* for resolution if no errors are present.
|
||||
* - ERR_ARG: dns client not initialized or invalid hostname
|
||||
*
|
||||
* @param hostname the hostname that is to be queried
|
||||
* @param addr pointer to a ip_addr_t where to store the address if it is already
|
||||
@@ -941,7 +942,7 @@ dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback foun
|
||||
if ((dns_pcb == NULL) || (addr == NULL) ||
|
||||
(!hostname) || (!hostname[0]) ||
|
||||
(strlen(hostname) >= DNS_MAX_NAME_LENGTH)) {
|
||||
return ERR_VAL;
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
#if LWIP_HAVE_LOOPIF
|
||||
|
||||
@@ -105,6 +105,9 @@
|
||||
#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff))
|
||||
#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h"
|
||||
#endif
|
||||
#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2))
|
||||
#error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work"
|
||||
#endif
|
||||
#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12)))
|
||||
#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h"
|
||||
#endif
|
||||
|
||||
@@ -494,12 +494,7 @@ autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr)
|
||||
*/
|
||||
ip_addr_t sipaddr, dipaddr;
|
||||
struct eth_addr netifaddr;
|
||||
netifaddr.addr[0] = netif->hwaddr[0];
|
||||
netifaddr.addr[1] = netif->hwaddr[1];
|
||||
netifaddr.addr[2] = netif->hwaddr[2];
|
||||
netifaddr.addr[3] = netif->hwaddr[3];
|
||||
netifaddr.addr[4] = netif->hwaddr[4];
|
||||
netifaddr.addr[5] = netif->hwaddr[5];
|
||||
ETHADDR16_COPY(netifaddr.addr, netif->hwaddr);
|
||||
|
||||
/* Copy struct ip_addr2 to aligned ip_addr, to support compilers without
|
||||
* structure packing (not using structure copy which breaks strict-aliasing rules).
|
||||
|
||||
@@ -191,7 +191,7 @@ icmp_input(struct pbuf *p, struct netif *inp)
|
||||
ip_addr_copy(iphdr->dest, *ip_current_src_addr());
|
||||
ICMPH_TYPE_SET(iecho, ICMP_ER);
|
||||
/* adjust the checksum */
|
||||
if (iecho->chksum >= PP_HTONS(0xffff - (ICMP_ECHO << 8))) {
|
||||
if (iecho->chksum >= PP_HTONS(0xffffU - (ICMP_ECHO << 8))) {
|
||||
iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1;
|
||||
} else {
|
||||
iecho->chksum += PP_HTONS(ICMP_ECHO << 8);
|
||||
|
||||
@@ -100,7 +100,7 @@ Steve Reynolds
|
||||
*/
|
||||
#define IGMP_TTL 1
|
||||
#define IGMP_MINLEN 8
|
||||
#define ROUTER_ALERT 0x9404
|
||||
#define ROUTER_ALERT 0x9404U
|
||||
#define ROUTER_ALERTLEN 4
|
||||
|
||||
/*
|
||||
|
||||
@@ -201,7 +201,7 @@ ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
|
||||
}
|
||||
|
||||
/* Incrementally update the IP checksum. */
|
||||
if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffff - 0x100)) {
|
||||
if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) {
|
||||
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1);
|
||||
} else {
|
||||
IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100));
|
||||
@@ -625,7 +625,7 @@ err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
|
||||
memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
|
||||
}
|
||||
#if CHECKSUM_GEN_IP_INLINE
|
||||
for (i = 0; i < optlen_aligned; i += sizeof(u16_t)) {
|
||||
for (i = 0; i < optlen_aligned/2; i++) {
|
||||
chk_sum += ((u16_t*)p->payload)[i];
|
||||
}
|
||||
#endif /* CHECKSUM_GEN_IP_INLINE */
|
||||
|
||||
@@ -93,7 +93,7 @@ ip4_addr_netmask_valid(u32_t netmask)
|
||||
u32_t nm_hostorder = lwip_htonl(netmask);
|
||||
|
||||
/* first, check for the first zero */
|
||||
for (mask = 1U << 31 ; mask != 0; mask >>= 1) {
|
||||
for (mask = 1UL << 31 ; mask != 0; mask >>= 1) {
|
||||
if ((nm_hostorder & mask) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -218,8 +218,10 @@ raw_sendto(struct raw_pcb *pcb, struct pbuf *p, ip_addr_t *ipaddr)
|
||||
LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
/* chain header q in front of given pbuf p */
|
||||
pbuf_chain(q, p);
|
||||
if (p->tot_len != 0) {
|
||||
/* chain header q in front of given pbuf p */
|
||||
pbuf_chain(q, p);
|
||||
}
|
||||
/* { first pbuf q points to header pbuf } */
|
||||
LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p));
|
||||
} else {
|
||||
|
||||
@@ -43,10 +43,12 @@
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/ip_frag.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/tcp_impl.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/snmp_asn1.h"
|
||||
#include "lwip/snmp_structs.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "netif/etharp.h"
|
||||
|
||||
/**
|
||||
|
||||
@@ -91,7 +91,7 @@ struct tcp_pcb *tcp_tw_pcbs;
|
||||
#define NUM_TCP_PCB_LISTS 4
|
||||
#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3
|
||||
/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */
|
||||
struct tcp_pcb **tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
|
||||
struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs,
|
||||
&tcp_active_pcbs, &tcp_tw_pcbs};
|
||||
|
||||
/** Only used for temporary storage. */
|
||||
@@ -173,7 +173,9 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data)
|
||||
* is erroneous, but this should never happen as the pcb has in those cases
|
||||
* been freed, and so any remaining handles are bogus. */
|
||||
err = ERR_OK;
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
if (pcb->local_port != 0) {
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
}
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
pcb = NULL;
|
||||
break;
|
||||
@@ -391,6 +393,7 @@ tcp_abort(struct tcp_pcb *pcb)
|
||||
* to any local address
|
||||
* @param port the local port to bind to
|
||||
* @return ERR_USE if the port is already in use
|
||||
* ERR_VAL if bind failed because the PCB is not in a valid state
|
||||
* ERR_OK if bound
|
||||
*/
|
||||
err_t
|
||||
@@ -400,7 +403,7 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
||||
int max_pcb_list = NUM_TCP_PCB_LISTS;
|
||||
struct tcp_pcb *cpcb;
|
||||
|
||||
LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
|
||||
LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL);
|
||||
|
||||
#if SO_REUSE
|
||||
/* Unless the REUSEADDR flag is set,
|
||||
@@ -408,11 +411,9 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
||||
We do not dump TIME_WAIT pcb's; they can still be matched by incoming
|
||||
packets using both local and remote IP addresses and ports to distinguish.
|
||||
*/
|
||||
#if SO_REUSE
|
||||
if ((pcb->so_options & SOF_REUSEADDR) != 0) {
|
||||
max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT;
|
||||
}
|
||||
#endif /* SO_REUSE */
|
||||
#endif /* SO_REUSE */
|
||||
|
||||
if (port == 0) {
|
||||
@@ -518,7 +519,9 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog)
|
||||
lpcb->ttl = pcb->ttl;
|
||||
lpcb->tos = pcb->tos;
|
||||
ip_addr_copy(lpcb->local_ip, pcb->local_ip);
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
if (pcb->local_port != 0) {
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
}
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
#if LWIP_CALLBACK_API
|
||||
lpcb->accept = tcp_accept_null;
|
||||
@@ -608,17 +611,19 @@ tcp_new_port(void)
|
||||
int i;
|
||||
struct tcp_pcb *pcb;
|
||||
#ifndef TCP_LOCAL_PORT_RANGE_START
|
||||
#define TCP_LOCAL_PORT_RANGE_START 4096
|
||||
#define TCP_LOCAL_PORT_RANGE_END 0x7fff
|
||||
/* From http://www.iana.org/assignments/port-numbers:
|
||||
"The Dynamic and/or Private Ports are those from 49152 through 65535" */
|
||||
#define TCP_LOCAL_PORT_RANGE_START 0xc000
|
||||
#define TCP_LOCAL_PORT_RANGE_END 0xffff
|
||||
#endif
|
||||
static u16_t port = TCP_LOCAL_PORT_RANGE_START;
|
||||
|
||||
again:
|
||||
if (++port > TCP_LOCAL_PORT_RANGE_END) {
|
||||
if (port++ >= TCP_LOCAL_PORT_RANGE_END) {
|
||||
port = TCP_LOCAL_PORT_RANGE_START;
|
||||
}
|
||||
/* Check all PCB lists. */
|
||||
for (i = 1; i < NUM_TCP_PCB_LISTS; i++) {
|
||||
for (i = 0; i < NUM_TCP_PCB_LISTS; i++) {
|
||||
for(pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) {
|
||||
if (pcb->local_port == port) {
|
||||
goto again;
|
||||
@@ -646,8 +651,9 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
||||
{
|
||||
err_t ret;
|
||||
u32_t iss;
|
||||
u16_t old_local_port;
|
||||
|
||||
LWIP_ERROR("tcp_connect: can only connected from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
|
||||
LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN);
|
||||
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port));
|
||||
if (ipaddr != NULL) {
|
||||
@@ -670,6 +676,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
||||
ip_addr_copy(pcb->local_ip, netif->ip_addr);
|
||||
}
|
||||
|
||||
old_local_port = pcb->local_port;
|
||||
if (pcb->local_port == 0) {
|
||||
pcb->local_port = tcp_new_port();
|
||||
}
|
||||
@@ -679,8 +686,8 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
||||
now that the 5-tuple is unique. */
|
||||
struct tcp_pcb *cpcb;
|
||||
int i;
|
||||
/* Don't check listen PCBs, check bound-, active- and TIME-WAIT PCBs. */
|
||||
for (i = 1; i < NUM_TCP_PCB_LISTS; i++) {
|
||||
/* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */
|
||||
for (i = 2; i < NUM_TCP_PCB_LISTS; i++) {
|
||||
for(cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) {
|
||||
if ((cpcb->local_port == pcb->local_port) &&
|
||||
(cpcb->remote_port == port) &&
|
||||
@@ -721,7 +728,9 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
||||
if (ret == ERR_OK) {
|
||||
/* SYN segment was enqueued, changed the pcbs state now */
|
||||
pcb->state = SYN_SENT;
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
if (old_local_port != 0) {
|
||||
TCP_RMV(&tcp_bound_pcbs, pcb);
|
||||
}
|
||||
TCP_REG(&tcp_active_pcbs, pcb);
|
||||
snmp_inc_tcpactiveopens();
|
||||
|
||||
@@ -740,7 +749,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port,
|
||||
void
|
||||
tcp_slowtmr(void)
|
||||
{
|
||||
struct tcp_pcb *pcb, *pcb2, *prev;
|
||||
struct tcp_pcb *pcb, *prev;
|
||||
u16_t eff_wnd;
|
||||
u8_t pcb_remove; /* flag if a PCB should be removed */
|
||||
u8_t pcb_reset; /* flag if a RST should be sent when removing */
|
||||
@@ -896,6 +905,7 @@ tcp_slowtmr(void)
|
||||
|
||||
/* If the PCB should be removed, do it. */
|
||||
if (pcb_remove) {
|
||||
struct tcp_pcb *pcb2;
|
||||
tcp_pcb_purge(pcb);
|
||||
/* Remove PCB from tcp_active_pcbs list. */
|
||||
if (prev != NULL) {
|
||||
@@ -913,9 +923,9 @@ tcp_slowtmr(void)
|
||||
pcb->local_port, pcb->remote_port);
|
||||
}
|
||||
|
||||
pcb2 = pcb->next;
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
pcb = pcb2;
|
||||
pcb2 = pcb;
|
||||
pcb = pcb->next;
|
||||
memp_free(MEMP_TCP_PCB, pcb2);
|
||||
} else {
|
||||
/* get the 'next' element now and work with 'prev' below (in case of abort) */
|
||||
prev = pcb;
|
||||
@@ -937,7 +947,7 @@ tcp_slowtmr(void)
|
||||
|
||||
|
||||
/* Steps through all of the TIME-WAIT PCBs. */
|
||||
prev = NULL;
|
||||
prev = NULL;
|
||||
pcb = tcp_tw_pcbs;
|
||||
while (pcb != NULL) {
|
||||
LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT);
|
||||
@@ -952,6 +962,7 @@ tcp_slowtmr(void)
|
||||
|
||||
/* If the PCB should be removed, do it. */
|
||||
if (pcb_remove) {
|
||||
struct tcp_pcb *pcb2;
|
||||
tcp_pcb_purge(pcb);
|
||||
/* Remove PCB from tcp_tw_pcbs list. */
|
||||
if (prev != NULL) {
|
||||
@@ -962,9 +973,9 @@ tcp_slowtmr(void)
|
||||
LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb);
|
||||
tcp_tw_pcbs = pcb->next;
|
||||
}
|
||||
pcb2 = pcb->next;
|
||||
memp_free(MEMP_TCP_PCB, pcb);
|
||||
pcb = pcb2;
|
||||
pcb2 = pcb;
|
||||
pcb = pcb->next;
|
||||
memp_free(MEMP_TCP_PCB, pcb2);
|
||||
} else {
|
||||
prev = pcb;
|
||||
pcb = pcb->next;
|
||||
@@ -999,7 +1010,7 @@ tcp_fasttmr(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* send delayed ACKs */
|
||||
/* send delayed ACKs */
|
||||
if (pcb && (pcb->flags & TF_ACK_DELAY)) {
|
||||
LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n"));
|
||||
tcp_ack_now(pcb);
|
||||
|
||||
@@ -291,7 +291,6 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
/* Set up a tcp_seg structure. */
|
||||
inseg.next = NULL;
|
||||
inseg.len = p->tot_len;
|
||||
inseg.dataptr = p->payload;
|
||||
inseg.p = p;
|
||||
inseg.tcphdr = tcphdr;
|
||||
|
||||
@@ -305,9 +304,10 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
TCP_EVENT_RECV(pcb, pcb->refused_data, ERR_OK, err);
|
||||
if (err == ERR_OK) {
|
||||
pcb->refused_data = NULL;
|
||||
} else {
|
||||
} else if ((err == ERR_ABRT) || (tcplen > 0)) {
|
||||
/* if err == ERR_ABRT, 'pcb' is already deallocated */
|
||||
/* drop incoming packets, because pcb is "full" */
|
||||
/* Drop incoming packets because pcb is "full" (only if the incoming
|
||||
segment contains data). */
|
||||
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n"));
|
||||
TCP_STATS_INC(tcp.drop);
|
||||
snmp_inc_tcpinerrs();
|
||||
@@ -346,6 +346,7 @@ tcp_input(struct pbuf *p, struct netif *inp)
|
||||
}
|
||||
|
||||
if (recv_data != NULL) {
|
||||
LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL);
|
||||
if (pcb->flags & TF_RXCLOSED) {
|
||||
/* received data although already closed -> abort (send RST) to
|
||||
notify the remote host that not all data has been processed */
|
||||
@@ -1165,9 +1166,6 @@ tcp_receive(struct tcp_pcb *pcb)
|
||||
LWIP_ASSERT("pbuf_header failed", 0);
|
||||
}
|
||||
}
|
||||
/* KJM following line changed to use p->payload rather than inseg->p->payload
|
||||
to fix bug #9076 */
|
||||
inseg.dataptr = p->payload;
|
||||
inseg.len -= (u16_t)(pcb->rcv_nxt - seqno);
|
||||
inseg.tcphdr->seqno = seqno = pcb->rcv_nxt;
|
||||
}
|
||||
|
||||
@@ -166,7 +166,6 @@ tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno,
|
||||
seg->flags = optflags;
|
||||
seg->next = NULL;
|
||||
seg->p = p;
|
||||
seg->dataptr = p->payload;
|
||||
seg->len = p->tot_len - optlen;
|
||||
#if TCP_OVERSIZE_DBGCHECK
|
||||
seg->oversize_left = 0;
|
||||
@@ -590,10 +589,6 @@ tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags)
|
||||
seg->chksum_swapped = chksum_swapped;
|
||||
seg->flags |= TF_SEG_DATA_CHECKSUMMED;
|
||||
#endif /* TCP_CHECKSUM_ON_COPY */
|
||||
/* Fix dataptr for the nocopy case */
|
||||
if ((apiflags & TCP_WRITE_FLAG_COPY) == 0) {
|
||||
seg->dataptr = (u8_t*)arg + pos;
|
||||
}
|
||||
|
||||
/* first segment of to-be-queued data? */
|
||||
if (queue == NULL) {
|
||||
@@ -773,6 +768,7 @@ tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags)
|
||||
TCP_STATS_INC(tcp.memerr);
|
||||
return ERR_MEM;
|
||||
}
|
||||
LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
|
||||
LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0);
|
||||
|
||||
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE,
|
||||
@@ -1067,7 +1063,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
||||
|
||||
/* Add any requested options. NB MSS option is only set on SYN
|
||||
packets, so ignore it here */
|
||||
LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)(seg->tcphdr + 1) % 4) == 0);
|
||||
LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % MEM_ALIGNMENT) == 0);
|
||||
opts = (u32_t *)(void *)(seg->tcphdr + 1);
|
||||
if (seg->flags & TF_SEG_OPTS_MSS) {
|
||||
TCP_BUILD_MSS_OPTION(*opts);
|
||||
@@ -1082,6 +1078,12 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set retransmission timer running if it is not currently enabled
|
||||
This must be set before checking the route. */
|
||||
if (pcb->rtime == -1) {
|
||||
pcb->rtime = 0;
|
||||
}
|
||||
|
||||
/* If we don't have a local IP address, we get one by
|
||||
calling ip_route(). */
|
||||
if (ip_addr_isany(&(pcb->local_ip))) {
|
||||
@@ -1092,11 +1094,6 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb)
|
||||
ip_addr_copy(pcb->local_ip, netif->ip_addr);
|
||||
}
|
||||
|
||||
/* Set retransmission timer running if it is not currently enabled */
|
||||
if(pcb->rtime == -1) {
|
||||
pcb->rtime = 0;
|
||||
}
|
||||
|
||||
if (pcb->rttest == 0) {
|
||||
pcb->rttest = tcp_ticks;
|
||||
pcb->rtseq = ntohl(seg->tcphdr->seqno);
|
||||
@@ -1443,7 +1440,9 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
|
||||
TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN);
|
||||
} else {
|
||||
/* Data segment, copy in one byte from the head of the unacked queue */
|
||||
*((char *)p->payload + TCP_HLEN) = *(char *)seg->dataptr;
|
||||
struct tcp_hdr *thdr = (struct tcp_hdr *)seg->p->payload;
|
||||
char *d = ((char *)p->payload + TCP_HLEN);
|
||||
pbuf_copy_partial(seg->p, d, 1, TCPH_HDRLEN(thdr) * 4);
|
||||
}
|
||||
|
||||
#if CHECKSUM_GEN_TCP
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include "lwip/timers.h"
|
||||
#include "lwip/tcp_impl.h"
|
||||
|
||||
#if LWIP_TIMERS
|
||||
|
||||
@@ -49,7 +50,6 @@
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/tcpip.h"
|
||||
|
||||
#include "lwip/tcp_impl.h"
|
||||
#include "lwip/ip_frag.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/dhcp.h"
|
||||
|
||||
@@ -520,8 +520,10 @@ udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, ip_addr_t *dst_ip,
|
||||
LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
/* chain header q in front of given pbuf p */
|
||||
pbuf_chain(q, p);
|
||||
if (p->tot_len != 0) {
|
||||
/* chain header q in front of given pbuf p (only if p contains data) */
|
||||
pbuf_chain(q, 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));
|
||||
@@ -744,8 +746,10 @@ udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, u16_t port)
|
||||
/* no port specified? */
|
||||
if (port == 0) {
|
||||
#ifndef UDP_LOCAL_PORT_RANGE_START
|
||||
#define UDP_LOCAL_PORT_RANGE_START 4096
|
||||
#define UDP_LOCAL_PORT_RANGE_END 0x7fff
|
||||
/* From http://www.iana.org/assignments/port-numbers:
|
||||
"The Dynamic and/or Private Ports are those from 49152 through 65535" */
|
||||
#define UDP_LOCAL_PORT_RANGE_START 0xc000
|
||||
#define UDP_LOCAL_PORT_RANGE_END 0xffff
|
||||
#endif
|
||||
port = UDP_LOCAL_PORT_RANGE_START;
|
||||
ipcb = udp_pcbs;
|
||||
|
||||
@@ -41,29 +41,29 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ICMP_ER 0 /* echo reply */
|
||||
#define ICMP_DUR 3 /* destination unreachable */
|
||||
#define ICMP_SQ 4 /* source quench */
|
||||
#define ICMP_RD 5 /* redirect */
|
||||
#define ICMP_ER 0 /* echo reply */
|
||||
#define ICMP_DUR 3 /* destination unreachable */
|
||||
#define ICMP_SQ 4 /* source quench */
|
||||
#define ICMP_RD 5 /* redirect */
|
||||
#define ICMP_ECHO 8 /* echo */
|
||||
#define ICMP_TE 11 /* time exceeded */
|
||||
#define ICMP_PP 12 /* parameter problem */
|
||||
#define ICMP_TS 13 /* timestamp */
|
||||
#define ICMP_TE 11 /* time exceeded */
|
||||
#define ICMP_PP 12 /* parameter problem */
|
||||
#define ICMP_TS 13 /* timestamp */
|
||||
#define ICMP_TSR 14 /* timestamp reply */
|
||||
#define ICMP_IRQ 15 /* information request */
|
||||
#define ICMP_IR 16 /* information reply */
|
||||
#define ICMP_IR 16 /* information reply */
|
||||
|
||||
enum icmp_dur_type {
|
||||
ICMP_DUR_NET = 0, /* net unreachable */
|
||||
ICMP_DUR_HOST = 1, /* host unreachable */
|
||||
ICMP_DUR_NET = 0, /* net unreachable */
|
||||
ICMP_DUR_HOST = 1, /* host unreachable */
|
||||
ICMP_DUR_PROTO = 2, /* protocol unreachable */
|
||||
ICMP_DUR_PORT = 3, /* port unreachable */
|
||||
ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
|
||||
ICMP_DUR_SR = 5 /* source route failed */
|
||||
ICMP_DUR_PORT = 3, /* port unreachable */
|
||||
ICMP_DUR_FRAG = 4, /* fragmentation needed and DF set */
|
||||
ICMP_DUR_SR = 5 /* source route failed */
|
||||
};
|
||||
|
||||
enum icmp_te_type {
|
||||
ICMP_TE_TTL = 0, /* time to live exceeded in transit */
|
||||
ICMP_TE_TTL = 0, /* time to live exceeded in transit */
|
||||
ICMP_TE_FRAG = 1 /* fragment reassembly time exceeded */
|
||||
};
|
||||
|
||||
|
||||
@@ -122,10 +122,10 @@ struct ip_hdr {
|
||||
PACK_STRUCT_FIELD(u16_t _id);
|
||||
/* fragment offset field */
|
||||
PACK_STRUCT_FIELD(u16_t _offset);
|
||||
#define IP_RF 0x8000 /* reserved fragment flag */
|
||||
#define IP_DF 0x4000 /* dont fragment flag */
|
||||
#define IP_MF 0x2000 /* more fragments flag */
|
||||
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
|
||||
#define IP_RF 0x8000U /* reserved fragment flag */
|
||||
#define IP_DF 0x4000U /* dont fragment flag */
|
||||
#define IP_MF 0x2000U /* more fragments flag */
|
||||
#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */
|
||||
/* time to live */
|
||||
PACK_STRUCT_FIELD(u8_t _ttl);
|
||||
/* protocol*/
|
||||
|
||||
@@ -168,12 +168,11 @@ struct netconn {
|
||||
/** maximum amount of bytes queued in recvmbox
|
||||
not used for TCP: adjust TCP_WND instead! */
|
||||
int recv_bufsize;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/** number of bytes currently in recvmbox to be received,
|
||||
tested against recv_bufsize to limit bytes on recvmbox
|
||||
for UDP and RAW
|
||||
@todo: should only be necessary with LWIP_SO_RCVBUF==1 */
|
||||
for UDP and RAW, used for FIONREAD */
|
||||
s16_t recv_avail;
|
||||
#endif /* LWIP_SO_RCVBUF */
|
||||
/** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */
|
||||
u8_t flags;
|
||||
#if LWIP_TCP
|
||||
|
||||
@@ -48,9 +48,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For the netconn API, these values are use as a bitmask! */
|
||||
#define NETCONN_SHUT_RD 1
|
||||
#define NETCONN_SHUT_WR 2
|
||||
#define NETCONN_SHUT_RDWR 3
|
||||
#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR)
|
||||
|
||||
/* IP addresses and port numbers are expected to be in
|
||||
* the same byte order as in the corresponding pcb.
|
||||
|
||||
@@ -106,6 +106,9 @@ PACK_STRUCT_END
|
||||
#endif
|
||||
|
||||
void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp);
|
||||
/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */
|
||||
#define dhcp_remove_struct(netif) do { (netif)->dhcp = NULL; } while(0)
|
||||
void dhcp_cleanup(struct netif *netif);
|
||||
/** start DHCP configuration */
|
||||
err_t dhcp_start(struct netif *netif);
|
||||
/** enforce early lease renewal (not needed normally)*/
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
|
||||
#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** DNS timer period */
|
||||
#define DNS_TMR_INTERVAL 1000
|
||||
|
||||
@@ -111,6 +115,10 @@ int dns_local_removehost(const char *hostname, const ip_addr_t *addr)
|
||||
err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr);
|
||||
#endif /* DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_DNS */
|
||||
|
||||
#endif /* __LWIP_DNS_H__ */
|
||||
|
||||
@@ -57,20 +57,19 @@ typedef s8_t err_t;
|
||||
#define ERR_INPROGRESS -5 /* Operation in progress */
|
||||
#define ERR_VAL -6 /* Illegal value. */
|
||||
#define ERR_WOULDBLOCK -7 /* Operation would block. */
|
||||
#define ERR_USE -8 /* Address in use. */
|
||||
#define ERR_ISCONN -9 /* Already connected. */
|
||||
|
||||
#define ERR_IS_FATAL(e) ((e) < ERR_VAL)
|
||||
#define ERR_IS_FATAL(e) ((e) < ERR_ISCONN)
|
||||
|
||||
#define ERR_ABRT -8 /* Connection aborted. */
|
||||
#define ERR_RST -9 /* Connection reset. */
|
||||
#define ERR_CLSD -10 /* Connection closed. */
|
||||
#define ERR_CONN -11 /* Not connected. */
|
||||
#define ERR_ABRT -10 /* Connection aborted. */
|
||||
#define ERR_RST -11 /* Connection reset. */
|
||||
#define ERR_CLSD -12 /* Connection closed. */
|
||||
#define ERR_CONN -13 /* Not connected. */
|
||||
|
||||
#define ERR_ARG -12 /* Illegal argument. */
|
||||
#define ERR_ARG -14 /* Illegal argument. */
|
||||
|
||||
#define ERR_USE -13 /* Address in use. */
|
||||
|
||||
#define ERR_IF -14 /* Low-level netif error */
|
||||
#define ERR_ISCONN -15 /* Already connected. */
|
||||
#define ERR_IF -15 /* Low-level netif error */
|
||||
|
||||
|
||||
#ifdef LWIP_DEBUG
|
||||
|
||||
@@ -47,7 +47,7 @@ extern "C" {
|
||||
/** For release candidates, this is set to 1..254
|
||||
* For official releases, this is set to 255 (LWIP_RC_RELEASE)
|
||||
* For development versions (CVS), this is set to 0 (LWIP_RC_DEVELOPMENT) */
|
||||
#define LWIP_VERSION_RC 1U
|
||||
#define LWIP_VERSION_RC 255U
|
||||
|
||||
/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */
|
||||
#define LWIP_RC_RELEASE 255U
|
||||
|
||||
@@ -68,7 +68,7 @@ typedef size_t mem_size_t;
|
||||
/* MEM_SIZE would have to be aligned, but using 64000 here instead of
|
||||
* 65535 leaves some room for alignment...
|
||||
*/
|
||||
#if MEM_SIZE > 64000l
|
||||
#if MEM_SIZE > 64000L
|
||||
typedef u32_t mem_size_t;
|
||||
#define MEM_SIZE_F U32_F
|
||||
#else
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
#include "lwip/inet.h"
|
||||
#include "lwip/sockets.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* some rarely used options */
|
||||
#ifndef LWIP_DNS_API_DECLARE_H_ERRNO
|
||||
#define LWIP_DNS_API_DECLARE_H_ERRNO 1
|
||||
@@ -111,6 +115,10 @@ int lwip_getaddrinfo(const char *nodename,
|
||||
lwip_getaddrinfo(nodname, servname, hints, res)
|
||||
#endif /* LWIP_COMPAT_SOCKETS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_DNS && LWIP_SOCKET */
|
||||
|
||||
#endif /* __LWIP_NETDB_H__ */
|
||||
|
||||
@@ -432,11 +432,14 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ARP_QUEUEING==1: Outgoing packets are queued during hardware address
|
||||
* resolution.
|
||||
* ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address
|
||||
* resolution. By default, only the most recent packet is queued per IP address.
|
||||
* This is sufficient for most protocols and mainly reduces TCP connection
|
||||
* startup time. Set this to 1 if you know your application sends more than one
|
||||
* packet in a row to an IP address that is not in the ARP cache.
|
||||
*/
|
||||
#ifndef ARP_QUEUEING
|
||||
#define ARP_QUEUEING 1
|
||||
#define ARP_QUEUEING 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -954,7 +957,7 @@
|
||||
* as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work.
|
||||
*/
|
||||
#ifndef TCP_SND_QUEUELEN
|
||||
#define TCP_SND_QUEUELEN (4 * (TCP_SND_BUF)/(TCP_MSS))
|
||||
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -59,7 +59,7 @@ struct sockaddr_in {
|
||||
struct sockaddr {
|
||||
u8_t sa_len;
|
||||
u8_t sa_family;
|
||||
u16_t sa_data[14];
|
||||
char sa_data[14];
|
||||
};
|
||||
|
||||
#ifndef socklen_t
|
||||
@@ -280,9 +280,9 @@ typedef struct ip_mreq {
|
||||
#endif
|
||||
|
||||
#ifndef SHUT_RD
|
||||
#define SHUT_RD 1
|
||||
#define SHUT_WR 2
|
||||
#define SHUT_RDWR 3
|
||||
#define SHUT_RD 0
|
||||
#define SHUT_WR 1
|
||||
#define SHUT_RDWR 2
|
||||
#endif
|
||||
|
||||
/* FD_SET used for lwip_select */
|
||||
|
||||
@@ -228,7 +228,7 @@ struct tcp_pcb {
|
||||
u16_t acked;
|
||||
|
||||
u16_t snd_buf; /* Available buffer space for sending (in bytes). */
|
||||
#define TCP_SNDQUEUELEN_OVERFLOW (0xffff-3)
|
||||
#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3)
|
||||
u16_t snd_queuelen; /* Available buffer space for sending (in tcp_segs). */
|
||||
|
||||
#if TCP_OVERSIZE
|
||||
|
||||
@@ -278,7 +278,6 @@ PACK_STRUCT_END
|
||||
struct tcp_seg {
|
||||
struct tcp_seg *next; /* used when putting segements on a queue */
|
||||
struct pbuf *p; /* buffer containing data + TCP header */
|
||||
void *dataptr; /* pointer to the TCP data in the pbuf */
|
||||
u16_t len; /* the TCP length of this segment */
|
||||
#if TCP_OVERSIZE_DBGCHECK
|
||||
u16_t oversize_left; /* Extra bytes available at the end of the last
|
||||
|
||||
@@ -94,8 +94,8 @@ PACK_STRUCT_BEGIN
|
||||
* if 'type' in ethernet header is ETHTYPE_VLAN.
|
||||
* See IEEE802.Q */
|
||||
struct eth_vlan_hdr {
|
||||
PACK_STRUCT_FIELD(u16_t tpid);
|
||||
PACK_STRUCT_FIELD(u16_t prio_vid);
|
||||
PACK_STRUCT_FIELD(u16_t tpid);
|
||||
} PACK_STRUCT_STRUCT;
|
||||
PACK_STRUCT_END
|
||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||
@@ -134,11 +134,11 @@ PACK_STRUCT_END
|
||||
/** 5 seconds period */
|
||||
#define ARP_TMR_INTERVAL 5000
|
||||
|
||||
#define ETHTYPE_ARP 0x0806
|
||||
#define ETHTYPE_IP 0x0800
|
||||
#define ETHTYPE_VLAN 0x8100
|
||||
#define ETHTYPE_PPPOEDISC 0x8863 /* PPP Over Ethernet Discovery Stage */
|
||||
#define ETHTYPE_PPPOE 0x8864 /* PPP Over Ethernet Session Stage */
|
||||
#define ETHTYPE_ARP 0x0806U
|
||||
#define ETHTYPE_IP 0x0800U
|
||||
#define ETHTYPE_VLAN 0x8100U
|
||||
#define ETHTYPE_PPPOEDISC 0x8863U /* PPP Over Ethernet Discovery Stage */
|
||||
#define ETHTYPE_PPPOE 0x8864U /* PPP Over Ethernet Session Stage */
|
||||
|
||||
/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables
|
||||
* or known to be 32-bit aligned within the protocol header. */
|
||||
|
||||
@@ -93,6 +93,9 @@ struct etharp_entry {
|
||||
#if ARP_QUEUEING
|
||||
/** Pointer to queue of pending outgoing packets on this ARP entry. */
|
||||
struct etharp_q_entry *q;
|
||||
#else /* ARP_QUEUEING */
|
||||
/** Pointer to a single pending outgoing packet on this ARP entry. */
|
||||
struct pbuf *q;
|
||||
#endif /* ARP_QUEUEING */
|
||||
ip_addr_t ipaddr;
|
||||
struct eth_addr ethaddr;
|
||||
@@ -154,6 +157,11 @@ free_etharp_q(struct etharp_q_entry *q)
|
||||
memp_free(MEMP_ARP_QUEUE, r);
|
||||
}
|
||||
}
|
||||
#else /* ARP_QUEUEING */
|
||||
|
||||
/** Compatibility define: free the queued pbuf */
|
||||
#define free_etharp_q(q) pbuf_free(q)
|
||||
|
||||
#endif /* ARP_QUEUEING */
|
||||
|
||||
/** Clean up ARP table entries */
|
||||
@@ -162,7 +170,6 @@ free_entry(int i)
|
||||
{
|
||||
/* remove from SNMP ARP index tree */
|
||||
snmp_delete_arpidx_tree(arp_table[i].netif, &arp_table[i].ipaddr);
|
||||
#if ARP_QUEUEING
|
||||
/* and empty packet queue */
|
||||
if (arp_table[i].q != NULL) {
|
||||
/* remove all queued packets */
|
||||
@@ -170,7 +177,6 @@ free_entry(int i)
|
||||
free_etharp_q(arp_table[i].q);
|
||||
arp_table[i].q = NULL;
|
||||
}
|
||||
#endif /* ARP_QUEUEING */
|
||||
/* recycle entry for re-use */
|
||||
arp_table[i].state = ETHARP_STATE_EMPTY;
|
||||
#if ETHARP_SUPPORT_STATIC_ENTRIES
|
||||
@@ -254,12 +260,10 @@ find_entry(ip_addr_t *ipaddr, u8_t flags)
|
||||
s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE;
|
||||
s8_t empty = ARP_TABLE_SIZE;
|
||||
u8_t i = 0, age_pending = 0, age_stable = 0;
|
||||
#if ARP_QUEUEING
|
||||
/* oldest entry with packets on queue */
|
||||
s8_t old_queue = ARP_TABLE_SIZE;
|
||||
/* its age */
|
||||
u8_t age_queue = 0;
|
||||
#endif /* ARP_QUEUEING */
|
||||
|
||||
/**
|
||||
* a) do a search through the cache, remember candidates
|
||||
@@ -295,14 +299,12 @@ find_entry(ip_addr_t *ipaddr, u8_t flags)
|
||||
/* pending entry? */
|
||||
if (state == ETHARP_STATE_PENDING) {
|
||||
/* pending with queued packets? */
|
||||
#if ARP_QUEUEING
|
||||
if (arp_table[i].q != NULL) {
|
||||
if (arp_table[i].ctime >= age_queue) {
|
||||
old_queue = i;
|
||||
age_queue = arp_table[i].ctime;
|
||||
}
|
||||
} else
|
||||
#endif /* ARP_QUEUEING */
|
||||
/* pending without queued packets? */
|
||||
{
|
||||
if (arp_table[i].ctime >= age_pending) {
|
||||
@@ -355,22 +357,18 @@ find_entry(ip_addr_t *ipaddr, u8_t flags)
|
||||
/* recycle oldest stable*/
|
||||
i = old_stable;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i));
|
||||
#if ARP_QUEUEING
|
||||
/* no queued packets should exist on stable entries */
|
||||
LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL);
|
||||
#endif /* ARP_QUEUEING */
|
||||
/* 3) found recyclable pending entry without queued packets? */
|
||||
} else if (old_pending < ARP_TABLE_SIZE) {
|
||||
/* recycle oldest pending */
|
||||
i = old_pending;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i));
|
||||
#if ARP_QUEUEING
|
||||
/* 4) found recyclable pending entry with queued packets? */
|
||||
} else if (old_queue < ARP_TABLE_SIZE) {
|
||||
/* recycle oldest pending (queued packets are free in free_entry) */
|
||||
i = old_queue;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q)));
|
||||
#endif /* ARP_QUEUEING */
|
||||
/* no empty or recyclable entries found */
|
||||
} else {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("find_entry: no empty or recyclable entries found\n"));
|
||||
@@ -486,8 +484,8 @@ update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethadd
|
||||
ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
|
||||
/* reset time stamp */
|
||||
arp_table[i].ctime = 0;
|
||||
#if ARP_QUEUEING
|
||||
/* this is where we will send out queued packets! */
|
||||
#if ARP_QUEUEING
|
||||
while (arp_table[i].q != NULL) {
|
||||
struct pbuf *p;
|
||||
/* remember remainder of queue */
|
||||
@@ -498,12 +496,16 @@ update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethadd
|
||||
p = q->p;
|
||||
/* now queue entry can be freed */
|
||||
memp_free(MEMP_ARP_QUEUE, q);
|
||||
#else /* ARP_QUEUEING */
|
||||
if (arp_table[i].q != NULL) {
|
||||
struct pbuf *p = arp_table[i].q;
|
||||
arp_table[i].q = NULL;
|
||||
#endif /* ARP_QUEUEING */
|
||||
/* send the queued IP packet */
|
||||
etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
|
||||
/* free the queued IP packet */
|
||||
pbuf_free(p);
|
||||
}
|
||||
#endif /* ARP_QUEUEING */
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
@@ -626,7 +628,7 @@ etharp_ip_input(struct netif *netif, struct pbuf *p)
|
||||
ethhdr = (struct eth_hdr *)p->payload;
|
||||
iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
|
||||
#if ETHARP_SUPPORT_VLAN
|
||||
if (ethhdr->type == ETHTYPE_VLAN) {
|
||||
if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
|
||||
iphdr = (struct ip_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
|
||||
}
|
||||
#endif /* ETHARP_SUPPORT_VLAN */
|
||||
@@ -691,7 +693,7 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
||||
ethhdr = (struct eth_hdr *)p->payload;
|
||||
hdr = (struct etharp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
|
||||
#if ETHARP_SUPPORT_VLAN
|
||||
if (ethhdr->type == ETHTYPE_VLAN) {
|
||||
if (ethhdr->type == PP_HTONS(ETHTYPE_VLAN)) {
|
||||
hdr = (struct etharp_hdr *)(((u8_t*)ethhdr) + SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR);
|
||||
}
|
||||
#endif /* ETHARP_SUPPORT_VLAN */
|
||||
@@ -700,11 +702,10 @@ etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
|
||||
if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) ||
|
||||
(hdr->hwlen != ETHARP_HWADDR_LEN) ||
|
||||
(hdr->protolen != sizeof(ip_addr_t)) ||
|
||||
(hdr->proto != PP_HTONS(ETHTYPE_IP)) ||
|
||||
(ethhdr->type != PP_HTONS(ETHTYPE_ARP))) {
|
||||
(hdr->proto != PP_HTONS(ETHTYPE_IP))) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
|
||||
("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
|
||||
hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen, ethhdr->type));
|
||||
("etharp_arp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n",
|
||||
hdr->hwtype, hdr->hwlen, hdr->proto, hdr->protolen));
|
||||
ETHARP_STATS_INC(etharp.proterr);
|
||||
ETHARP_STATS_INC(etharp.drop);
|
||||
pbuf_free(p);
|
||||
@@ -871,14 +872,25 @@ etharp_output(struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr)
|
||||
/* outside local network? */
|
||||
if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask)) &&
|
||||
!ip_addr_islinklocal(ipaddr)) {
|
||||
/* interface has default gateway? */
|
||||
if (!ip_addr_isany(&netif->gw)) {
|
||||
/* send to hardware address of default gateway IP address */
|
||||
ipaddr = &(netif->gw);
|
||||
/* no default gateway available */
|
||||
} else {
|
||||
/* no route to destination error (default gateway missing) */
|
||||
return ERR_RTE;
|
||||
#if LWIP_AUTOIP
|
||||
struct ip_hdr *iphdr = (struct ip_hdr*)((u8_t*)q->payload +
|
||||
sizeof(struct eth_hdr));
|
||||
/* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with
|
||||
a link-local source address must always be "directly to its destination
|
||||
on the same physical link. The host MUST NOT send the packet to any
|
||||
router for forwarding". */
|
||||
if (!ip_addr_islinklocal(&iphdr->src))
|
||||
#endif /* LWIP_AUTOIP */
|
||||
{
|
||||
/* interface has default gateway? */
|
||||
if (!ip_addr_isany(&netif->gw)) {
|
||||
/* send to hardware address of default gateway IP address */
|
||||
ipaddr = &(netif->gw);
|
||||
/* no default gateway available */
|
||||
} else {
|
||||
/* no route to destination error (default gateway missing) */
|
||||
return ERR_RTE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if LWIP_NETIF_HWADDRHINT
|
||||
@@ -1004,7 +1016,7 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
|
||||
result = etharp_send_ip(netif, q, srcaddr, &(arp_table[i].ethaddr));
|
||||
/* pending entry? (either just created or already pending */
|
||||
} else if (arp_table[i].state == ETHARP_STATE_PENDING) {
|
||||
#if ARP_QUEUEING /* queue the given q packet */
|
||||
/* entry is still pending, queue the given packet 'q' */
|
||||
struct pbuf *p;
|
||||
int copy_needed = 0;
|
||||
/* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but
|
||||
@@ -1036,6 +1048,7 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
|
||||
/* packet could be taken over? */
|
||||
if (p != NULL) {
|
||||
/* queue packet ... */
|
||||
#if ARP_QUEUEING
|
||||
struct etharp_q_entry *new_entry;
|
||||
/* allocate a new arp queue entry */
|
||||
new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE);
|
||||
@@ -1060,18 +1073,23 @@ etharp_query(struct netif *netif, ip_addr_t *ipaddr, struct pbuf *q)
|
||||
/* the pool MEMP_ARP_QUEUE is empty */
|
||||
pbuf_free(p);
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
|
||||
/* { result == ERR_MEM } through initialization */
|
||||
result = ERR_MEM;
|
||||
}
|
||||
#else /* ARP_QUEUEING */
|
||||
/* always queue one packet per ARP request only, freeing a previously queued packet */
|
||||
if (arp_table[i].q != NULL) {
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
|
||||
pbuf_free(arp_table[i].q);
|
||||
}
|
||||
arp_table[i].q = p;
|
||||
result = ERR_OK;
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i));
|
||||
#endif /* ARP_QUEUEING */
|
||||
} else {
|
||||
ETHARP_STATS_INC(etharp.memerr);
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q));
|
||||
/* { result == ERR_MEM } through initialization */
|
||||
result = ERR_MEM;
|
||||
}
|
||||
#else /* ARP_QUEUEING */
|
||||
/* q && state == PENDING && ARP_QUEUEING == 0 => result = ERR_MEM */
|
||||
/* { result == ERR_MEM } through initialization */
|
||||
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: Ethernet destination address unknown, queueing disabled, packet %p dropped\n", (void *)q));
|
||||
#endif /* ARP_QUEUEING */
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1199,6 +1217,14 @@ ethernet_input(struct pbuf *p, struct netif *netif)
|
||||
{
|
||||
struct eth_hdr* ethhdr;
|
||||
u16_t type;
|
||||
s16_t ip_hdr_offset = SIZEOF_ETH_HDR;
|
||||
|
||||
if (p->len <= SIZEOF_ETH_HDR) {
|
||||
/* a packet with only an ethernet header (or less) is not valid for us */
|
||||
ETHARP_STATS_INC(etharp.proterr);
|
||||
ETHARP_STATS_INC(etharp.drop);
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
/* points to packet payload, which starts with an Ethernet header */
|
||||
ethhdr = (struct eth_hdr *)p->payload;
|
||||
@@ -1214,6 +1240,12 @@ ethernet_input(struct pbuf *p, struct netif *netif)
|
||||
#if ETHARP_SUPPORT_VLAN
|
||||
if (type == PP_HTONS(ETHTYPE_VLAN)) {
|
||||
struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR);
|
||||
if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
|
||||
/* a packet with only an ethernet/vlan header (or less) is not valid for us */
|
||||
ETHARP_STATS_INC(etharp.proterr);
|
||||
ETHARP_STATS_INC(etharp.drop);
|
||||
goto free_and_return;
|
||||
}
|
||||
#ifdef ETHARP_VLAN_CHECK /* if not, allow all VLANs */
|
||||
if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
|
||||
/* silently ignore this packet: not for our VLAN */
|
||||
@@ -1222,6 +1254,7 @@ ethernet_input(struct pbuf *p, struct netif *netif)
|
||||
}
|
||||
#endif /* ETHARP_VLAN_CHECK */
|
||||
type = vlan->tpid;
|
||||
ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
|
||||
}
|
||||
#endif /* ETHARP_SUPPORT_VLAN */
|
||||
|
||||
@@ -1241,7 +1274,7 @@ ethernet_input(struct pbuf *p, struct netif *netif)
|
||||
etharp_ip_input(netif, p);
|
||||
#endif /* ETHARP_TRUST_IP_MAC */
|
||||
/* skip Ethernet header */
|
||||
if(pbuf_header(p, -(s16_t)SIZEOF_ETH_HDR)) {
|
||||
if(pbuf_header(p, -ip_hdr_offset)) {
|
||||
LWIP_ASSERT("Can't move over header in packet", 0);
|
||||
goto free_and_return;
|
||||
} else {
|
||||
|
||||
@@ -344,7 +344,9 @@ static void
|
||||
pppRecvWakeup(int pd)
|
||||
{
|
||||
PPPDEBUG(LOG_DEBUG, ("pppRecvWakeup: unit %d\n", pd));
|
||||
sio_read_abort(pppControl[pd].fd);
|
||||
if (pppControl[pd].openFlag != 0) {
|
||||
sio_read_abort(pppControl[pd].fd);
|
||||
}
|
||||
}
|
||||
#endif /* PPPOS_SUPPORT */
|
||||
|
||||
@@ -363,7 +365,6 @@ pppLinkTerminated(int pd)
|
||||
PPPControl* pc;
|
||||
pppRecvWakeup(pd);
|
||||
pc = &pppControl[pd];
|
||||
pppDrop(&pc->rx); /* bug fix #17726 */
|
||||
|
||||
PPPDEBUG(LOG_DEBUG, ("pppLinkTerminated: unit %d: linkStatusCB=%p errCode=%d\n", pd, pc->linkStatusCB, pc->errCode));
|
||||
if (pc->linkStatusCB) {
|
||||
@@ -439,7 +440,7 @@ pppInit(void)
|
||||
|
||||
magicInit();
|
||||
|
||||
subnetMask = PP_HTONL(0xffffff00);
|
||||
subnetMask = PP_HTONL(0xffffff00UL);
|
||||
|
||||
for (i = 0; i < NUM_PPP; i++) {
|
||||
/* Initialize each protocol to the standard option set. */
|
||||
@@ -681,20 +682,8 @@ pppClose(int pd)
|
||||
void
|
||||
pppSigHUP(int pd)
|
||||
{
|
||||
#if PPPOE_SUPPORT
|
||||
PPPControl *pc = &pppControl[pd];
|
||||
if(pc->ethif) {
|
||||
PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd));
|
||||
pppHup(pd);
|
||||
} else
|
||||
#endif /* PPPOE_SUPPORT */
|
||||
{
|
||||
#if PPPOS_SUPPORT
|
||||
PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd));
|
||||
pppHup(pd);
|
||||
pppRecvWakeup(pd);
|
||||
#endif /* PPPOS_SUPPORT */
|
||||
}
|
||||
PPPDEBUG(LOG_DEBUG, ("pppSigHUP: unit %d sig_hup -> pppHupCB\n", pd));
|
||||
pppHup(pd);
|
||||
}
|
||||
|
||||
#if PPPOS_SUPPORT
|
||||
@@ -1704,8 +1693,8 @@ pppInput(void *arg)
|
||||
}
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
protocol = htons(protocol);
|
||||
SMEMCPY(nb->payload, &protocol, sizeof(protocol));
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
SMEMCPY(nb->payload, &protocol, sizeof(protocol));
|
||||
lcp_sprotrej(pd, nb->payload, nb->len);
|
||||
}
|
||||
break;
|
||||
@@ -1809,6 +1798,7 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l)
|
||||
pppDrop(pcrx);
|
||||
/* Otherwise it's a good packet so pass it on. */
|
||||
} else {
|
||||
struct pbuf *inp;
|
||||
/* Trim off the checksum. */
|
||||
if(pcrx->inTail->len >= 2) {
|
||||
pcrx->inTail->len -= 2;
|
||||
@@ -1827,18 +1817,20 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l)
|
||||
}
|
||||
|
||||
/* Dispatch the packet thereby consuming it. */
|
||||
inp = pcrx->inHead;
|
||||
/* Packet consumed, release our references. */
|
||||
pcrx->inHead = NULL;
|
||||
pcrx->inTail = NULL;
|
||||
#if PPP_INPROC_MULTITHREADED
|
||||
if(tcpip_callback_with_block(pppInput, pcrx->inHead, 0) != ERR_OK) {
|
||||
if(tcpip_callback_with_block(pppInput, inp, 0) != ERR_OK) {
|
||||
PPPDEBUG(LOG_ERR, ("pppInProc[%d]: tcpip_callback() failed, dropping packet\n", pcrx->pd));
|
||||
pbuf_free(pcrx->inHead);
|
||||
pbuf_free(inp);
|
||||
LINK_STATS_INC(link.drop);
|
||||
snmp_inc_ifindiscards(&pppControl[pcrx->pd].netif);
|
||||
}
|
||||
#else /* PPP_INPROC_MULTITHREADED */
|
||||
pppInput(pcrx->inHead);
|
||||
pppInput(inp);
|
||||
#endif /* PPP_INPROC_MULTITHREADED */
|
||||
pcrx->inHead = NULL;
|
||||
pcrx->inTail = NULL;
|
||||
}
|
||||
|
||||
/* Prepare for a new packet. */
|
||||
@@ -1912,10 +1904,12 @@ pppInProc(PPPControlRx *pcrx, u_char *s, int l)
|
||||
case PDDATA: /* Process data byte. */
|
||||
/* Make space to receive processed data. */
|
||||
if (pcrx->inTail == NULL || pcrx->inTail->len == PBUF_POOL_BUFSIZE) {
|
||||
if(pcrx->inTail) {
|
||||
if (pcrx->inTail != NULL) {
|
||||
pcrx->inTail->tot_len = pcrx->inTail->len;
|
||||
if (pcrx->inTail != pcrx->inHead) {
|
||||
pbuf_cat(pcrx->inHead, pcrx->inTail);
|
||||
/* give up the inTail reference now */
|
||||
pcrx->inTail = NULL;
|
||||
}
|
||||
}
|
||||
/* If we haven't started a packet, we need a packet header. */
|
||||
|
||||
@@ -90,7 +90,8 @@ create_arp_response(ip_addr_t *adr)
|
||||
|
||||
etharphdr->hwtype = htons(/*HWTYPE_ETHERNET*/ 1);
|
||||
etharphdr->proto = htons(ETHTYPE_IP);
|
||||
etharphdr->_hwlen_protolen = htons((ETHARP_HWADDR_LEN << 8) | sizeof(ip_addr_t));
|
||||
etharphdr->hwlen = ETHARP_HWADDR_LEN;
|
||||
etharphdr->protolen = sizeof(ip_addr_t);
|
||||
etharphdr->opcode = htons(ARP_REPLY);
|
||||
|
||||
SMEMCPY(ðarphdr->sipaddr, adr, sizeof(ip_addr_t));
|
||||
|
||||
@@ -88,7 +88,8 @@ tcp_create_segment(ip_addr_t* src_ip, ip_addr_t* dst_ip,
|
||||
memcpy((char*)tcphdr + sizeof(struct tcp_hdr), data, data_len);
|
||||
|
||||
/* calculate checksum */
|
||||
tcphdr->chksum = inet_chksum_pseudo(p, &(iphdr->src), &(iphdr->dest),
|
||||
|
||||
tcphdr->chksum = inet_chksum_pseudo(p, src_ip, dst_ip,
|
||||
IP_PROTO_TCP, p->tot_len);
|
||||
|
||||
pbuf_header(p, sizeof(struct ip_hdr));
|
||||
@@ -193,3 +194,20 @@ test_tcp_new_counters_pcb(struct test_tcp_counters* counters)
|
||||
}
|
||||
return pcb;
|
||||
}
|
||||
|
||||
/** Calls tcp_input() after adjusting current_iphdr_dest */
|
||||
void test_tcp_input(struct pbuf *p, struct netif *inp)
|
||||
{
|
||||
struct ip_hdr *iphdr = (struct ip_hdr*)p->payload;
|
||||
ip_addr_copy(current_iphdr_dest, iphdr->dest);
|
||||
ip_addr_copy(current_iphdr_src, iphdr->src);
|
||||
current_netif = inp;
|
||||
current_header = iphdr;
|
||||
|
||||
tcp_input(p, inp);
|
||||
|
||||
current_iphdr_dest.addr = 0;
|
||||
current_iphdr_src.addr = 0;
|
||||
current_netif = NULL;
|
||||
current_header = NULL;
|
||||
}
|
||||
|
||||
@@ -33,4 +33,6 @@ err_t test_tcp_counters_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err
|
||||
|
||||
struct tcp_pcb* test_tcp_new_counters_pcb(struct test_tcp_counters* counters);
|
||||
|
||||
void test_tcp_input(struct pbuf *p, struct netif *inp);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -76,7 +76,7 @@ START_TEST(test_tcp_recv_inseq)
|
||||
EXPECT(p != NULL);
|
||||
if (p != NULL) {
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p, &netif);
|
||||
test_tcp_input(p, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 1);
|
||||
|
||||
@@ -180,7 +180,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
||||
EXPECT(p_fin != NULL);
|
||||
if ((pinseq != NULL) && (p_8_9 != NULL) && (p_4_8 != NULL) && (p_4_10 != NULL) && (p_2_14 != NULL) && (p_fin != NULL)) {
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_8_9, &netif);
|
||||
test_tcp_input(p_8_9, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -192,7 +192,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 9); /* includes FIN */
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_4_8, &netif);
|
||||
test_tcp_input(p_4_8, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -206,7 +206,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_4_10, &netif);
|
||||
test_tcp_input(p_4_10, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -220,7 +220,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 9); /* includes FIN */
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_2_14, &netif);
|
||||
test_tcp_input(p_2_14, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -232,7 +232,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_fin, &netif);
|
||||
test_tcp_input(p_fin, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -244,7 +244,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_OOSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 15); /* includes FIN */
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(pinseq, &netif);
|
||||
test_tcp_input(pinseq, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 1);
|
||||
EXPECT(counters.recv_calls == 1);
|
||||
@@ -330,7 +330,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||
if ((pinseq != NULL) && (p_1_2 != NULL) && (p_4_8 != NULL) && (p_3_11 != NULL) && (p_2_12 != NULL)
|
||||
&& (p_15_1 != NULL) && (p_15_1a != NULL) && (pinseqFIN != NULL)) {
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_1_2, &netif);
|
||||
test_tcp_input(p_1_2, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -342,7 +342,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 2);
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_4_8, &netif);
|
||||
test_tcp_input(p_4_8, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -356,7 +356,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 8);
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_3_11, &netif);
|
||||
test_tcp_input(p_3_11, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -371,7 +371,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 11);
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_2_12, &netif);
|
||||
test_tcp_input(p_2_12, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -385,7 +385,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 1) == 12);
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(pinseq, &netif);
|
||||
test_tcp_input(pinseq, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 1);
|
||||
@@ -394,7 +394,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||
EXPECT(pcb->ooseq == NULL);
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_15_1, &netif);
|
||||
test_tcp_input(p_15_1, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 1);
|
||||
@@ -406,7 +406,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_15_1a, &netif);
|
||||
test_tcp_input(p_15_1a, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 1);
|
||||
@@ -418,7 +418,7 @@ START_TEST(test_tcp_recv_ooseq_FIN_INSEQ)
|
||||
EXPECT_OOSEQ(tcp_oos_seg_tcplen(pcb, 0) == 1);
|
||||
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(pinseqFIN, &netif);
|
||||
test_tcp_input(pinseqFIN, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 1);
|
||||
EXPECT(counters.recv_calls == 2);
|
||||
@@ -480,7 +480,7 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin)
|
||||
TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
|
||||
EXPECT(p != NULL);
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p, &netif);
|
||||
test_tcp_input(p, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -504,7 +504,7 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin)
|
||||
p_ovr = tcp_create_rx_segment(pcb, &data_full_wnd[TCP_MSS*(k+1)], TCP_MSS, TCP_MSS*(k+1), 0, TCP_ACK);
|
||||
EXPECT(p_ovr != NULL);
|
||||
/* pass the segment to tcp_input */
|
||||
tcp_input(p_ovr, &netif);
|
||||
test_tcp_input(p_ovr, &netif);
|
||||
/* check if counters are as expected */
|
||||
EXPECT(counters.close_calls == 0);
|
||||
EXPECT(counters.recv_calls == 0);
|
||||
@@ -516,7 +516,7 @@ START_TEST(test_tcp_recv_ooseq_overrun_rxwin)
|
||||
EXPECT_OOSEQ(datalen == datalen2);
|
||||
|
||||
/* now pass inseq */
|
||||
tcp_input(pinseq, &netif);
|
||||
test_tcp_input(pinseq, &netif);
|
||||
EXPECT(pcb->ooseq == NULL);
|
||||
|
||||
/* make sure the pcb is freed */
|
||||
|
||||
Reference in New Issue
Block a user