Compare commits

...

166 Commits

Author SHA1 Message Date
Simon Goldschmidt
6ca936f6b5 Prepare 2.1.3 release 2021-11-10 19:25:03 +01:00
Hu Keping
e7b74570d9 Remove unnecessary files in release tarball
This patch adds a few entries in .gitattributes to specify files that
should never end up in a distribution tarball.

Signed-off-by: Hu Keping <hukeping@huawei.com>
2021-11-10 19:18:11 +01:00
Sylvain Rochet
018c64ab94 PPP: assert if ppp_set_* functions are called when session is not dead
ppp_set_* functions that set the PPP session parameters must only be
called when the session is in a dead state (i.e. disconnected),
otherwise not fatal but surprising results may happen.
2021-10-13 21:30:13 +02:00
Sylvain Rochet
7e92fb3d7f PPP: remove LWIP_ASSERT_CORE_LOCKED on ppp_set_auth function
We do not have equivalents in PPPAPI for ppp_set_* functions because
calling them only makes sense while session is disconnected, furthermore
they are only setting structure members of the session configuration.
2021-10-13 21:29:29 +02:00
Dirk Ziegelmeier
051fbea5e6 Fix bug #54805: IP address can not be obtained over dhcp if PBUF_POOL_BUFSIZE is too small
Patch by Christoph Chang
2021-10-03 12:33:58 +02:00
Florent Matignon
214e2d90f3 bug #54700: Unexpected expiry of pending ARP table entry
New etharp queries should restart the 5 second timeout on the ARP
table entry if it is still pending.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
(cherry picked from commit ffbe075d56)
2021-10-01 20:31:59 +02:00
Simon Goldschmidt
4022a19cbc altcp: fix altcp_tcp_close for LISTEN pcb
See bug #55219

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
(cherry picked from commit 064d816ea1)
2021-10-01 19:59:02 +02:00
Simon Goldschmidt
a32ea1e793 dhcp: don't set a default gateway if dhcp server doesn't give one
see bug #60578
2021-09-24 12:24:58 +02:00
Simon Goldschmidt
f67f2692d4 mqtt: check data_cb != NULL 2021-09-24 00:36:22 +02:00
Karol Domagalski
3b745f7154 ip4: ip4addr_aton: fix parsing of the octal IP representation 2021-09-24 00:29:45 +02:00
Erik Ekman
d876d3c4df ip6: Fix incorrect assert in ip6_frag()
New test case now passes.

Fixes bug #57374 (Found by Hiromasa Ito).
2021-09-24 00:12:20 +02:00
Erik Ekman
e8b0c52806 ip6: Add test for fragmenting special packet
Reproduces bug #57374 (Found by Hiromasa Ito).
2021-09-24 00:12:11 +02:00
Erik Ekman
5bd7518343 netdb: Accept '0' as service in lwip_getaddrinfo
Fixes bug #59925
2021-09-23 23:57:32 +02:00
Eric Koldeweij
51265f3f7d ip6: Fix crash in ip6_output with debug enabled
It turns out the crash only occurs if LWIP_DEBUG is enabled. If the
parameter dest is NULL the function tries to find a route using the
destination address of the packet instead. If this fails as well a
debug message is printed but it is still using dest causing a NULL
pointer dereference and crash at src/core/ipv6/ip6.c line 1312.

[erik@kryo.se: Apply fix to ip6_output_hinted as well]
2021-09-23 23:51:01 +02:00
Christoffer Lind
2e4932f23b dhcp: generate new xid for DHCP release 2021-09-23 23:44:11 +02:00
Simon Goldschmidt
dbd0bc8a2c netdb: fix alignment warning in debug output
see bug #58650
2021-09-15 08:05:41 +02:00
Oliver Hitz
e5627ec649 tcp: make tcp_listen() inherit the netbuf_idx of the original pcb
This simple patch causes tcp_listen() to inherit the netbuf_idx setting
of the original pcb. Without this, it is not possible to restrict a
socket to a specific interface using SO_BINDTODEVICE before listening.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-09-15 08:03:24 +02:00
Erik Ekman
5c8fd3158d unit: Support check v0.13.0 and later
Function name no longer needs to be fed separately when adding tests.

Also fix collision of non-static net_test variables in dhcp and netif
tests.
2021-08-16 08:56:06 +02:00
Erik Ekman
d5843944cc netif: Add test for netif_find 2021-08-16 08:45:25 +02:00
Erik Ekman
f62be85576 netif: Add test for netif_is_flag_set() 2021-08-16 08:45:25 +02:00
Simon Goldschmidt
f1bd63046e api_lib: fix duplicate NULL check with sys_sem_valid() 2021-08-16 08:36:09 +02:00
Simon Goldschmidt
ed6c951a19 Prepare v2.1.3.rc1
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 14:54:38 +02:00
Erik Ekman
ad9e7a6d87 lowpan6: Use arch-independent printf formatters 2021-08-15 12:53:16 +02:00
Thomas Mueller
6f7b26b1a8 Fix typo in definition of netif_is_flag_set() macro 2021-08-15 12:52:46 +02:00
Erik Ekman
ecd6009a5e icmp6: Don't copy too much data
Fix of the fix for bug #58553
2021-08-15 11:05:31 +02:00
Erik Ekman
6ffe30d9ba icmp6: Fix copying of chained pbuf in reply
Fixes bug #58553, and the newly added unit test.

The pbuf_take_at loop should probably be made into a pbuf library
function, which would avoid this mistake in the future and provide
a simpler implementation of pbuf_copy.
2021-08-15 11:05:16 +02:00
Simon Goldschmidt
8f5a0aaacb icmp6: keep to the RFC and send as much as possible with icmp6 error messages
See bug 56013

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 11:04:23 +02:00
Dirk Ziegelmeier
ba3b04e7fe Add #define for minimum IPv6 MTU length 2021-08-15 11:03:47 +02:00
Erik Ekman
379d55044e zepif: Copy possibly chained output pbuf properly
Fixes bug #58554
2021-08-15 10:57:17 +02:00
Erik Ekman
843a116155 pbuf: Add pbuf_copy_partial_pbuf library function
Like pbuf_copy, but can copy part of a pbuf to an offset in another.
pbuf_copy now uses this function internally.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 10:56:50 +02:00
Simon Goldschmidt
1c6202c414 pbuf: fix allocating large PBUF_RAM
See bug #59974
2021-08-15 10:32:21 +02:00
yuanjm
066a2b022d lwip_selscan: lwip_selscan return -1 without setting errno number
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 10:31:40 +02:00
Simon Goldschmidt
aca41b0beb icmp: Fix copied length in response packets
Fixes bug #59364, reported by Yi Guai
2021-08-15 10:30:20 +02:00
Erik Ekman
b5e8ab6c15 tcp: Fix double free in tcp_split_unsent_seg()
Fixes bug #57377 (found by Hiromasa Ito).
2021-08-15 10:24:47 +02:00
Hannes Gredler
896c8a9f72 tcp_out: fix tcp_output_fill_options() arguments
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 10:23:06 +02:00
Simon Goldschmidt
59ecea3d8c Fix last commit for all netif loopback traffic 2021-08-15 10:20:31 +02:00
Nick Ballhorn-Wagner
b1f8ce8769 fix memory leak in netif_loop_output if tcpip_try_callback fails
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 10:20:11 +02:00
Patrick Schlangen
8c43d83689 Fix select_waiting not being decremented for sockets closed while in lwip_select()
See bug #57445. Short version of the description there: lwip_select() failed
to decrement 'select_waiting' of a socket since that code part failed on
'free_pending' sockets. However, the code does not have to check that as it
has marked the socket to be in use itself earlier.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 10:17:44 +02:00
Simon Goldschmidt
87d44bbfcd sntp: ensure sntp_retry_timeout reaches the configured limit
See bug #57620

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 10:17:25 +02:00
Simon Goldschmidt
07d3b3330d pbuf: avoid using multiple PBUF_POOL buffers for IPv6
Use 'PBUF_IP_HLEN+PBUF_TRANSPORT_HLEN' instead of '40' to calculate
PBUF_POOL_BUFSIZE (the size of each PBUF_POOL buffer) since the former
can be 60 when IPv6 is enabled.

See bug #56355

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 10:17:02 +02:00
Simon Goldschmidt
61349cf124 opt: make LWIP_IPV6_SEND_ROUTER_SOLICIT default to LWIP_IPV6
This ensures struct netif doesn't contain 'rs_count' if LWIP_IPV6
is disabled but LWIP_IPV6_SEND_ROUTER_SOLICIT is at its default.

See bug #56509
2021-08-15 10:16:40 +02:00
David Girault
7316b26740 sntp: remove existing timeout before creating new
This prevents sntp using more than 2 timeouts.
See bug #56431
2021-08-15 10:15:59 +02:00
Axel Lin
d4b3a006dc netif_find: correctly check if atoi means '0' or error
Fixes: 4528215c99 ("netif_find: check if atoi means '0' or error")
Signed-off-by: Axel Lin <axel.lin@ingics.com>
2021-08-15 10:15:38 +02:00
Simon Goldschmidt
2f8886794f netif_find: check if atoi means '0' or error
Since atoi() returns 0 on error, we need to check if name[2] is '0'.
If it's not, atoi() failed.
2021-08-15 10:15:05 +02:00
Christoffer Lind
02ab8c91a9 sys_arch_mbox_tryfetch not validated correctly
sys_arch_mbox_tryfetch() shall return SYS_MBOX_EMPTY or 0 according
to the documentation. Wherever the function is used the return
value is incorrectly compared to SYS_ARCH_TIMEOUT. For now
SYS_MBOX_EMPTY is defined to SYS_ARCH_TIMEOUT so this is not an
issue as long as SYS_MBOX_EMPTY isn't re-defined.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 10:14:19 +02:00
Simon Goldschmidt
74ea1e43ca dhcp: don't use LWIP_ERROR in dhcp_parse_reply()
See bug #56643

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2021-08-15 10:11:33 +02:00
Joan Lledó
e9000658fb IF_NAMESIZE: define it only if it's not defined before by system headers 2021-08-15 10:08:43 +02:00
Simon Goldschmidt
d58e0f1a1a fix compiling unit tests after adding compile-time check for LWIP_NETCONN_FULLDUPLEX 2021-08-15 10:07:58 +02:00
Simon Goldschmidt
674c4ed080 LWIP_NETCONN_FULLDUPLEX is not alpha any more 2021-08-15 10:07:09 +02:00
Dirk Ziegelmeier
a68d6f1a9a Fix bug #56136: The netif->mtu6 was updated by Router Advertisement abnomally
Using patch from Gao Quingahui plus improvement
2021-08-15 10:06:37 +02:00
Dirk Ziegelmeier
c0643e21ed Apply patch for bug #56239: compile fail when disable TCP 2021-08-15 09:43:40 +02:00
Dirk Ziegelmeier
3fbb84f950 Fix bug #55702: SSI bug
Apply patch from Stanislav
2021-08-15 09:41:43 +02:00
Dirk Ziegelmeier
053f5aa10d Fix compile of last patch 2021-08-15 09:40:51 +02:00
Dirk Ziegelmeier
6b9264b49e Fix bug #55972: The Neighbour Solicitation used to do IPv6 address resolution was wrong
Apply patch from Gao Qingshui
2021-08-15 09:40:33 +02:00
Dirk Ziegelmeier
e60f9bb24f Fix bug #55973: The parsing of max response time in MLD Query message was wrong
Apply patch from Gao Qingshui
2021-08-15 09:40:18 +02:00
Simon Goldschmidt
1bb6e7f52d udp_bind: fix missing parenthesis warning
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
(cherry picked from commit 3b5eb7ca90)
2019-02-27 10:31:56 +01:00
Jacob Kroon
108ca1521e PPP, PPPoE: use service name and concentrator name
Make pppoe_create() actually store the passed service name and
concentrator name, so that they are passed in the PADI/PADR/PADS
packets.

Assume that the user application won't be freeing the strings and just
copy the string pointers, therefore remove the mem_free() in
pppoe_destroy().

Since only the pointers are copied now, make them 'const' in
pppoe_softc.

Signed-off-by: Sylvain Rochet <gradator@gradator.net>
(cherry picked from commit c02fea0961)
2019-02-26 16:26:22 +01:00
Sylvain Rochet
ea2bb9cd5b PPP, PPPoE: remove leftover from PPPOE_SCNAME_SUPPORT support
Stupid me managed to push a pending patch, remove it.

