|
|
|
@ -215,6 +215,7 @@ static err_t proxy_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) { |
|
|
|
|
|
|
|
|
|
|
|
struct tcp_proxy_mapping *m = find_mapping_by_port(p, newpcb->local_port); |
|
|
|
struct tcp_proxy_mapping *m = find_mapping_by_port(p, newpcb->local_port); |
|
|
|
if (m) { memcpy(pc->dest_ip, m->remote_ip, 4); pc->dest_port = m->remote_port; } |
|
|
|
if (m) { memcpy(pc->dest_ip, m->remote_ip, 4); pc->dest_port = m->remote_port; } |
|
|
|
|
|
|
|
else { memcpy(pc->dest_ip, &newpcb->local_ip, 4); pc->dest_port = htons(newpcb->local_port); } |
|
|
|
pc->tun_ip = newpcb->local_ip; |
|
|
|
pc->tun_ip = newpcb->local_ip; |
|
|
|
|
|
|
|
|
|
|
|
tcp_arg(newpcb, pc); |
|
|
|
tcp_arg(newpcb, pc); |
|
|
|
@ -333,6 +334,24 @@ static err_t proxy_connected_cb(void *arg, struct tcp_pcb *pcb, err_t err) { |
|
|
|
return LERR_OK; |
|
|
|
return LERR_OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
|
|
|
|
// Ensure dynamic listen pcb for transparent outbound TCP proxying
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
|
|
|
|
static void tcp_proxy_ensure_outbound_listen(struct tcp_proxy* p, uint16_t dport_net) { |
|
|
|
|
|
|
|
if (!p->has_remote_mappings) return; |
|
|
|
|
|
|
|
uint16_t dport_host = ntohs(dport_net); |
|
|
|
|
|
|
|
struct tcp_pcb* lp = p->lwip->listen_pcbs; |
|
|
|
|
|
|
|
while (lp) { if (lp->local_port == dport_host) return; lp = lp->next; } |
|
|
|
|
|
|
|
struct tcp_pcb* lpcb = tcp_new(p->lwip); |
|
|
|
|
|
|
|
if (!lpcb) return; |
|
|
|
|
|
|
|
tcp_bind(lpcb, INADDR_ANY, dport_host); |
|
|
|
|
|
|
|
struct tcp_pcb* listen_pcb = tcp_listen(lpcb); |
|
|
|
|
|
|
|
if (listen_pcb) { |
|
|
|
|
|
|
|
tcp_arg(listen_pcb, p); tcp_accept(listen_pcb, proxy_accept_cb); |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "TCP proxy: dynamic listen on port %u", dport_host); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
// ====================================================================
|
|
|
|
// Input: IP packet → lwip_tcp
|
|
|
|
// Input: IP packet → lwip_tcp
|
|
|
|
// ====================================================================
|
|
|
|
// ====================================================================
|
|
|
|
@ -367,6 +386,8 @@ static void tcp_proxy_raw_read(int fd, void* arg) { |
|
|
|
uint16_t ip_hdr_len = (pkt[0] & 0x0F) * 4; |
|
|
|
uint16_t ip_hdr_len = (pkt[0] & 0x0F) * 4; |
|
|
|
uint16_t ip_total = ((uint16_t)pkt[2] << 8) | pkt[3]; |
|
|
|
uint16_t ip_total = ((uint16_t)pkt[2] << 8) | pkt[3]; |
|
|
|
if (ip_hdr_len >= 20 && ip_total >= ip_hdr_len && (size_t)ip_total <= remaining) { |
|
|
|
if (ip_hdr_len >= 20 && ip_total >= ip_hdr_len && (size_t)ip_total <= remaining) { |
|
|
|
|
|
|
|
uint16_t dport_net; memcpy(&dport_net, pkt + ip_hdr_len + 2, 2); |
|
|
|
|
|
|
|
tcp_proxy_ensure_outbound_listen(p, dport_net); |
|
|
|
uint32_t src_ip, dst_ip; |
|
|
|
uint32_t src_ip, dst_ip; |
|
|
|
memcpy(&src_ip, pkt + 12, 4); memcpy(&dst_ip, pkt + 16, 4); |
|
|
|
memcpy(&src_ip, pkt + 12, 4); memcpy(&dst_ip, pkt + 16, 4); |
|
|
|
uint16_t tcp_len = ip_total - ip_hdr_len; |
|
|
|
uint16_t tcp_len = ip_total - ip_hdr_len; |
|
|
|
@ -393,6 +414,8 @@ static void tcp_proxy_tun_input(struct ll_queue* q, void* arg) { |
|
|
|
uint16_t ip_hdr_len = (ip[0] & 0x0F) * 4; |
|
|
|
uint16_t ip_hdr_len = (ip[0] & 0x0F) * 4; |
|
|
|
uint16_t ip_total = ((uint16_t)ip[2] << 8) | ip[3]; |
|
|
|
uint16_t ip_total = ((uint16_t)ip[2] << 8) | ip[3]; |
|
|
|
if (ip_hdr_len >= 20 && ip_total >= ip_hdr_len && len >= ip_total) { |
|
|
|
if (ip_hdr_len >= 20 && ip_total >= ip_hdr_len && len >= ip_total) { |
|
|
|
|
|
|
|
uint16_t dport_net; memcpy(&dport_net, ip + ip_hdr_len + 2, 2); |
|
|
|
|
|
|
|
tcp_proxy_ensure_outbound_listen(p, dport_net); |
|
|
|
uint32_t src_ip, dst_ip; |
|
|
|
uint32_t src_ip, dst_ip; |
|
|
|
memcpy(&src_ip, ip + 12, 4); memcpy(&dst_ip, ip + 16, 4); |
|
|
|
memcpy(&src_ip, ip + 12, 4); memcpy(&dst_ip, ip + 16, 4); |
|
|
|
uint16_t tcp_len = ip_total - ip_hdr_len; |
|
|
|
uint16_t tcp_len = ip_total - ip_hdr_len; |
|
|
|
|