diff --git a/ext/lwipopts.h b/ext/lwipopts.h index 3679eb2..1daebe7 100644 --- a/ext/lwipopts.h +++ b/ext/lwipopts.h @@ -47,7 +47,7 @@ // IPV6 Related #define LWIP_IPV6 1 -#define LWIP_IPV4 0 +#define LWIP_IPV4 1 //#define LWIP_IPV6_AUTOCONFIG 1 #define IP6_DEBUG 1 diff --git a/make-linux.mk b/make-linux.mk index 6d29056..265f497 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -87,6 +87,7 @@ INCLUDES+= -Iext \ -I$(PICOTCP_DIR)/build/include +# Stack selection / parameters # lwIP debug ifeq ($(SDK_LWIP_DEBUG),1) LWIP_FLAGS+=SDK_LWIP_DEBUG=1 @@ -109,6 +110,18 @@ endif +# TCP protocol version +ifeq ($(SDK_IPV4),1) + STACK_FLAGS+=-DSDK_IPV4 +endif + +ifeq ($(SDK_IPV6),1) + STACK_FLAGS+=-DSDK_IPV6 +endif + + + + # Debug output for the SDK # Specific levels can be controlled in src/SDK_Debug.h diff --git a/src/SDK_EthernetTap.cpp b/src/SDK_EthernetTap.cpp index 7fb0a9a..4f798e0 100644 --- a/src/SDK_EthernetTap.cpp +++ b/src/SDK_EthernetTap.cpp @@ -49,6 +49,7 @@ #include "pico_ipv4.h" #include "pico_icmp4.h" #include "pico_dev_tap.h" + #include "pico_socket.h" #elif defined(SDK_JIP) #include "SDK_jip.hpp" #endif @@ -64,6 +65,8 @@ #include "lwip/api.h" #include "lwip/ip.h" #include "lwip/ip_addr.h" + #include "lwip/ip4_addr.h" + #include "lwip/tcp.h" #include "lwip/init.h" #include "lwip/mem.h" @@ -72,6 +75,10 @@ #include "lwip/udp.h" #include "lwip/tcp.h" + #include "lwip/netif.h" +#include "lwip/dhcp.h" +#include "netif/etharp.h" + //#include "lwip/etharp.h" //#include "lwip/ip_addr.h" //#include "lwip/tcp_impl.h" @@ -288,7 +295,7 @@ void NetconEthernetTap::lwIP_init_interface(const InetAddress &ip) if (ip.isV4()) { DEBUG_INFO("IPV4"); // Set IP - static ip4_addr_t ipaddr, netmask, gw; + static ip4_addr ipaddr, netmask, gw; IP4_ADDR(&gw,127,0,0,1); ipaddr.addr = *((u32_t *)ip.rawIpData()); netmask.addr = *((u32_t *)ip.netmask().rawIpData()); @@ -308,7 +315,7 @@ void NetconEthernetTap::lwIP_init_interface(const InetAddress &ip) lwipstack->__netif_set_up(&interface); } */ - +/* if(ip.isV6()) { DEBUG_INFO("IPV6"); @@ -335,6 +342,7 @@ void NetconEthernetTap::lwIP_init_interface(const InetAddress &ip) interface6.state = this; interface6.flags = NETIF_FLAG_LINK_UP | NETIF_FLAG_UP; } + */ } } @@ -350,6 +358,7 @@ void NetconEthernetTap::picoTCP_init_interface(const InetAddress &ip) if(ip.isV4()) { + /* int id; struct pico_ip4 ipaddr, netmask; ipaddr.addr = *((u32_t *)ip.rawIpData()); @@ -367,11 +376,30 @@ void NetconEthernetTap::picoTCP_init_interface(const InetAddress &ip) DEBUG_ERROR("device init failed"); return; } - DEBUG_INFO("successfully initialized device"); + DEBUG_INFO("successfully initialized device with IPV4 address"); // picostack->__pico_icmp4_ping("10.8.8.1", 20, 1000, 10000, 64, cb_ping); + */ } if(ip.isV6()) { + int id; + struct pico_ip6 ipaddr, netmask; + picostack->__pico_string_to_ipv6("fd56:5799:d8f6:1238:8c99:93b4:9d8e:24f6", ipaddr.addr); + picostack->__pico_string_to_ipv6("ffff:ffff:ffff:ffff:ffff:ff00:0000:0000", netmask.addr); + picostack->__pico_ipv6_link_add(&picodev, ipaddr, netmask); + + picodev.send = pico_eth_send; // tx + picodev.poll = pico_eth_poll; // rx + + // Register the device in picoTCP + uint8_t mac[PICO_SIZE_ETH]; + _mac.copyTo(mac, PICO_SIZE_ETH); + DEBUG_ATTN("mac = %s", _mac.toString().c_str()); + if( 0 != picostack->__pico_device_init(&picodev, "p0", mac)) { + DEBUG_ERROR("device init failed"); + return; + } + DEBUG_INFO("successfully initialized device with IPV6 address"); } } } @@ -718,9 +746,9 @@ void NetconEthernetTap::phyOnUnixClose(PhySocket *sock,void **uptr) { } -void NetconEthernetTap::processReceivedData(PhySocket *sock,void **uptr,bool lwip_invoked) +void NetconEthernetTap::handleRead(PhySocket *sock,void **uptr,bool lwip_invoked) { - //DEBUG_EXTRA("processReceivedData(sock=%p): lwip_invoked = %d\n", (void*)&sock, lwip_invoked); + //DEBUG_EXTRA("handleRead(sock=%p): lwip_invoked = %d\n", (void*)&sock, lwip_invoked); if(!lwip_invoked) { _tcpconns_m.lock(); _rx_buf_m.lock(); @@ -780,7 +808,7 @@ void NetconEthernetTap::processReceivedData(PhySocket *sock,void **uptr,bool lwi void NetconEthernetTap::phyOnUnixWritable(PhySocket *sock,void **uptr,bool lwip_invoked) { - processReceivedData(sock,uptr,lwip_invoked); + handleRead(sock,uptr,lwip_invoked); } void NetconEthernetTap::phyOnUnixData(PhySocket *sock, void **uptr, void *data, ssize_t len) @@ -1288,7 +1316,7 @@ void NetconEthernetTap::handleGetpeername(PhySocket *sock, PhySocket *rpcSock, v void NetconEthernetTap::handleBind(PhySocket *sock, PhySocket *rpcSock, void **uptr, struct bind_st *bind_rpc) { - + /* Mutex::Lock _l(_tcpconns_m); struct sockaddr_in *rawAddr = (struct sockaddr_in *) &bind_rpc->addr; int err, port = lwipstack->__lwip_ntohs(rawAddr->sin_port); @@ -1364,6 +1392,7 @@ void NetconEthernetTap::handleBind(PhySocket *sock, PhySocket *rpcSock, void **u DEBUG_ERROR(" unable to locate Connection"); sendReturnValue(rpcSock, -1, EBADF); } + */ } void NetconEthernetTap::handleListen(PhySocket *sock, PhySocket *rpcSock, void **uptr, struct listen_st *listen_rpc) @@ -1440,15 +1469,45 @@ Connection * NetconEthernetTap::handleSocketProxy(PhySocket *sock, int socket_ty return NULL; } -static void cb_tcpclient(uint16_t ev, struct pico_socket *s) -{ - DEBUG_ERROR("ACTIVITY!"); -} +#if defined(SDK_PICOTCP) + static void cb_tcpclient(uint16_t ev, struct pico_socket *s) + { + printf("ACTIVITY on pico_socket!\n"); + if (ev & PICO_SOCK_EV_RD) { + printf("PICO_SOCK_EV_RD\n"); + } + + if (ev & PICO_SOCK_EV_CONN) { + printf("Connection established with server.\n"); + } + + if (ev & PICO_SOCK_EV_FIN) { + printf("Socket closed. Exit normally. \n"); + //picotap->__pico_timer_add(2000, compare_results, NULL); + } + + if (ev & PICO_SOCK_EV_ERR) { + printf("Socket error received:. Bailing out.\n"/*, strerror(pico_err)*/); + exit(1); + } + + if (ev & PICO_SOCK_EV_CLOSE) { + printf("Socket received close from peer - Wrong case if not all client data sent!\n"); + picotap->picostack->__pico_socket_close(s); + return; + } + + if (ev & PICO_SOCK_EV_WR) { + printf("PICO_SOCK_EV_WR\n"); + } + } +#endif Connection * NetconEthernetTap::handleSocket(PhySocket *sock, void **uptr, struct socket_st* socket_rpc) { DEBUG_ATTN("sock=%p, sock_type=%d", (void*)&sock, socket_rpc->socket_type); + // lwIP #if defined(SDK_LWIP) struct udp_pcb *new_udp_PCB = NULL; struct tcp_pcb *new_tcp_PCB = NULL; @@ -1482,15 +1541,18 @@ Connection * NetconEthernetTap::handleSocket(PhySocket *sock, void **uptr, struc sendReturnValue(_phy.getDescriptor(sock), -1, ENOMEM); return NULL; + // picoTCP #elif defined(SDK_PICOTCP) - DEBUG_ERROR("opening socket"); - - struct pico_socket * psock = picostack->__pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpclient); - DEBUG_ERROR("fin"); - - if(psock) - { + struct pico_socket * psock; + #if defined(SDK_IPV4) + psock = picostack->__pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_TCP, &cb_tcpclient); + #elif defined(SDK_IPV6) + psock = picostack->__pico_socket_open(PICO_PROTO_IPV6, PICO_PROTO_TCP, &cb_tcpclient); + #endif + if(psock) { DEBUG_ATTN("psock = %p", (void*)psock); + int yes = 1; + //picostack->__pico_socket_setoption(psock, PICO_TCP_NODELAY, &yes); Connection * newConn = new Connection(); *uptr = newConn; newConn->type = socket_rpc->socket_type; @@ -1498,14 +1560,11 @@ Connection * NetconEthernetTap::handleSocket(PhySocket *sock, void **uptr, struc newConn->local_addr = NULL; newConn->peer_addr = NULL; newConn->picosock = psock; - //if(newConn->type == SOCK_DGRAM) newConn->pico_UDP_sock = new_udp_PCB; - //if(newConn->type == SOCK_STREAM) newConn->pico_TCP_sock = new_tcp_PCB; _Connections.push_back(newConn); return newConn; } - else - { - DEBUG_ERROR("psock == NULL"); + else { + DEBUG_ERROR("failed to create pico_socket"); } return NULL; #endif @@ -1610,10 +1669,11 @@ int NetconEthernetTap::handleConnectProxy(PhySocket *sock, struct sockaddr_in *r void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Connection *conn, struct connect_st* connect_rpc) { DEBUG_ATTN("sock=%p", (void*)&sock); + Mutex::Lock _l(_tcpconns_m); + struct sockaddr_in *rawAddr = (struct sockaddr_in *) &connect_rpc->addr; + // lwIP #if defined(SDK_LWIP) - Mutex::Lock _l(_tcpconns_m); - struct sockaddr_in *rawAddr = (struct sockaddr_in *) &connect_rpc->addr; int port = lwipstack->__lwip_ntohs(rawAddr->sin_port); ip_addr_t connAddr = convert_ip(rawAddr); int err = 0, ip = rawAddr->sin_addr.s_addr; @@ -1699,10 +1759,41 @@ void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Conne DEBUG_ERROR(" could not locate PCB based on application-provided fd"); sendReturnValue(rpcSock, -1, EBADF); } + + // picoTCP #elif defined(SDK_PICOTCP) - int ret = pico_socket_connect(s, &dst.ip4, send_port); - DEBUG_ATTN("ret = %d", ret); - sendReturnValue(rpcSock, 0, ERR_OK); + if(conn->picosock) { + pico_address paddr; + int ret; + + union pico_address dst = { + .ip4 = {0}, .ip6 = {{0}} + }; + + #if defined(SDK_IPV4) + //unsigned int addr = inet_addr("10.8.8.1"); + paddr.ip4.addr = rawAddr->sin_addr.s_addr; + ret = picostack->__pico_socket_connect(conn->picosock, &paddr.ip4, rawAddr->sin_port); + #elif defined(SDK_IPV6) + //unsigned int addr = inet_addr("10.8.8.1"); + struct pico_ip6 zaddr; + //picostack->__pico_string_to_ipv6("fd56:5799:d8f6:1238:8c99:9322:30ce:418a", zaddr.addr); + memcpy(zaddr.addr, &(rawAddr->sin_addr.s_addr), sizeof(rawAddr->sin_addr.s_addr)); + ret = picostack->__pico_socket_connect(conn->picosock, &zaddr, rawAddr->sin_port); + #endif + + if(ret == PICO_ERR_EPROTONOSUPPORT) { + DEBUG_ERROR("PICO_ERR_EPROTONOSUPPORT"); + } + if(ret == PICO_ERR_EINVAL) { + DEBUG_ERROR("PICO_ERR_EINVAL"); + } + if(ret == PICO_ERR_EHOSTUNREACH) { + DEBUG_ERROR("PICO_ERR_EHOSTUNREACH"); + } + + sendReturnValue(rpcSock, 0, ERR_OK); + } return; #endif } diff --git a/src/SDK_EthernetTap.hpp b/src/SDK_EthernetTap.hpp index ff732c9..0f2a9b4 100644 --- a/src/SDK_EthernetTap.hpp +++ b/src/SDK_EthernetTap.hpp @@ -454,7 +454,7 @@ namespace ZeroTier { void phyOnTcpClose(PhySocket *sock,void **uptr); void phyOnTcpData(PhySocket *sock,void **uptr,void *data,unsigned long len); - void processReceivedData(PhySocket *sock,void **uptr,bool lwip_invoked); + void handleRead(PhySocket *sock,void **uptr,bool lwip_invoked); void phyOnTcpWritable(PhySocket *sock,void **uptr); /* diff --git a/src/SDK_Proxy.cpp b/src/SDK_Proxy.cpp index 9a8ddea..d55953c 100644 --- a/src/SDK_Proxy.cpp +++ b/src/SDK_Proxy.cpp @@ -446,7 +446,7 @@ namespace ZeroTier void NetconEthernetTap::phyOnTcpWritable(PhySocket *sock,void **uptr/*, bool lwip_invoked*/) { DEBUG_INFO("sock=%p", (void*)&sock); - processReceivedData(sock,uptr,true); + handleRead(sock,uptr,true); } // RX data on stream socks and send back over client sock's underlying fd diff --git a/src/SDK_lwip.hpp b/src/SDK_lwip.hpp index c3c1a37..504f04b 100644 --- a/src/SDK_lwip.hpp +++ b/src/SDK_lwip.hpp @@ -59,8 +59,12 @@ struct tcp_pcb; #define ETHIP6_OUTPUT_SIG struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr #define ETHARP_OUTPUT_SIG struct netif *netif, struct pbuf *q, const ip6_addr_t *ipaddr //#define ETHARP_OUTPUT_SIG struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr -#define NETIF_ADD_SIG struct netif *netif, void *state, netif_init_fn init, netif_input_fn input -//#define NETIF_ADD_SIG struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input + +//#if defined(LWIP_IPV6) + #define NETIF_ADD_SIG struct netif *netif, void *state, netif_init_fn init, netif_input_fn input +//#elif defined(LWIP_IPV4) +// #define NETIF_ADD_SIG struct netif *netif, ip_addr_t *ipaddr, ip_addr_t *netmask, ip_addr_t *gw, void *state, netif_init_fn init, netif_input_fn input +//#endif #define ETHERNET_INPUT_SIG struct pbuf *p, struct netif *netif #define IP_INPUT_SIG struct pbuf *p, struct netif *inp diff --git a/src/SDK_pico.hpp b/src/SDK_pico.hpp index 6c81ebd..30315b8 100644 --- a/src/SDK_pico.hpp +++ b/src/SDK_pico.hpp @@ -40,18 +40,12 @@ #endif -#if defined(SDK_LWIP) - #include "SDK_lwip.hpp" -#elif defined(SDK_PICOTCP) - #include "SDK_pico.hpp" +#include "SDK_pico.hpp" - #include "pico_stack.h" - #include "pico_ipv4.h" - #include "pico_icmp4.h" - #include "pico_dev_tap.h" -#elif defined(SDK_JIP) - #include "SDK_jip.hpp" -#endif +#include "pico_stack.h" +#include "pico_ipv4.h" +#include "pico_icmp4.h" +#include "pico_dev_tap.h" #define PICO_STRING_TO_IPV4_SIG const char *ipstr, uint32_t *ip @@ -77,6 +71,8 @@ #define PICO_SOCKET_CLOSE_SIG struct pico_socket *s #define PICO_SOCKET_SHUTDOWN_SIG struct pico_socket *s, int mode +#define PICO_IPV6_LINK_ADD_SIG struct pico_device *dev, struct pico_ip6 address, struct pico_ip6 netmask + namespace ZeroTier { /** @@ -128,6 +124,7 @@ namespace ZeroTier { int (*_pico_socket_close)(PICO_SOCKET_CLOSE_SIG); int (*_pico_socket_shutdown)(PICO_SOCKET_SHUTDOWN_SIG); + int (*_pico_ipv6_link_add)(PICO_IPV6_LINK_ADD_SIG); Mutex _lock; Mutex _lock_mem; @@ -184,6 +181,7 @@ namespace ZeroTier { _pico_socket_close = (int(*)(PICO_SOCKET_CLOSE_SIG))&pico_socket_close; _pico_socket_shutdown = (int(*)(PICO_SOCKET_SHUTDOWN_SIG))&pico_socket_shutdown; + _pico_ipv6_link_add = (int(*)(PICO_IPV6_LINK_ADD_SIG))&pico_ipv6_link_add; #endif @@ -217,6 +215,8 @@ namespace ZeroTier { _pico_socket_close = (int(*)(PICO_SOCKET_CLOSE_SIG))dlsym(_libref, "pico_socket_close"); _pico_socket_shutdown = (int(*)(PICO_SOCKET_SHUTDOWN_SIG))dlsym(_libref, "pico_socket_shutdown"); + _pico_ipv6_link_add = (int(*)(PICO_IPV6_LINK_ADD_SIG))dlsym(_libref, "pico_ipv6_link_add"); + #endif } @@ -250,6 +250,8 @@ namespace ZeroTier { inline int __pico_socket_write(PICO_SOCKET_WRITE_SIG) throw() { Mutex::Lock _l(_lock); return _pico_socket_write(s, buf, len); } inline int __pico_socket_close(PICO_SOCKET_CLOSE_SIG) throw() { Mutex::Lock _l(_lock); return _pico_socket_close(s); } inline int __pico_socket_shutdown(PICO_SOCKET_SHUTDOWN_SIG) throw() { Mutex::Lock _l(_lock); return _pico_socket_shutdown(s, mode); } + + inline int __pico_ipv6_link_add(PICO_IPV6_LINK_ADD_SIG) throw() { Mutex::Lock _l(_lock); return _pico_ipv6_link_add(dev, address, netmask); } }; } // namespace ZeroTier diff --git a/tests/api_test/tcp_server.c b/tests/api_test/tcp_server.c index 2b7d553..a501964 100644 --- a/tests/api_test/tcp_server.c +++ b/tests/api_test/tcp_server.c @@ -20,40 +20,20 @@ int main(int argc , char *argv[]) int sock, client_sock, c, read_size, ipv = atoi(argv[1]), port = atoi(argv[2]); char client_message[2000]; - struct sockaddr_storage server, client; - struct sockaddr_in6 *server6 = (struct sockaddr_in6 *)&server; - struct sockaddr_in *server4 = (struct sockaddr_in *)&server; + char str[100]; + int comm_fd; + + struct sockaddr_in servaddr; + struct sockaddr_in client; + + sock = socket(AF_INET, SOCK_STREAM, 0); + bzero( &servaddr, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htons(INADDR_ANY); + servaddr.sin_port = htons(port); + bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)); - // IPV4 - if(ipv == 4) - { - printf("ipv4 mode\n"); - if((sock = socket(AF_INET, SOCK_STREAM , 0)) < 0) { - printf("could not create socket"); - return 0; - } - server4->sin_family = AF_INET; - server4->sin_addr.s_addr = INADDR_ANY; - server4->sin_port = htons(port); - } - // IPV6 - if(ipv == 6) - { - printf("ipv6 mode\n"); - if((sock = socket(AF_INET6, SOCK_STREAM , 0)) < 0) { - printf("could not create socket"); - return 0; - } - server6->sin6_family = AF_INET6; - server6->sin6_addr = in6addr_any; - server6->sin6_port = htons(port); - } - - printf("binding on port %d\n", port); - if( bind(sock,(struct sockaddr *)&server , sizeof(server)) < 0) { - perror("bind failed. Error"); - return 0; - } printf("listening\n"); listen(sock , 3); printf("waiting to accept\n");