Signed-off-by: Sylvain Rochet <gradator@gradator.net>
(cherry picked from commit 48615984c7)
2019-02-26 16:26:21 +01:00
Jacob Kroon
e6d05db86f PPP, PPPoE: fix build when PPPOE_SCNAME_SUPPORT is defined
lwip/src/netif/ppp/pppoe.c:768:24: error: pointer targets in passing argument 1 of ‘strlen’ differ in signedness [-Werror=poin$
     l1 = (int)strlen(sc->sc_service_name);
lwip/src/netif/ppp/pppoe.c:772:24: error: pointer targets in passing argument 1 of ‘strlen’ differ in signedness [-Werror=poin$
     l2 = (int)strlen(sc->sc_concentrator_name);

sc->sc_service_name and sc->sc_concentrator_name are best defined as
char* because there are passed to libc strings functions which expect
a char*.

Signed-off-by: Sylvain Rochet <gradator@gradator.net>
(cherry picked from commit 7eab5947af)
2019-02-26 16:26:21 +01:00
Sylvain Rochet
d1f920a7d1 PPP, PPPoE: rename PPPOE_TODO to PPPOE_SCNAME_SUPPORT, prepare service name and concentrator support
Rename PPPOE_TODO to PPPOE_SCNAME_SUPPORT because this is the only
feature enclosed by them. Prepare for proper service name and
concentrator name support by moving PPPOE_SCNAME_SUPPORT define to
ppp_opts.h.

Signed-off-by: Sylvain Rochet <gradator@gradator.net>
(cherry picked from commit 96548ede2b)
2019-02-26 16:26:21 +01:00
Simon Goldschmidt
fee64d7515 udp: fix udp_bind for IPADDR_TYPE_ANY
See bug #55171

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
(cherry picked from commit 752cdb1a53)
2019-02-26 16:25:19 +01:00
Jacob Kroon
aad77fcacb Fix compile of UDP unit test
Fix building unit tests via contrib/ports/unix/check on Debian 9, gcc 6.3.0.

Fixes:
  <snip>/ip_addr.h:105:58: error: the comparison will always evaluate as ‘true’ for the address of ‘ip1’ will never be NULL [-Werror=address]
   #define IP_SET_TYPE(ipaddr, iptype)     do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr),iptype); }}while(0)

Signed-off-by: Jacob Kroon <jacob.kroon@gmail.com>
(cherry picked from commit 2f098c42a7)
2019-02-26 16:25:10 +01:00
Dirk Ziegelmeier
bebf072b77 Fix bug #55171: Binding UDP PCB with different IP type PCBs does not work
by additionally checking IP address type

(cherry picked from commit 2ff0db9a9b)
2019-02-26 16:23:06 +01:00
Dirk Ziegelmeier
7f53f7ced4 Add testcase for bug #55171: Binding UDP PCB with different IP type PCBs does not work
(cherry picked from commit 91037b4c28)
2019-02-26 16:23:05 +01:00
Simon Goldschmidt
91a4d59eb4 dhcp_release_and_stop: don't clear netif ip address that was not assigned by dhcp.c
See bug #55380
2019-02-18 13:15:37 +01:00
David Girault
1bd34ea364 altcp_tls: assert in altcp_mbedtls_bio_recv if bad state
(cherry picked from commit 3cb6ae7770)
2019-02-18 13:13:24 +01:00
David Girault
a9a215c52e altcp: support for setting keepalive parameters
(cherry picked from commit b04d8a6a6c)
2019-02-18 13:13:24 +01:00
David Girault
5cea646b12 altcp_tls_mbedtls: remove entropy/ctr_drbg from altcp_tls_config struct
Use only one entropy/ctr_drbg context for all altcp_tls_config structure allocated.

(Small adjustments before committing: fix coding style, adapt to changes in master)

(cherry picked from commit b298afabdc)
2019-02-18 13:13:10 +01:00
Simon Goldschmidt
ff14bbb3c1 altcp_tls_mbedtls: listen: free members of the ssl context
The ssl context is not used on listening pcbs. This includes freeing
input/output buffers, so saves ~32KByte by default.

(cherry picked from commit 282389a332)
2019-02-18 13:12:42 +01:00
Simon Goldschmidt
89be04ce7a altcp_tls: add functions to create servers with multiple certificates
(cherry picked from commit 3f583a1757)
2019-02-18 13:12:19 +01:00
Simon Goldschmidt
4b3c59e4cc altcp_tls_mbedtls: add session tickes, improve configuration for session cache
(cherry picked from commit 6f232b7c3f)
2019-02-18 13:12:18 +01:00
Simon Goldschmidt
beeb300c18 altcp_tls_mbedtls: add debug output of mbedtls library
(cherry picked from commit 54448559bb)
2019-02-18 13:12:18 +01:00
Simon Goldschmidt
79732693f3 altcp_tls_mbedtls: use mbedtls_entropy_func for mbedtls_ctr_drbg_seed
This is the default way for mbedTLS. Add entropy sources via defines (see
mbedtls_entropy_init).

This removes the use of ALTCP_MBEDTLS_RNG_FN

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
(cherry picked from commit 153c295b6f)
2019-02-18 13:12:17 +01:00
Simon Goldschmidt
ef3d12c60e altcp_tls: whitespace cleanup 2019-02-18 13:11:27 +01:00
Simon Goldschmidt
608a2f9741 Revert "altcp_tls_mbedtls: implement mbedTLS debug output, comment fixes"
This reverts commit 422623a87b.
2019-02-18 13:09:32 +01:00
Dirk Ziegelmeier
174cc87227 Fix LWIP_ERROR macro - it should never be fatal (LWIP_ASSERT)
The only difference should be:
- LWIP_DEBUG enabled  -> print a diag message
- LWIP_DEBUG disabled -> NO diag message is printed

(cherry picked from commit e479bd56df)
2019-02-18 13:05:53 +01:00
David J. Fiddes
0d6d8922f2 Implement RFC4075 Receive SNTP servers via DHCPv6
This adds support for RFC4075 SNTP server configuration via DHCPv6.
The DHCPv6 options transmitted are now conditional on how LwIP is
configured.

A new SNTP application option SNTP_GET_SERVERS_FROM_DHCPV6 is used
to enable. For simplicity this is configured to use the global
LWIP_DHCP6_GET_NTP_SRV configuration setting.

Tests:
 - Check the global options now control the DHCPv6 request sent
   in Wireshark
 - Check against 0, 1 and 3 SNTP servers configured on an odhcpd
   server configured to support RFC 4075 SNTP server lists.
   Verify that the SNTP server list is updated on connection
   establishment on an ESP8266 WeMOS D1.
 - Verify that SNTP packets are sent and recieved from a
   configured server and that system time is updated.

Signed-off-by: David J. Fiddes <D.J@fiddes.net>
(cherry picked from commit 8f2f43f093)
2019-02-18 13:02:48 +01:00
David Girault
67350e3c01 mqtt: remove bad assert in mqtt_message_received()
- client->msg_idx can be > MQTT_VAR_HEADER_BUFFER_LEN in long message splitted in multiple pbufs
- renamed fixed_hdr_idx to fixed_hdr_len because it is length of fixed header in rx_buffer, not an index to it
- removed the cpy_start as data always copied right after the fixed header

(cherry picked from commit 2cc420e434)
2019-02-18 13:01:37 +01:00
Simon Goldschmidt
1a6455bc25 tcp: improve debug message a little
(cherry picked from commit ed561a578b)
2019-02-18 13:00:17 +01:00
Dirk Ziegelmeier
e1528e084d Fix bug #55537: Crash in SYN_SENT state when TCP_INPUT_DEBUG logs are ON
(cherry picked from commit 4c19a909c2)
2019-02-18 13:00:16 +01:00
Dirk Ziegelmeier
1892f445e2 Apply patch #9737: Fix DHCPv6 DNS server assignment
(cherry picked from commit 941300c21c)
2019-02-18 12:59:10 +01:00
Dirk Ziegelmeier
484f0fbafa Fix bug #55536: lwIP 2.1.2: netconn_delete() called twice from lwip_accept()
netconn is deleted in free_socket() call

(cherry picked from commit 3efc43531b)
2019-02-18 12:58:55 +01:00
Dirk Ziegelmeier
5378fd84df Add documentation on how to debug memory pool sizes
(cherry picked from commit a215eba50e)
2019-02-18 12:58:27 +01:00
Dirk Ziegelmeier
9d8b8d9c69 TCP/UDP documentation: Add reference to PCB mempool #defines
(cherry picked from commit 8bf2e21b4d)
2019-02-18 12:58:19 +01:00
Dirk Ziegelmeier
cd91647999 Fix bug #55513: Uninitialized variable in struct netconn
using patch from Karol Domagalski

(cherry picked from commit 926e399355)
2019-02-18 12:56:51 +01:00
Simon Goldschmidt
5cc46d7989 nd6: fix copying more than one DNS server
See bug #55163

(cherry picked from commit dcb29c591f)
2019-02-18 12:55:33 +01:00
Dirk Ziegelmeier
fe4395336a Fix bug #55078: Add custom data to pbuf struct
Add a #define that users can use to store custom data on a pbuf

(cherry picked from commit 92a18bf638)
2019-02-18 12:55:05 +01:00
Dirk Ziegelmeier
9d97a467ca netbiosns_name_decode: Take CONST char* as first argument
(cherry picked from commit 10e0130a4a)
2019-02-18 12:51:05 +01:00
Simon Goldschmidt
039056370d next release in this branch will be 2.1.3 2018-11-22 21:02:32 +01:00
Simon Goldschmidt
159e31b689 Prepare 2.1.2 release 2018-11-22 20:57:02 +01:00
Simon Goldschmidt
17c60d2728 Fix CHANGELOG for 2.1.2 2018-11-22 20:56:33 +01:00
Jens Nielsen
52e75369c1 Fix netbiosns expecting too large packet
(cherry picked from commit b0c753da96)
2018-11-22 11:38:31 +01:00
Dirk Ziegelmeier
66706f469d Fix bug #55034: apps/smtp.c fails to compile with strict C compatibility because of strnlen
by replacing strnlen with strlen. It's a user-supplied string, so we can assume it is correctly \0 terminated (as done several times elsewhere in the code)

(cherry picked from commit aa83bdf490)
2018-11-19 14:48:54 +01:00
Simon Goldschmidt
98d1cb1c00 tcp_recved: fix overflow check
Improved fix instead of patch #9699.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-11-12 20:55:23 +01:00
Simon Goldschmidt
1940cae827 Revert "tcp_recved: check for overflow and warn about too big values"
This reverts commit ebb0dc14a7.
It changes the behaviour to assert for applications running good so far.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-11-12 20:47:01 +01:00
Simon Goldschmidt
d184463e2a next release in this branch will be 2.1.2 2018-11-08 22:36:01 +01:00
Simon Goldschmidt
3b53b6e481 Prepare 2.1.1 release 2018-11-08 22:15:01 +01:00
Simon Goldschmidt
78ee1ee2cf Update CHANGELOG for 2.1.1 2018-11-08 22:07:58 +01:00
Simon Goldschmidt
422623a87b altcp_tls_mbedtls: implement mbedTLS debug output, comment fixes 2018-11-08 20:48:31 +01:00
Axel Lin
4aa6df7633 sockets: Fix missing err_to_errno conversion for ERR_VAL in lwip_recvmsg
Signed-off-by: Axel Lin <axel.lin@ingics.com>
(cherry picked from commit 7bcf0d3334)
2018-11-08 16:53:40 +01:00
Joan Lledó
2d2336014c Remove assertion about the end of pollfd array
See bug #54933.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
(cherry picked from commit 284659156d)
2018-11-06 13:15:04 +01:00
Dirk Ziegelmeier
def427bcaf Fix bug #54670: 127.0.0.1 sent out to netif_default?
(cherry picked from commit 7c2267b966)
2018-11-06 13:14:22 +01:00
Axel Lin
ba3a39957d Fix mqtt unit test broken ebb0dc14a7
Fixes: ebb0dc14a7 ("tcp_recved: check for overflow and warn about too big values")
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Acked-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-10-30 21:21:08 +08:00
Simon Goldschmidt
f58324b576 altcp_tls_mbedtls: update list of todos
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-10-26 20:43:12 +02:00
David GIRAULT
205cd7c1f6 bug #54744: if altcp_close() called from recv() callback, there is some write to freed memory
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
(cherry picked from commit 6e994f9df2)
2018-10-26 19:59:33 +02:00
Simon Goldschmidt
398333da9a snmp: avoid NULL pointer dereference, fix return values 2018-10-24 20:39:08 +02:00
Simon Goldschmidt
e678219bdf snmp: fix coding style in last commit 2018-10-23 20:00:16 +02:00
Dirk Ziegelmeier
830217ac78 SNMP: Avoid NULL pointer dereference in snmp_scalar.c 2018-10-23 19:57:44 +02:00
Simon Goldschmidt
e4db22d9f5 fix missing standard includes
These were a problem only if arch.h does not include them.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-10-23 19:57:11 +02:00
Simon Goldschmidt
c8e9772cd0 This branch is for developing 2.1.x versions 2018-10-18 09:03:11 +02:00
Dirk Ziegelmeier
437b11f869 Fix bug #54850: lwip definition of htonX and ntohX do not properly cast to unsigned when byte order is Big Endian
Changes suggested by Ivan Warren
2018-10-17 21:45:18 +02:00
Simon Goldschmidt
b7bee87fb5 Add a unit test for bug #54833 (tcp_abort with wrong ports)
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-10-17 21:44:44 +02:00
Simon Goldschmidt
2f3ef94ad4 Fix bug #54806 (ppp: invalid LWIP_ASSERT_CORE_LOCKED() check)
pppos_input() is safe to call from outside tcpip_thread when
PPP_INPROC_IRQ_SAFE == 1, so only check if PPP_INPROC_IRQ_SAFE == 0

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-10-17 21:44:30 +02:00
Simon Goldschmidt
7154e51ff2 Revert "tcp_abandon: no need to buffer pcb->local_port"
This reverts commit 1570dd8ad1.

Buffering pcb->local_port is needed because TCP_PCB_REMOVE_ACTIVE()
sets it to 0 via tcp_pcb_remove() (comment: "reset the local port
to prevent the pcb from being 'bound'").

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-10-17 21:44:20 +02:00
Jonas Rabenstein
db46863f75 err.h: move typedef of err_t after enum definition
This allows for 'typedef err_enum_t err_t' and thus strong type checking
of the enum in c++.
2018-10-17 21:44:04 +02:00
Jonas Rabenstein
ebb0dc14a7 tcp_recved: check for overflow and warn about too big values 2018-10-17 21:43:57 +02:00
Joan Lledó
368128a647 alloc_socket(): Check for LWIP_SOCKET_POLL when setting select-related variables 2018-10-17 21:43:34 +02:00
Dirk Ziegelmeier
bc25863d1b Apply patch #9694: Update prev pointer when skipping entries in tcp_slowtmr to prevent hitting assertion 2018-10-17 21:43:09 +02:00
Martine Lenders
130f947037 lowpan6.c: Fix IEEE 802.15.4 address setting
Reverts a regression introduced in
3a8af612b3:

Use hardware address fetched from neighbor cache *not* the hardware
address of the interface as destination address.

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-10-17 21:42:55 +02:00
Simon Goldschmidt
e6a8415df3 Prepare 2.1.0 release
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-09-26 21:11:39 +02:00
Simon Goldschmidt
54a8112eb9 Documentation improvements for 2.1.0 (changelog, altcp) 2018-09-26 14:37:52 +02:00
Simon Goldschmidt
b9fc8cae68 Documentation improvements for 2.1.0 (mainly altcp/altcp_tls) 2018-09-24 22:44:32 +02:00
Simon Goldschmidt
a044c807f8 altcp_tls: rename altcp_tls_new -> altcp_tls_wrap, add altcp_tls_new
The new altcp_tls_new() is a type safe version of altcp_tls_alloc()

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-09-24 22:29:54 +02:00
Simon Goldschmidt
6229f9ef71 icmp_send_response: fix parameter order for LWIP_HOOK_IP4_ROUTE_SRC 2018-09-17 21:28:50 +02:00
Simon Goldschmidt
66838a70f3 more documentation preparations for v2.1.0 release 2018-09-17 21:16:58 +02:00
Simon Goldschmidt
dea74a24aa Fix CHANGELOG consistency from 2.0.3 branch to 2.1.0 2018-09-16 21:41:33 +02:00
Simon Goldschmidt
effdeef2fe some preparations for v2.1.0 release 2018-09-16 21:17:40 +02:00
Simon Goldschmidt
c18df357d9 some preparations for v2.1.0 release 2018-09-14 21:32:11 +02:00
Simon Goldschmidt
74c5ac7302 cpack: change file name of generated sources file
This should match the old release ZIPs: "lwip-x.y.z.zip"

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-09-13 21:54:58 +02:00
Simon Goldschmidt
0189e7b02f mqtt: allow user + pass longer than 255 chars
See bug #54655:
"MQTT brokers such as Google Cloud IoT Core requires MQTT clients
to send JSON Web Token (JWT) as password field of the MQTT Connect
packet. JWT can be more than 255 bytes.
Currently, the MQTT library restricts password to be less than 256
bytes, thus it prevents connectivity to Google Cloud IoT Core."

Fix that by just converting the local variables for these from u8_t
to u16_t.

Suggested-by: Richmond Umagat <richmond.umagat@brtchip.com>
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-09-13 14:59:08 +02:00
Dirk Ziegelmeier
796f98beb2 Fix no newline at end of http_client.c 2018-09-12 22:41:07 +02:00
Simon Goldschmidt
fc24d4139f altcp_tls_mbedtls: convert #error on too small TCP_WND to warning
Many TLS use cases are OK with a small TCP_WND, so don't prevent these
by having a preprocessor check that cannot be disabled.
2018-09-12 22:24:05 +02:00
Simon Goldschmidt
bbf80b05c8 ppp: fix implicit conversion from size_t to u8_t
Found when compiling with VS2017
2018-09-12 22:22:10 +02:00
Simon Goldschmidt
bc48eb512e Fix bug #54506 (LWIP_CHECKSUM_ON_COPY causes wrong checksum (0xFFFF))
one's complement sum was not correctly done, which could result in the
checksum being 0xFFFF instead of 0 in some cases.
2018-09-12 21:56:16 +02:00
Dirk Ziegelmeier
cdfa3dfa9d http_client.c: Fix compile when TCP is disabled 2018-09-12 08:27:43 +02:00
Dirk Ziegelmeier
be18fa98e4 Fix cleanup of existing documentation of target lwipdocs 2018-09-11 08:16:01 +02:00
Dirk Ziegelmeier
257dc1d6fd Fix doxygen warnings in altcp_proxyconnect.c 2018-09-10 13:30:50 +02:00
Dirk Ziegelmeier
236d6df495 Fix lwipdocs target in Filelists.cmake
EXCLUDE_FROM_ALL is not supported at add_custom_target()
2018-09-10 13:28:01 +02:00
Simon Goldschmidt
93b2074f2b Remove LWIP_DHCP_CHECK_LINK_UP define as it's useless
See bug #54574

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-09-07 21:01:32 +02:00
Simon Goldschmidt
7749088a83 Fix 2way-auth connections for TLS clients
TLS clients that need 2-way authentication (e.g. Amazon AWS IoT cloud mqtt)
need to pass a certificate and private key when creating the tls altcp_pcb.

Added a new function altcp_tls_create_config_client_2wayauth() for this that
replaces altcp_tls_create_config_client() for such clients.

See bug #54601.
2018-09-07 20:59:31 +02:00
Dirk Ziegelmeier
24fc93e12f Remove checks that the SO_* socket options and SOF_* lwIP-internal flags match
not needed any more since commit b0344518e8
"sockets.c: Don't rely on #defines in socket.h to be in sync with ip.h
Map SO_* to SOF_* #defines"

Reported by Joan Lledó on mailinglist 6.Sep.2018
2018-09-07 10:01:59 +02:00
Martine Lenders
264b89764d Make zepif dependent on LWIP_UDP config
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-09-04 22:10:53 +02:00
Sylvain Rochet
fa3826a1d3 PPP: improve randomization of LCP magic number after power-up
magic_init() is first time called from ppp_init(), which is called from
lwip_init(). If system has no RTC, sys_jiffies() returns same value in
this moment after every power-up or system reset. This value used in LCP
magic number generation after ppp_connect(), which leads to same magic
number after every restart. Subsequent magic_randomize() calls takes
place in ppp_input(), after magic number generation.

Call magic_randomize() somewhere near start of ppp_connect() (and
ppp_listen()) as it might be called later at a random time.

Signed-off-by: Sylvain Rochet <gradator@gradator.net>
2018-08-31 10:12:50 +02:00
Dirk Ziegelmeier
dac4cb05f7 Fix bug #54569: Compiler warning in ip4.c: unused parameter dest 2018-08-29 08:55:25 +02:00
Axel Lin
7b7bc349ae netif/lowpan6_ble: Fix comment for parameter order of ble_addr_to_eui64
Signed-off-by: Axel Lin <axel.lin@ingics.com>
2018-08-19 22:47:43 +08:00
Axel Lin
bcd6c8a2d3 apps/sntp: Fix parameter name in doxygen comments
Make the parameter name in doxygen comments consistent wit the code.

Signed-off-by: Axel Lin <axel.lin@ingics.com>
2018-08-19 21:41:47 +08:00
Simon Goldschmidt
0674aa60fe sntp_getservername: fix parameter name in doxygen comments
Reported-by: Gisle Vanem <gisle.vanem@gmail.com>
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-08-18 20:23:24 +02:00
Dirk Ziegelmeier
e351937ea4 More cmake build system cleanups 2018-08-09 09:50:29 +02:00
Simon Goldschmidt
e8683ea9df api_lib: fix NETCONN_MBOX_WAITING_DEC() for LWIP_NETCONN_FULLDUPLEX
This was a copy & paste bug from ...INC()
2018-08-07 13:39:41 +02:00
Simon Goldschmidt
6363edc1db mqtt: fix reference function name in comment 2018-08-07 13:38:39 +02:00
Dirk Ziegelmeier
a19ea8b8d6 Cleanup CMAKE build system
Use target-specific commands for compile flags only
2018-08-06 13:05:35 +02:00
Dirk Ziegelmeier
aafc0adfe1 Fix bug #54381: SNMP RAW_DATA support is broken 2018-07-26 14:16:00 +02:00
Dirk Ziegelmeier
298951c738 Remove .clang-format for now, not sure if we are going to use it 2018-07-24 09:32:26 +02:00
Simon Goldschmidt
258cab1b22 fix bug #54315 (IPV6_V6ONLY socket accepts IPV4 connections)
Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
2018-07-23 21:47:33 +02:00
Simon Goldschmidt
c3d8b1ca80 add 'extern "C" {}' for cplusplus in ppp headers 2018-07-23 20:04:56 +02:00
Simon Goldschmidt
b5b31d86b2 fix dependencies in lwip/prot/dhcp.h and lwip/prot/igmp.h 2018-07-23 17:33:28 +02:00
Simon Goldschmidt
5bef7ea72f add 'extern "C" {}' for cplusplus in many headers 2018-07-19 22:05:43 +02:00
Simon Goldschmidt
633205ba78 fix bug #54254 (ppp/utils.c: use lwip_isdigit()) 2018-07-19 21:48:04 +02:00
Dirk Ziegelmeier
eeb2218b3d Revert "Test / RFC: Reformat a few files using clang-format"
This reverts commit 8b4a8159a8.

We do not want to do this shortly before a release. Reformatting (buggy reformatting) may introduce new bugs.
2018-07-18 08:34:01 +02:00
Dirk Ziegelmeier
0985e925a1 Fix bug #54327: V2.1.0rc1 pbuf.c misses stdint.h include
... without reformatting the document (clang-format)
2018-07-18 07:31:47 +02:00
Dirk Ziegelmeier
cffb5cc087 Revert "Fix bug #54327: V2.1.0rc1 pbuf.c misses stdint.h include"
This reverts commit 4e74421dac.
2018-07-18 07:30:41 +02:00
Dirk Ziegelmeier
8b4a8159a8 Test / RFC: Reformat a few files using clang-format
Does it compile? Does it look good (enough)?
2018-07-17 21:15:48 +02:00
Dirk Ziegelmeier
4e74421dac Fix bug #54327: V2.1.0rc1 pbuf.c misses stdint.h include 2018-07-17 20:45:09 +02:00
Dirk Ziegelmeier
cd1dd4f5b1 Clang-format: Remove "AlignConsecutiveAssignments: true"
This seems to be "Dirk Ziegelmeier-Style" not lwIP-Style :-)
2018-07-16 11:00:23 +02:00
Dirk Ziegelmeier
8841fdc8ea Add .clang-format file that matches lwIP style "close enough" 2018-07-15 11:46:22 +02:00
Dirk Ziegelmeier
02d6716ffd Remove non-working astylerc 2018-07-15 10:24:13 +02:00
123 changed files with 2009 additions and 557 deletions

6
.gitattributes vendored
View File

@@ -2,3 +2,9 @@
*.txt text
*.c text
*.h text
# For git archive
.gitignore export-ignore
.gitattributes export-ignore
.travis.yml export-ignore
.vscode export-ignore

242
CHANGELOG
View File

@@ -1,10 +1,109 @@
HISTORY
* These are only the most important changes. For a full list, use git log:
http://git.savannah.nongnu.org/cgit/lwip.git
(git master)
* [Enter new changes just after this line - do not remove this line]
(STABLE-2.1.2):
++ Bugfixes:
2018-11-21: Jens Nielsen
* netbiosns.c: fix expecting too large packet (bug #55069)
2018-11-19: Dirk Ziegelmeier
* smtp.c: fix compiling with strict C compatibility because of strnlen (bug #55034)
2018-11-12: Simon Goldschmidt
* tcp.c: fix overflow check in tcp_recved triggering invalid assertion (bug #55015)
2018-11-12: Simon Goldschmidt
* tcp.c: fix a bug in sending RST segments (sent from port 0)
(STABLE-2.1.1):
++ Bugfixes:
2018-11-01: Joan Lledó
* sockets.c: fix bad assertion in lwip_poll_dec_sockets_used() (bug #54933)
2018-11-01: Dirk Ziegelmeier
* ip4.c: don't send 127.* to default netif (bug #54670)
2018-10-23: David Girault
* altcp_tls_mbedtls.c: fix use-after free (bug #54774)
2018-10-23: Ognjen Bjelica, Dirk Ziegelmeier
* snmp_scalar.c: Avoid NULL pointer dereference (bug #54886)
2018-10-23: Simon Goldschmidt
* Fix missing standard includes in multiple files
2018-10-17: Ivan Warren
* def.h: fix casting htonX and ntohX to u16_t (bug #54850)
2018-10-12: Simon Goldschmidt
* Revert "tcp_abandon: no need to buffer pcb->local_port" (fix that source port was 0 for RST
called when aborting a connection)
2018-10-11: Jonas Rabenstein
* tcp.c: tcp_recved: check for overflow and warn about too big values (patch #9699)
2018-10-06: Joan Lledó
* sockets.c: alloc_socket(): Check for LWIP_SOCKET_POLL when setting select-
related variables (patch #9696)
2018-10-04: Spencer
* tcp.c: Update prev pointer when skipping entries in tcp_slowtmr (patch #9694)
2018-09-27: Martine Lenders
* lowpan6.c: Fix IEEE 802.15.4 address setting (bug #54749)
(STABLE-2.1.0):
++ New features:
2018-06-17: Simon Goldschmidt
* lwiperf: implemented iPerf client mode
2018-04-23: Dirk Ziegelmeier
* added cmake build files
2018-03-04: Ray Abram
* netbios responder: respond to '*' queries
2018-02-23: Benjamin Aigner
* 6lowpan: add 6lowpan-over-BLE netif (based on existing 6lowpan netif)
2018-02-22: Simon Goldschmidt
* ipv6: add support for stateless DHCPv6 (to get DNS servers in SLAAC nets)
2018-02-16: Simon Goldschmidt
* add raw API http(s) client (with proxy support)
2018-02-01: Simon Goldschmidt
* tcp: add hooks to implement additional socket options
2018-02-01: Simon Goldschmidt
* tcp: add hooks to implement tcp md5 signatures or similar (see contrib/addons for an example)
2018-01-05: Simon Goldschmidt
* Added sys_mbox_trypost_fromisr() and tcpip_callbackmsg_trycallback_fromisr()
These can be used to post preallocated messages from an ISR to the tcpip thread
(e.g. when using FreeRTOS)
2018-01-02: Dirk Ziegelmeier
* task #14780: Add debug helper asserts to ensure threading/locking requirements are met
2017-11-21: Simon Goldschmidt
* task #14600: tcp_alloc(): kill TF_CLOSEPEND connections before other ESTABLISHED
2017-11-21: Simon Goldschmidt
* makefsdata: added option "-ssi:<filename>" to control SSI tag checking/insertion
through a list of filenames, not by checking the file extension at runtime
2017-11-20: Joel Cunningham
* netconn: add LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE to use external DNS resolver (patch #9427)
@@ -44,7 +143,7 @@ HISTORY
* dhcp: added two hooks for adding and parsing user defined DHCP options
2017-04-25: Joel Cunningham
* sockets: added CMSG and IP_PKTINFO for use with recvmsg (task #14247)
* sockets: added recvmsg for UDP (together with CMSG and IP_PKTINFO) (task #14247)
2017-04-20: Joel Cunningham
* tcp: added Appropriate Byte Counting support (task #14128)
@@ -53,6 +152,13 @@ HISTORY
* netconn/sockets: remove fatal error handling, fix asynchronous error handling,
ensure data before RST can be received
2017-03-30: Simon Goldschmidt
* added "application layered TCP" connection API (altcp) for seamless integration
of TLS or proxy connections
2017-03-09: Simon Goldschmidt
* sockets: add recvmsg for TCP
2017-03-02: Joel Cunningham
* netconn/sockets: vectorize netconn_write for TCP, treating a vectored I/O write
atomically in regards to TCP segmentation (patch #8882)
@@ -63,17 +169,11 @@ HISTORY
2017-02-28: Simon Goldschmidt
* Added LWIP_SINGLE_NETIF for small targets with only one netif
2017-02-17: Simon Goldschmidt
* Improved DNS_LOCAL_HOSTLIST interface
2017-02-10: David van Moolenbroek
* Implement UDP and RAW multicast support for IPv6 (core API, not netconn/sockets)
2017-02-10: Simon Goldschmidt
* tcp_close does not fail on memory error (instead, FIN is sent from tcp_tmr)
2017-02-04: David van Moolenbroek
- IPv6 scopes support
* IPv6 scopes support
2017-01-20: Joel Cunningham
* sockets: add interface name/index APIs (task #14314)
@@ -86,6 +186,34 @@ HISTORY
++ Bugfixes:
2018-06-19: Simon Goldschmidt
* tcp: fix RTO timer not working if link is down
2018-06-15: Sylvain Rochet
* ppp: multiple smaller bugfixes
2018-05-17: Simon Goldschmidt
* etharp: arp table can now be bigger than 127 entries
2018-04-25: Jens Nielsen
* tftp server: correctly handle retransmissions
2018-04-18: Simon Goldschmidt
sockets: fix race conditions when closing full-duplex sockets
2018-03-09: Simon Goldschmidt
* 6lowpan: fix to work against contiki; added ZigBee encapsulation netif for tests
2018-02-04: Simon Goldschmidt
* sockets: fix inconsistencies on close (inconsistent error codes, double FIN)
2018-01-05: Dirk Ziegelmeier
* Fix bug #52748: the bug in timeouts.c by reimplementing timer logic to use
absolute instead of relative timeout values
2017-12-31: Dirk Ziegelmeier
* Fix bug #52704: DHCP and bad OFFER: Stop timeout only if offer is accepted
2017-11-08: Joel Cunningham
* netif: ensure link and admin states are up in issue reports (bug #52353)
@@ -120,8 +248,50 @@ HISTORY
* sockets.c: task #14420 (Remove sys_sem_signal from inside SYS_ARCH_PROTECT
crit section) done for LWIP_TCPIP_CORE_LOCKING==1
2017-02-24: Simon Goldschmidt
* sockets.c: fixed close race conditions in lwip_select (for LWIP_NETCONN_FULLDUPLEX)
2017-02-24: Simon Goldschmidt
* sockets.c: fixed that select ignored invalid/not open sockets in the fd_sets (bug #50392)
2017-01-11: David van Moolenbroek
* Lots of IPv6 related fixes and improvements
(STABLE-2.0.3)
++ Bugfixes:
2017-09-11: Simon Goldschmidt
* tcp_in.c: fix bug #51937 (leaking tcp_pcbs on passive close with unacked data)
2017-08-02: Abroz Bizjak/Simon Goldschmidt
* multiple fixes in IPv4 reassembly (leading to corrupted datagrams received)
2017-03-30: Simon Goldschmidt
* dhcp.c: return ERR_VAL instead of asserting on offset-out-of-pbuf
2017-03-23: Dirk Ziegelmeier
* dhcp.h: fix bug #50618 (dhcp_remove_struct() macro does not work)
(STABLE-2.0.2)
++ New features:
2017-02-10: Dirk Ziegelmeier
* Implement task #14367: Hooks need a better place to be defined:
We now have a #define for a header file name that is #included in every .c
file that provides hooks.
2017-02-10: Simon Goldschmidt
* tcp_close does not fail on memory error (instead, FIN is sent from tcp_tmr)
++ Bugfixes:
2017-03-08
* tcp: do not keep sending SYNs when getting ACKs
2017-03-08: Joel Cunningham
* tcp: initialize ssthresh to TCP_SND_BUF (bug #50476)
* tcp: Initialize ssthresh to TCP_SND_BUF (bug #50476)
2017-03-01: Simon Goldschmidt
* httpd: LWIP_HTTPD_POST_MANUAL_WND: fixed double-free when httpd_post_data_recved
@@ -130,23 +300,57 @@ HISTORY
2017-02-28: David van Moolenbroek/Simon Goldschmidt
* tcp: fixed bug #50418: LWIP_EVENT_API: fix invalid calbacks for SYN_RCVD pcb
2017-02-24: Simon Goldschmidt
* sockets.c: fixed close race conditions in lwip_select (for LWIP_NETCONN_FULLDUPLEX)
2017-02-24: Simon Goldschmidt
* sockets.c: fixed that select ignored invalid/not open sockets in the fd_sets (bug #50392)
2017-02-17: Simon Goldschmidt
* dns: Improved DNS_LOCAL_HOSTLIST interface (bug #50325)
2017-02-16: Simon Goldschmidt
* LWIP_NETCONN_FULLDUPLEX: fixed shutdown during write (bug #50274)
2017-02-13: Simon Goldschmidt/Dirk Ziegelmeier
* For tiny targtes, LWIP_RAND is optional (fix compile time checks)
2017-02-10: Simon Goldschmidt
* tcp: Fixed bug #47485 (tcp_close() should not fail on memory error) by retrying
to send FIN from tcp_fasttmr
2017-02-09: Simon Goldschmidt
* sockets: Fixed bug #44032 (LWIP_NETCONN_FULLDUPLEX: select might work on
invalid/reused socket) by not allowing to reallocate a socket that has
"select_waiting != 0"
2017-02-09: Simon Goldschmidt
* httpd: Fixed bug #50059 (httpd LWIP_HTTPD_SUPPORT_11_KEEPALIVE vs.
LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED)
2017-02-08: Dirk Ziegelmeier
* Rename "IPv6 mapped IPv4 addresses" to their correct name from RFC4191:
"IPv4-mapped IPv6 address"
2017-02-08: Luc Revardel
* mld6.c: Fix bug #50220 (mld6_leavegroup does not send ICMP6_TYPE_MLD, even
if last reporter)
2017-02-08: David van Moolenbroek
* ip6.c: Patch #9250: fix source substitution in ip6_output_if()
2017-02-08: Simon Goldschmidt
* tcp_out.c: Fixed bug #50090 (last_unsent->oversize_left can become wrong value
in tcp_write error path)
2017-02-02: Dirk Ziegelmeier
* Fix bug #50206: UDP Netconn bind to IP6_ADDR_ANY fails
2017-01-18: Dirk Ziegelmeier
* Fix zero-copy RX, see bug bug #50064. PBUF_REFs were not supported as ARP requests.
2017-01-11: David van Moolenbroek
* Lots of IPv6 related fixes and improvements
2017-01-15: Axel Lin, Dirk Ziegelmeier
* minor bug fixes in mqtt
2017-01-11: Knut Andre Tidemann
* sockets/netconn: fix broken default ICMPv6 handling of checksums
(STABLE-2.0.1)
++ New features:
2016-12-31: Simon Goldschmidt
@@ -186,7 +390,7 @@ HISTORY
2016-12-05: Dirk Ziegelmeier
* fixed compiling with IPv4 disabled (IPv6 only case)
2016-11-28: Simon Goldschmidt
* api_lib.c: fixed bug #49725 (send-timeout: netconn_write() can return
ERR_OK without all bytes being written)
@@ -215,7 +419,7 @@ HISTORY
2016-11-11: Dirk Ziegelmeier
* sockets.c: fixed bug #49578 (dropping multicast membership does not work
with LWIP_SOCKET_OFFSET)
(STABLE-2.0.0)
++ New features:

View File

@@ -12,6 +12,7 @@ set(CPACK_PACKAGE_VERSION_MAJOR "${LWIP_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${LWIP_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${LWIP_VERSION_REVISION}")
set(CPACK_SOURCE_IGNORE_FILES "/build/;${CPACK_SOURCE_IGNORE_FILES};.git")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "lwip-${LWIP_VERSION_MAJOR}.${LWIP_VERSION_MINOR}.${LWIP_VERSION_REVISION}")
include(CPack)
# Target for package generation

11
FEATURES Normal file
View File

@@ -0,0 +1,11 @@
lwIP is a small independent implementation of the TCP/IP protocol suite targeted at embedded systems.
The focus of the lwIP TCP/IP implementation is to reduce resource usage while still having a full scale TCP. This makes lwIP suitable for use in embedded systems with tens of kilobytes of free RAM and room for around 40 kilobytes of code ROM.
Main features include:
- Protocols: IP, IPv6, ICMP, ND, MLD, UDP, TCP, IGMP, ARP, PPPoS, PPPoE, 6LowPAN (via IEEE 802.15.4, BLE or ZEP; since v2.1.0)
- DHCP client, stateless DHCPv6 (since v2.1.0), DNS client (incl. mDNS hostname resolver), AutoIP/APIPA (Zeroconf), SNMP agent (v1, v2c, v3 (since v2.1.0), private MIB support & MIB compiler)
- APIs: specialized APIs for enhanced performance & zero copy, optional Berkeley-alike socket API
- Extended features: IP forwarding over multiple network interfaces
- Extended TCP features: congestion control, RTT estimation and fast recovery/fast retransmit, sending SACKs (since v2.1.0), "altcp": nearly transparent TLS for any tcp pcb (since v2.1.0)
- Addon applications: HTTP server (HTTPS via altcp), HTTP(S) client (since v2.1.0), SNTP client, SMTP client (SMTPS via altcp), ping, NetBIOS nameserver, mDNS responder, MQTT client (TLS support since v2.1.0), TFTP server, iPerf2 counterpart

22
README
View File

@@ -1,15 +1,15 @@
INTRODUCTION
lwIP is a small independent implementation of the TCP/IP protocol
suite that has been developed by Adam Dunkels at the Computer and
Networks Architectures (CNA) lab at the Swedish Institute of Computer
Science (SICS).
lwIP is a small independent implementation of the TCP/IP protocol suite.
The focus of the lwIP TCP/IP implementation is to reduce the RAM usage
while still having a full scale TCP. This making lwIP suitable for use
in embedded systems with tens of kilobytes of free RAM and room for
around 40 kilobytes of code ROM.
lwIP was originally developed by Adam Dunkels at the Computer and Networks
Architectures (CNA) lab at the Swedish Institute of Computer Science (SICS)
and is now developed and maintained by a worldwide network of developers.
FEATURES
@@ -22,22 +22,28 @@ FEATURES
* ND (Neighbor discovery and stateless address autoconfiguration for IPv6).
Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862
(Address autoconfiguration)
* DHCP, AutoIP/APIPA (Zeroconf) and (stateless) DHCPv6
* UDP (User Datagram Protocol) including experimental UDP-lite extensions
* TCP (Transmission Control Protocol) with congestion control, RTT estimation
and fast recovery/fast retransmit
fast recovery/fast retransmit and sending SACKs
* raw/native API for enhanced performance
* Optional Berkeley-like socket API
* DNS (Domain names resolver)
* TLS: optional layered TCP ("altcp") for nearly transparent TLS for any
TCP-based protocol (ported to mbedTLS) (see changelog for more info)
* PPPoS and PPPoE (Point-to-point protocol over Serial/Ethernet)
* DNS (Domain name resolver incl. mDNS)
* 6LoWPAN (via IEEE 802.15.4, BLE or ZEP)
APPLICATIONS
* HTTP server with SSI and CGI
* SNMPv2c agent with MIB compiler (Simple Network Management Protocol)
* HTTP server with SSI and CGI (HTTPS via altcp)
* SNMPv2c agent with MIB compiler (Simple Network Management Protocol), v3 via altcp
* SNTP (Simple network time protocol)
* NetBIOS name service responder
* MDNS (Multicast DNS) responder
* iPerf server implementation
* MQTT client (TLS support via altcp)
LICENSE

View File

@@ -8,45 +8,40 @@ with newer versions.
* [Enter new changes just after this line - do not remove this line]
(2.1.0)
++ Application changes:
* tcpip_trycallback() was renamed to tcpip_callbackmsg_trycallback() to avoid confusion
with tcpip_try_callback()
* Use the new altcp API for seamless TLS integration into existing TCP applications (see changelog)
* TCP only kills existing connections with a LOWER priority than the one currently being opened.
Previous implementations also kill existing connections of the SAME priority.
* ip4_route_src: parameter order is reversed: ip4_route_src(dest, src) -> ip4_route_src(src, dest)
to make parameter order consistent with other ip*_route*() functions.
Same also applies to LWIP_HOOK_IP4_ROUTE_SRC() parameter order.
* pbuf API: pbuf->type (an u8_t holding the enum 'pbuf_type') has changed to only hold a
description of the pbuf (e.g. data following pbuf struct, data volatile, allocation
source heap/pool/etc.). As a consequence, applications can't test pbuf->type any more.
Use pbuf_match_type(pbuf, type) instead.
* socket API: according to the standard, SO_ERROR now only returns asynchronous errors.
All other/normal/synchronous errors are (and always were) available via 'errno'.
LWIP_SOCKET_SET_ERRNO has been removed - 'errno' is always set - and required!
* httpd LWIP_HTTPD_CGI_SSI: httpd_cgi_handler() has an additional parameter "struct fs_file *"
++ Port changes:
* tcpip_trycallback() was renamed to tcpip_callbackmsg_trycallback() to avoid confusion
with tcpip_try_callback()
* compatibility headers: moved from 'src/include/posix' to 'src/include/compat/posix',
'src/include/compat/stdc' etc.
* The IPv6 implementation now supports address scopes. All addresses that have a scope according
to the default policy (link-local unicast addresses, interface-local and link-local multicast
addresses) should now have a zone set on them before being passed to the core API, although
lwIP will currently attempt to select a zone on the caller's behalf when necessary.
Applications that directly assign IPv6 addresses to interfaces (which is NOT recommended)
must now ensure that link-local addresses carry the netif's zone. See the new ip6_zone.h header
file for more information and relevant macros. For now it is still possible to turn off scopes
support through the new LWIP_IPV6_SCOPES option. When upgrading an implementation that uses the
core API directly, it is highly recommended to enable LWIP_IPV6_SCOPES_DEBUG at least for
a while, to ensure e.g. proper address initialization.
* The IPv6 implementation now supports address scopes. (See LWIP_IPV6_SCOPES documentation
and ip6_zone.h for more documentation)
* LWIP_HOOK_DHCP_APPEND_OPTIONS() has changed, see description in opt.h (options_out_len is not
available in struct dhcp any more)
* httpd LWIP_HTTPD_CGI_SSI: httpd_cgi_handler() has an additional parameter "struct fs_file *"
* Added debug helper asserts to ensure threading/locking requirements are met (define
LWIP_MARK_TCPIP_THREAD() and LWIP_ASSERT_CORE_LOCKED()).
* Added sys_mbox_trypost_fromisr() and tcpip_callbackmsg_trycallback_fromisr()
These can be used to post preallocated messages from an ISR to the tcpip thread
(e.g. when using FreeRTOS)
(2.0.2)

View File

@@ -1,22 +0,0 @@
# lwIP astyle formatting options
# NOT FINISHED - DON'T USE
# braces and indent
style=otbs
indent=spaces=2
attach-extern-c
#attach-closing-while
# indentation
indent-switches
#max-continuation-indent=40
# padding
pad-oper
pad-comma
pad-header
align-pointer=name
# formatting
break-one-line-headers
keep-one-line-blocks
# don't use "other options" (e.g. formatted) in this file
# send them as additional command line options

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = "lwIP"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = "2.1.0.rc1"
PROJECT_NUMBER = "2.1.3"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@@ -101,6 +101,20 @@
/**
* @page changelog Changelog
*
* 2.1.0
* -----
* * Support TLS via new @ref altcp_api connection API (https, smtps, mqtt over TLS)
* * Switch to cmake as the main build system (Makefile file lists are still
* maintained for now)
* * Improve IPv6 support: support address scopes, support stateless DHCPv6, bugfixes
* * Add debug helper asserts to ensure threading/locking requirements are met
* * Add sys_mbox_trypost_fromisr() and tcpip_callbackmsg_trycallback_fromisr()
* (for FreeRTOS, mainly)
* * socket API: support poll(), sendmsg() and recvmsg(); fix problems on close
*
* Detailed Changelog
* ------------------
* @verbinclude "CHANGELOG"
*/
@@ -190,6 +204,15 @@
* Read especially sections "Cache coherency" and "Buffer alignment".
*/
/**
* @page mem_err Debugging memory pool sizes
* If you have issues with lwIP and you are using memory pools, check that your pools
* are correctly sized.\n
* To debug pool sizes, \#define LWIP_STATS and MEMP_STATS to 1. Check the global variable
* lwip_stats.memp[] using a debugger. If the "err" member of a pool is > 0, the pool
* may be too small for your application and you need to increase its size.
*/
/**
* @page bugs Reporting bugs
* Please report bugs in the lwIP bug tracker at savannah.\n

View File

@@ -10,11 +10,11 @@
set(LWIP_VERSION_MAJOR "2")
set(LWIP_VERSION_MINOR "1")
set(LWIP_VERSION_REVISION "0")
set(LWIP_VERSION_REVISION "3")
# LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases
# LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions
# Numbers 1..31 are reserved for release candidates
set(LWIP_VERSION_RC "1")
set(LWIP_VERSION_RC "LWIP_RC_RELEASE")
if ("${LWIP_VERSION_RC}" STREQUAL "LWIP_RC_RELEASE")
set(LWIP_VERSION_STRING
@@ -257,21 +257,23 @@ find_package(Doxygen)
if (DOXYGEN_FOUND)
message("Doxygen build started")
add_custom_target(lwipdocs EXCLUDE_FROM_ALL
add_custom_target(lwipdocs
COMMAND ${CMAKE_COMMAND} -E remove_directory ${DOXYGEN_DIR}/${DOXYGEN_OUTPUT_DIR}/html
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
WORKING_DIRECTORY ${DOXYGEN_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM)
# Remove old docs before generating new ones to prevent stale files
add_custom_command(TARGET lwipdocs
PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E remove_directory ${DOXYGEN_DIR}/${DOXYGEN_OUTPUT_DIR}/html
)
else (DOXYGEN_FOUND)
message("Doxygen needs to be installed to generate the doxygen documentation")
endif (DOXYGEN_FOUND)
# lwIP libraries
add_library(lwipcore EXCLUDE_FROM_ALL ${lwipnoapps_SRCS})
target_compile_options(lwipcore PRIVATE ${LWIP_COMPILER_FLAGS})
target_compile_definitions(lwipcore PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
target_include_directories(lwipcore PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})
add_library(lwipallapps EXCLUDE_FROM_ALL ${lwipallapps_SRCS})
target_compile_options(lwipallapps PRIVATE ${LWIP_COMPILER_FLAGS})
target_compile_definitions(lwipallapps PRIVATE ${LWIP_DEFINITIONS} ${LWIP_MBEDTLS_DEFINITIONS})
target_include_directories(lwipallapps PRIVATE ${LWIP_INCLUDE_DIRS} ${LWIP_MBEDTLS_INCLUDE_DIRS})

View File

@@ -95,7 +95,7 @@
#define NETCONN_RECVMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->recvmbox) && (((conn)->flags & NETCONN_FLAG_MBOXINVALID) == 0))
#define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & (NETCONN_FLAG_MBOXCLOSED|NETCONN_FLAG_MBOXINVALID)) == 0))
#define NETCONN_MBOX_WAITING_INC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1)
#define NETCONN_MBOX_WAITING_DEC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1)
#define NETCONN_MBOX_WAITING_DEC(conn) SYS_ARCH_DEC(conn->mbox_threads_waiting, 1)
#else /* LWIP_NETCONN_FULLDUPLEX */
#define NETCONN_RECVMBOX_WAITABLE(conn) sys_mbox_valid(&(conn)->recvmbox)
#define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & NETCONN_FLAG_MBOXCLOSED) == 0))
@@ -201,16 +201,16 @@ netconn_prepare_delete(struct netconn *conn)
API_MSG_VAR_ALLOC(msg);
API_MSG_VAR_REF(msg).conn = conn;
#if LWIP_TCP
#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
/* get the time we started, which is later compared to
sys_now() + conn->send_timeout */
API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now();
#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
#if LWIP_TCP
API_MSG_VAR_REF(msg).msg.sd.polls_left =
((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
#endif /* LWIP_TCP */
#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
#endif /* LWIP_TCP */
err = netconn_apimsg(lwip_netconn_do_delconn, &API_MSG_VAR_REF(msg));
API_MSG_VAR_FREE(msg);
@@ -500,7 +500,7 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
NETCONN_MBOX_WAITING_INC(conn);
if (netconn_is_nonblocking(conn)) {
if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_ARCH_TIMEOUT) {
if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_MBOX_EMPTY) {
API_MSG_VAR_FREE_ACCEPT(msg);
NETCONN_MBOX_WAITING_DEC(conn);
return ERR_WOULDBLOCK;
@@ -597,7 +597,7 @@ netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
NETCONN_MBOX_WAITING_INC(conn);
if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) ||
(conn->flags & NETCONN_FLAG_MBOXCLOSED) || (conn->pending_err != ERR_OK)) {
if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_ARCH_TIMEOUT) {
if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_MBOX_EMPTY) {
err_t err;
NETCONN_MBOX_WAITING_DEC(conn);
err = netconn_err(conn);
@@ -1346,7 +1346,7 @@ void
netconn_thread_init(void)
{
sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
if ((sem == NULL) || !sys_sem_valid(sem)) {
if (!sys_sem_valid(sem)) {
/* call alloc only once */
LWIP_NETCONN_THREAD_SEM_ALLOC();
LWIP_ASSERT("LWIP_NETCONN_THREAD_SEM_ALLOC() failed", sys_sem_valid(LWIP_NETCONN_THREAD_SEM_GET()));
@@ -1357,7 +1357,7 @@ void
netconn_thread_cleanup(void)
{
sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET();
if ((sem != NULL) && sys_sem_valid(sem)) {
if (sys_sem_valid(sem)) {
/* call free only once */
LWIP_NETCONN_THREAD_SEM_FREE();
}

View File

@@ -716,6 +716,9 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
conn->pending_err = ERR_OK;
conn->type = t;
conn->pcb.tcp = NULL;
#if LWIP_NETCONN_FULLDUPLEX
conn->mbox_threads_waiting = 0;
#endif
/* If all sizes are the same, every compiler should optimize this switch to nothing */
switch (NETCONNTYPE_GROUP(t)) {

View File

@@ -128,8 +128,7 @@ lwip_gethostbyname(const char *name)
if (s_hostent.h_addr_list != NULL) {
u8_t idx;
for (idx = 0; s_hostent.h_addr_list[idx]; idx++) {
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx]));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t *)s_hostent.h_addr_list[idx])));
LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa(s_phostent_addr[idx])));
}
}
#endif /* DNS_DEBUG */
@@ -306,7 +305,11 @@ lwip_getaddrinfo(const char *nodename, const char *servname,
/* service name specified: convert to port number
* @todo?: currently, only ASCII integers (port numbers) are supported (AI_NUMERICSERV)! */
port_nr = atoi(servname);
if ((port_nr <= 0) || (port_nr > 0xffff)) {
if (port_nr == 0 && (servname[0] != '0')) {
/* atoi failed - service was not numeric */
return EAI_SERVICE;
}
if ((port_nr < 0) || (port_nr > 0xffff)) {
return EAI_SERVICE;
}
}

View File

@@ -522,14 +522,14 @@ alloc_socket(struct netconn *newconn, int accepted)
after having marked it as used. */
SYS_ARCH_UNPROTECT(lev);
sockets[i].lastdata.pbuf = NULL;
#if LWIP_SOCKET_SELECT
#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL
LWIP_ASSERT("sockets[i].select_waiting == 0", sockets[i].select_waiting == 0);
sockets[i].rcvevent = 0;
/* TCP sendbuf is empty, but the socket is not yet writable until connected
* (unless it has been created by accept()). */
sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1);
sockets[i].errevent = 0;
#endif /* LWIP_SOCKET_SELECT */
#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */
return i + LWIP_SOCKET_OFFSET;
}
SYS_ARCH_UNPROTECT(lev);
@@ -688,7 +688,6 @@ lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
err = netconn_peer(newconn, &naddr, &port);
if (err != ERR_OK) {
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err));
netconn_delete(newconn);
free_socket(nsock, 1);
sock_set_errno(sock, err_to_errno(err));
done_socket(sock);
@@ -1305,7 +1304,7 @@ lwip_recvmsg(int s, struct msghdr *message, int flags)
if ((message->msg_iov[i].iov_base == NULL) || ((ssize_t)message->msg_iov[i].iov_len <= 0) ||
((size_t)(ssize_t)message->msg_iov[i].iov_len != message->msg_iov[i].iov_len) ||
((ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len) <= 0)) {
sock_set_errno(sock, ERR_VAL);
sock_set_errno(sock, err_to_errno(ERR_VAL));
done_socket(sock);
return -1;
}
@@ -2073,7 +2072,9 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
/* Call lwip_selscan again: there could have been events between
the last scan (without us on the list) and putting us on the list! */
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
if (!nready) {
if (nready < 0) {
set_errno(EBADF);
} else if (!nready) {
/* Still none ready, just wait to be woken */
if (timeout == 0) {
/* Wait forever */
@@ -2102,7 +2103,8 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
(exceptset && FD_ISSET(i, exceptset))) {
struct lwip_sock *sock;
SYS_ARCH_PROTECT(lev);
sock = tryget_socket_unconn_locked(i);
sock = tryget_socket_unconn_nouse(i);
LWIP_ASSERT("socket gone at the end of select", sock != NULL);
if (sock != NULL) {
/* for now, handle select_waiting==0... */
LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0);
@@ -2110,7 +2112,6 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
sock->select_waiting--;
}
SYS_ARCH_UNPROTECT(lev);
done_socket(sock);
} else {
SYS_ARCH_UNPROTECT(lev);
/* Not a valid socket */
@@ -2147,6 +2148,11 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
/* See what's set now after waiting */
nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready));
if (nready < 0) {
set_errno(EBADF);
lwip_select_dec_sockets_used(maxfdp1, &used_sockets);
return -1;
}
}
}
}
@@ -2304,7 +2310,6 @@ lwip_poll_dec_sockets_used(struct pollfd *fds, nfds_t nfds)
/* Go through each struct pollfd in the array. */
for (fdi = 0; fdi < nfds; fdi++) {
struct lwip_sock *sock = tryget_socket_unconn_nouse(fds[fdi].fd);
LWIP_ASSERT("socket gone at the end of select", sock != NULL);
if (sock != NULL) {
done_socket(sock);
}

View File

@@ -217,7 +217,7 @@ tcpip_thread_poll_one(void)
int ret = 0;
struct tcpip_msg *msg;
if (sys_arch_mbox_tryfetch(&tcpip_mbox, (void **)&msg) != SYS_ARCH_TIMEOUT) {
if (sys_arch_mbox_tryfetch(&tcpip_mbox, (void **)&msg) != SYS_MBOX_EMPTY) {
LOCK_TCPIP_CORE();
if (msg != NULL) {
tcpip_thread_handle_msg(msg);

View File

@@ -40,17 +40,13 @@
* track of the ratio of application data and TLS overhead would be too much.
*
* Mandatory security-related configuration:
* - define ALTCP_MBEDTLS_RNG_FN to a custom GOOD rng function returning 0 on success:
* int my_rng_fn(void *ctx, unsigned char *buffer , size_t len)
* - ensure to add at least one strong entropy source to your mbedtls port (implement
* mbedtls_platform_entropy_poll or mbedtls_hardware_poll providing strong entropy)
* - define ALTCP_MBEDTLS_ENTROPY_PTR and ALTCP_MBEDTLS_ENTROPY_LEN to something providing
* GOOD custom entropy
*
* Missing things / @todo:
* - RX data is acknowledged after receiving (tcp_recved is called when enqueueing
* the pbuf for mbedTLS receive, not when processed by mbedTLS or the inner
* connection; altcp_recved() from inner connection does nothing)
* - Client connections starting with 'connect()' are not handled yet...
* - some unhandled things are caught by LWIP_ASSERTs...
* - some unhandled/untested things migh be caught by LWIP_ASSERTs...
*/
#include "lwip/opt.h"
@@ -80,6 +76,7 @@
#include "mbedtls/platform.h"
#include "mbedtls/memory_buffer_alloc.h"
#include "mbedtls/ssl_cache.h"
#include "mbedtls/ssl_ticket.h"
#include "mbedtls/ssl_internal.h" /* to call mbedtls_flush_output after ERR_MEM */
@@ -99,16 +96,30 @@ extern const struct altcp_functions altcp_mbedtls_functions;
/** Our global mbedTLS configuration (server-specific, not connection-specific) */
struct altcp_tls_config {
mbedtls_ssl_config conf;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_x509_crt *cert;
mbedtls_pk_context *pkey;
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
uint8_t cert_count;
uint8_t cert_max;
uint8_t pkey_count;
uint8_t pkey_max;
mbedtls_x509_crt *ca;
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
/** Inter-connection cache for fast connection startup */
struct mbedtls_ssl_cache_context cache;
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && ALTCP_MBEDTLS_USE_SESSION_TICKETS
mbedtls_ssl_ticket_context ticket_ctx;
#endif
};
/** Entropy and random generator are shared by all mbedTLS configuration */
struct altcp_tls_entropy_rng {
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
int ref;
};
static struct altcp_tls_entropy_rng *altcp_tls_entropy_rng;
static err_t altcp_mbedtls_lower_recv(void *arg, struct altcp_pcb *inner_conn, struct pbuf *p, err_t err);
static err_t altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_conn);
static err_t altcp_mbedtls_lower_recv_process(struct altcp_pcb *conn, altcp_mbedtls_state_t *state);
@@ -308,17 +319,20 @@ altcp_mbedtls_pass_rx_data(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
LWIP_ASSERT("state != NULL", state != NULL);
buf = state->rx_app;
if (buf) {
state->rx_app = NULL;
if (conn->recv) {
u16_t tot_len = state->rx_app->tot_len;
u16_t tot_len = buf->tot_len;
/* this needs to be increased first because the 'recved' call may come nested */
state->rx_passed_unrecved += tot_len;
state->flags |= ALTCP_MBEDTLS_FLAGS_UPPER_CALLED;
err = conn->recv(conn->arg, conn, state->rx_app, ERR_OK);
err = conn->recv(conn->arg, conn, buf, ERR_OK);
if (err != ERR_OK) {
if (err == ERR_ABRT) {
return ERR_ABRT;
}
/* not received, leave the pbuf(s) queued (and decrease 'unrecved' again) */
LWIP_ASSERT("state == conn->state", state == conn->state);
state->rx_app = buf;
state->rx_passed_unrecved -= tot_len;
LWIP_ASSERT("state->rx_passed_unrecved >= 0", state->rx_passed_unrecved >= 0);
if (state->rx_passed_unrecved < 0) {
@@ -329,7 +343,6 @@ altcp_mbedtls_pass_rx_data(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
} else {
pbuf_free(buf);
}
state->rx_app = NULL;
} else if ((state->flags & (ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED | ALTCP_MBEDTLS_FLAGS_RX_CLOSED)) ==
ALTCP_MBEDTLS_FLAGS_RX_CLOSE_QUEUED) {
state->flags |= ALTCP_MBEDTLS_FLAGS_RX_CLOSED;
@@ -338,6 +351,11 @@ altcp_mbedtls_pass_rx_data(struct altcp_pcb *conn, altcp_mbedtls_state_t *state)
}
}
/* application may have close the connection */
if (conn->state != state) {
/* return error code to ensure altcp_mbedtls_handle_rx_appldata() exits the loop */
return ERR_CLSD;
}
return ERR_OK;
}
@@ -443,6 +461,7 @@ altcp_mbedtls_bio_recv(void *ctx, unsigned char *buf, size_t len)
return MBEDTLS_ERR_NET_INVALID_CONTEXT;
}
state = (altcp_mbedtls_state_t *)conn->state;
LWIP_ASSERT("state != NULL", state != NULL);
p = state->rx;
/* @todo: return MBEDTLS_ERR_NET_CONN_RESET/MBEDTLS_ERR_NET_RECV_FAILED? */
@@ -604,7 +623,7 @@ altcp_mbedtls_setup(void *conf, struct altcp_pcb *conn, struct altcp_pcb *inner_
}
struct altcp_pcb *
altcp_tls_new(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb)
altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb)
{
struct altcp_pcb *ret;
if (inner_pcb == NULL) {
@@ -630,71 +649,96 @@ altcp_tls_context(struct altcp_pcb *conn)
return NULL;
}
#if ALTCP_MBEDTLS_DEBUG != LWIP_DBG_OFF
#if ALTCP_MBEDTLS_LIB_DEBUG != LWIP_DBG_OFF
static void
altcp_mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str)
{
LWIP_UNUSED_ARG(str);
LWIP_UNUSED_ARG(level);
LWIP_UNUSED_ARG(ctx);
LWIP_UNUSED_ARG(file);
LWIP_UNUSED_ARG(line);
LWIP_UNUSED_ARG(ctx);
/* @todo: output debug string :-) */
LWIP_UNUSED_ARG(str);
if (level >= ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN) {
LWIP_DEBUGF(ALTCP_MBEDTLS_LIB_DEBUG, ("%s:%04d: %s", file, line, str));
}
}
#endif
#ifndef ALTCP_MBEDTLS_RNG_FN
/** ATTENTION: It is *really* important to *NOT* use this dummy RNG in production code!!!! */
static int
dummy_rng(void *ctx, unsigned char *buffer, size_t len)
{
static size_t ctr;
size_t i;
LWIP_UNUSED_ARG(ctx);
for (i = 0; i < len; i++) {
buffer[i] = (unsigned char)++ctr;
}
return 0;
}
#define ALTCP_MBEDTLS_RNG_FN dummy_rng
#endif /* ALTCP_MBEDTLS_RNG_FN */
/** Create new TLS configuration
* ATTENTION: Server certificate and private key have to be added outside this function!
*/
static struct altcp_tls_config *
altcp_tls_create_config(int is_server)
altcp_tls_create_config(int is_server, uint8_t cert_count, uint8_t pkey_count, int have_ca)
{
size_t sz;
int ret;
struct altcp_tls_config *conf;
mbedtls_x509_crt *mem;
if (TCP_WND < MBEDTLS_SSL_MAX_CONTENT_LEN) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG|LWIP_DBG_LEVEL_SERIOUS,
("altcp_tls: TCP_WND is smaller than the RX decrypion buffer, connection RX might stall!\n"));
}
altcp_mbedtls_mem_init();
sz = sizeof(struct altcp_tls_config) + sizeof(mbedtls_x509_crt);
if (is_server) {
sz += sizeof(mbedtls_pk_context);
sz = sizeof(struct altcp_tls_config);
if (cert_count > 0) {
sz += (cert_count * sizeof(mbedtls_x509_crt));
}
if (have_ca) {
sz += sizeof(mbedtls_x509_crt);
}
if (pkey_count > 0) {
sz += (pkey_count * sizeof(mbedtls_pk_context));
}
conf = (struct altcp_tls_config *)altcp_mbedtls_alloc_config(sz);
if (conf == NULL) {
return NULL;
}
conf->cert = (mbedtls_x509_crt *)(conf + 1);
if (is_server) {
conf->pkey = (mbedtls_pk_context *)((conf->cert) + 1);
conf->cert_max = cert_count;
mem = (mbedtls_x509_crt *)(conf + 1);
if (cert_count > 0) {
conf->cert = mem;
mem += cert_count;
}
if (have_ca) {
conf->ca = mem;
mem++;
}
conf->pkey_max = pkey_count;
if (pkey_count > 0) {
conf->pkey = (mbedtls_pk_context *)mem;
}
mbedtls_ssl_config_init(&conf->conf);
mbedtls_entropy_init(&conf->entropy);
mbedtls_ctr_drbg_init(&conf->ctr_drbg);
/* Seed the RNG */
ret = mbedtls_ctr_drbg_seed(&conf->ctr_drbg, ALTCP_MBEDTLS_RNG_FN, &conf->entropy, ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret));
altcp_mbedtls_free_config(conf);
return NULL;
if (!altcp_tls_entropy_rng) {
altcp_tls_entropy_rng = (struct altcp_tls_entropy_rng *)altcp_mbedtls_alloc_config(sizeof(struct altcp_tls_entropy_rng));
if (altcp_tls_entropy_rng) {
altcp_tls_entropy_rng->ref = 1;
mbedtls_entropy_init(&altcp_tls_entropy_rng->entropy);
mbedtls_ctr_drbg_init(&altcp_tls_entropy_rng->ctr_drbg);
/* Seed the RNG, only once */
ret = mbedtls_ctr_drbg_seed(&altcp_tls_entropy_rng->ctr_drbg,
mbedtls_entropy_func, &altcp_tls_entropy_rng->entropy,
ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret));
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
altcp_tls_entropy_rng = NULL;
altcp_mbedtls_free_config(conf);
return NULL;
}
} else {
altcp_mbedtls_free_config(conf);
return NULL;
}
} else {
altcp_tls_entropy_rng->ref++;
}
/* Setup ssl context (@todo: what's different for a client here? -> might better be done on listen/connect) */
@@ -702,24 +746,105 @@ altcp_tls_create_config(int is_server)
MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_config_defaults failed: %d\n", ret));
if (altcp_tls_entropy_rng->ref == 1) {
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
altcp_tls_entropy_rng = NULL;
}
altcp_mbedtls_free_config(conf);
return NULL;
}
mbedtls_ssl_conf_authmode(&conf->conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
mbedtls_ssl_conf_rng(&conf->conf, mbedtls_ctr_drbg_random, &conf->ctr_drbg);
#if ALTCP_MBEDTLS_DEBUG != LWIP_DBG_OFF
mbedtls_ssl_conf_rng(&conf->conf, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg);
#if ALTCP_MBEDTLS_LIB_DEBUG != LWIP_DBG_OFF
mbedtls_ssl_conf_dbg(&conf->conf, altcp_mbedtls_debug, stdout);
#endif
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
#if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_USE_SESSION_CACHE
mbedtls_ssl_conf_session_cache(&conf->conf, &conf->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set);
mbedtls_ssl_cache_set_timeout(&conf->cache, 30);
mbedtls_ssl_cache_set_max_entries(&conf->cache, 30);
mbedtls_ssl_cache_set_timeout(&conf->cache, ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS);
mbedtls_ssl_cache_set_max_entries(&conf->cache, ALTCP_MBEDTLS_SESSION_CACHE_SIZE);
#endif
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && ALTCP_MBEDTLS_USE_SESSION_TICKETS
mbedtls_ssl_ticket_init(&conf->ticket_ctx);
ret = mbedtls_ssl_ticket_setup(&conf->ticket_ctx, mbedtls_ctr_drbg_random, &altcp_tls_entropy_rng->ctr_drbg,
ALTCP_MBEDTLS_SESSION_TICKET_CIPHER, ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS);
if (ret) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_ticket_setup failed: %d\n", ret));
altcp_mbedtls_free_config(conf);
return NULL;
}
mbedtls_ssl_conf_session_tickets_cb(&conf->conf, mbedtls_ssl_ticket_write, mbedtls_ssl_ticket_parse,
&conf->ticket_ctx);
#endif
return conf;
}
struct altcp_tls_config *altcp_tls_create_config_server(uint8_t cert_count)
{
struct altcp_tls_config *conf = altcp_tls_create_config(1, cert_count, cert_count, 0);
if (conf == NULL) {
return NULL;
}
mbedtls_ssl_conf_ca_chain(&conf->conf, NULL, NULL);
return conf;
}
err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config,
const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len)
{
int ret;
mbedtls_x509_crt *srvcert;
mbedtls_pk_context *pkey;
if (config->cert_count >= config->cert_max) {
return ERR_MEM;
}
if (config->pkey_count >= config->pkey_max) {
return ERR_MEM;
}
srvcert = config->cert + config->cert_count;
mbedtls_x509_crt_init(srvcert);
pkey = config->pkey + config->pkey_count;
mbedtls_pk_init(pkey);
/* Load the certificates and private key */
ret = mbedtls_x509_crt_parse(srvcert, cert, cert_len);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d\n", ret));
return ERR_VAL;
}
ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
mbedtls_x509_crt_free(srvcert);
return ERR_VAL;
}
ret = mbedtls_ssl_conf_own_cert(&config->conf, srvcert, pkey);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d\n", ret));
mbedtls_x509_crt_free(srvcert);
mbedtls_pk_free(pkey);
return ERR_VAL;
}
config->cert_count++;
config->pkey_count++;
return ERR_OK;
}
/** Create new TLS configuration
* This is a suboptimal version that gets the encrypted private key and its password,
* as well as the server certificate.
@@ -729,71 +854,94 @@ altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len)
{
int ret;
mbedtls_x509_crt *srvcert;
mbedtls_pk_context *pkey;
struct altcp_tls_config *conf = altcp_tls_create_config(1);
struct altcp_tls_config *conf = altcp_tls_create_config_server(1);
if (conf == NULL) {
return NULL;
}
srvcert = conf->cert;
mbedtls_x509_crt_init(srvcert);
pkey = conf->pkey;
mbedtls_pk_init(pkey);
/* Load the certificates and private key */
ret = mbedtls_x509_crt_parse(srvcert, cert, cert_len);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d\n", ret));
if (altcp_tls_config_server_add_privkey_cert(conf, privkey, privkey_len,
privkey_pass, privkey_pass_len, cert, cert_len) != ERR_OK) {
altcp_mbedtls_free_config(conf);
return NULL;
}
ret = mbedtls_pk_parse_key(pkey, (const unsigned char *) privkey, privkey_len, privkey_pass, privkey_pass_len);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_public_key failed: %d\n", ret));
mbedtls_x509_crt_free(srvcert);
altcp_mbedtls_free_config(conf);
return conf;
}
static struct altcp_tls_config *
altcp_tls_create_config_client_common(const u8_t *ca, size_t ca_len, int is_2wayauth)
{
int ret;
struct altcp_tls_config *conf = altcp_tls_create_config(0, (is_2wayauth) ? 1 : 0, (is_2wayauth) ? 1 : 0, ca != NULL);
if (conf == NULL) {
return NULL;
}
mbedtls_ssl_conf_ca_chain(&conf->conf, srvcert->next, NULL);
ret = mbedtls_ssl_conf_own_cert(&conf->conf, srvcert, pkey);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d\n", ret));
mbedtls_x509_crt_free(srvcert);
mbedtls_pk_free(pkey);
altcp_mbedtls_free_config(conf);
return NULL;
/* Initialize the CA certificate if provided
* CA certificate is optional (to save memory) but recommended for production environment
* Without CA certificate, connection will be prone to man-in-the-middle attacks */
if (ca) {
mbedtls_x509_crt_init(conf->ca);
ret = mbedtls_x509_crt_parse(conf->ca, ca, ca_len);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse ca failed: %d 0x%x", ret, -1*ret));
altcp_mbedtls_free_config(conf);
return NULL;
}
mbedtls_ssl_conf_ca_chain(&conf->conf, conf->ca, NULL);
}
return conf;
}
struct altcp_tls_config *
altcp_tls_create_config_client(const u8_t *cert, size_t cert_len)
altcp_tls_create_config_client(const u8_t *ca, size_t ca_len)
{
return altcp_tls_create_config_client_common(ca, ca_len, 0);
}
struct altcp_tls_config *
altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len)
{
int ret;
mbedtls_x509_crt *acc_cert;
struct altcp_tls_config *conf = altcp_tls_create_config(0);
struct altcp_tls_config *conf;
if (!cert || !privkey) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("altcp_tls_create_config_client_2wayauth: certificate and priv key required"));
return NULL;
}
conf = altcp_tls_create_config_client_common(ca, ca_len, 1);
if (conf == NULL) {
return NULL;
}
/* Initialise certificates, allocated with conf */
acc_cert = conf->cert;
mbedtls_x509_crt_init(acc_cert);
/* Load the certificates */
ret = mbedtls_x509_crt_parse(acc_cert, cert, cert_len);
/* Initialize the client certificate and corresponding private key */
mbedtls_x509_crt_init(conf->cert);
ret = mbedtls_x509_crt_parse(conf->cert, cert, cert_len);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse failed: %d", ret));
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_x509_crt_parse cert failed: %d 0x%x", ret, -1*ret));
altcp_mbedtls_free_config(conf->cert);
return NULL;
}
mbedtls_pk_init(conf->pkey);
ret = mbedtls_pk_parse_key(conf->pkey, privkey, privkey_len, privkey_pass, privkey_pass_len);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_pk_parse_key failed: %d 0x%x", ret, -1*ret));
altcp_mbedtls_free_config(conf);
return NULL;
}
ret = mbedtls_ssl_conf_own_cert(&conf->conf, conf->cert, conf->pkey);
if (ret != 0) {
LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_conf_own_cert failed: %d 0x%x", ret, -1*ret));
altcp_mbedtls_free_config(conf);
return NULL;
}
mbedtls_ssl_conf_ca_chain(&conf->conf, acc_cert, NULL);
return conf;
}
@@ -803,8 +951,26 @@ altcp_tls_free_config(struct altcp_tls_config *conf)
if (conf->pkey) {
mbedtls_pk_free(conf->pkey);
}
mbedtls_x509_crt_free(conf->cert);
if (conf->cert) {
mbedtls_x509_crt_free(conf->cert);
}
if (conf->ca) {
mbedtls_x509_crt_free(conf->ca);
}
altcp_mbedtls_free_config(conf);
if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref)
altcp_tls_entropy_rng->ref--;
}
void
altcp_tls_free_entropy(void)
{
if (altcp_tls_entropy_rng && altcp_tls_entropy_rng->ref == 0) {
mbedtls_ctr_drbg_free(&altcp_tls_entropy_rng->ctr_drbg);
mbedtls_entropy_free(&altcp_tls_entropy_rng->entropy);
altcp_mbedtls_free_config(altcp_tls_entropy_rng);
altcp_tls_entropy_rng = NULL;
}
}
/* "virtual" functions */
@@ -861,6 +1027,11 @@ altcp_mbedtls_listen(struct altcp_pcb *conn, u8_t backlog, err_t *err)
}
lpcb = altcp_listen_with_backlog_and_err(conn->inner_conn, backlog, err);
if (lpcb != NULL) {
altcp_mbedtls_state_t *state = (altcp_mbedtls_state_t *)conn->state;
/* Free members of the ssl context (not used on listening pcb). This
includes freeing input/output buffers, so saves ~32KByte by default */
mbedtls_ssl_free(&state->ssl_context);
conn->inner_conn = lpcb;
altcp_accept(lpcb, altcp_mbedtls_lower_accept);
return conn;
@@ -1086,6 +1257,10 @@ const struct altcp_functions altcp_mbedtls_functions = {
altcp_default_get_tcp_addrinfo,
altcp_default_get_ip,
altcp_default_get_port
#if LWIP_TCP_KEEPALIVE
, altcp_default_keepalive_disable
, altcp_default_keepalive_enable
#endif
#ifdef LWIP_DEBUG
, altcp_default_dbg_get_tcp_state
#endif

View File

@@ -51,6 +51,8 @@
#include "lwip/mem.h"
#include "lwip/init.h"
#include <stdio.h>
/** This string is passed in the HTTP header as "User-Agent: " */
#ifndef ALTCP_PROXYCONNECT_CLIENT_AGENT
#define ALTCP_PROXYCONNECT_CLIENT_AGENT "lwIP/" LWIP_VERSION_STRING " (http://savannah.nongnu.org/projects/lwip)"
@@ -384,7 +386,7 @@ altcp_proxyconnect_new_tcp(struct altcp_proxyconnect_config *config, u8_t ip_typ
/** Allocator function to allocate a proxy connect altcp pcb connecting directly
* via tcp to the proxy.
*
* The returned pcb is a chain: <altcp_proxyconnect> - <altcp_tcp> - <tcp pcb>
* The returned pcb is a chain: altcp_proxyconnect - altcp_tcp - tcp pcb
*
* This function is meant for use with @ref altcp_new.
*
@@ -402,7 +404,7 @@ altcp_proxyconnect_alloc(void *arg, u8_t ip_type)
/** Allocator function to allocate a TLS connection through a proxy.
*
* The returned pcb is a chain: <altcp_tls> - <altcp_proxyconnect> - <altcp_tcp> - <tcp pcb>
* The returned pcb is a chain: altcp_tls - altcp_proxyconnect - altcp_tcp - tcp pcb
*
* This function is meant for use with @ref altcp_new.
*
@@ -418,7 +420,7 @@ altcp_proxyconnect_tls_alloc(void *arg, u8_t ip_type)
struct altcp_pcb *tls_pcb;
proxy_pcb = altcp_proxyconnect_new_tcp(&cfg->proxy, ip_type);
tls_pcb = altcp_tls_new(cfg->tls_config, proxy_pcb);
tls_pcb = altcp_tls_wrap(cfg->tls_config, proxy_pcb);
if (tls_pcb == NULL) {
altcp_close(proxy_pcb);

View File

@@ -55,8 +55,11 @@
#include "lwip/init.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if LWIP_TCP && LWIP_CALLBACK_API
/**
* HTTPC_DEBUG: Enable debugging for HTTP client.
*/
@@ -902,3 +905,5 @@ httpc_get_file_dns_to_disk(const char* server_name, u16_t port, const char* uri,
return ERR_OK;
}
#endif /* LWIP_HTTPC_HAVE_FILE_IO */
#endif /* LWIP_TCP && LWIP_CALLBACK_API */

View File

@@ -1301,6 +1301,22 @@ http_send_data_ssi(struct altcp_pcb *pcb, struct http_state *hs)
ssi->tag_state = TAG_NONE;
}
#if LWIP_HTTPD_DYNAMIC_FILE_READ && !LWIP_HTTPD_SSI_INCLUDE_TAG
if ((ssi->tag_state == TAG_NONE) &&
(ssi->parsed - hs->file < ssi->tag_index)) {
for(u16_t i = 0;i < ssi->tag_index;i++) {
ssi->tag_insert[i] = http_ssi_tag_desc[ssi->tag_type].lead_in[i];
}
ssi->tag_insert_len = ssi->tag_index;
hs->file += ssi->parsed - hs->file;
hs->left -= ssi->parsed - hs->file;
ssi->tag_end = hs->file;
ssi->tag_index = 0;
ssi->tag_state = TAG_SENDING;
break;
}
#endif
/* Move on to the next character in the buffer */
ssi->parse_left--;
ssi->parsed++;
@@ -2685,10 +2701,7 @@ void
httpd_inits(struct altcp_tls_config *conf)
{
#if LWIP_ALTCP_TLS
struct altcp_pcb *pcb_tls;
struct altcp_pcb *pcb_tcp = altcp_tcp_new_ip_type(IPADDR_TYPE_ANY);
LWIP_ASSERT("httpd_init: tcp_new failed", pcb_tcp != NULL);
pcb_tls = altcp_tls_new(conf, pcb_tcp);
struct altcp_pcb *pcb_tls = altcp_tls_new(conf, IPADDR_TYPE_ANY);
LWIP_ASSERT("httpd_init: altcp_tls_new failed", pcb_tls != NULL);
httpd_init_pcb(pcb_tls, HTTPD_SERVER_PORT_HTTPS);
#else /* LWIP_ALTCP_TLS */

View File

@@ -664,25 +664,24 @@ mqtt_incomming_suback(struct mqtt_request_t *r, u8_t result)
/**
* Complete MQTT message received or buffer full
* @param client MQTT client
* @param fixed_hdr_idx header index
* @param fixed_hdr_len length of fixed header
* @param length length received part
* @param remaining_length Remaining length of complete message
*/
static mqtt_connection_status_t
mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_idx, u16_t length, u32_t remaining_length)
mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_len, u16_t length, u32_t remaining_length)
{
mqtt_connection_status_t res = MQTT_CONNECT_ACCEPTED;
u8_t *var_hdr_payload = client->rx_buffer + fixed_hdr_idx;
size_t var_hdr_payload_bufsize = sizeof(client->rx_buffer) - fixed_hdr_idx;
u8_t *var_hdr_payload = client->rx_buffer + fixed_hdr_len;
size_t var_hdr_payload_bufsize = sizeof(client->rx_buffer) - fixed_hdr_len;
/* Control packet type */
u8_t pkt_type = MQTT_CTL_PACKET_TYPE(client->rx_buffer[0]);
u16_t pkt_id = 0;
LWIP_ASSERT("client->msg_idx < MQTT_VAR_HEADER_BUFFER_LEN", client->msg_idx < MQTT_VAR_HEADER_BUFFER_LEN);
LWIP_ASSERT("fixed_hdr_idx <= client->msg_idx", fixed_hdr_idx <= client->msg_idx);
LWIP_ERROR("buffer length mismatch", fixed_hdr_idx + length <= MQTT_VAR_HEADER_BUFFER_LEN,
LWIP_ASSERT("fixed_hdr_len <= client->msg_idx", fixed_hdr_len <= client->msg_idx);
LWIP_ERROR("buffer length mismatch", fixed_hdr_len + length <= MQTT_VAR_HEADER_BUFFER_LEN,
return MQTT_CONNECT_DISCONNECTED);
if (pkt_type == MQTT_MSG_TYPE_CONNACK) {
@@ -773,7 +772,9 @@ mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_idx, u16_t length, u
LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received short packet (payload)\n"));
goto out_disconnect;
}
client->data_cb(client->inpub_arg, var_hdr_payload + payload_offset, payload_length, remaining_length == 0 ? MQTT_DATA_FLAG_LAST : 0);
if (client->data_cb != NULL) {
client->data_cb(client->inpub_arg, var_hdr_payload + payload_offset, payload_length, remaining_length == 0 ? MQTT_DATA_FLAG_LAST : 0);
}
/* Reply if QoS > 0 */
if (remaining_length == 0 && qos > 0) {
/* Send PUBACK for QoS 1 or PUBREC for QoS 2 */
@@ -840,61 +841,59 @@ mqtt_parse_incoming(mqtt_client_t *client, struct pbuf *p)
{
u16_t in_offset = 0;
u32_t msg_rem_len = 0;
u8_t fixed_hdr_idx = 0;
u8_t fixed_hdr_len = 0;
u8_t b = 0;
while (p->tot_len > in_offset) {
/* We ALWAYS parse the header here first. Even if the header was not
included in this segment, we re-parse it here by buffering it in
client->rx_buffer. client->msg_idx keeps track of this. */
if ((fixed_hdr_idx < 2) || ((b & 0x80) != 0)) {
if ((fixed_hdr_len < 2) || ((b & 0x80) != 0)) {
if (fixed_hdr_idx < client->msg_idx) {
if (fixed_hdr_len < client->msg_idx) {
/* parse header from old pbuf (buffered in client->rx_buffer) */
b = client->rx_buffer[fixed_hdr_idx];
b = client->rx_buffer[fixed_hdr_len];
} else {
/* parse header from this pbuf and save it in client->rx_buffer in case
it comes in segmented */
b = pbuf_get_at(p, in_offset++);
client->rx_buffer[client->msg_idx++] = b;
}
fixed_hdr_idx++;
fixed_hdr_len++;
if (fixed_hdr_idx >= 2) {
if (fixed_hdr_len >= 2) {
/* fixed header contains at least 2 bytes but can contain more, depending on
'remaining length'. All bytes but the last of this have 0x80 set to
indicate more bytes are coming. */
msg_rem_len |= (u32_t)(b & 0x7f) << ((fixed_hdr_idx - 2) * 7);
msg_rem_len |= (u32_t)(b & 0x7f) << ((fixed_hdr_len - 2) * 7);
if ((b & 0x80) == 0) {
/* fixed header is done */
LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_parse_incoming: Remaining length after fixed header: %"U32_F"\n", msg_rem_len));
if (msg_rem_len == 0) {
/* Complete message with no extra headers of payload received */
mqtt_message_received(client, fixed_hdr_idx, 0, 0);
mqtt_message_received(client, fixed_hdr_len, 0, 0);
client->msg_idx = 0;
fixed_hdr_idx = 0;
fixed_hdr_len = 0;
} else {
/* Bytes remaining in message (changes remaining length if this is
not the first segment of this message) */
msg_rem_len = (msg_rem_len + fixed_hdr_idx) - client->msg_idx;
msg_rem_len = (msg_rem_len + fixed_hdr_len) - client->msg_idx;
}
}
}
} else {
/* Fixed header has been parsed, parse variable header */
u16_t cpy_len, cpy_start, buffer_space;
cpy_start = (client->msg_idx - fixed_hdr_idx) % (MQTT_VAR_HEADER_BUFFER_LEN - fixed_hdr_idx) + fixed_hdr_idx;
u16_t cpy_len, buffer_space;
/* Allow to copy the lesser one of available length in input data or bytes remaining in message */
cpy_len = (u16_t)LWIP_MIN((u16_t)(p->tot_len - in_offset), msg_rem_len);
/* Limit to available space in buffer */
buffer_space = MQTT_VAR_HEADER_BUFFER_LEN - cpy_start;
buffer_space = MQTT_VAR_HEADER_BUFFER_LEN - fixed_hdr_len;
if (cpy_len > buffer_space) {
cpy_len = buffer_space;
}
pbuf_copy_partial(p, client->rx_buffer + cpy_start, cpy_len, in_offset);
pbuf_copy_partial(p, client->rx_buffer + fixed_hdr_len, cpy_len, in_offset);
/* Advance get and put indexes */
client->msg_idx += cpy_len;
@@ -904,7 +903,7 @@ mqtt_parse_incoming(mqtt_client_t *client, struct pbuf *p)
LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_parse_incoming: msg_idx: %"U32_F", cpy_len: %"U16_F", remaining %"U32_F"\n", client->msg_idx, cpy_len, msg_rem_len));
if ((msg_rem_len == 0) || (cpy_len == buffer_space)) {
/* Whole message received or buffer is full */
mqtt_connection_status_t res = mqtt_message_received(client, fixed_hdr_idx, (cpy_start + cpy_len) - fixed_hdr_idx, msg_rem_len);
mqtt_connection_status_t res = mqtt_message_received(client, fixed_hdr_len, cpy_len, msg_rem_len);
if (res != MQTT_CONNECT_ACCEPTED) {
return res;
}
@@ -912,7 +911,7 @@ mqtt_parse_incoming(mqtt_client_t *client, struct pbuf *p)
/* Reset parser state */
client->msg_idx = 0;
/* msg_tot_len = 0; */
fixed_hdr_idx = 0;
fixed_hdr_len = 0;
}
}
}
@@ -1289,7 +1288,7 @@ mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port,
/* Length is the sum of 2+"MQTT", protocol level, flags and keep alive */
u16_t remaining_length = 2 + 4 + 1 + 1 + 2;
u8_t flags = 0, will_topic_len = 0, will_msg_len = 0;
u8_t client_user_len = 0, client_pass_len = 0;
u16_t client_user_len = 0, client_pass_len = 0;
LWIP_ASSERT_CORE_LOCKED();
LWIP_ASSERT("mqtt_client_connect: client != NULL", client != NULL);
@@ -1330,9 +1329,9 @@ mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port,
if (client_info->client_user != NULL) {
flags |= MQTT_CONNECT_FLAG_USERNAME;
len = strlen(client_info->client_user);
LWIP_ERROR("mqtt_client_connect: client_info->client_user length overflow", len <= 0xFF, return ERR_VAL);
LWIP_ERROR("mqtt_client_connect: client_info->client_user length overflow", len <= 0xFFFF, return ERR_VAL);
LWIP_ERROR("mqtt_client_connect: client_info->client_user length must be > 0", len > 0, return ERR_VAL);
client_user_len = (u8_t)len;
client_user_len = (u16_t)len;
len = remaining_length + 2 + client_user_len;
LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);
remaining_length = (u16_t)len;
@@ -1340,9 +1339,9 @@ mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port,
if (client_info->client_pass != NULL) {
flags |= MQTT_CONNECT_FLAG_PASSWORD;
len = strlen(client_info->client_pass);
LWIP_ERROR("mqtt_client_connect: client_info->client_pass length overflow", len <= 0xFF, return ERR_VAL);
LWIP_ERROR("mqtt_client_connect: client_info->client_pass length overflow", len <= 0xFFFF, return ERR_VAL);
LWIP_ERROR("mqtt_client_connect: client_info->client_pass length must be > 0", len > 0, return ERR_VAL);
client_pass_len = (u8_t)len;
client_pass_len = (u16_t)len;
len = remaining_length + 2 + client_pass_len;
LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL);
remaining_length = (u16_t)len;
@@ -1362,20 +1361,17 @@ mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port,
return ERR_MEM;
}
client->conn = altcp_tcp_new();
#if LWIP_ALTCP && LWIP_ALTCP_TLS
if (client_info->tls_config) {
client->conn = altcp_tls_new(client_info->tls_config, IP_GET_TYPE(ip_addr));
} else
#endif
{
client->conn = altcp_tcp_new_ip_type(IP_GET_TYPE(ip_addr));
}
if (client->conn == NULL) {
return ERR_MEM;
}
#if LWIP_ALTCP && LWIP_ALTCP_TLS
if (client_info->tls_config) {
struct altcp_pcb *pcb_tls = altcp_tls_new(client_info->tls_config, client->conn);
if (pcb_tls == NULL) {
altcp_close(client->conn);
return ERR_MEM;
}
client->conn = pcb_tls;
}
#endif
/* Set arg pointer for callbacks */
altcp_arg(client->conn, client);

View File

@@ -111,6 +111,22 @@ PACK_STRUCT_END
# include "arch/epstruct.h"
#endif
/** NetBIOS message question part */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct netbios_question_hdr {
PACK_STRUCT_FLD_8(u8_t nametype);
PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN * 2) + 1]);
PACK_STRUCT_FIELD(u16_t type);
PACK_STRUCT_FIELD(u16_t cls);
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/epstruct.h"
#endif
/** NetBIOS message name part */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
@@ -224,12 +240,12 @@ static struct udp_pcb *netbiosns_pcb;
/** Decode a NetBIOS name (from packet to string) */
static int
netbiosns_name_decode(char *name_enc, char *name_dec, int name_dec_len)
netbiosns_name_decode(const char *name_enc, char *name_dec, int name_dec_len)
{
char *pname;
char cname;
char cnbname;
int idx = 0;
const char *pname;
char cname;
char cnbname;
int idx = 0;
LWIP_UNUSED_ARG(name_dec_len);
@@ -335,11 +351,11 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
/* if packet is valid */
if (p != NULL) {
char netbios_name[NETBIOS_NAME_LEN + 1];
struct netbios_hdr *netbios_hdr = (struct netbios_hdr *)p->payload;
struct netbios_name_hdr *netbios_name_hdr = (struct netbios_name_hdr *)(netbios_hdr + 1);
struct netbios_hdr *netbios_hdr = (struct netbios_hdr *)p->payload;
struct netbios_question_hdr *netbios_question_hdr = (struct netbios_question_hdr *)(netbios_hdr + 1);
/* is the packet long enough (we need the header in one piece) */
if (p->len < (sizeof(struct netbios_hdr) + sizeof(struct netbios_name_hdr))) {
if (p->len < (sizeof(struct netbios_hdr) + sizeof(struct netbios_question_hdr))) {
/* packet too short */
pbuf_free(p);
return;
@@ -352,9 +368,9 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) &&
(netbios_hdr->questions == PP_NTOHS(1))) {
/* decode the NetBIOS name */
netbiosns_name_decode((char *)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name));
netbiosns_name_decode((char *)(netbios_question_hdr->encname), netbios_name, sizeof(netbios_name));
/* check the request type */
if (netbios_name_hdr->type == PP_HTONS(NETB_QTYPE_NB)) {
if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NB)) {
/* if the packet is for us */
if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) {
struct pbuf *q;
@@ -376,10 +392,10 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
resp->resp_hdr.additionalRRs = 0;
/* prepare NetBIOS header datas */
MEMCPY( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname));
resp->resp_name.nametype = netbios_name_hdr->nametype;
resp->resp_name.type = netbios_name_hdr->type;
resp->resp_name.cls = netbios_name_hdr->cls;
MEMCPY( resp->resp_name.encname, netbios_question_hdr->encname, sizeof(netbios_question_hdr->encname));
resp->resp_name.nametype = netbios_question_hdr->nametype;
resp->resp_name.type = netbios_question_hdr->type;
resp->resp_name.cls = netbios_question_hdr->cls;
resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL);
resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags) + sizeof(resp->resp_name.addr));
resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE);
@@ -393,7 +409,7 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
}
}
#if LWIP_NETBIOS_RESPOND_NAME_QUERY
} else if (netbios_name_hdr->type == PP_HTONS(NETB_QTYPE_NBSTAT)) {
} else if (netbios_question_hdr->type == PP_HTONS(NETB_QTYPE_NBSTAT)) {
/* if the packet is for us or general query */
if (!lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) ||
!lwip_strnicmp(netbios_name, "*", sizeof(NETBIOS_LOCAL_NAME))) {
@@ -419,9 +435,9 @@ netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t
/* resp->answer_hdr.authorityRRs = PP_HTONS(0); done by memset() */
/* resp->answer_hdr.additionalRRs = PP_HTONS(0); done by memset() */
/* we will copy the length of the station name */
resp->name_size = netbios_name_hdr->nametype;
resp->name_size = netbios_question_hdr->nametype;
/* we will copy the queried name */
MEMCPY(resp->query_name, netbios_name_hdr->encname, (NETBIOS_NAME_LEN * 2) + 1);
MEMCPY(resp->query_name, netbios_question_hdr->encname, (NETBIOS_NAME_LEN * 2) + 1);
/* NBSTAT */
resp->packet_type = PP_HTONS(0x21);
/* Internet name */

View File

@@ -65,7 +65,7 @@
#include "lwip/altcp_tcp.h"
#include "lwip/altcp_tls.h"
#include <string.h> /* strnlen, memcpy */
#include <string.h> /* strlen, memcpy */
#include <stdlib.h>
/** TCP poll interval. Unit is 0.5 sec. */
@@ -353,9 +353,8 @@ smtp_set_server_addr(const char* server)
LWIP_ASSERT_CORE_LOCKED();
if (server != NULL) {
/* strnlen: returns length WITHOUT terminating 0 byte OR
* SMTP_MAX_SERVERNAME_LEN+1 when string is too long */
len = strnlen(server, SMTP_MAX_SERVERNAME_LEN+1);
/* strlen: returns length WITHOUT terminating 0 byte */
len = strlen(server);
}
if (len > SMTP_MAX_SERVERNAME_LEN) {
return ERR_MEM;
@@ -460,18 +459,15 @@ smtp_setup_pcb(struct smtp_session *s, const ip_addr_t* remote_ip)
struct altcp_pcb* pcb;
LWIP_UNUSED_ARG(remote_ip);
pcb = altcp_tcp_new_ip_type(IP_GET_TYPE(remote_ip));
if (pcb != NULL) {
#if LWIP_ALTCP && LWIP_ALTCP_TLS
if (smtp_server_tls_config) {
struct altcp_pcb *pcb_tls = altcp_tls_new(smtp_server_tls_config, pcb);
if (pcb_tls == NULL) {
altcp_close(pcb);
return NULL;
}
pcb = pcb_tls;
}
if (smtp_server_tls_config) {
pcb = altcp_tls_new(smtp_server_tls_config, IP_GET_TYPE(remote_ip));
} else
#endif
{
pcb = altcp_tcp_new_ip_type(IP_GET_TYPE(remote_ip));
}
if (pcb != NULL) {
altcp_arg(pcb, s);
altcp_recv(pcb, smtp_tcp_recv);
altcp_err(pcb, smtp_tcp_err);

View File

@@ -451,10 +451,10 @@ snmp_process_varbind(struct snmp_request *request, struct snmp_varbind *vb, u8_t
}
} else {
s16_t len = node_instance.get_value(&node_instance, vb->value);
vb->type = node_instance.asn1_type;
if (len >= 0) {
vb->value_len = (u16_t)len; /* cast is OK because we checked >= 0 above */
vb->type = node_instance.asn1_type;
LWIP_ASSERT("SNMP_MAX_VALUE_SIZE is configured too low", (vb->value_len & ~SNMP_GET_VALUE_RAW_DATA) <= SNMP_MAX_VALUE_SIZE);
err = snmp_append_outbound_varbind(&request->outbound_pbuf_stream, vb);

View File

@@ -193,28 +193,40 @@ snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, st
static s16_t
snmp_scalar_array_get_value(struct snmp_node_instance *instance, void *value)
{
s16_t result = -1;
const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
const struct snmp_scalar_array_node_def *array_node_def = (const struct snmp_scalar_array_node_def *)instance->reference.const_ptr;
return array_node->get_value(array_node_def, value);
if (array_node->get_value != NULL) {
result = array_node->get_value(array_node_def, value);
}
return result;
}
static snmp_err_t
snmp_scalar_array_set_test(struct snmp_node_instance *instance, u16_t value_len, void *value)
{
snmp_err_t result = SNMP_ERR_NOTWRITABLE;
const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
const struct snmp_scalar_array_node_def *array_node_def = (const struct snmp_scalar_array_node_def *)instance->reference.const_ptr;
return array_node->set_test(array_node_def, value_len, value);
if (array_node->set_test != NULL) {
result = array_node->set_test(array_node_def, value_len, value);
}
return result;
}
static snmp_err_t
snmp_scalar_array_set_value(struct snmp_node_instance *instance, u16_t value_len, void *value)
{
snmp_err_t result = SNMP_ERR_NOTWRITABLE;
const struct snmp_scalar_array_node *array_node = (const struct snmp_scalar_array_node *)(const void *)instance->node;
const struct snmp_scalar_array_node_def *array_node_def = (const struct snmp_scalar_array_node_def *)instance->reference.const_ptr;
return array_node->set_value(array_node_def, value_len, value);
if (array_node->set_value != NULL) {
result = array_node->set_value(array_node_def, value_len, value);
}
return result;
}
#endif /* LWIP_SNMP */

View File

@@ -55,7 +55,11 @@ threadsync_get_value_synced(void *ctx)
{
struct threadsync_data *call_data = (struct threadsync_data *)ctx;
call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value);
if (call_data->proxy_instance.get_value != NULL) {
call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value);
} else {
call_data->retval.s16 = -1;
}
sys_sem_signal(&call_data->threadsync_node->instance->sem);
}
@@ -76,7 +80,11 @@ threadsync_set_test_synced(void *ctx)
{
struct threadsync_data *call_data = (struct threadsync_data *)ctx;
call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
if (call_data->proxy_instance.set_test != NULL) {
call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
} else {
call_data->retval.err = SNMP_ERR_NOTWRITABLE;
}
sys_sem_signal(&call_data->threadsync_node->instance->sem);
}
@@ -98,7 +106,11 @@ threadsync_set_value_synced(void *ctx)
{
struct threadsync_data *call_data = (struct threadsync_data *)ctx;
call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
if (call_data->proxy_instance.set_value != NULL) {
call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value);
} else {
call_data->retval.err = SNMP_ERR_NOTWRITABLE;
}
sys_sem_signal(&call_data->threadsync_node->instance->sem);
}

View File

@@ -238,9 +238,9 @@ struct sntp_server {
};
static struct sntp_server sntp_servers[SNTP_MAX_SERVERS];
#if SNTP_GET_SERVERS_FROM_DHCP
#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
static u8_t sntp_set_servers_from_dhcp;
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
#if SNTP_SUPPORT_MULTIPLE_SERVERS
/** The currently used server (initialized to 0) */
static u8_t sntp_current_server;
@@ -371,6 +371,7 @@ sntp_retry(void *arg)
sntp_retry_timeout));
/* set up a timer to send a retry and increase the retry delay */
sys_untimeout(sntp_request, NULL);
sys_timeout(sntp_retry_timeout, sntp_request, NULL);
#if SNTP_RETRY_TIMEOUT_EXP
@@ -382,6 +383,8 @@ sntp_retry(void *arg)
if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) &&
(new_retry_timeout > sntp_retry_timeout)) {
sntp_retry_timeout = new_retry_timeout;
} else {
sntp_retry_timeout = SNTP_RETRY_TIMEOUT_MAX;
}
}
#endif /* SNTP_RETRY_TIMEOUT_EXP */
@@ -558,6 +561,7 @@ sntp_send_request(const ip_addr_t *server_addr)
sntp_servers[sntp_current_server].reachability <<= 1;
#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
/* set up receive timeout: try next server or retry on timeout */
sys_untimeout(sntp_try_next_server, NULL);
sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL);
#if SNTP_CHECK_RESPONSE >= 1
/* save server address to verify it in sntp_recv */
@@ -567,6 +571,7 @@ sntp_send_request(const ip_addr_t *server_addr)
LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n",
(u32_t)SNTP_RETRY_TIMEOUT));
/* out of memory: set up a timer to send a retry */
sys_untimeout(sntp_request, NULL);
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL);
}
}
@@ -635,6 +640,7 @@ sntp_request(void *arg)
} else {
/* address conversion failed, try another server */
LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n"));
sys_untimeout(sntp_try_next_server, NULL);
sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL);
}
}
@@ -648,6 +654,7 @@ void
sntp_init(void)
{
/* LWIP_ASSERT_CORE_LOCKED(); is checked by udp_new() */
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_init: SNTP initialised\n"));
#ifdef SNTP_SERVER_ADDRESS
#if SNTP_SERVER_DNS
@@ -750,7 +757,7 @@ sntp_getreachability(u8_t idx)
}
#endif /* SNTP_MONITOR_SERVER_REACHABILITY */
#if SNTP_GET_SERVERS_FROM_DHCP
#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
/**
* Config SNTP server handling by IP address, name, or DHCP; clear table
* @param set_servers_from_dhcp enable or disable getting server addresses from dhcp
@@ -764,7 +771,7 @@ sntp_servermode_dhcp(int set_servers_from_dhcp)
sntp_set_servers_from_dhcp = new_mode;
}
}
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
/**
* @ingroup sntp
@@ -793,8 +800,8 @@ sntp_setserver(u8_t idx, const ip_addr_t *server)
/**
* Initialize one of the NTP servers by IP address, required by DHCP
*
* @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param dnsserver IP address of the NTP server to set
* @param num the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param server IP address of the NTP server to set
*/
void
dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server)
@@ -816,6 +823,33 @@ dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server)
}
#endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */
#if LWIP_IPV6_DHCP6 && SNTP_GET_SERVERS_FROM_DHCPV6
/**
* Initialize one of the NTP servers by IP address, required by DHCPV6
*
* @param num the number of NTP server addresses to set must be < SNTP_MAX_SERVERS
* @param server array of IP address of the NTP servers to set
*/
void
dhcp6_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs)
{
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u NTP server(s) via DHCPv6\n",
(sntp_set_servers_from_dhcp ? "Got" : "Rejected"),
num_ntp_servers));
if (sntp_set_servers_from_dhcp && num_ntp_servers) {
u8_t i;
for (i = 0; (i < num_ntp_servers) && (i < SNTP_MAX_SERVERS); i++) {
LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: NTP server %u: %s\n",
i, ipaddr_ntoa(&ntp_server_addrs[i])));
sntp_setserver(i, &ntp_server_addrs[i]);
}
for (i = num_ntp_servers; i < SNTP_MAX_SERVERS; i++) {
sntp_setserver(i, NULL);
}
}
}
#endif /* LWIP_DHCPv6 && SNTP_GET_SERVERS_FROM_DHCPV6 */
/**
* @ingroup sntp
* Obtain one of the currently configured by IP address (or DHCP) NTP servers
@@ -837,8 +871,8 @@ sntp_getserver(u8_t idx)
/**
* Initialize one of the NTP servers by name
*
* @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param dnsserver DNS name of the NTP server to set, to be resolved at contact time
* @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS
* @param server DNS name of the NTP server to set, to be resolved at contact time
*/
void
sntp_setservername(u8_t idx, const char *server)
@@ -852,7 +886,7 @@ sntp_setservername(u8_t idx, const char *server)
/**
* Obtain one of the currently configured by name NTP servers.
*
* @param numdns the index of the NTP server
* @param idx the index of the NTP server
* @return IP address of the indexed NTP server or NULL if the NTP
* server has not been configured by name (or at all)
*/

