mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-18 20:10:53 +00:00
Add hook for TCP Initial Sequence Number generation
lwIP produces a TCP Initial Sequence Number (ISN) for each new TCP connection. The current algorithm is simple and predictable however. The result is that lwIP TCP connections may be the target of TCP spoofing attacks. The problem of such attacks is well known, and a recommended ISN generation algorithm is standardized in RFC 6528. This algorithm requires a high-resolution timer and cryptographic hashing function, though. The implementation (or best-effort approximation) of both of these aspects is well beyond the scope of lwIP itself. For that reason, this patch adds LWIP_HOOK_TCP_ISN, a hook that allows each platform to implement its own ISN generation using locally available means. The hook provides full flexibility, in that the hook may generate anything from a simple random number (by being set to LWIP_RAND()) to a full RFC 6528 implementation. Implementation note: Users of the hook would typically declare the function prototype of the hook function in arch/cc.h, as this is the last place where such prototypes can be supplied. However, at that point, the ip_addr_t type has not yet been defined. For that reason, this patch removes the leading underscore from "struct _ip_addr", so that a prototype of the hook function can use "struct ip_addr" instead of "ip_addr_t". Signed-off-by: sg <goldsimon@gmx.de>
This commit is contained in:
parent
da15132aa0
commit
a8b986bbb6
@ -880,10 +880,11 @@ tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port,
|
||||
#endif /* SO_REUSE */
|
||||
}
|
||||
|
||||
iss = tcp_next_iss();
|
||||
iss = tcp_next_iss(pcb);
|
||||
pcb->rcv_nxt = 0;
|
||||
pcb->snd_nxt = iss;
|
||||
pcb->lastack = iss - 1;
|
||||
pcb->snd_wl2 = iss - 1;
|
||||
pcb->snd_lbb = iss - 1;
|
||||
/* Start with a window that does not need scaling. When window scaling is
|
||||
enabled and used, the window is enlarged when both sides agree on scaling. */
|
||||
@ -1491,7 +1492,6 @@ struct tcp_pcb *
|
||||
tcp_alloc(u8_t prio)
|
||||
{
|
||||
struct tcp_pcb *pcb;
|
||||
u32_t iss;
|
||||
|
||||
pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB);
|
||||
if (pcb == NULL) {
|
||||
@ -1554,11 +1554,6 @@ tcp_alloc(u8_t prio)
|
||||
pcb->sv = 3000 / TCP_SLOW_INTERVAL;
|
||||
pcb->rtime = -1;
|
||||
pcb->cwnd = 1;
|
||||
iss = tcp_next_iss();
|
||||
pcb->snd_wl2 = iss;
|
||||
pcb->snd_nxt = iss;
|
||||
pcb->lastack = iss;
|
||||
pcb->snd_lbb = iss;
|
||||
pcb->tmr = tcp_ticks;
|
||||
pcb->last_timer = tcp_timer_ctr;
|
||||
|
||||
@ -1826,12 +1821,18 @@ tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
|
||||
* @return u32_t pseudo random sequence number
|
||||
*/
|
||||
u32_t
|
||||
tcp_next_iss(void)
|
||||
tcp_next_iss(struct tcp_pcb *pcb)
|
||||
{
|
||||
#ifdef LWIP_HOOK_TCP_ISN
|
||||
return LWIP_HOOK_TCP_ISN(&pcb->local_ip, pcb->local_port, &pcb->remote_ip, pcb->remote_port);
|
||||
#else /* LWIP_HOOK_TCP_ISN */
|
||||
static u32_t iss = 6510;
|
||||
|
||||
LWIP_UNUSED_ARG(pcb);
|
||||
|
||||
iss += tcp_ticks; /* XXX */
|
||||
return iss;
|
||||
#endif /* LWIP_HOOK_TCP_ISN */
|
||||
}
|
||||
|
||||
#if TCP_CALCULATE_EFF_SEND_MSS
|
||||
|
@ -542,6 +542,7 @@ static void
|
||||
tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
{
|
||||
struct tcp_pcb *npcb;
|
||||
u32_t iss;
|
||||
err_t rc;
|
||||
|
||||
if (flags & TCP_RST) {
|
||||
@ -589,6 +590,11 @@ tcp_listen_input(struct tcp_pcb_listen *pcb)
|
||||
npcb->state = SYN_RCVD;
|
||||
npcb->rcv_nxt = seqno + 1;
|
||||
npcb->rcv_ann_right_edge = npcb->rcv_nxt;
|
||||
iss = tcp_next_iss(npcb);
|
||||
npcb->snd_wl2 = iss;
|
||||
npcb->snd_nxt = iss;
|
||||
npcb->lastack = iss;
|
||||
npcb->snd_lbb = iss;
|
||||
npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */
|
||||
npcb->callback_arg = pcb->callback_arg;
|
||||
#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG
|
||||
|
@ -66,7 +66,7 @@ enum lwip_ip_addr_type {
|
||||
* A union struct for both IP version's addresses.
|
||||
* ATTENTION: watch out for its size when adding IPv6 address scope!
|
||||
*/
|
||||
typedef struct _ip_addr {
|
||||
typedef struct ip_addr {
|
||||
union {
|
||||
ip6_addr_t ip6;
|
||||
ip4_addr_t ip4;
|
||||
|
@ -2410,6 +2410,29 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* LWIP_HOOK_TCP_ISN:
|
||||
* Hook for generation of the Initial Sequence Number (ISN) for a new TCP
|
||||
* connection. The default lwIP ISN generation algorithm is very basic and may
|
||||
* allow for TCP spoofing attacks. This hook provides the means to implement
|
||||
* the standardized ISN generation algorithm from RFC 6528, or any other
|
||||
* desired algorithm (e.g., it can be set to LWIP_RAND()), as a replacement.
|
||||
* Called from tcp_connect() and tcp_listen_input() when an ISN is needed for
|
||||
* a new TCP connection, if TCP support (@ref LWIP_TCP) is enabled.\n
|
||||
* Signature: u32_t my_hook_tcp_isn(const ip_addr_t* local_ip, u16_t local_port, const ip_addr_t* remote_ip, u16_t remote_port);
|
||||
* - it may be necessary to use "struct ip_addr" (ip4_addr, ip6_addr) instead of "ip_addr_t" in function declarations\n
|
||||
* Arguments:
|
||||
* - local_ip: pointer to the local IP address of the connection
|
||||
* - local_port: local port number of the connection (host-byte order)
|
||||
* - remote_ip: pointer to the remote IP address of the connection
|
||||
* - remote_port: remote port number of the connection (host-byte order)\n
|
||||
* Return value:
|
||||
* - the 32-bit Initial Sequence Number to use for the new TCP connection.
|
||||
*/
|
||||
#ifdef __DOXYGEN__
|
||||
#define LWIP_HOOK_TCP_ISN(local_ip, local_port, remote_ip, remote_port)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* LWIP_HOOK_IP4_INPUT(pbuf, input_netif):
|
||||
* - called from ip_input() (IPv4)
|
||||
|
@ -452,7 +452,7 @@ void tcp_rst(u32_t seqno, u32_t ackno,
|
||||
const ip_addr_t *local_ip, const ip_addr_t *remote_ip,
|
||||
u16_t local_port, u16_t remote_port);
|
||||
|
||||
u32_t tcp_next_iss(void);
|
||||
u32_t tcp_next_iss(struct tcp_pcb *pcb);
|
||||
|
||||
err_t tcp_keepalive(struct tcp_pcb *pcb);
|
||||
err_t tcp_zero_window_probe(struct tcp_pcb *pcb);
|
||||
|
Loading…
Reference in New Issue
Block a user