Compare commits
166 Commits
STABLE-2_1
...
STABLE-2_1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ca936f6b5 | ||
|
|
e7b74570d9 | ||
|
|
018c64ab94 | ||
|
|
7e92fb3d7f | ||
|
|
051fbea5e6 | ||
|
|
214e2d90f3 | ||
|
|
4022a19cbc | ||
|
|
a32ea1e793 | ||
|
|
f67f2692d4 | ||
|
|
3b745f7154 | ||
|
|
d876d3c4df | ||
|
|
e8b0c52806 | ||
|
|
5bd7518343 | ||
|
|
51265f3f7d | ||
|
|
2e4932f23b | ||
|
|
dbd0bc8a2c | ||
|
|
e5627ec649 | ||
|
|
5c8fd3158d | ||
|
|
d5843944cc | ||
|
|
f62be85576 | ||
|
|
f1bd63046e | ||
|
|
ed6c951a19 | ||
|
|
ad9e7a6d87 | ||
|
|
6f7b26b1a8 | ||
|
|
ecd6009a5e | ||
|
|
6ffe30d9ba | ||
|
|
8f5a0aaacb | ||
|
|
ba3b04e7fe | ||
|
|
379d55044e | ||
|
|
843a116155 | ||
|
|
1c6202c414 | ||
|
|
066a2b022d | ||
|
|
aca41b0beb | ||
|
|
b5e8ab6c15 | ||
|
|
896c8a9f72 | ||
|
|
59ecea3d8c | ||
|
|
b1f8ce8769 | ||
|
|
8c43d83689 | ||
|
|
87d44bbfcd | ||
|
|
07d3b3330d | ||
|
|
61349cf124 | ||
|
|
7316b26740 | ||
|
|
d4b3a006dc | ||
|
|
2f8886794f | ||
|
|
02ab8c91a9 | ||
|
|
74ea1e43ca | ||
|
|
e9000658fb | ||
|
|
d58e0f1a1a | ||
|
|
674c4ed080 | ||
|
|
a68d6f1a9a | ||
|
|
c0643e21ed | ||
|
|
3fbb84f950 | ||
|
|
053f5aa10d | ||
|
|
6b9264b49e | ||
|
|
e60f9bb24f | ||
|
|
1bb6e7f52d | ||
|
|
108ca1521e | ||
|
|
ea2bb9cd5b | ||
|
|
e6d05db86f | ||
|
|
d1f920a7d1 | ||
|
|
fee64d7515 | ||
|
|
aad77fcacb | ||
|
|
bebf072b77 | ||
|
|
7f53f7ced4 | ||
|
|
91a4d59eb4 | ||
|
|
1bd34ea364 | ||
|
|
a9a215c52e | ||
|
|
5cea646b12 | ||
|
|
ff14bbb3c1 | ||
|
|
89be04ce7a | ||
|
|
4b3c59e4cc | ||
|
|
beeb300c18 | ||
|
|
79732693f3 | ||
|
|
ef3d12c60e | ||
|
|
608a2f9741 | ||
|
|
174cc87227 | ||
|
|
0d6d8922f2 | ||
|
|
67350e3c01 | ||
|
|
1a6455bc25 | ||
|
|
e1528e084d | ||
|
|
1892f445e2 | ||
|
|
484f0fbafa | ||
|
|
5378fd84df | ||
|
|
9d8b8d9c69 | ||
|
|
cd91647999 | ||
|
|
5cc46d7989 | ||
|
|
fe4395336a | ||
|
|
9d97a467ca | ||
|
|
039056370d | ||
|
|
159e31b689 | ||
|
|
17c60d2728 | ||
|
|
52e75369c1 | ||
|
|
66706f469d | ||
|
|
98d1cb1c00 | ||
|
|
1940cae827 | ||
|
|
d184463e2a | ||
|
|
3b53b6e481 | ||
|
|
78ee1ee2cf | ||
|
|
422623a87b | ||
|
|
4aa6df7633 | ||
|
|
2d2336014c | ||
|
|
def427bcaf | ||
|
|
ba3a39957d | ||
|
|
f58324b576 | ||
|
|
205cd7c1f6 | ||
|
|
398333da9a | ||
|
|
e678219bdf | ||
|
|
830217ac78 | ||
|
|
e4db22d9f5 | ||
|
|
c8e9772cd0 | ||
|
|
437b11f869 | ||
|
|
b7bee87fb5 | ||
|
|
2f3ef94ad4 | ||
|
|
7154e51ff2 | ||
|
|
db46863f75 | ||
|
|
ebb0dc14a7 | ||
|
|
368128a647 | ||
|
|
bc25863d1b | ||
|
|
130f947037 | ||
|
|
e6a8415df3 | ||
|
|
54a8112eb9 | ||
|
|
b9fc8cae68 | ||
|
|
a044c807f8 | ||
|
|
6229f9ef71 | ||
|
|
66838a70f3 | ||
|
|
dea74a24aa | ||
|
|
effdeef2fe | ||
|
|
c18df357d9 | ||
|
|
74c5ac7302 | ||
|
|
0189e7b02f | ||
|
|
796f98beb2 | ||
|
|
fc24d4139f | ||
|
|
bbf80b05c8 | ||
|
|
bc48eb512e | ||
|
|
cdfa3dfa9d | ||
|
|
be18fa98e4 | ||
|
|
257dc1d6fd | ||
|
|
236d6df495 | ||
|
|
93b2074f2b | ||
|
|
7749088a83 | ||
|
|
24fc93e12f | ||
|
|
264b89764d | ||
|
|
fa3826a1d3 | ||
|
|
dac4cb05f7 | ||
|
|
7b7bc349ae | ||
|
|
bcd6c8a2d3 | ||
|
|
0674aa60fe | ||
|
|
e351937ea4 | ||
|
|
e8683ea9df | ||
|
|
6363edc1db | ||
|
|
a19ea8b8d6 | ||
|
|
aafc0adfe1 | ||
|
|
298951c738 | ||
|
|
258cab1b22 | ||
|
|
c3d8b1ca80 | ||
|
|
b5b31d86b2 | ||
|
|
5bef7ea72f | ||
|
|
633205ba78 | ||
|
|
eeb2218b3d | ||
|
|
0985e925a1 | ||
|
|
cffb5cc087 | ||
|
|
8b4a8159a8 | ||
|
|
4e74421dac | ||
|
|
cd1dd4f5b1 | ||
|
|
8841fdc8ea | ||
|
|
02d6716ffd |
6
.gitattributes
vendored
6
.gitattributes
vendored
@@ -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
242
CHANGELOG
@@ -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:
|
||||
|
||||
@@ -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
11
FEATURES
Normal 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
22
README
@@ -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
|
||||
|
||||
35
UPGRADING
35
UPGRADING
@@ -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)
|
||||
|
||||
|
||||
22
astylerc
22
astylerc
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
121
src/core/altcp.c
121
src/core/altcp.c
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 &&
|
||||
|
||||
@@ -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;);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -72,7 +72,7 @@ extern "C" {
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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" {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user