View File

@@ -1,14 +1,85 @@
/**
* @file
* @defgroup altcp Application layered TCP
* @ingroup callbackstyle_api
* Application layered TCP connection API (to be used from TCPIP thread)\n
* This interface mimics the tcp callback API to the application while preventing
* direct linking (much like virtual functions).
* This way, an application can make use of other application layer protocols
* on top of TCP without knowing the details (e.g. TLS, proxy connection).
* @defgroup altcp Application layered TCP Functions
* @ingroup altcp_api
*
* This file contains the common functions for altcp to work.
* For more details see @ref altcp_api.
*/
/**
* @defgroup altcp_api Application layered TCP Introduction
* @ingroup callbackstyle_api
*
* Overview
* --------
* altcp (application layered TCP connection API; to be used from TCPIP thread)
* is an abstraction layer that prevents applications linking hard against the
* @ref tcp.h functions while providing the same functionality. It is used to
* e.g. add SSL/TLS (see LWIP_ALTCP_TLS) or proxy-connect support to an application
* written for the tcp callback API without that application knowing the
* protocol details.
*
* * This interface mimics the tcp callback API to the application while preventing
* direct linking (much like virtual functions).
* * This way, an application can make use of other application layer protocols
* on top of TCP without knowing the details (e.g. TLS, proxy connection).
* * This is achieved by simply including "lwip/altcp.h" instead of "lwip/tcp.h",
* replacing "struct tcp_pcb" with "struct altcp_pcb" and prefixing all functions
* with "altcp_" instead of "tcp_".
*
* With altcp support disabled (LWIP_ALTCP==0), applications written against the
* altcp API can still be compiled but are directly linked against the tcp.h
* callback API and then cannot use layered protocols. To minimize code changes
* in this case, the use of altcp_allocators is strongly suggested.
*
* Usage
* -----
* To make use of this API from an existing tcp raw API application:
* * Include "lwip/altcp.h" instead of "lwip/tcp.h"
* * Replace "struct tcp_pcb" with "struct altcp_pcb"
* * Prefix all called tcp API functions with "altcp_" instead of "tcp_" to link
* against the altcp functions
* * @ref altcp_new (and @ref altcp_new_ip_type/@ref altcp_new_ip6) take
* an @ref altcp_allocator_t as an argument, whereas the original tcp API
* functions take no arguments.
* * An @ref altcp_allocator_t allocator is an object that holds a pointer to an
* allocator object and a corresponding state (e.g. for TLS, the corresponding
* state may hold certificates or keys). This way, the application does not
* even need to know if it uses TLS or pure TCP, this is handled at runtime
* by passing a specific allocator.
* * An application can alternatively bind hard to the altcp_tls API by calling
* @ref altcp_tls_new or @ref altcp_tls_wrap.
* * The TLS layer is not directly implemented by lwIP, but a port to mbedTLS is
* provided.
* * Another altcp layer is proxy-connect to use TLS behind a HTTP proxy (see
* @ref altcp_proxyconnect.h)
*
* altcp_allocator_t
* -----------------
* An altcp allocator is created by the application by combining an allocator
* callback function and a corresponding state, e.g.:\code{.c}
* static const unsigned char cert[] = {0x2D, ... (see mbedTLS doc for how to create this)};
* struct altcp_tls_config * conf = altcp_tls_create_config_client(cert, sizeof(cert));
* altcp_allocator_t tls_allocator = {
* altcp_tls_alloc, conf
* };
* \endcode
*
*
* struct altcp_tls_config
* -----------------------
* The struct altcp_tls_config holds state that is needed to create new TLS client
* or server connections (e.g. certificates and private keys).
*
* It is not defined by lwIP itself but by the TLS port (e.g. altcp_tls to mbedTLS
* adaption). However, the parameters used to create it are defined in @ref
* altcp_tls.h (see @ref altcp_tls_create_config_server_privkey_cert for servers
* and @ref altcp_tls_create_config_client/@ref altcp_tls_create_config_client_2wayauth
* for clients).
*
* For mbedTLS, ensure that certificates can be parsed by 'mbedtls_x509_crt_parse()' and
* private keys can be parsed by 'mbedtls_pk_parse_key()'.
*/
/*
@@ -430,6 +501,24 @@ altcp_get_port(struct altcp_pcb *conn, int local)
return 0;
}
#if LWIP_TCP_KEEPALIVE
void
altcp_keepalive_disable(struct altcp_pcb *conn)
{
if (conn && conn->fns && conn->fns->keepalive_disable) {
conn->fns->keepalive_disable(conn);
}
}
void
altcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count)
{
if (conn && conn->fns && conn->fns->keepalive_enable) {
conn->fns->keepalive_enable(conn, idle, intvl, count);
}
}
#endif
#ifdef LWIP_DEBUG
enum tcp_state
altcp_dbg_get_tcp_state(struct altcp_pcb *conn)
@@ -595,6 +684,24 @@ altcp_default_get_port(struct altcp_pcb *conn, int local)
return 0;
}
#if LWIP_TCP_KEEPALIVE
void
altcp_default_keepalive_disable(struct altcp_pcb *conn)
{
if (conn && conn->inner_conn) {
altcp_keepalive_disable(conn->inner_conn);
}
}
void
altcp_default_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count)
{
if (conn && conn->inner_conn) {
altcp_keepalive_enable(conn->inner_conn, idle, intvl, count);
}
}
#endif
#ifdef LWIP_DEBUG
enum tcp_state
altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn)

View File

@@ -58,23 +58,29 @@
/** This standard allocator function creates an altcp pcb for
* TLS over TCP */
struct altcp_pcb *
altcp_tls_alloc(void *arg, u8_t ip_type)
altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type)
{
struct altcp_pcb *inner_conn, *ret;
struct altcp_tls_config *config = (struct altcp_tls_config *)arg;
LWIP_UNUSED_ARG(ip_type);
inner_conn = altcp_tcp_new_ip_type(ip_type);
if (inner_conn == NULL) {
return NULL;
}
ret = altcp_tls_new(config, inner_conn);
ret = altcp_tls_wrap(config, inner_conn);
if (ret == NULL) {
altcp_close(inner_conn);
}
return ret;
}
/** This standard allocator function creates an altcp pcb for
* TLS over TCP */
struct altcp_pcb *
altcp_tls_alloc(void *arg, u8_t ip_type)
{
return altcp_tls_new((struct altcp_tls_config *)arg, ip_type);
}
#endif /* LWIP_ALTCP_TLS */

