Last active
April 24, 2020 07:42
-
-
Save wongsyrone/2a2c134e8f927364e598d2a6e706f4a8 to your computer and use it in GitHub Desktop.
badvpn change to Lwip 1.4(.1 maybe)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c | |
index 4b38999c..1acc2558 100644 | |
--- a/src/core/ipv4/ip4.c | |
+++ b/src/core/ipv4/ip4.c | |
@@ -473,6 +473,12 @@ ip_input(struct pbuf *p, struct netif *inp) | |
} | |
} | |
+ /* if we're pretending we are everyone for TCP, assume the packet is for source interface if it | |
+ isn't for a local address */ | |
+ if (netif == NULL && (inp->flags & NETIF_FLAG_PRETEND_TCP) && IPH_PROTO(iphdr) == IP_PROTO_TCP) { | |
+ netif = inp; | |
+ } | |
+ | |
/* packet not for us? */ | |
if (netif == NULL) { | |
/* packet not for us, route or discard */ | |
diff --git a/src/core/ipv6/ip6.c b/src/core/ipv6/ip6.c | |
index 94e423a2..1eb91f96 100644 | |
--- a/src/core/ipv6/ip6.c | |
+++ b/src/core/ipv6/ip6.c | |
@@ -477,6 +477,12 @@ netif_found: | |
IP6_STATS_INC(ip6.drop); | |
goto ip6_input_cleanup; | |
} | |
+ | |
+ /* if we're pretending we are everyone for TCP, assume the packet is for source interface if it | |
+ isn't for a local address */ | |
+ if (netif == NULL && (inp->flags & NETIF_FLAG_PRETEND_TCP) && IP6H_NEXTH(ip6hdr) == IP6_NEXTH_TCP) { | |
+ netif = inp; | |
+ } | |
/* packet not for us? */ | |
if (netif == NULL) { | |
diff --git a/src/core/ipv6/nd6.c b/src/core/ipv6/nd6.c | |
index 44629dbe..513db985 100644 | |
--- a/src/core/ipv6/nd6.c | |
+++ b/src/core/ipv6/nd6.c | |
@@ -621,7 +621,10 @@ nd6_input(struct pbuf *p, struct netif *inp) | |
void | |
nd6_tmr(void) | |
{ | |
- s8_t i, j; | |
+ s8_t i; | |
+#if LWIP_IPV6_AUTOCONFIG | |
+ s8_t j; | |
+#endif | |
struct netif * netif; | |
/* Process neighbor entries. */ | |
@@ -1397,7 +1400,9 @@ nd6_new_onlink_prefix(ip6_addr_t * prefix, struct netif * netif) | |
/* Found empty prefix entry. */ | |
prefix_list[i].netif = netif; | |
ip6_addr_set(&(prefix_list[i].prefix), prefix); | |
+#if LWIP_IPV6_AUTOCONFIG | |
prefix_list[i].flags = 0; | |
+#endif | |
return i; | |
} | |
} | |
diff --git a/src/core/netif.c b/src/core/netif.c | |
index f8133f76..dcc87580 100644 | |
--- a/src/core/netif.c | |
+++ b/src/core/netif.c | |
@@ -349,6 +349,13 @@ netif_find(char *name) | |
return NULL; | |
} | |
+int netif_is_named (struct netif *netif, const char name[3]) | |
+{ | |
+ u8_t num = name[2] - '0'; | |
+ | |
+ return (!memcmp(netif->name, name, 2) && netif->num == num); | |
+} | |
+ | |
/** | |
* Change the IP address of a network interface | |
* | |
@@ -435,6 +442,15 @@ netif_set_gw(struct netif *netif, ip_addr_t *gw) | |
ip4_addr4_16(&netif->gw))); | |
} | |
+void netif_set_pretend_tcp (struct netif *netif, u8_t pretend) | |
+{ | |
+ if (pretend) { | |
+ netif->flags |= NETIF_FLAG_PRETEND_TCP; | |
+ } else { | |
+ netif->flags &= ~NETIF_FLAG_PRETEND_TCP; | |
+ } | |
+} | |
+ | |
/** | |
* Change the netmask of a network interface | |
* | |
@@ -842,7 +858,7 @@ netif_matches_ip6_addr(struct netif * netif, ip6_addr_t * ip6addr) | |
void | |
netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit) | |
{ | |
- u8_t i, addr_index; | |
+ u8_t i, addr_index, min_len; | |
/* Link-local prefix. */ | |
netif->ip6_addr[0].addr[0] = PP_HTONL(0xfe800000ul); | |
@@ -865,8 +881,9 @@ netif_create_ip6_linklocal_address(struct netif * netif, u8_t from_mac_48bit) | |
netif->ip6_addr[0].addr[2] = 0; | |
netif->ip6_addr[0].addr[3] = 0; | |
+ min_len = netif->hwaddr_len < 8 ? netif->hwaddr_len : 8; | |
addr_index = 3; | |
- for (i = 0; i < 8; i++) { | |
+ for (i = 0; i < min_len; i++) { | |
if (i == 4) { | |
addr_index--; | |
} | |
diff --git a/src/core/tcp.c b/src/core/tcp.c | |
index a0cbb159..55496d05 100644 | |
--- a/src/core/tcp.c | |
+++ b/src/core/tcp.c | |
@@ -209,7 +209,7 @@ tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) | |
* is erroneous, but this should never happen as the pcb has in those cases | |
* been freed, and so any remaining handles are bogus. */ | |
err = ERR_OK; | |
- if (pcb->local_port != 0) { | |
+ if (pcb->local_port != 0 || pcb->bound_to_netif) { | |
TCP_RMV(&tcp_bound_pcbs, pcb); | |
} | |
memp_free(MEMP_TCP_PCB, pcb); | |
@@ -484,6 +484,7 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) | |
} | |
} | |
+ pcb->bound_to_netif = 0; | |
if (!ipX_addr_isany(PCB_ISIPV6(pcb), ip_2_ipX(ipaddr))) { | |
ipX_addr_set(PCB_ISIPV6(pcb), &pcb->local_ip, ip_2_ipX(ipaddr)); | |
} | |
@@ -492,6 +493,32 @@ tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port) | |
LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); | |
return ERR_OK; | |
} | |
+ | |
+err_t | |
+tcp_bind_to_netif(struct tcp_pcb *pcb, const char ifname[3]) | |
+{ | |
+ LWIP_ERROR("tcp_bind_if: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); | |
+ | |
+ /* Check if the interface is already in use */ | |
+ for (int i = 0; i < NUM_TCP_PCB_LISTS; i++) { | |
+ for(struct tcp_pcb *cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { | |
+ if (IP_PCB_IPVER_EQ(pcb, cpcb) && | |
+ cpcb->bound_to_netif && | |
+ !memcmp(cpcb->local_netif, ifname, sizeof(cpcb->local_netif))) { | |
+ return ERR_USE; | |
+ } | |
+ } | |
+ } | |
+ | |
+ pcb->bound_to_netif = 1; | |
+ ipX_addr_set_any(PCB_ISIPV6(pcb), &pcb->local_ip); | |
+ pcb->local_port = 0; | |
+ memcpy(pcb->local_netif, ifname, sizeof(pcb->local_netif)); | |
+ TCP_REG(&tcp_bound_pcbs, pcb); | |
+ LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind_to_netif: bind to interface %c%c%c\n", ifname[0], ifname[1], ifname[2])); | |
+ return ERR_OK; | |
+} | |
+ | |
#if LWIP_CALLBACK_API | |
/** | |
* Default accept callback if no accept callback is specified by the user. | |
@@ -534,7 +561,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) | |
return pcb; | |
} | |
#if SO_REUSE | |
- if (ip_get_option(pcb, SOF_REUSEADDR)) { | |
+ if (ip_get_option(pcb, SOF_REUSEADDR) && !pcb->have_local_netif) { | |
/* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage | |
is declared (listen-/connection-pcb), we have to make sure now that | |
this port is only used once for every local IP. */ | |
@@ -554,7 +581,9 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) | |
return NULL; | |
} | |
lpcb->callback_arg = pcb->callback_arg; | |
+ lpcb->bound_to_netif = pcb->bound_to_netif; | |
lpcb->local_port = pcb->local_port; | |
+ memcpy(lpcb->local_netif, pcb->local_netif, sizeof(pcb->local_netif)); | |
lpcb->state = LISTEN; | |
lpcb->prio = pcb->prio; | |
lpcb->so_options = pcb->so_options; | |
@@ -566,7 +595,7 @@ tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) | |
lpcb->accept_any_ip_version = 0; | |
#endif /* LWIP_IPV6 */ | |
ipX_addr_copy(PCB_ISIPV6(pcb), lpcb->local_ip, pcb->local_ip); | |
- if (pcb->local_port != 0) { | |
+ if (pcb->local_port != 0 || pcb->bound_to_netif) { | |
TCP_RMV(&tcp_bound_pcbs, pcb); | |
} | |
memp_free(MEMP_TCP_PCB, pcb); | |
@@ -722,6 +751,7 @@ tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, u16_t port, | |
u16_t old_local_port; | |
LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); | |
+ LWIP_ERROR("tcp_connect: cannot connect pcb bound to netif", !pcb->bound_to_netif, return ERR_VAL); | |
LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); | |
if (ipaddr != NULL) { | |
@@ -1536,16 +1566,19 @@ tcp_pcb_purge(struct tcp_pcb *pcb) | |
LWIP_ASSERT("tcp_pcb_purge: pcb->state == SYN_RCVD but tcp_listen_pcbs is NULL", | |
tcp_listen_pcbs.listen_pcbs != NULL); | |
for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { | |
- if ((lpcb->local_port == pcb->local_port) && | |
- IP_PCB_IPVER_EQ(pcb, lpcb) && | |
- (ipX_addr_isany(PCB_ISIPV6(lpcb), &lpcb->local_ip) || | |
- ipX_addr_cmp(PCB_ISIPV6(lpcb), &pcb->local_ip, &lpcb->local_ip))) { | |
+ if ((!lpcb->bound_to_netif && !pcb->bound_to_netif && | |
+ (lpcb->local_port == pcb->local_port) && | |
+ IP_PCB_IPVER_EQ(pcb, lpcb) && | |
+ (ipX_addr_isany(PCB_ISIPV6(lpcb), &lpcb->local_ip) || | |
+ ipX_addr_cmp(PCB_ISIPV6(lpcb), &pcb->local_ip, &lpcb->local_ip))) || | |
+ (lpcb->bound_to_netif && pcb->bound_to_netif && | |
+ !memcmp(lpcb->local_netif, pcb->local_netif, sizeof(pcb->local_netif)))) { | |
/* port and address of the listen pcb match the timed-out pcb */ | |
LWIP_ASSERT("tcp_pcb_purge: listen pcb does not have accepts pending", | |
lpcb->accepts_pending > 0); | |
lpcb->accepts_pending--; | |
break; | |
- } | |
+ } | |
} | |
} | |
#endif /* TCP_LISTEN_BACKLOG */ | |
diff --git a/src/core/tcp_in.c b/src/core/tcp_in.c | |
index dacf5cf9..6c382d06 100644 | |
--- a/src/core/tcp_in.c | |
+++ b/src/core/tcp_in.c | |
@@ -219,8 +219,16 @@ tcp_input(struct pbuf *p, struct netif *inp) | |
/* Finally, if we still did not get a match, we check all PCBs that | |
are LISTENing for incoming connections. */ | |
prev = NULL; | |
+ struct tcp_pcb_listen *netif_pcb = NULL; | |
+ struct tcp_pcb *netif_pcb_prev = NULL; | |
for(lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { | |
- if (lpcb->local_port == tcphdr->dest) { | |
+ if (lpcb->bound_to_netif) { | |
+ if (IP_PCB_IPVER_INPUT_MATCH(lpcb) && netif_is_named(inp, lpcb->local_netif)) { | |
+ netif_pcb = lpcb; | |
+ netif_pcb_prev = prev; | |
+ } | |
+ } | |
+ else if (lpcb->local_port == tcphdr->dest) { | |
#if LWIP_IPV6 | |
if (lpcb->accept_any_ip_version) { | |
/* found an ANY-match */ | |
@@ -257,6 +265,10 @@ tcp_input(struct pbuf *p, struct netif *inp) | |
prev = lpcb_prev; | |
} | |
#endif /* SO_REUSE */ | |
+ if (lpcb == NULL && netif_pcb) { | |
+ lpcb = netif_pcb; | |
+ prev = netif_pcb_prev; | |
+ } | |
if (lpcb != NULL) { | |
/* Move this PCB to the front of the list so that subsequent | |
lookups will be faster (we exploit locality in TCP segment | |
@@ -495,7 +507,9 @@ tcp_listen_input(struct tcp_pcb_listen *pcb) | |
#endif /* LWIP_IPV6 */ | |
ipX_addr_copy(ip_current_is_v6(), npcb->local_ip, *ipX_current_dest_addr()); | |
ipX_addr_copy(ip_current_is_v6(), npcb->remote_ip, *ipX_current_src_addr()); | |
- npcb->local_port = pcb->local_port; | |
+ npcb->bound_to_netif = pcb->bound_to_netif; | |
+ npcb->local_port = tcphdr->dest; | |
+ memcpy(npcb->local_netif, pcb->local_netif, sizeof(pcb->local_netif)); | |
npcb->remote_port = tcphdr->src; | |
npcb->state = SYN_RCVD; | |
npcb->rcv_nxt = seqno + 1; | |
diff --git a/src/include/lwip/arch.h b/src/include/lwip/arch.h | |
index 4d6df773..101a7530 100644 | |
--- a/src/include/lwip/arch.h | |
+++ b/src/include/lwip/arch.h | |
@@ -32,6 +32,8 @@ | |
#ifndef __LWIP_ARCH_H__ | |
#define __LWIP_ARCH_H__ | |
+#include "arch/cc.h" | |
+ | |
#ifndef LITTLE_ENDIAN | |
#define LITTLE_ENDIAN 1234 | |
#endif | |
@@ -40,8 +42,6 @@ | |
#define BIG_ENDIAN 4321 | |
#endif | |
-#include "arch/cc.h" | |
- | |
/** Temporary: define format string for size_t if not defined in cc.h */ | |
#ifndef SZT_F | |
#define SZT_F U32_F | |
diff --git a/src/include/lwip/netif.h b/src/include/lwip/netif.h | |
index 322d2d0e..f9770324 100644 | |
--- a/src/include/lwip/netif.h | |
+++ b/src/include/lwip/netif.h | |
@@ -97,6 +97,9 @@ extern "C" { | |
/** If set, the netif has IGMP capability. | |
* Set by the netif driver in its init function. */ | |
#define NETIF_FLAG_IGMP 0x80U | |
+/** Whether to pretend that we are every host for TCP packets. | |
+ * Set by netif_set_pretend_tcp. */ | |
+#define NETIF_FLAG_PRETEND_TCP 0x100U | |
/** Function prototype for netif init functions. Set up flags and output/linkoutput | |
* callback functions in this function. | |
@@ -235,7 +238,7 @@ struct netif { | |
/** link level hardware address of this interface */ | |
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; | |
/** flags (see NETIF_FLAG_ above) */ | |
- u8_t flags; | |
+ u16_t flags; | |
/** descriptive abbreviation */ | |
char name[2]; | |
/** number of this interface */ | |
@@ -321,11 +324,14 @@ void netif_remove(struct netif * netif); | |
structure. */ | |
struct netif *netif_find(char *name); | |
+int netif_is_named (struct netif *netif, const char name[3]); | |
+ | |
void netif_set_default(struct netif *netif); | |
void netif_set_ipaddr(struct netif *netif, ip_addr_t *ipaddr); | |
void netif_set_netmask(struct netif *netif, ip_addr_t *netmask); | |
void netif_set_gw(struct netif *netif, ip_addr_t *gw); | |
+void netif_set_pretend_tcp(struct netif *netif, u8_t pretend); | |
void netif_set_up(struct netif *netif); | |
void netif_set_down(struct netif *netif); | |
diff --git a/src/include/lwip/tcp.h b/src/include/lwip/tcp.h | |
index 0ab301f0..535b6a38 100644 | |
--- a/src/include/lwip/tcp.h | |
+++ b/src/include/lwip/tcp.h | |
@@ -163,7 +163,9 @@ enum tcp_state { | |
enum tcp_state state; /* TCP state */ \ | |
u8_t prio; \ | |
/* ports are in host byte order */ \ | |
- u16_t local_port | |
+ int bound_to_netif; \ | |
+ u16_t local_port; \ | |
+ char local_netif[3] | |
/* the TCP protocol control block */ | |
@@ -346,6 +348,7 @@ void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); | |
void tcp_recved (struct tcp_pcb *pcb, u16_t len); | |
err_t tcp_bind (struct tcp_pcb *pcb, ip_addr_t *ipaddr, | |
u16_t port); | |
+err_t tcp_bind_to_netif (struct tcp_pcb *pcb, const char ifname[3]); | |
err_t tcp_connect (struct tcp_pcb *pcb, ip_addr_t *ipaddr, | |
u16_t port, tcp_connected_fn connected); | |
diff --git a/src/include/netif/etharp.h b/src/include/netif/etharp.h | |
index 92d57ae4..8275a28f 100644 | |
--- a/src/include/netif/etharp.h | |
+++ b/src/include/netif/etharp.h | |
@@ -214,10 +214,10 @@ err_t ethernet_input(struct pbuf *p, struct netif *netif); | |
extern const struct eth_addr ethbroadcast, ethzero; | |
-#endif /* LWIP_ARP || LWIP_ETHERNET */ | |
- | |
#ifdef __cplusplus | |
} | |
#endif | |
+#endif /* LWIP_ARP || LWIP_ETHERNET */ | |
+ | |
#endif /* __NETIF_ARP_H__ */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And a patch for lwip 1710fc1a89578dfaaff684a1aafbc4d16e346f79 and later