View File

@@ -49,6 +49,7 @@
#include "lwip/altcp_tcp.h"
#include "lwip/priv/altcp_priv.h"
#include "lwip/tcp.h"
#include "lwip/priv/tcp_priv.h"
#include "lwip/mem.h"
#include <string.h>
@@ -160,21 +161,25 @@ static void
altcp_tcp_remove_callbacks(struct tcp_pcb *tpcb)
{
tcp_arg(tpcb, NULL);
tcp_recv(tpcb, NULL);
tcp_sent(tpcb, NULL);
tcp_err(tpcb, NULL);
tcp_poll(tpcb, NULL, tpcb->pollinterval);
if (tpcb->state != LISTEN) {
tcp_recv(tpcb, NULL);
tcp_sent(tpcb, NULL);
tcp_err(tpcb, NULL);
tcp_poll(tpcb, NULL, tpcb->pollinterval);
}
}
static void
altcp_tcp_setup_callbacks(struct altcp_pcb *conn, struct tcp_pcb *tpcb)
{
tcp_arg(tpcb, conn);
tcp_recv(tpcb, altcp_tcp_recv);
tcp_sent(tpcb, altcp_tcp_sent);
tcp_err(tpcb, altcp_tcp_err);
/* tcp_poll is set when interval is set by application */
/* listen is set totally different :-) */
/* this might be called for LISTN when close fails... */
if (tpcb->state != LISTEN) {
tcp_recv(tpcb, altcp_tcp_recv);
tcp_sent(tpcb, altcp_tcp_sent);
tcp_err(tpcb, altcp_tcp_err);
/* tcp_poll is set when interval is set by application */
}
}
static void
@@ -446,6 +451,31 @@ altcp_tcp_setprio(struct altcp_pcb *conn, u8_t prio)
}
}
#if LWIP_TCP_KEEPALIVE
static void
altcp_tcp_keepalive_disable(struct altcp_pcb *conn)
{
if (conn && conn->state) {
struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
ALTCP_TCP_ASSERT_CONN(conn);
ip_reset_option(pcb, SOF_KEEPALIVE);
}
}
static void
altcp_tcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t cnt)
{
if (conn && conn->state) {
struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state;
ALTCP_TCP_ASSERT_CONN(conn);
ip_set_option(pcb, SOF_KEEPALIVE);
pcb->keep_idle = idle ? idle : TCP_KEEPIDLE_DEFAULT;
pcb->keep_intvl = intvl ? intvl : TCP_KEEPINTVL_DEFAULT;
pcb->keep_cnt = cnt ? cnt : TCP_KEEPCNT_DEFAULT;
}
}
#endif
static void
altcp_tcp_dealloc(struct altcp_pcb *conn)
{
@@ -535,6 +565,10 @@ const struct altcp_functions altcp_tcp_functions = {
altcp_tcp_get_tcp_addrinfo,
altcp_tcp_get_ip,
altcp_tcp_get_port
#if LWIP_TCP_KEEPALIVE
, altcp_tcp_keepalive_disable
, altcp_tcp_keepalive_enable
#endif
#ifdef LWIP_DEBUG
, altcp_tcp_dbg_get_tcp_state
#endif

View File

@@ -237,18 +237,9 @@ PACK_STRUCT_END
#error "NETCONN_MORE != TCP_WRITE_FLAG_MORE"
#endif
#endif /* LWIP_NETCONN && LWIP_TCP */
#if LWIP_SOCKET
/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */
#if SO_REUSEADDR != SOF_REUSEADDR
#error "WARNING: SO_REUSEADDR != SOF_REUSEADDR"
#if LWIP_NETCONN_FULLDUPLEX && !LWIP_NETCONN_SEM_PER_THREAD
#error "For LWIP_NETCONN_FULLDUPLEX to work, LWIP_NETCONN_SEM_PER_THREAD is required"
#endif
#if SO_KEEPALIVE != SOF_KEEPALIVE
#error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE"
#endif
#if SO_BROADCAST != SOF_BROADCAST
#error "WARNING: SO_BROADCAST != SOF_BROADCAST"
#endif
#endif /* LWIP_SOCKET */
/* Compile-time checks for deprecated options.

View File

@@ -127,6 +127,11 @@
#define LWIP_DHCP_PROVIDE_DNS_SERVERS 0
#endif
#ifndef LWIP_DHCP_INPUT_ERROR
#define LWIP_DHCP_INPUT_ERROR(message, expression, handler) do { if (!(expression)) { \
handler;} } while(0)
#endif
/** Option handling: options are parsed in dhcp_parse_reply
* and saved in an array where other functions can load them from.
* This might be moved into the struct dhcp (not necessarily since
@@ -784,14 +789,11 @@ dhcp_start(struct netif *netif)
}
dhcp->pcb_allocated = 1;
#if LWIP_DHCP_CHECK_LINK_UP
if (!netif_is_link_up(netif)) {
/* set state INIT and wait for dhcp_network_changed() to call dhcp_discover() */
dhcp_set_state(dhcp, DHCP_STATE_INIT);
return ERR_OK;
}
#endif /* LWIP_DHCP_CHECK_LINK_UP */
/* (re)start the DHCP negotiation */
result = dhcp_discover(netif);
@@ -1118,13 +1120,6 @@ dhcp_bind(struct netif *netif)
}
ip4_addr_copy(gw_addr, dhcp->offered_gw_addr);
/* gateway address not given? */
if (ip4_addr_isany_val(gw_addr)) {
/* copy network address */
ip4_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(0x00000001UL));
}
#if LWIP_DHCP_AUTOIP_COOP
if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
@@ -1352,6 +1347,7 @@ dhcp_release_and_stop(struct netif *netif)
/* create and initialize the DHCP message header */
struct pbuf *p_out;
u16_t options_out_len;
dhcp_set_state(dhcp, DHCP_STATE_OFF);
p_out = dhcp_create_msg(netif, dhcp, DHCP_RELEASE, &options_out_len);
if (p_out != NULL) {
struct dhcp_msg *msg_out = (struct dhcp_msg *)p_out->payload;
@@ -1368,10 +1364,12 @@ dhcp_release_and_stop(struct netif *netif)
/* sending release failed, but that's not a problem since the correct behaviour of dhcp does not rely on release */
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n"));
}
}
/* remove IP address from interface (prevents routing from selecting this interface) */
netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
/* remove IP address from interface (prevents routing from selecting this interface) */
netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4);
} else {
dhcp_set_state(dhcp, DHCP_STATE_OFF);
}
#if LWIP_DHCP_AUTOIP_COOP
if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) {
@@ -1380,8 +1378,6 @@ dhcp_release_and_stop(struct netif *netif)
}
#endif /* LWIP_DHCP_AUTOIP_COOP */
dhcp_set_state(dhcp, DHCP_STATE_OFF);
if (dhcp->pcb_allocated != 0) {
dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */
dhcp->pcb_allocated = 0;
@@ -1512,6 +1508,7 @@ dhcp_parse_reply(struct pbuf *p, struct dhcp *dhcp)
u8_t *options;
u16_t offset;
u16_t offset_max;
u16_t options_offset;
u16_t options_idx;
u16_t options_idx_max;
struct pbuf *q;
@@ -1544,6 +1541,7 @@ dhcp_parse_reply(struct pbuf *p, struct dhcp *dhcp)
options_idx_max = p->tot_len;
again:
q = p;
options_offset = options_idx;
while ((q != NULL) && (options_idx >= q->len)) {
options_idx = (u16_t)(options_idx - q->len);
options_idx_max = (u16_t)(options_idx_max - q->len);
@@ -1582,58 +1580,58 @@ again:
/* will be increased below */
break;
case (DHCP_OPTION_SUBNET_MASK):
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_SUBNET_MASK;
break;
case (DHCP_OPTION_ROUTER):
decode_len = 4; /* only copy the first given router */
LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_ROUTER;
break;
#if LWIP_DHCP_PROVIDE_DNS_SERVERS
case (DHCP_OPTION_DNS_SERVER):
/* special case: there might be more than one server */
LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
/* limit number of DNS servers */
decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS);
LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_DNS_SERVER;
break;
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
case (DHCP_OPTION_LEASE_TIME):
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_LEASE_TIME;
break;
#if LWIP_DHCP_GET_NTP_SRV
case (DHCP_OPTION_NTP):
/* special case: there might be more than one server */
LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;);
/* limit number of NTP servers */
decode_len = LWIP_MIN(len, 4 * LWIP_DHCP_MAX_NTP_SERVERS);
LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_NTP_SERVER;
break;
#endif /* LWIP_DHCP_GET_NTP_SRV*/
case (DHCP_OPTION_OVERLOAD):
LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len == 1", len == 1, return ERR_VAL;);
/* decode overload only in options, not in file/sname: invalid packet */
LWIP_ERROR("overload in file/sname", options_idx == DHCP_OPTIONS_OFS, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("overload in file/sname", options_offset == DHCP_OPTIONS_OFS, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_OVERLOAD;
break;
case (DHCP_OPTION_MESSAGE_TYPE):
LWIP_ERROR("len == 1", len == 1, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len == 1", len == 1, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_MSG_TYPE;
break;
case (DHCP_OPTION_SERVER_ID):
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_SERVER_ID;
break;
case (DHCP_OPTION_T1):
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_T1;
break;
case (DHCP_OPTION_T2):
LWIP_ERROR("len == 4", len == 4, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("len == 4", len == 4, return ERR_VAL;);
decode_idx = DHCP_OPTION_IDX_T2;
break;
default:
@@ -1665,7 +1663,7 @@ decode_next:
if (decode_len > 4) {
/* decode more than one u32_t */
u16_t next_val_offset;
LWIP_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;);
dhcp_got_option(dhcp, decode_idx);
dhcp_set_option_value(dhcp, decode_idx, lwip_htonl(value));
decode_len = (u8_t)(decode_len - 4);
@@ -1680,7 +1678,7 @@ decode_next:
} else if (decode_len == 4) {
value = lwip_ntohl(value);
} else {
LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;);
value = ((u8_t *)&value)[0];
}
dhcp_got_option(dhcp, decode_idx);
@@ -1693,7 +1691,7 @@ decode_next:
offset_max = (u16_t)(offset_max - q->len);
if (offset < offset_max) {
q = q->next;
LWIP_ERROR("next pbuf was null", q != NULL, return ERR_VAL;);
LWIP_DHCP_INPUT_ERROR("next pbuf was null", q != NULL, return ERR_VAL;);
options = (u8_t *)q->payload;
} else {
/* We've run out of bytes, probably no end marker. Don't proceed. */

View File

@@ -983,6 +983,14 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
/* We don't re-send arp request in etharp_tmr, but we still queue packets,
since this failure could be temporary, and the next packet calling
etharp_query again could lead to sending the queued packets. */
} else {
/* ARP request successfully sent */
if ((arp_table[i].state == ETHARP_STATE_PENDING) && !is_new_entry) {
/* A new ARP request has been sent for a pending entry. Reset the ctime to
not let it expire too fast. */
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: reset ctime for entry %"S16_F"\n", (s16_t)i));
arp_table[i].ctime = 0;
}
}
if (q == NULL) {
return result;

View File

@@ -62,7 +62,7 @@
#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1
#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */
/* The amount of data from the original packet to return in a dest-unreachable */
/* The maximum amount of data from the original packet to return in a dest-unreachable */
#define ICMP_DEST_UNREACH_DATASIZE 8
static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code);
@@ -345,20 +345,26 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
struct icmp_echo_hdr *icmphdr;
ip4_addr_t iphdr_src;
struct netif *netif;
u16_t response_pkt_len;
/* increase number of messages attempted to send */
MIB2_STATS_INC(mib2.icmpoutmsgs);
/* ICMP header + IP header + 8 bytes of data */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE,
PBUF_RAM);
/* Keep IP header + up to 8 bytes */
response_pkt_len = IP_HLEN + ICMP_DEST_UNREACH_DATASIZE;
if (p->tot_len < response_pkt_len) {
response_pkt_len = p->tot_len;
}
/* ICMP header + part of original packet */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + response_pkt_len, PBUF_RAM);
if (q == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n"));
MIB2_STATS_INC(mib2.icmpouterrors);
return;
}
LWIP_ASSERT("check that first pbuf can hold icmp message",
(q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE)));
(q->len >= (sizeof(struct icmp_echo_hdr) + response_pkt_len)));
iphdr = (struct ip_hdr *)p->payload;
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from "));
@@ -375,14 +381,14 @@ icmp_send_response(struct pbuf *p, u8_t type, u8_t code)
/* copy fields from original packet */
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload,
IP_HLEN + ICMP_DEST_UNREACH_DATASIZE);
response_pkt_len);
ip4_addr_copy(iphdr_src, iphdr->src);
#ifdef LWIP_HOOK_IP4_ROUTE_SRC
{
ip4_addr_t iphdr_dst;
ip4_addr_copy(iphdr_dst, iphdr->dest);
netif = ip4_route_src(&iphdr_src, &iphdr_dst);
netif = ip4_route_src(&iphdr_dst, &iphdr_src);
}
#else
netif = ip4_route(&iphdr_src);

View File

@@ -163,6 +163,9 @@ ip4_route(const ip4_addr_t *dest)
}
#endif /* LWIP_MULTICAST_TX_OPTIONS */
/* bug #54569: in case LWIP_SINGLE_NETIF=1 and LWIP_DEBUGF() disabled, the following loop is optimized away */
LWIP_UNUSED_ARG(dest);
/* iterate through netifs */
NETIF_FOREACH(netif) {
/* is the netif up, does it have a link and a valid address? */
@@ -211,7 +214,7 @@ ip4_route(const ip4_addr_t *dest)
#endif /* !LWIP_SINGLE_NETIF */
if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) ||
ip4_addr_isany_val(*netif_ip4_addr(netif_default))) {
ip4_addr_isany_val(*netif_ip4_addr(netif_default)) || ip4_addr_isloopback(dest)) {
/* No matching netif found and default netif is not usable.
If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */
LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",

View File

@@ -173,6 +173,8 @@ ip4addr_aton(const char *cp, ip4_addr_t *addr)
}
for (;;) {
if (lwip_isdigit(c)) {
if((base == 8) && ((u32_t)(c - '0') >= 8))
break;
val = (val * base) + (u32_t)(c - '0');
c = *++cp;
} else if (base == 16 && lwip_isxdigit(c)) {

View File

@@ -451,7 +451,16 @@ dhcp6_msg_finalize(u16_t options_out_len, struct pbuf *p_out)
static void
dhcp6_information_request(struct netif *netif, struct dhcp6 *dhcp6)
{
const u16_t requested_options[] = {DHCP6_OPTION_DNS_SERVERS, DHCP6_OPTION_DOMAIN_LIST, DHCP6_OPTION_SNTP_SERVERS};
const u16_t requested_options[] = {
#if LWIP_DHCP6_PROVIDE_DNS_SERVERS
DHCP6_OPTION_DNS_SERVERS,
DHCP6_OPTION_DOMAIN_LIST
#endif
#if LWIP_DHCP6_GET_NTP_SRV
, DHCP6_OPTION_SNTP_SERVERS
#endif
};
u16_t msecs;
struct pbuf *p_out;
u16_t options_out_len;
@@ -527,7 +536,7 @@ dhcp6_handle_config_reply(struct netif *netif, struct pbuf *p_msg_in)
u16_t idx;
u8_t n;
memset(&dns_addr, 0, sizeof(dns_addr));
ip_addr_set_zero_ip6(&dns_addr);
dns_addr6 = ip_2_ip6(&dns_addr);
for (n = 0, idx = op_start; (idx < op_start + op_len) && (n < LWIP_DHCP6_PROVIDE_DNS_SERVERS);
n++, idx += sizeof(struct ip6_addr_packed)) {

View File

@@ -57,9 +57,9 @@
#include <string.h>
#if LWIP_ICMP6_DATASIZE == 0
#if !LWIP_ICMP6_DATASIZE || (LWIP_ICMP6_DATASIZE > (IP6_MIN_MTU_LENGTH - IP6_HLEN - ICMP6_HLEN))
#undef LWIP_ICMP6_DATASIZE
#define LWIP_ICMP6_DATASIZE 8
#define LWIP_ICMP6_DATASIZE (IP6_MIN_MTU_LENGTH - IP6_HLEN - ICMP6_HLEN)
#endif
/* Forward declarations */
@@ -387,26 +387,35 @@ icmp6_send_response_with_addrs_and_netif(struct pbuf *p, u8_t code, u32_t data,
{
struct pbuf *q;
struct icmp6_hdr *icmp6hdr;
u16_t datalen = LWIP_MIN(p->tot_len, LWIP_ICMP6_DATASIZE);
u16_t offset;
/* ICMPv6 header + IPv6 header + data */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE,
/* ICMPv6 header + datalen (as much of the offending packet as possible) */
q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + datalen,
PBUF_RAM);
if (q == NULL) {
LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n"));
ICMP6_STATS_INC(icmp6.memerr);
return;
}
LWIP_ASSERT("check that first pbuf can hold icmp 6message",
(q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE)));
LWIP_ASSERT("check that first pbuf can hold icmp6 header",
(q->len >= (sizeof(struct icmp6_hdr))));
icmp6hdr = (struct icmp6_hdr *)q->payload;
icmp6hdr->type = type;
icmp6hdr->code = code;
icmp6hdr->data = lwip_htonl(data);
/* copy fields from original packet */
SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload,
IP6_HLEN + LWIP_ICMP6_DATASIZE);
/* copy fields from original packet (which may be a chain of pbufs) */
offset = sizeof(struct icmp6_hdr);
while (p && datalen) {
u16_t len = LWIP_MIN(datalen, p->len);
err_t res = pbuf_take_at(q, p->payload, len, offset);
if (res != ERR_OK) break;
datalen -= len;
offset += len;
p = p->next;
}
/* calculate checksum */
icmp6hdr->chksum = 0;

View File

@@ -1305,6 +1305,7 @@ ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
netif = ip6_route(&src_addr, &dest_addr);
dest = &dest_addr;
}
if (netif == NULL) {
@@ -1364,6 +1365,7 @@ ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest,
ip6_addr_copy_from_packed(src_addr, ip6hdr->src);
ip6_addr_copy_from_packed(dest_addr, ip6hdr->dest);
netif = ip6_route(&src_addr, &dest_addr);
dest = &dest_addr;
}
if (netif == NULL) {

View File

@@ -781,7 +781,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest)
return ERR_MEM;
}
LWIP_ASSERT("this needs a pbuf in one piece!",
(p->len >= (IP6_HLEN)));
(rambuf->len >= (IP6_HLEN)));
SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN);
ip6hdr = (struct ip6_hdr *)rambuf->payload;
frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN);

View File

@@ -253,7 +253,7 @@ mld6_input(struct pbuf *p, struct netif *inp)
while (group != NULL) {
if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
(!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
mld6_delayed_report(group, mld_hdr->max_resp_delay);
mld6_delayed_report(group, lwip_ntohs(mld_hdr->max_resp_delay));
}
group = group->next;
}
@@ -265,7 +265,7 @@ mld6_input(struct pbuf *p, struct netif *inp)
group = mld6_lookfor_group(inp, ip6_current_dest_addr());
if (group != NULL) {
/* Schedule a report. */
mld6_delayed_report(group, mld_hdr->max_resp_delay);
mld6_delayed_report(group, lwip_ntohs(mld_hdr->max_resp_delay));
}
}
break; /* ICMP6_TYPE_MLQ */

View File

@@ -693,11 +693,11 @@ nd6_input(struct pbuf *p, struct netif *inp)
}
mtu_opt = (struct mtu_option *)buffer;
mtu32 = lwip_htonl(mtu_opt->mtu);
if ((mtu32 >= 1280) && (mtu32 <= 0xffff)) {
if ((mtu32 >= IP6_MIN_MTU_LENGTH) && (mtu32 <= 0xffff)) {
#if LWIP_ND6_ALLOW_RA_UPDATES
if (inp->mtu) {
/* don't set the mtu for IPv6 higher than the netif driver supports */
inp->mtu6 = LWIP_MIN(inp->mtu, (u16_t)mtu32);
inp->mtu6 = LWIP_MIN(LWIP_MIN(inp->mtu, inp->mtu6), (u16_t)mtu32);
} else {
inp->mtu6 = (u16_t)mtu32;
}
@@ -766,7 +766,7 @@ nd6_input(struct pbuf *p, struct netif *inp)
rdnss_opt = (struct rdnss_option *)buffer;
num = (rdnss_opt->length - 1) / 2;
for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++) {
for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++, copy_offset += sizeof(ip6_addr_p_t)) {
ip_addr_t rdnss_address;
/* Copy directly from pbuf to get an aligned, zoned copy of the prefix. */
@@ -1182,15 +1182,27 @@ nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags)
{
struct ns_header *ns_hdr;
struct pbuf *p;
const ip6_addr_t *src_addr;
const ip6_addr_t *src_addr = NULL;
u16_t lladdr_opt_len;
LWIP_ASSERT("target address is required", target_addr != NULL);
if (!(flags & ND6_SEND_FLAG_ANY_SRC) &&
ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) {
/* Use link-local address as source address. */
src_addr = netif_ip6_addr(netif, 0);
if (!(flags & ND6_SEND_FLAG_ANY_SRC)) {
int i;
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
ip6_addr_netcmp(target_addr, netif_ip6_addr(netif, i))) {
src_addr = netif_ip6_addr(netif, i);
break;
}
}
if (i == LWIP_IPV6_NUM_ADDRESSES) {
LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("ICMPv6 NS: no available src address\n"));
ND6_STATS_INC(nd6.err);
return;
}
/* calculate option length (in 8-byte-blocks) */
lladdr_opt_len = ((netif->hwaddr_len + 2) + 7) >> 3;
} else {
@@ -2300,7 +2312,7 @@ nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif)
return netif_mtu6(netif);
}
return 1280; /* Minimum MTU */
return IP6_MIN_MTU_LENGTH; /* Minimum MTU */
}

View File

@@ -348,10 +348,6 @@ netif_add(struct netif *netif,
#if LWIP_IPV6 && LWIP_IPV6_MLD
netif->mld_mac_filter = NULL;
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
#if ENABLE_LOOPBACK
netif->loop_first = NULL;
netif->loop_last = NULL;
#endif /* ENABLE_LOOPBACK */
/* remember netif specific state information data */
netif->state = state;
@@ -359,9 +355,16 @@ netif_add(struct netif *netif,
netif->input = input;
NETIF_RESET_HINTS(netif);
#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
#if ENABLE_LOOPBACK
netif->loop_first = NULL;
netif->loop_last = NULL;
#if LWIP_LOOPBACK_MAX_PBUFS
netif->loop_cnt_current = 0;
#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
netif->reschedule_poll = 0;
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
#endif /* ENABLE_LOOPBACK */
#if LWIP_IPV4
netif_set_addr(netif, ipaddr, netmask, gw);
@@ -1031,6 +1034,10 @@ netif_set_link_down(struct netif *netif)
if (netif->flags & NETIF_FLAG_LINK_UP) {
netif_clear_flags(netif, NETIF_FLAG_LINK_UP);
#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
netif->mtu6 = netif->mtu;
#endif
NETIF_LINK_CALLBACK(netif);
#if LWIP_NETIF_EXT_STATUS_CALLBACK
{
@@ -1062,11 +1069,12 @@ netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callb
/**
* @ingroup netif
* Send an IP packet to be received on the same netif (loopif-like).
* The pbuf is simply copied and handed back to netif->input.
* In multithreaded mode, this is done directly since netif->input must put
* the packet on a queue.
* In callback mode, the packet is put on an internal queue and is fed to
* The pbuf is copied and added to an internal queue which is fed to
* netif->input by netif_poll().
* In multithreaded mode, the call to netif_poll() is queued to be done on the
* TCP/IP thread.
* In callback mode, the user has the responsibility to call netif_poll() in
* the main loop of their application.
*
* @param netif the lwip network interface structure
* @param p the (IP) packet to 'send'
@@ -1143,6 +1151,12 @@ netif_loop_output(struct netif *netif, struct pbuf *p)
LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL);
netif->loop_last->next = r;
netif->loop_last = last;
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
if (netif->reschedule_poll) {
schedule_poll = 1;
netif->reschedule_poll = 0;
}
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
} else {
netif->loop_first = r;
netif->loop_last = last;
@@ -1160,7 +1174,11 @@ netif_loop_output(struct netif *netif, struct pbuf *p)
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
/* For multithreading environment, schedule a call to netif_poll */
if (schedule_poll) {
tcpip_try_callback((tcpip_callback_fn)netif_poll, netif);
if (tcpip_try_callback((tcpip_callback_fn)netif_poll, netif) != ERR_OK) {
SYS_ARCH_PROTECT(lev);
netif->reschedule_poll = 1;
SYS_ARCH_UNPROTECT(lev);
}
}
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
@@ -1710,6 +1728,10 @@ netif_find(const char *name)
}
num = (u8_t)atoi(&name[2]);
if (!num && (name[2] != '0')) {
/* this means atoi has failed */
return NULL;
}
NETIF_FOREACH(netif) {
if (num == netif->num &&

View File

@@ -271,7 +271,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
break;
}
case PBUF_RAM: {
u16_t payload_len = (u16_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length));
mem_size_t payload_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length));
mem_size_t alloc_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len);
/* bug #50040: Check for integer overflow when calculating alloc_len */
@@ -960,54 +960,88 @@ pbuf_dechain(struct pbuf *p)
err_t
pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
{
size_t offset_to = 0, offset_from = 0, len;
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n",
(const void *)p_to, (const void *)p_from));
LWIP_ERROR("pbuf_copy: invalid source", p_from != NULL, return ERR_ARG;);
return pbuf_copy_partial_pbuf(p_to, p_from, p_from->tot_len, 0);
}
/**
* @ingroup pbuf
* Copy part or all of one packet buffer into another, to a specified offset.
*
* @note Only data in one packet is copied, no packet queue!
* @note Argument order is shared with pbuf_copy, but different than pbuf_copy_partial.
*
* @param p_to pbuf destination of the copy
* @param p_from pbuf source of the copy
* @param copy_len number of bytes to copy
* @param offset offset in destination pbuf where to copy to
*
* @return ERR_OK if copy_len bytes were copied
* ERR_ARG if one of the pbufs is NULL or p_from is shorter than copy_len
* or p_to is not big enough to hold copy_len at offset
* ERR_VAL if any of the pbufs are part of a queue
*/
err_t
pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_len, u16_t offset)
{
size_t offset_to = offset, offset_from = 0, len_calc;
u16_t len;
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy_partial_pbuf(%p, %p, %"U16_F", %"U16_F")\n",
(const void *)p_to, (const void *)p_from, copy_len, offset));
/* is the copy_len in range? */
LWIP_ERROR("pbuf_copy_partial_pbuf: copy_len bigger than source", ((p_from != NULL) &&
(p_from->tot_len >= copy_len)), return ERR_ARG;);
/* is the target big enough to hold the source? */
LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) &&
(p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;);
LWIP_ERROR("pbuf_copy_partial_pbuf: target not big enough", ((p_to != NULL) &&
(p_to->tot_len >= (offset + copy_len))), return ERR_ARG;);
/* iterate through pbuf chain */
do {
/* copy one part of the original chain */
if ((p_to->len - offset_to) >= (p_from->len - offset_from)) {
/* complete current p_from fits into current p_to */
len = p_from->len - offset_from;
len_calc = p_from->len - offset_from;
} else {
/* current p_from does not fit into current p_to */
len = p_to->len - offset_to;
len_calc = p_to->len - offset_to;
}
len = (u16_t)LWIP_MIN(copy_len, len_calc);
MEMCPY((u8_t *)p_to->payload + offset_to, (u8_t *)p_from->payload + offset_from, len);
offset_to += len;
offset_from += len;
copy_len -= len;
LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len);
LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len);
if (offset_from >= p_from->len) {
/* on to next p_from (if any) */
offset_from = 0;
p_from = p_from->next;
LWIP_ERROR("p_from != NULL", (p_from != NULL) || (copy_len == 0), return ERR_ARG;);
}
if (offset_to == p_to->len) {
/* on to next p_to (if any) */
offset_to = 0;
p_to = p_to->next;
LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL), return ERR_ARG;);
LWIP_ERROR("p_to != NULL", (p_to != NULL) || (copy_len == 0), return ERR_ARG;);
}
if ((p_from != NULL) && (p_from->len == p_from->tot_len)) {
/* don't copy more than one packet! */
LWIP_ERROR("pbuf_copy() does not allow packet queues!",
LWIP_ERROR("pbuf_copy_partial_pbuf() does not allow packet queues!",
(p_from->next == NULL), return ERR_VAL;);
}
if ((p_to != NULL) && (p_to->len == p_to->tot_len)) {
/* don't copy more than one packet! */
LWIP_ERROR("pbuf_copy() does not allow packet queues!",
LWIP_ERROR("pbuf_copy_partial_pbuf() does not allow packet queues!",
(p_to->next == NULL), return ERR_VAL;);
}
} while (p_from);
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n"));
} while (copy_len);
LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy_partial_pbuf: copy complete.\n"));
return ERR_OK;
}
@@ -1074,7 +1108,7 @@ void *
pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset)
{
const struct pbuf *q;
uint16_t out_offset;
u16_t out_offset;
LWIP_ERROR("pbuf_get_contiguous: invalid buf", (p != NULL), return NULL;);
LWIP_ERROR("pbuf_get_contiguous: invalid dataptr", (buffer != NULL), return NULL;);

View File

@@ -583,6 +583,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
tcp_free(pcb);
} else {
int send_rst = 0;
u16_t local_port = 0;
enum tcp_state last_state;
seqno = pcb->snd_nxt;
ackno = pcb->rcv_nxt;
@@ -597,6 +598,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
}
} else {
send_rst = reset;
local_port = pcb->local_port;
TCP_PCB_REMOVE_ACTIVE(pcb);
}
if (pcb->unacked != NULL) {
@@ -613,7 +615,7 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
tcp_backlog_accepted(pcb);
if (send_rst) {
LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n"));
tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, pcb->local_port, pcb->remote_port);
tcp_rst(pcb, seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port);
}
last_state = pcb->state;
tcp_free(pcb);
@@ -645,6 +647,7 @@ tcp_abort(struct tcp_pcb *pcb)
* bound to all local IP addresses.
* If another connection is bound to the same port, the function will
* return ERR_USE, otherwise ERR_OK is returned.
* @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
*
* @param pcb the tcp_pcb to bind (no check is done whether this pcb is
* already bound!)
@@ -734,7 +737,11 @@ tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
}
}
if (!ip_addr_isany(ipaddr)) {
if (!ip_addr_isany(ipaddr)
#if LWIP_IPV4 && LWIP_IPV6
|| (IP_GET_TYPE(ipaddr) != IP_GET_TYPE(&pcb->local_ip))
#endif /* LWIP_IPV4 && LWIP_IPV6 */
) {
ip_addr_set(&pcb->local_ip, ipaddr);
}
pcb->local_port = port;
@@ -883,7 +890,7 @@ tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err)
lpcb->state = LISTEN;
lpcb->prio = pcb->prio;
lpcb->so_options = pcb->so_options;
lpcb->netif_idx = NETIF_NO_INDEX;
lpcb->netif_idx = pcb->netif_idx;
lpcb->ttl = pcb->ttl;
lpcb->tos = pcb->tos;
#if LWIP_IPV4 && LWIP_IPV6
@@ -962,6 +969,7 @@ void
tcp_recved(struct tcp_pcb *pcb, u16_t len)
{
u32_t wnd_inflation;
tcpwnd_size_t rcv_wnd;
LWIP_ASSERT_CORE_LOCKED();
@@ -971,19 +979,13 @@ tcp_recved(struct tcp_pcb *pcb, u16_t len)
LWIP_ASSERT("don't call tcp_recved for listen-pcbs",
pcb->state != LISTEN);
pcb->rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len);
if (pcb->rcv_wnd > TCP_WND_MAX(pcb)) {
rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len);
if ((rcv_wnd > TCP_WND_MAX(pcb)) || (rcv_wnd < pcb->rcv_wnd)) {
/* window got too big or tcpwnd_size_t overflow */
LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: window got too big or tcpwnd_size_t overflow\n"));
pcb->rcv_wnd = TCP_WND_MAX(pcb);
} else if (pcb->rcv_wnd == 0) {
/* rcv_wnd overflowed */
if (TCP_STATE_IS_CLOSING(pcb->state)) {
/* In passive close, we allow this, since the FIN bit is added to rcv_wnd
by the stack itself, since it is not mandatory for an application
to call tcp_recved() for the FIN bit, but e.g. the netconn API does so. */
pcb->rcv_wnd = TCP_WND_MAX(pcb);
} else {
LWIP_ASSERT("tcp_recved: len wrapped rcv_wnd\n", 0);
}
} else {
pcb->rcv_wnd = rcv_wnd;
}
wnd_inflation = tcp_update_rcv_ann_wnd(pcb);
@@ -1215,6 +1217,7 @@ tcp_slowtmr_start:
LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT);
if (pcb->last_timer == tcp_timer_ctr) {
/* skip this pcb, we have already processed it */
prev = pcb;
pcb = pcb->next;
continue;
}
@@ -1931,6 +1934,7 @@ tcp_alloc(u8_t prio)
* any of the TCP PCB lists.
* The pcb is not put on any list until binding using tcp_bind().
* If memory is not available for creating the new pcb, NULL is returned.
* @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
*
* @internal: Maybe there should be a idle TCP PCB list where these
* PCBs are put on. Port reservation using tcp_bind() is implemented but
@@ -1950,6 +1954,7 @@ tcp_new(void)
* Creates a new TCP protocol control block but doesn't
* place it on any of the TCP PCB lists.
* The pcb is not put on any list until binding using tcp_bind().
* @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
*
* @param type IP address type, see @ref lwip_ip_addr_type definitions.
* If you want to listen to IPv4 and IPv6 (dual-stack) connections,
@@ -2065,6 +2070,7 @@ tcp_err(struct tcp_pcb *pcb, tcp_err_fn err)
* @ingroup tcp_raw
* Used for specifying the function that should be called when a
* LISTENing connection has been connected to another host.
* @see MEMP_NUM_TCP_PCB_LISTEN and MEMP_NUM_TCP_PCB
*
* @param pcb tcp_pcb to set the accept callback
* @param accept callback function to call for this pcb when LISTENing

View File

@@ -852,8 +852,9 @@ tcp_process(struct tcp_pcb *pcb)
/* Do different things depending on the TCP state. */
switch (pcb->state) {
case SYN_SENT:
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno,
pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno)));
LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %s %"U32_F"\n",
ackno, pcb->snd_nxt, pcb->unacked ? "" : " empty:",
pcb->unacked ? lwip_ntohl(pcb->unacked->tcphdr->seqno) : 0));
/* received SYN ACK with expected sequence number? */
if ((flags & TCP_ACK) && (flags & TCP_SYN)
&& (ackno == pcb->lastack + 1)) {

View File

@@ -913,6 +913,7 @@ tcp_split_unsent_seg(struct tcp_pcb *pcb, u16_t split)
seg = tcp_create_segment(pcb, p, remainder_flags, lwip_ntohl(useg->tcphdr->seqno) + split, optflags);
if (seg == NULL) {
p = NULL; /* Freed by tcp_create_segment */
LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS,
("tcp_split_unsent_seg: could not create new TCP segment\n"));
goto memerr;
@@ -1585,8 +1586,8 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum);
seg->chksum_swapped = 0;
}
acc += (u16_t)~(seg->chksum);
seg->tcphdr->chksum = FOLD_U32T(acc);
acc = (u16_t)~acc + seg->chksum;
seg->tcphdr->chksum = (u16_t)~FOLD_U32T(acc);
#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK
if (chksum_slow != seg->tcphdr->chksum) {
TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(
@@ -2002,7 +2003,7 @@ tcp_rst(const struct tcp_pcb *pcb, u32_t seqno, u32_t ackno,
LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n"));
return;
}
tcp_output_fill_options(pcb, p, 0, optlen);
tcp_output_fill_options(pcb, p, 0, 0);
MIB2_STATS_INC(mib2.tcpoutrsts);
@@ -2096,7 +2097,7 @@ tcp_keepalive(struct tcp_pcb *pcb)
("tcp_keepalive: could not allocate memory for pbuf\n"));
return ERR_MEM;
}
tcp_output_fill_options(pcb, p, 0, optlen);
tcp_output_fill_options(pcb, p, 0, 0);
err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);
LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n",
@@ -2178,7 +2179,7 @@ tcp_zero_window_probe(struct tcp_pcb *pcb)
if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
pcb->snd_nxt = snd_nxt;
}
tcp_output_fill_options(pcb, p, 0, optlen);
tcp_output_fill_options(pcb, p, 0, 0);
err = tcp_output_control_segment(pcb, p, &pcb->local_ip, &pcb->remote_ip);

View File

@@ -997,9 +997,13 @@ udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port)
{
/* port matches that of PCB in list and REUSEADDR not set -> reject */
if ((ipcb->local_port == port) &&
(((IP_GET_TYPE(&ipcb->local_ip) == IP_GET_TYPE(ipaddr)) &&
/* IP address matches or any IP used? */
(ip_addr_cmp(&ipcb->local_ip, ipaddr) || ip_addr_isany(ipaddr) ||
ip_addr_isany(&ipcb->local_ip))) {
(ip_addr_cmp(&ipcb->local_ip, ipaddr) ||
ip_addr_isany(ipaddr) ||
ip_addr_isany(&ipcb->local_ip))) ||
(IP_GET_TYPE(&ipcb->local_ip) == IPADDR_TYPE_ANY) ||
(IP_GET_TYPE(ipaddr) == IPADDR_TYPE_ANY))) {
/* other PCB already binds to this local IP and port */
LWIP_DEBUGF(UDP_DEBUG,
("udp_bind: local port %"U16_F" already bound by another pcb\n", port));
@@ -1208,6 +1212,7 @@ udp_remove(struct udp_pcb *pcb)
* Creates a new UDP pcb which can be used for UDP communication. The
* pcb is not active until it has either been bound to a local address
* or connected to a remote address.
* @see MEMP_NUM_UDP_PCB
*
* @return The UDP PCB which was created. NULL if the PCB data structure
* could not be allocated.
@@ -1242,7 +1247,8 @@ udp_new(void)
* Create a UDP PCB for specific IP type.
* The pcb is not active until it has either been bound to a local address
* or connected to a remote address.
*
* @see MEMP_NUM_UDP_PCB
*
* @param type IP address type, see @ref lwip_ip_addr_type definitions.
* If you want to listen to IPv4 and IPv6 (dual-stack) packets,
* supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE.

View File

@@ -1,12 +1,9 @@
/**
* @file
* Application layered TCP connection API (to be used from TCPIP thread)\n
* This interface mimics the tcp callback API to the application while preventing
* direct linking (much like virtual functions).
* This way, an application can make use of other application layer protocols
* on top of TCP without knowing the details (e.g. TLS, proxy connection).
*
* This file contains the generic API.
* For more details see @ref altcp_api.
*/
/*
@@ -132,6 +129,11 @@ err_t altcp_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr,
ip_addr_t *altcp_get_ip(struct altcp_pcb *conn, int local);
u16_t altcp_get_port(struct altcp_pcb *conn, int local);
#if LWIP_TCP_KEEPALIVE
void altcp_keepalive_disable(struct altcp_pcb *conn);
void altcp_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
#endif
#ifdef LWIP_DEBUG
enum tcp_state altcp_dbg_get_tcp_state(struct altcp_pcb *conn);
#endif

View File

@@ -61,7 +61,22 @@ extern "C" {
struct altcp_tls_config;
/** @ingroup altcp_tls
* Create an ALTCP_TLS server configuration handle
* Create an ALTCP_TLS server configuration handle prepared for multiple certificates
*/
struct altcp_tls_config *altcp_tls_create_config_server(uint8_t cert_count);
/** @ingroup altcp_tls
* Add a certificate to an ALTCP_TLS server configuration handle
*/
err_t altcp_tls_config_server_add_privkey_cert(struct altcp_tls_config *config,
const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Create an ALTCP_TLS server configuration handle with one certificate
* (short version of calling @ref altcp_tls_create_config_server and
* @ref altcp_tls_config_server_add_privkey_cert)
*/
struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
@@ -72,20 +87,44 @@ struct altcp_tls_config *altcp_tls_create_config_server_privkey_cert(const u8_t
*/
struct altcp_tls_config *altcp_tls_create_config_client(const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Create an ALTCP_TLS client configuration handle with two-way server/client authentication
*/
struct altcp_tls_config *altcp_tls_create_config_client_2wayauth(const u8_t *ca, size_t ca_len, const u8_t *privkey, size_t privkey_len,
const u8_t *privkey_pass, size_t privkey_pass_len,
const u8_t *cert, size_t cert_len);
/** @ingroup altcp_tls
* Free an ALTCP_TLS configuration handle
*/
void altcp_tls_free_config(struct altcp_tls_config *conf);
/** @ingroup altcp_tls
* Create new ALTCP_TLS layer
* Free an ALTCP_TLS global entropy instance.
* All ALTCP_TLS configuration are linked to one altcp_tls_entropy_rng structure
* that handle an unique system entropy & ctr_drbg instance.
* This function allow application to free this altcp_tls_entropy_rng structure
* when all configuration referencing it were destroyed.
* This function does nothing if some ALTCP_TLS configuration handle are still
* active.
*/
struct altcp_pcb *altcp_tls_new(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb);
void altcp_tls_free_entropy(void);
/** @ingroup altcp_tls
* Create new ALTCP_TLS layer
* This allocator function fits to @ref altcp_allocator_t / @ref altcp_new.
* 'arg' must contain a struct altcp_tls_config *.
* Create new ALTCP_TLS layer wrapping an existing pcb as inner connection (e.g. TLS over TCP)
*/
struct altcp_pcb *altcp_tls_wrap(struct altcp_tls_config *config, struct altcp_pcb *inner_pcb);
/** @ingroup altcp_tls
* Create new ALTCP_TLS pcb and its inner tcp pcb
*/
struct altcp_pcb *altcp_tls_new(struct altcp_tls_config *config, u8_t ip_type);
/** @ingroup altcp_tls
* Create new ALTCP_TLS layer pcb and its inner tcp pcb.
* Same as @ref altcp_tls_new but this allocator function fits to
* @ref altcp_allocator_t / @ref altcp_new.\n
'arg' must contain a struct altcp_tls_config *.
*/
struct altcp_pcb *altcp_tls_alloc(void *arg, u8_t ip_type);

View File

@@ -47,6 +47,10 @@
#include "lwip/ip_addr.h"
#ifdef __cplusplus
extern "C" {
#endif
struct altcp_proxyconnect_config {
ip_addr_t proxy_addr;
u16_t proxy_port;
@@ -67,5 +71,9 @@ struct altcp_proxyconnect_tls_config {
struct altcp_pcb *altcp_proxyconnect_tls_alloc(void *arg, u8_t ip_type);
#endif /* LWIP_ALTCP_TLS */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_ALTCP */
#endif /* LWIP_HDR_APPS_ALTCP_PROXYCONNECT_H */

View File

@@ -55,11 +55,49 @@
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_OFF
#endif
/** Set a session timeout in seconds for the basic session cache
/** Configure lwIP debug level of the mbedTLS library */
#ifndef ALTCP_MBEDTLS_LIB_DEBUG
#define ALTCP_MBEDTLS_LIB_DEBUG LWIP_DBG_OFF
#endif
/** Configure minimum internal debug level of the mbedTLS library */
#ifndef ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN
#define ALTCP_MBEDTLS_LIB_DEBUG_LEVEL_MIN 0
#endif
/** Enable the basic session cache
* ATTENTION: Using a session cache can lower security by reusing keys!
*/
#ifndef ALTCP_MBEDTLS_USE_SESSION_CACHE
#define ALTCP_MBEDTLS_USE_SESSION_CACHE 0
#endif
/** Maximum cache size of the basic session cache */
#ifndef ALTCP_MBEDTLS_SESSION_CACHE_SIZE
#define ALTCP_MBEDTLS_SESSION_CACHE_SIZE 30
#endif
/** Set a session timeout in seconds for the basic session cache */
#ifndef ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS
#define ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS 0
#define ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS (60 * 60)
#endif
/** Use session tickets to speed up connection setup (needs
* MBEDTLS_SSL_SESSION_TICKETS enabled in mbedTLS config).
* ATTENTION: Using session tickets can lower security by reusing keys!
*/
#ifndef ALTCP_MBEDTLS_USE_SESSION_TICKETS
#define ALTCP_MBEDTLS_USE_SESSION_TICKETS 0
#endif
/** Session ticket cipher */
#ifndef ALTCP_MBEDTLS_SESSION_TICKET_CIPHER
#define ALTCP_MBEDTLS_SESSION_TICKET_CIPHER MBEDTLS_CIPHER_AES_256_GCM
#endif
/** Maximum timeout for session tickets */
#ifndef ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS
#define ALTCP_MBEDTLS_SESSION_TICKET_TIMEOUT_SECONDS (60 * 60 * 24)
#endif
#endif /* LWIP_ALTCP */

View File

@@ -45,6 +45,8 @@
#include "lwip/prot/iana.h"
#include "lwip/pbuf.h"
#if LWIP_TCP && LWIP_CALLBACK_API
#ifdef __cplusplus
extern "C" {
#endif
@@ -153,4 +155,6 @@ err_t httpc_get_file_dns_to_disk(const char* server_name, u16_t port, const char
}
#endif
#endif /* LWIP_TCP && LWIP_CALLBACK_API */
#endif /* LWIP_HDR_APPS_HTTP_CLIENT_H */

View File

@@ -41,6 +41,10 @@
#include "lwip/apps/mdns_opts.h"
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_MDNS_RESPONDER
enum mdns_sd_proto {
@@ -94,4 +98,8 @@ void mdns_resp_announce(struct netif *netif);
#endif /* LWIP_MDNS_RESPONDER */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_MDNS_H */

View File

@@ -40,6 +40,10 @@
#include "lwip/apps/mdns_opts.h"
#include "lwip/pbuf.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_MDNS_RESPONDER
/* Domain struct and methods - visible for unit tests */
@@ -63,4 +67,8 @@ u16_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain
#endif /* LWIP_MDNS_RESPONDER */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_MDNS_PRIV_H */

View File

@@ -116,7 +116,7 @@ typedef enum
* @ingroup mqtt
* Function prototype for mqtt connection status callback. Called when
* client has connected to the server after initiating a mqtt connection attempt by
* calling mqtt_connect() or when connection is closed by server or an error
* calling mqtt_client_connect() or when connection is closed by server or an error
*
* @param client MQTT client itself
* @param arg Additional argument to pass to the callback function

View File

@@ -34,10 +34,18 @@
#include "lwip/apps/netbiosns_opts.h"
#ifdef __cplusplus
extern "C" {
#endif
void netbiosns_init(void);
#ifndef NETBIOS_LWIP_NAME
void netbiosns_set_name(const char* hostname);
#endif
void netbiosns_stop(void);
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_NETBIOS_H */

View File

@@ -1,6 +1,10 @@
#ifndef LWIP_HDR_APPS_SMTP_H
#define LWIP_HDR_APPS_SMTP_H
#ifdef __cplusplus
extern "C" {
#endif
#include "lwip/apps/smtp_opts.h"
#include "lwip/err.h"
#include "lwip/prot/iana.h"
@@ -117,4 +121,8 @@ void smtp_send_mail_int(void *arg);
const char* smtp_result_str(u8_t smtp_result);
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SMTP_H */

View File

@@ -72,7 +72,7 @@ extern "C" {
/**
* @}
*/
#ifdef __cplusplus
}
#endif

View File

@@ -191,7 +191,7 @@ typedef snmp_err_t (*node_instance_set_test_method)(struct snmp_node_instance*,
typedef snmp_err_t (*node_instance_set_value_method)(struct snmp_node_instance*, u16_t, void*);
typedef void (*node_instance_release_method)(struct snmp_node_instance*);
#define SNMP_GET_VALUE_RAW_DATA 0x8000
#define SNMP_GET_VALUE_RAW_DATA 0x4000 /* do not use 0x8000 because return value of node_instance_get_value_method is signed16 and 0x8000 would be the signed bit */
/** SNMP node instance */
struct snmp_node_instance

View File

@@ -38,23 +38,27 @@
#include "lwip/apps/snmp_opts.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
#if LWIP_SNMP && LWIP_SNMP_V3
typedef enum
typedef enum
{
SNMP_V3_AUTH_ALGO_INVAL = 0,
SNMP_V3_AUTH_ALGO_MD5 = 1,
SNMP_V3_AUTH_ALGO_SHA = 2
} snmpv3_auth_algo_t;
typedef enum
typedef enum
{
SNMP_V3_PRIV_ALGO_INVAL = 0,
SNMP_V3_PRIV_ALGO_DES = 1,
SNMP_V3_PRIV_ALGO_AES = 2
} snmpv3_priv_algo_t;
typedef enum
typedef enum
{
SNMP_V3_USER_STORAGETYPE_OTHER = 1,
SNMP_V3_USER_STORAGETYPE_VOLATILE = 2,
@@ -103,4 +107,8 @@ void snmpv3_password_to_key_sha(
#endif
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_APPS_SNMP_V3_H */

View File

@@ -67,11 +67,11 @@ void sntp_setservername(u8_t idx, const char *server);
const char *sntp_getservername(u8_t idx);
#endif /* SNTP_SERVER_DNS */
#if SNTP_GET_SERVERS_FROM_DHCP
#if SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6
void sntp_servermode_dhcp(int set_servers_from_dhcp);
#else /* SNTP_GET_SERVERS_FROM_DHCP */
#else /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
#define sntp_servermode_dhcp(x)
#endif /* SNTP_GET_SERVERS_FROM_DHCP */
#endif /* SNTP_GET_SERVERS_FROM_DHCP || SNTP_GET_SERVERS_FROM_DHCPV6 */
#ifdef __cplusplus
}

View File

@@ -67,6 +67,12 @@
#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV
#endif
/** Set this to 1 to implement the callback function called by dhcpv6 when
* NTP servers are received. */
#if !defined SNTP_GET_SERVERS_FROM_DHCPV6 || defined __DOXYGEN__
#define SNTP_GET_SERVERS_FROM_DHCPV6 LWIP_DHCP6_GET_NTP_SRV
#endif
/** Set this to 1 to support DNS names (or IP address strings) to set sntp servers
* One server address/name can be defined as default if SNTP_SERVER_DNS == 1:
* \#define SNTP_SERVER_ADDRESS "pool.ntp.org"

View File

@@ -120,9 +120,7 @@
#endif /* LWIP_NOASSERT */
#ifndef LWIP_ERROR
#ifndef LWIP_NOASSERT
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_ASSERT(message)
#elif defined LWIP_DEBUG
#ifdef LWIP_DEBUG
#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_DIAG((message))
#else
#define LWIP_PLATFORM_ERROR(message)

View File

@@ -83,14 +83,14 @@ extern "C" {
#endif
#if BYTE_ORDER == BIG_ENDIAN
#define lwip_htons(x) (x)
#define lwip_ntohs(x) (x)
#define lwip_htonl(x) (x)
#define lwip_ntohl(x) (x)
#define PP_HTONS(x) (x)
#define PP_NTOHS(x) (x)
#define PP_HTONL(x) (x)
#define PP_NTOHL(x) (x)
#define lwip_htons(x) ((u16_t)(x))
#define lwip_ntohs(x) ((u16_t)(x))
#define lwip_htonl(x) ((u32_t)(x))
#define lwip_ntohl(x) ((u32_t)(x))
#define PP_HTONS(x) ((u16_t)(x))
#define PP_NTOHS(x) ((u16_t)(x))
#define PP_HTONL(x) ((u32_t)(x))
#define PP_NTOHL(x) ((u32_t)(x))
#else /* BYTE_ORDER != BIG_ENDIAN */
#ifndef lwip_htons
u16_t lwip_htons(u16_t x);

View File

@@ -47,6 +47,10 @@
#include "lwip/err.h"
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
/** period (in milliseconds) of the application calling dhcp6_tmr() */
#define DHCP6_TIMER_MSECS 500
@@ -91,6 +95,10 @@ extern void dhcp6_set_ntp_servers(u8_t num_ntp_servers, const ip_addr_t* ntp_ser
#define netif_dhcp6_data(netif) ((struct dhcp6*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP6))
#ifdef __cplusplus
}
#endif
#endif /* LWIP_IPV6_DHCP6 */
#endif /* LWIP_HDR_IP6_DHCP6_H */

View File

@@ -49,14 +49,6 @@ extern "C" {
* @{
*/
/** Define LWIP_ERR_T in cc.h if you want to use
* a different type for your platform (must be signed). */
#ifdef LWIP_ERR_T
typedef LWIP_ERR_T err_t;
#else /* LWIP_ERR_T */
typedef s8_t err_t;
#endif /* LWIP_ERR_T*/
/** Definitions for error constants. */
typedef enum {
/** No error, everything OK. */
@@ -96,6 +88,14 @@ typedef enum {
ERR_ARG = -16
} err_enum_t;
/** Define LWIP_ERR_T in cc.h if you want to use
* a different type for your platform (must be signed). */
#ifdef LWIP_ERR_T
typedef LWIP_ERR_T err_t;
#else /* LWIP_ERR_T */
typedef s8_t err_t;
#endif /* LWIP_ERR_T*/
/**
* @}
*/

View File

@@ -49,7 +49,9 @@
extern "C" {
#endif
#ifndef IF_NAMESIZE
#define IF_NAMESIZE NETIF_NAMESIZE
#endif
char * lwip_if_indextoname(unsigned int ifindex, char *ifname);
unsigned int lwip_if_nametoindex(const char *ifname);

View File

@@ -54,11 +54,11 @@ extern "C" {
/** x.X.x: Minor version of the stack */
#define LWIP_VERSION_MINOR 1
/** x.x.X: Revision of the stack */
#define LWIP_VERSION_REVISION 0
#define LWIP_VERSION_REVISION 3
/** For release candidates, this is set to 1..254
* For official releases, this is set to 255 (LWIP_RC_RELEASE)
* For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */
#define LWIP_VERSION_RC 1
#define LWIP_VERSION_RC LWIP_RC_RELEASE
/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */
#define LWIP_RC_RELEASE 255

View File

@@ -85,6 +85,10 @@
#ifndef LWIP_HDR_IP6_ZONE_H
#define LWIP_HDR_IP6_ZONE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup ip6_zones IPv6 Zones
* @ingroup ip6
@@ -293,4 +297,8 @@ enum lwip_ipv6_scope_type
#endif /* LWIP_IPV6 */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_IP6_ZONE_H */

View File

@@ -386,6 +386,10 @@ struct netif {
#if LWIP_LOOPBACK_MAX_PBUFS
u16_t loop_cnt_current;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
#if LWIP_NETIF_LOOPBACK_MULTITHREADING
/* Used if the original scheduling failed. */
u8_t reschedule_poll;
#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
#endif /* ENABLE_LOOPBACK */
};
@@ -451,7 +455,7 @@ void netif_set_gw(struct netif *netif, const ip4_addr_t *gw);
#define netif_set_flags(netif, set_flags) do { (netif)->flags = (u8_t)((netif)->flags | (set_flags)); } while(0)
#define netif_clear_flags(netif, clr_flags) do { (netif)->flags = (u8_t)((netif)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
#define netif_is_flag_set(nefif, flag) (((netif)->flags & (flag)) != 0)
#define netif_is_flag_set(netif, flag) (((netif)->flags & (flag)) != 0)
void netif_set_up(struct netif *netif);
void netif_set_down(struct netif *netif);

View File

@@ -930,16 +930,6 @@
#define DHCP_DOES_ARP_CHECK (LWIP_DHCP && LWIP_ARP)
#endif
/**
* LWIP_DHCP_CHECK_LINK_UP==1: dhcp_start() only really starts if the netif has
* NETIF_FLAG_LINK_UP set in its flags. As this is only an optimization and
* netif drivers might not set this flag, the default is off. If enabled,
* netif_set_link_up() must be called to continue dhcp starting.
*/
#if !defined LWIP_DHCP_CHECK_LINK_UP
#define LWIP_DHCP_CHECK_LINK_UP 0
#endif
/**
* LWIP_DHCP_BOOTP_FILE==1: Store offered_si_addr and boot_file_name.
*/
@@ -1489,15 +1479,19 @@
#define LWIP_TCP_PCB_NUM_EXT_ARGS 0
#endif
/** LWIP_ALTCP==1: enable the altcp API
/** LWIP_ALTCP==1: enable the altcp API.
* altcp is an abstraction layer that prevents applications linking against the
* tcp.h functions but provides the same functionality. It is used to e.g. add
* SSL/TLS or proxy-connect support to an application written for the tcp callback
* API without that application knowing the protocol details.
* Applications written against the altcp API are directly linked against the
* tcp callback API for LWIP_ALTCP==0, but then cannot use layered protocols.
*
* With LWIP_ALTCP==0, applications written against the altcp API can still be
* compiled but are directly linked against the tcp.h callback API and then
* cannot use layered protocols.
*
* See @ref altcp_api
*/
#ifndef LWIP_ALTCP
#if !defined LWIP_ALTCP || defined __DOXYGEN__
#define LWIP_ALTCP 0
#endif
@@ -1506,7 +1500,7 @@
* A port to ARM mbedtls is provided with lwIP, see apps/altcp_tls/ directory
* and LWIP_ALTCP_TLS_MBEDTLS option.
*/
#ifndef LWIP_ALTCP_TLS
#if !defined LWIP_ALTCP_TLS || defined __DOXYGEN__
#define LWIP_ALTCP_TLS 0
#endif
@@ -1551,16 +1545,24 @@
* TCP_MSS, IP header, and link header.
*/
#if !defined PBUF_POOL_BUFSIZE || defined __DOXYGEN__
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+PBUF_IP_HLEN+PBUF_TRANSPORT_HLEN+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
#endif
/**
* LWIP_PBUF_REF_T: Refcount type in pbuf.
* Default width of u8_t can be increased if 255 refs are not enough for you.
*/
#ifndef LWIP_PBUF_REF_T
#if !defined LWIP_PBUF_REF_T || defined __DOXYGEN__
#define LWIP_PBUF_REF_T u8_t
#endif
/**
* LWIP_PBUF_CUSTOM_DATA: Store private data on pbufs (e.g. timestamps)
* This extends struct pbuf so user can store custom data on every pbuf.
*/
#if !defined LWIP_PBUF_CUSTOM_DATA || defined __DOXYGEN__
#define LWIP_PBUF_CUSTOM_DATA
#endif
/**
* @}
*/
@@ -1918,11 +1920,8 @@
/** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread,
* writing from a 2nd thread and closing from a 3rd thread at the same time.
* ATTENTION: This is currently really alpha! Some requirements:
* - LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from
* multiple threads at once
* - sys_mbox_free() has to unblock receive tasks waiting on recvmbox/acceptmbox
* and prevent a task pending on this during/after deletion
* LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from
* multiple threads at once!
*/
#if !defined LWIP_NETCONN_FULLDUPLEX || defined __DOXYGEN__
#define LWIP_NETCONN_FULLDUPLEX 0
@@ -2392,6 +2391,18 @@
* LWIP_IPV6_SCOPES==1: Enable support for IPv6 address scopes, ensuring that
* e.g. link-local addresses are really treated as link-local. Disable this
* setting only for single-interface configurations.
* All addresses that have a scope according to the default policy (link-local
* unicast addresses, interface-local and link-local multicast addresses) should
* now have a zone set on them before being passed to the core API, although
* lwIP will currently attempt to select a zone on the caller's behalf when
* necessary. Applications that directly assign IPv6 addresses to interfaces
* (which is NOT recommended) must now ensure that link-local addresses carry
* the netif's zone. See the new ip6_zone.h header file for more information and
* relevant macros. For now it is still possible to turn off scopes support
* through the new LWIP_IPV6_SCOPES option. When upgrading an implementation that
* uses the core API directly, it is highly recommended to enable
* LWIP_IPV6_SCOPES_DEBUG at least for a while, to ensure e.g. proper address
* initialization.
*/
#if !defined LWIP_IPV6_SCOPES || defined __DOXYGEN__
#define LWIP_IPV6_SCOPES (LWIP_IPV6 && !LWIP_SINGLE_NETIF)
@@ -2440,7 +2451,7 @@
* network startup.
*/
#if !defined LWIP_IPV6_SEND_ROUTER_SOLICIT || defined __DOXYGEN__
#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1
#define LWIP_IPV6_SEND_ROUTER_SOLICIT LWIP_IPV6
#endif
/**
@@ -2485,10 +2496,12 @@
/**
* LWIP_ICMP6_DATASIZE: bytes from original packet to send back in
* ICMPv6 error messages.
* ICMPv6 error messages (0 = default of IP6_MIN_MTU_LENGTH)
* ATTENTION: RFC4443 section 2.4 says IP6_MIN_MTU_LENGTH is a MUST,
* so override this only if you absolutely have to!
*/
#if !defined LWIP_ICMP6_DATASIZE || defined __DOXYGEN__
#define LWIP_ICMP6_DATASIZE 8
#define LWIP_ICMP6_DATASIZE 0
#endif
/**

View File

@@ -219,6 +219,9 @@ struct pbuf {
/** For incoming packets, this contains the input netif's index */
u8_t if_idx;
/** In case the user needs to store data custom data on a pbuf */
LWIP_PBUF_CUSTOM_DATA
};
@@ -293,6 +296,7 @@ void pbuf_cat(struct pbuf *head, struct pbuf *tail);
void pbuf_chain(struct pbuf *head, struct pbuf *tail);
struct pbuf *pbuf_dechain(struct pbuf *p);
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from);
err_t pbuf_copy_partial_pbuf(struct pbuf *p_to, const struct pbuf *p_from, u16_t copy_len, u16_t offset);
u16_t pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset);
void *pbuf_get_contiguous(const struct pbuf *p, void *buffer, size_t bufsize, u16_t len, u16_t offset);
err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len);

View File

@@ -85,6 +85,11 @@ typedef err_t (*altcp_get_tcp_addrinfo_fn)(struct altcp_pcb *conn, int local, ip
typedef ip_addr_t *(*altcp_get_ip_fn)(struct altcp_pcb *conn, int local);
typedef u16_t (*altcp_get_port_fn)(struct altcp_pcb *conn, int local);
#if LWIP_TCP_KEEPALIVE
typedef void (*altcp_keepalive_disable_fn)(struct altcp_pcb *conn);
typedef void (*altcp_keepalive_enable_fn)(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
#endif
#ifdef LWIP_DEBUG
typedef enum tcp_state (*altcp_dbg_get_tcp_state_fn)(struct altcp_pcb *conn);
#endif
@@ -111,6 +116,10 @@ struct altcp_functions {
altcp_get_tcp_addrinfo_fn addrinfo;
altcp_get_ip_fn getip;
altcp_get_port_fn getport;
#if LWIP_TCP_KEEPALIVE
altcp_keepalive_disable_fn keepalive_disable;
altcp_keepalive_enable_fn keepalive_enable;
#endif
#ifdef LWIP_DEBUG
altcp_dbg_get_tcp_state_fn dbg_get_tcp_state;
#endif
@@ -133,6 +142,10 @@ void altcp_default_dealloc(struct altcp_pcb *conn);
err_t altcp_default_get_tcp_addrinfo(struct altcp_pcb *conn, int local, ip_addr_t *addr, u16_t *port);
ip_addr_t *altcp_default_get_ip(struct altcp_pcb *conn, int local);
u16_t altcp_default_get_port(struct altcp_pcb *conn, int local);
#if LWIP_TCP_KEEPALIVE
void altcp_default_keepalive_disable(struct altcp_pcb *conn);
void altcp_default_keepalive_enable(struct altcp_pcb *conn, u32_t idle, u32_t intvl, u32_t count);
#endif
#ifdef LWIP_DEBUG
enum tcp_state altcp_default_dbg_get_tcp_state(struct altcp_pcb *conn);
#endif

View File

@@ -39,6 +39,8 @@
#define LWIP_HDR_PROT_DHCP_H
#include "lwip/opt.h"
#include "lwip/arch.h"
#include "lwip/prot/ip4.h"
#ifdef __cplusplus
extern "C" {

View File

@@ -41,6 +41,10 @@
#ifndef LWIP_HDR_PROT_IANA_H
#define LWIP_HDR_PROT_IANA_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup iana
* Hardware types
@@ -86,4 +90,8 @@ enum lwip_iana_port_number {
LWIP_IANA_PORT_SECURE_MQTT = 8883
};
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_PROT_IANA_H */

View File

@@ -146,6 +146,8 @@ PACK_STRUCT_END
# include "arch/epstruct.h"
#endif
#define ICMP6_HLEN 8
/** This is the ICMP6 header adapted for echo req/resp. */
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"

View File

@@ -41,6 +41,10 @@
#ifndef LWIP_HDR_PROT_IEEE_H
#define LWIP_HDR_PROT_IEEE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ingroup ieee
* A list of often ethtypes (although lwIP does not use all of them).
@@ -80,4 +84,8 @@ enum lwip_ieee_eth_type {
ETHTYPE_QINQ = 0x9100U
};
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_PROT_IEEE_H */

View File

@@ -38,7 +38,7 @@
#define LWIP_HDR_PROT_IGMP_H
#include "lwip/arch.h"
#include "lwip/ip4_addr.h"
#include "lwip/prot/ip4.h"
#ifdef __cplusplus
extern "C" {

View File

@@ -39,6 +39,10 @@
#include "lwip/arch.h"
#ifdef __cplusplus
extern "C" {
#endif
#define IP_PROTO_ICMP 1
#define IP_PROTO_IGMP 2
#define IP_PROTO_UDP 17
@@ -48,4 +52,8 @@
/** This operates on a void* by loading the first byte */
#define IP_HDR_GET_VERSION(ptr) ((*(u8_t*)(ptr)) >> 4)
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_PROT_IP_H */

View File

@@ -43,7 +43,9 @@
#ifdef __cplusplus
extern "C" {
#endif
#define IP6_MIN_MTU_LENGTH 1280
/** This is the packed version of ip6_addr_t,
used in network headers that are itself packed */
#ifdef PACK_STRUCT_USE_INCLUDES

View File

@@ -42,6 +42,10 @@
#include "lwip/err.h"
#include "lwip/prot/ethernet.h"
#ifdef __cplusplus
extern "C" {
#endif
struct netif;
#if (BRIDGEIF_MAX_PORTS < 0) || (BRIDGEIF_MAX_PORTS >= 64)
@@ -116,4 +120,8 @@ void* bridgeif_fdb_init(u16_t max_fdb_entries);
#define BRIDGEIF_WRITE_UNPROTECT(lev)
#endif /* BRIDGEIF_PORT_NETIFS_OUTPUT_DIRECT */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_NETIF_BRIDGEIF_H */

View File

@@ -39,6 +39,10 @@
#include "lwip/opt.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
@@ -101,5 +105,8 @@ PACK_STRUCT_END
#define IEEE_802154_FC_SRC_ADDR_MODE_SHORT (IEEE_802154_ADDR_MODE_SHORT << 14)
#define IEEE_802154_FC_SRC_ADDR_MODE_EXT (IEEE_802154_ADDR_MODE_EXT << 14)
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_NETIF_IEEE802154_H */

View File

@@ -36,6 +36,10 @@
#ifndef CCP_H
#define CCP_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* CCP codes.
*/
@@ -152,5 +156,9 @@ extern const struct protent ccp_protent;
void ccp_resetrequest(ppp_pcb *pcb); /* Issue a reset-request. */
#ifdef __cplusplus
}
#endif
#endif /* CCP_H */
#endif /* PPP_SUPPORT && CCP_SUPPORT */

View File

@@ -36,6 +36,10 @@
#include "ppp.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* CHAP packets begin with a standard header with code, id, len (2 bytes).
*/
@@ -188,5 +192,9 @@ extern void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_c
/* Represents the CHAP protocol to the main pppd code */
extern const struct protent chap_protent;
#ifdef __cplusplus
}
#endif
#endif /* CHAP_H */
#endif /* PPP_SUPPORT && CHAP_SUPPORT */

View File

@@ -34,6 +34,13 @@
#include "netif/ppp/ppp_opts.h"
#if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */
#ifndef ECP_H
#define ECP_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ecp_options {
bool required; /* Is ECP required? */
unsigned enctype; /* Encryption type */
@@ -47,4 +54,9 @@ extern ecp_options ecp_hisoptions[];
extern const struct protent ecp_protent;
#ifdef __cplusplus
}
#endif
#endif /* ECP_H */
#endif /* PPP_SUPPORT && ECP_SUPPORT */

View File

@@ -41,6 +41,10 @@
#ifndef EUI64_H
#define EUI64_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* @todo:
*
@@ -90,5 +94,9 @@ typedef union
char *eui64_ntoa(eui64_t); /* Returns ascii representation of id */
#ifdef __cplusplus
}
#endif
#endif /* EUI64_H */
#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */

View File

@@ -50,6 +50,10 @@
#include "ppp.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Packet header = Code, id, length.
*/
@@ -170,6 +174,9 @@ void fsm_input(fsm *f, u_char *inpacket, int l);
void fsm_protreject(fsm *f);
void fsm_sdata(fsm *f, u_char code, u_char id, const u_char *data, int datalen);
#ifdef __cplusplus
}
#endif
#endif /* FSM_H */
#endif /* PPP_SUPPORT */

View File

@@ -48,6 +48,10 @@
#ifndef IPCP_H
#define IPCP_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Options.
*/
@@ -122,5 +126,9 @@ char *ip_ntoa (u32_t);
extern const struct protent ipcp_protent;
#ifdef __cplusplus
}
#endif
#endif /* IPCP_H */
#endif /* PPP_SUPPORT && PPP_IPV4_SUPPORT */

View File

@@ -146,6 +146,10 @@
#include "eui64.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Options.
*/
@@ -179,5 +183,9 @@ typedef struct ipv6cp_options {
extern const struct protent ipv6cp_protent;
#ifdef __cplusplus
}
#endif
#endif /* IPV6CP_H */
#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */

View File

@@ -50,6 +50,10 @@
#include "ppp.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Options.
*/
@@ -167,5 +171,9 @@ extern const struct protent lcp_protent;
#define DEFLOOPBACKFAIL 10
#endif /* moved to ppp_opts.h */
#ifdef __cplusplus
}
#endif
#endif /* LCP_H */
#endif /* PPP_SUPPORT */

View File

@@ -80,6 +80,10 @@
#ifndef MAGIC_H
#define MAGIC_H
#ifdef __cplusplus
extern "C" {
#endif
/***********************
*** PUBLIC FUNCTIONS ***
***********************/
@@ -117,6 +121,10 @@ void magic_random_bytes(unsigned char *buf, u32_t buf_len);
*/
u32_t magic_pow(u8_t pow);
#ifdef __cplusplus
}
#endif
#endif /* MAGIC_H */
#endif /* PPP_SUPPORT */

View File

@@ -41,6 +41,10 @@
#include "netif/ppp/pppcrypt.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MPPE_PAD 4 /* MPPE growth per frame */
#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */
@@ -169,5 +173,9 @@ err_t mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t
void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state);
err_t mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb);
#ifdef __cplusplus
}
#endif
#endif /* MPPE_H */
#endif /* PPP_SUPPORT && MPPE_SUPPORT */

View File

@@ -47,6 +47,10 @@
#include "lwip/ip6_addr.h"
#endif /* PPP_IPV6_SUPPORT */
#ifdef __cplusplus
extern "C" {
#endif
/* Disable non-working or rarely used PPP feature, so rarely that we don't want to bloat ppp_opts.h with them */
#ifndef PPP_OPTIONS
#define PPP_OPTIONS 0
@@ -685,6 +689,10 @@ err_t ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg);
#define ppp_set_netif_linkcallback(ppp, link_cb) \
netif_set_link_callback(ppp->netif, link_cb);
#ifdef __cplusplus
}
#endif
#endif /* PPP_H */
#endif /* PPP_SUPPORT */

View File

@@ -53,6 +53,10 @@
#include "ppp.h"
#include "pppdebug.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Memory used for control packets.
*
@@ -710,5 +714,9 @@ void ppp_dump_packet(ppp_pcb *pcb, const char *tag, unsigned char *p, int len);
* 1 + PPP_IPV4_SUPPORT + PPP_IPV6_SUPPORT + CCP_SUPPORT
*/
#ifdef __cplusplus
}
#endif
#endif /* PPP_SUPPORT */
#endif /* LWIP_HDR_PPP_IMPL_H */

View File

@@ -44,6 +44,13 @@
#define PPPOE_SUPPORT 0
#endif
/**
* PPPOE_SCNAME_SUPPORT==1: Enable PPP Over Ethernet Service Name and Concentrator Name support
*/
#ifndef PPPOE_SCNAME_SUPPORT
#define PPPOE_SCNAME_SUPPORT 0
#endif
/**
* PPPOL2TP_SUPPORT==1: Enable PPP Over L2TP
*/

View File

@@ -44,6 +44,10 @@
*/
#include "lwip/arch.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Map hashes and ciphers functions to PolarSSL
*/
@@ -131,6 +135,10 @@
void pppcrypt_56_to_64_bit_key(u_char *key, u_char *des_key);
#ifdef __cplusplus
}
#endif
#endif /* PPPCRYPT_H */
#endif /* PPP_SUPPORT */

View File

@@ -40,6 +40,10 @@
#ifndef PPPDEBUG_H
#define PPPDEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
/* Trace levels. */
#define LOG_CRITICAL (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE)
#define LOG_ERR (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE)
@@ -75,6 +79,10 @@
#endif /* PPP_DEBUG */
#ifdef __cplusplus
}
#endif
#endif /* PPPDEBUG_H */
#endif /* PPP_SUPPORT */

View File

@@ -76,6 +76,10 @@
#include "ppp.h"
#include "lwip/etharp.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef PACK_STRUCT_USE_INCLUDES
# include "arch/bpstruct.h"
#endif
@@ -145,10 +149,10 @@ struct pppoe_softc {
u16_t sc_session; /* PPPoE session id */
u8_t sc_state; /* discovery phase or session connected */
#ifdef PPPOE_TODO
u8_t *sc_service_name; /* if != NULL: requested name of service */
u8_t *sc_concentrator_name; /* if != NULL: requested concentrator id */
#endif /* PPPOE_TODO */
#if PPPOE_SCNAME_SUPPORT
const char *sc_service_name; /* if != NULL: requested name of service */
const char *sc_concentrator_name; /* if != NULL: requested concentrator id */
#endif /* PPPOE_SCNAME_SUPPORT */
u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */
u8_t sc_ac_cookie_len; /* length of cookie data */
#ifdef PPPOE_SERVER
@@ -174,6 +178,10 @@ ppp_pcb *pppoe_create(struct netif *pppif,
void pppoe_disc_input(struct netif *netif, struct pbuf *p);
void pppoe_data_input(struct netif *netif, struct pbuf *p);
#ifdef __cplusplus
}
#endif
#endif /* PPP_OE_H */
#endif /* PPP_SUPPORT && PPPOE_SUPPORT */

View File

@@ -39,6 +39,10 @@
#include "ppp.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Timeout */
#define PPPOL2TP_CONTROL_TIMEOUT (5*1000) /* base for quick timeout calculation */
#define PPPOL2TP_SLOW_RETRY (60*1000) /* persistent retry interval */
@@ -197,5 +201,9 @@ ppp_pcb *pppol2tp_create(struct netif *pppif,
const u8_t *secret, u8_t secret_len,
ppp_link_status_cb_fn link_status_cb, void *ctx_cb);
#ifdef __cplusplus
}
#endif
#endif /* PPPOL2TP_H */
#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */

View File

@@ -42,6 +42,10 @@
#include "ppp.h"
#include "vj.h"
#ifdef __cplusplus
extern "C" {
#endif
/* PPP packet parser states. Current state indicates operation yet to be
* completed. */
enum {
@@ -114,5 +118,9 @@ void pppos_input(ppp_pcb *ppp, u8_t* data, int len);
err_t pppos_input_sys(struct pbuf *p, struct netif *inp);
#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */
#ifdef __cplusplus
}
#endif
#endif /* PPPOS_H */
#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */

Some files were not shown because too many files have changed in this diff Show More