diff --git a/ext/picotcp/include/pico_protocol.h b/ext/picotcp/include/pico_protocol.h index fd7c122..67c86ff 100644 --- a/ext/picotcp/include/pico_protocol.h +++ b/ext/picotcp/include/pico_protocol.h @@ -92,4 +92,6 @@ int pico_protocol_network_loop(int loop_score, int direction); int pico_protocol_transport_loop(int loop_score, int direction); int pico_protocol_socket_loop(int loop_score, int direction); +// static pico_err_t get_pico_err(); + #endif diff --git a/ext/picotcp/stack/pico_protocol.c b/ext/picotcp/stack/pico_protocol.c index c1b4657..9bad18b 100644 --- a/ext/picotcp/stack/pico_protocol.c +++ b/ext/picotcp/stack/pico_protocol.c @@ -11,6 +11,13 @@ #include "pico_protocol.h" #include "pico_tree.h" +/* +static pico_err_t get_pico_err() +{ + return pico_err; +} +*/ + struct pico_proto_rr { struct pico_tree *t; diff --git a/ext/picotcp/stack/pico_socket.c b/ext/picotcp/stack/pico_socket.c index 839f57d..cf1af6c 100644 --- a/ext/picotcp/stack/pico_socket.c +++ b/ext/picotcp/stack/pico_socket.c @@ -165,16 +165,27 @@ PICO_TREE_DECLARE(TCPTable, sockport_cmp); struct pico_sockport *pico_get_sockport(uint16_t proto, uint16_t port) { + printf("pico_get_sockport\n"); struct pico_sockport test = INIT_SOCKPORT; test.number = port; - if (proto == PICO_PROTO_UDP) + if (proto == PICO_PROTO_UDP){ + printf("pico_get_sockport: proto UDP?\n"); + return pico_tree_findKey(&UDPTable, &test); + } + + else if (proto == PICO_PROTO_TCP){ + printf("pico_get_sockport: proto TCP?\n"); - else if (proto == PICO_PROTO_TCP) return pico_tree_findKey(&TCPTable, &test); + } - else return NULL; + else + { + printf("pico_get_sockport: proto NULL?\n"); + return NULL; + } } #ifdef PICO_SUPPORT_IPV4 @@ -324,6 +335,7 @@ int pico_is_port_free(uint16_t proto, uint16_t port, void *addr, void *net) static int pico_check_socket(struct pico_socket *s) { + printf("pico_check_socket\n"); struct pico_sockport *test; struct pico_socket *found; struct pico_tree_node *index; @@ -331,6 +343,8 @@ static int pico_check_socket(struct pico_socket *s) test = pico_get_sockport(PROTO(s), s->local_port); if (!test) { + printf("!test\n"); + return -1; } @@ -341,6 +355,8 @@ static int pico_check_socket(struct pico_socket *s) } } + printf("no key found\n"); + return -1; } @@ -686,6 +702,7 @@ static int pico_socket_transport_read(struct pico_socket *s, void *buf, int len) return pico_socket_tcp_read(s, buf, (uint32_t)len); else return 0; } +#include int pico_socket_read(struct pico_socket *s, void *buf, int len) { @@ -711,17 +728,25 @@ int pico_socket_read(struct pico_socket *s, void *buf, int len) static int pico_socket_write_check_state(struct pico_socket *s) { + printf("pico_socket_write_check_state\n"); + if ((s->state & PICO_SOCKET_STATE_BOUND) == 0) { + printf("PICO_ERR_EIO\n"); + pico_err = PICO_ERR_EIO; return -1; } if ((s->state & PICO_SOCKET_STATE_CONNECTED) == 0) { + printf("PICO_ERR_ENOTCONN\n"); + pico_err = PICO_ERR_ENOTCONN; return -1; } if (s->state & PICO_SOCKET_STATE_SHUT_LOCAL) { /* check if in shutdown state */ + printf("PICO_ERR_ESHUTDOWN\n"); + pico_err = PICO_ERR_ESHUTDOWN; return -1; } @@ -731,7 +756,11 @@ static int pico_socket_write_check_state(struct pico_socket *s) static int pico_socket_write_attempt(struct pico_socket *s, const void *buf, int len) { + printf("pico_socket_write_attempt\n"); + if (pico_socket_write_check_state(s) < 0) { + printf("pico_socket_write_check_state = -1\n"); + return -1; } else { return pico_socket_sendto(s, buf, len, &s->remote_addr, s->remote_port); @@ -740,13 +769,18 @@ static int pico_socket_write_attempt(struct pico_socket *s, const void *buf, int int pico_socket_write(struct pico_socket *s, const void *buf, int len) { + printf("pico_socket_write\n"); if (!s || buf == NULL) { + printf("PICO_ERR_EINVAL\n"); + pico_err = PICO_ERR_EINVAL; return -1; } else { /* check if exists in tree */ /* See task #178 */ if (pico_check_socket(s) != 0) { + printf("PICO_ERR_EINVAL?\n"); + pico_err = PICO_ERR_EINVAL; return -1; } diff --git a/src/SDK_EthernetTap.cpp b/src/SDK_EthernetTap.cpp index 4f798e0..77f9812 100644 --- a/src/SDK_EthernetTap.cpp +++ b/src/SDK_EthernetTap.cpp @@ -50,6 +50,7 @@ #include "pico_icmp4.h" #include "pico_dev_tap.h" #include "pico_socket.h" + #include "pico_protocol.h" #elif defined(SDK_JIP) #include "SDK_jip.hpp" #endif @@ -65,7 +66,7 @@ #include "lwip/api.h" #include "lwip/ip.h" #include "lwip/ip_addr.h" - #include "lwip/ip4_addr.h" +#include "lwip/ip4_addr.h" #include "lwip/tcp.h" #include "lwip/init.h" @@ -75,13 +76,6 @@ #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" //#if !defined(__IOS__) && !defined(__ANDROID__) && !defined(__UNITY_3D__) && !defined(__XCODE__) // const ip_addr_t ip_addr_any = { IPADDR_ANY }; @@ -98,6 +92,7 @@ static err_t tapif_init(struct netif *netif) return ERR_OK; } +pico_err_t pico_err; static void cb_ping(struct pico_icmp4_stats *s) @@ -355,10 +350,9 @@ void NetconEthernetTap::picoTCP_init_interface(const InetAddress &ip) if (std::find(_ips.begin(),_ips.end(),ip) == _ips.end()) { _ips.push_back(ip); std::sort(_ips.begin(),_ips.end()); - + #if defined(SDK_IPV4) if(ip.isV4()) { - /* int id; struct pico_ip4 ipaddr, netmask; ipaddr.addr = *((u32_t *)ip.rawIpData()); @@ -378,19 +372,19 @@ void NetconEthernetTap::picoTCP_init_interface(const InetAddress &ip) } DEBUG_INFO("successfully initialized device with IPV4 address"); // picostack->__pico_icmp4_ping("10.8.8.1", 20, 1000, 10000, 64, cb_ping); - */ } + #elif defined(SDK_IPV6) 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); + struct pico_ip6 ipaddr, netmask; + char ipv6_str[INET6_ADDRSTRLEN], nm_str[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, ip.rawIpData(), ipv6_str, INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, ip.netmask().rawIpData(), nm_str, INET6_ADDRSTRLEN); + picostack->__pico_string_to_ipv6(ipv6_str, ipaddr.addr); + picostack->__pico_string_to_ipv6(nm_str, 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); @@ -401,6 +395,7 @@ void NetconEthernetTap::picoTCP_init_interface(const InetAddress &ip) } DEBUG_INFO("successfully initialized device with IPV6 address"); } + #endif } } @@ -1472,27 +1467,27 @@ Connection * NetconEthernetTap::handleSocketProxy(PhySocket *sock, int socket_ty #if defined(SDK_PICOTCP) static void cb_tcpclient(uint16_t ev, struct pico_socket *s) { - printf("ACTIVITY on pico_socket!\n"); + DEBUG_INFO("ACTIVITY on pico_socket!\n"); if (ev & PICO_SOCK_EV_RD) { - printf("PICO_SOCK_EV_RD\n"); + DEBUG_INFO("PICO_SOCK_EV_RD\n"); } if (ev & PICO_SOCK_EV_CONN) { - printf("Connection established with server.\n"); + DEBUG_INFO("Connection established with server.\n"); } if (ev & PICO_SOCK_EV_FIN) { - printf("Socket closed. Exit normally. \n"); + DEBUG_INFO("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)*/); + DEBUG_INFO("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"); + DEBUG_INFO("Socket received close from peer - Wrong case if not all client data sent!\n"); picotap->picostack->__pico_socket_close(s); return; } @@ -1770,15 +1765,20 @@ void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Conne .ip4 = {0}, .ip6 = {{0}} }; + // TODO: Rewrite this #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_ip4 zaddr; + struct sockaddr_in *in4 = (struct sockaddr_in*)&connect_rpc->addr; + char ipv4_str[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &(in4->sin_addr), ipv4_str, INET_ADDRSTRLEN); + picostack->__pico_string_to_ipv4(ipv4_str, &(zaddr.addr)); + ret = picostack->__pico_socket_connect(conn->picosock, &zaddr, rawAddr->sin_port); + #elif defined(SDK_IPV6) // "fd56:5799:d8f6:1238:8c99:9322:30ce:418a" 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)); + struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&connect_rpc->addr; + char ipv6_str[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &(in6->sin6_addr), ipv6_str, INET6_ADDRSTRLEN); + picostack->__pico_string_to_ipv6(ipv6_str, zaddr.addr); ret = picostack->__pico_socket_connect(conn->picosock, &zaddr, rawAddr->sin_port); #endif @@ -1791,7 +1791,6 @@ void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Conne if(ret == PICO_ERR_EHOSTUNREACH) { DEBUG_ERROR("PICO_ERR_EHOSTUNREACH"); } - sendReturnValue(rpcSock, 0, ERR_OK); } return; @@ -1801,106 +1800,152 @@ void NetconEthernetTap::handleConnect(PhySocket *sock, PhySocket *rpcSock, Conne void NetconEthernetTap::handleWrite(Connection *conn) { DEBUG_EXTRA("conn=%p", (void*)&conn); - if(!conn || (!conn->TCP_pcb && !conn->UDP_pcb)) { - DEBUG_ERROR(" invalid connection"); - return; - } - if(conn->type == SOCK_DGRAM) { - if(!conn->UDP_pcb) { - DEBUG_ERROR(" invalid UDP_pcb, type=SOCK_DGRAM"); - return; - } - // TODO: Packet re-assembly hasn't yet been tested with lwIP so UDP packets are limited to MTU-sized chunks - int udp_trans_len = conn->txsz < ZT_UDP_DEFAULT_PAYLOAD_MTU ? conn->txsz : ZT_UDP_DEFAULT_PAYLOAD_MTU; - - DEBUG_EXTRA(" allocating pbuf chain of size=%d for UDP packet, txsz=%d", udp_trans_len, conn->txsz); - struct pbuf * pb = lwipstack->__pbuf_alloc(PBUF_TRANSPORT, udp_trans_len, PBUF_POOL); - if(!pb){ - DEBUG_ERROR(" unable to allocate new pbuf of size=%d", conn->txsz); - return; - } - memcpy(pb->payload, conn->txbuf, udp_trans_len); - int err = lwipstack->__udp_send(conn->UDP_pcb, pb); - - if(err == ERR_MEM) { - DEBUG_ERROR(" error sending packet. out of memory"); - } else if(err == ERR_RTE) { - DEBUG_ERROR(" could not find route to destinations address"); - } else if(err != ERR_OK) { - DEBUG_ERROR(" error sending packet - %d", err); - } else { - // Success - int buf_remaining = (conn->txsz)-udp_trans_len; - if(buf_remaining) - memmove(&conn->txbuf, (conn->txbuf+udp_trans_len), buf_remaining); - conn->txsz -= udp_trans_len; + + // lwIP + #if defined(SDK_LWIP) + if(!conn || (!conn->TCP_pcb && !conn->UDP_pcb)) { + DEBUG_ERROR(" invalid connection"); + return; + } + if(conn->type == SOCK_DGRAM) { + if(!conn->UDP_pcb) { + DEBUG_ERROR(" invalid UDP_pcb, type=SOCK_DGRAM"); + return; + } + // TODO: Packet re-assembly hasn't yet been tested with lwIP so UDP packets are limited to MTU-sized chunks + int udp_trans_len = conn->txsz < ZT_UDP_DEFAULT_PAYLOAD_MTU ? conn->txsz : ZT_UDP_DEFAULT_PAYLOAD_MTU; + + DEBUG_EXTRA(" allocating pbuf chain of size=%d for UDP packet, txsz=%d", udp_trans_len, conn->txsz); + struct pbuf * pb = lwipstack->__pbuf_alloc(PBUF_TRANSPORT, udp_trans_len, PBUF_POOL); + if(!pb){ + DEBUG_ERROR(" unable to allocate new pbuf of size=%d", conn->txsz); + return; + } + memcpy(pb->payload, conn->txbuf, udp_trans_len); + int err = lwipstack->__udp_send(conn->UDP_pcb, pb); + + if(err == ERR_MEM) { + DEBUG_ERROR(" error sending packet. out of memory"); + } else if(err == ERR_RTE) { + DEBUG_ERROR(" could not find route to destinations address"); + } else if(err != ERR_OK) { + DEBUG_ERROR(" error sending packet - %d", err); + } else { + // Success + int buf_remaining = (conn->txsz)-udp_trans_len; + if(buf_remaining) + memmove(&conn->txbuf, (conn->txbuf+udp_trans_len), buf_remaining); + conn->txsz -= udp_trans_len; - #if DEBUG_LEVEL >= MSG_TRANSFER - struct sockaddr_in * addr_in2 = (struct sockaddr_in *)conn->peer_addr; - int port = lwipstack->__lwip_ntohs(addr_in2->sin_port); - int ip = addr_in2->sin_addr.s_addr; - unsigned char d[4]; - d[0] = ip & 0xFF; - d[1] = (ip >> 8) & 0xFF; - d[2] = (ip >> 16) & 0xFF; - d[3] = (ip >> 24) & 0xFF; - DEBUG_TRANS("UDP TX ---> :: {TX: ------, RX: ------, sock=%p} :: %d bytes (dest_addr=%d.%d.%d.%d:%d)", - (void*)conn->sock, udp_trans_len, d[0], d[1], d[2], d[3], port); - #endif - } - lwipstack->__pbuf_free(pb); - return; - } - else if(conn->type == SOCK_STREAM) { - if(!conn->TCP_pcb) { - DEBUG_ERROR(" invalid TCP_pcb, type=SOCK_STREAM"); - return; - } - // How much we are currently allowed to write to the connection - int sndbuf = conn->TCP_pcb->snd_buf; - int err, sz, r; - - if(!sndbuf) { - // PCB send buffer is full, turn off readability notifications for the - // corresponding PhySocket until nc_sent() is called and confirms that there is - // now space on the buffer - if(!conn->probation) { - DEBUG_ERROR(" LWIP stack is full, sndbuf == 0"); - _phy.setNotifyReadable(conn->sock, false); - conn->probation = true; - } - return; - } - if(conn->txsz <= 0) - return; // Nothing to write - if(!conn->listening) - lwipstack->__tcp_output(conn->TCP_pcb); + #if DEBUG_LEVEL >= MSG_TRANSFER + struct sockaddr_in * addr_in2 = (struct sockaddr_in *)conn->peer_addr; + int port = lwipstack->__lwip_ntohs(addr_in2->sin_port); + int ip = addr_in2->sin_addr.s_addr; + unsigned char d[4]; + d[0] = ip & 0xFF; + d[1] = (ip >> 8) & 0xFF; + d[2] = (ip >> 16) & 0xFF; + d[3] = (ip >> 24) & 0xFF; + DEBUG_TRANS("UDP TX ---> :: {TX: ------, RX: ------, sock=%p} :: %d bytes (dest_addr=%d.%d.%d.%d:%d)", + (void*)conn->sock, udp_trans_len, d[0], d[1], d[2], d[3], port); + #endif + } + lwipstack->__pbuf_free(pb); + return; + } + else if(conn->type == SOCK_STREAM) { + if(!conn->TCP_pcb) { + DEBUG_ERROR(" invalid TCP_pcb, type=SOCK_STREAM"); + return; + } + // How much we are currently allowed to write to the connection + int sndbuf = conn->TCP_pcb->snd_buf; + int err, sz, r; + + if(!sndbuf) { + // PCB send buffer is full, turn off readability notifications for the + // corresponding PhySocket until nc_sent() is called and confirms that there is + // now space on the buffer + if(!conn->probation) { + DEBUG_ERROR(" LWIP stack is full, sndbuf == 0"); + _phy.setNotifyReadable(conn->sock, false); + conn->probation = true; + } + return; + } + if(conn->txsz <= 0) + return; // Nothing to write + if(!conn->listening) + lwipstack->__tcp_output(conn->TCP_pcb); - if(conn->sock) { - r = conn->txsz < sndbuf ? conn->txsz : sndbuf; - // Writes data pulled from the client's socket buffer to LWIP. This merely sends the - // data to LWIP to be enqueued and eventually sent to the network. - if(r > 0) { - err = lwipstack->__tcp_write(conn->TCP_pcb, &conn->txbuf, r, TCP_WRITE_FLAG_COPY); - lwipstack->__tcp_output(conn->TCP_pcb); - if(err != ERR_OK) { - DEBUG_ERROR(" error while writing to PCB, err=%d", err); - if(err == -1) - DEBUG_ERROR("out of memory"); - return; - } else { - sz = (conn->txsz)-r; - if(sz) - memmove(&conn->txbuf, (conn->txbuf+r), sz); - conn->txsz -= r; - int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ; - DEBUG_TRANS("TCP TX ---> :: {TX: %.3f%%, RX: %.3f%%, sock=%p} :: %d bytes", - (float)conn->txsz / (float)max, (float)conn->rxsz / max, (void*)&conn->sock, r); - return; - } - } - } - } + if(conn->sock) { + r = conn->txsz < sndbuf ? conn->txsz : sndbuf; + // Writes data pulled from the client's socket buffer to LWIP. This merely sends the + // data to LWIP to be enqueued and eventually sent to the network. + if(r > 0) { + err = lwipstack->__tcp_write(conn->TCP_pcb, &conn->txbuf, r, TCP_WRITE_FLAG_COPY); + lwipstack->__tcp_output(conn->TCP_pcb); + if(err != ERR_OK) { + DEBUG_ERROR(" error while writing to PCB, err=%d", err); + if(err == -1) + DEBUG_ERROR("out of memory"); + return; + } else { + // adjust buffer + sz = (conn->txsz)-r; + if(sz) + memmove(&conn->txbuf, (conn->txbuf+r), sz); + conn->txsz -= r; + int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ; + DEBUG_TRANS("TCP TX ---> :: {TX: %.3f%%, RX: %.3f%%, sock=%p} :: %d bytes", + (float)conn->txsz / (float)max, (float)conn->rxsz / max, (void*)&conn->sock, r); + return; + } + } + } + } + + // picoTCP + #elif defined(SDK_PICOTCP) + if(!conn || !conn->picosock) { + DEBUG_ERROR(" invalid connection"); + return; + } + int r, max_write_len = conn->txsz < ZT_MAX_MTU ? conn->txsz : ZT_MAX_MTU; + if((r = picostack->__pico_socket_write(conn->picosock, &conn->txbuf, max_write_len)) < 0) { + DEBUG_ERROR("unable to write to pico_socket(%p)", (void*)&(conn->picosock)); + return; + } + + /* + if(pico_err == PICO_ERR_EINVAL) + DEBUG_ERROR("PICO_ERR_EINVAL - invalid argument"); + if(pico_err == PICO_ERR_EIO) + DEBUG_ERROR("PICO_ERR_EIO - input/output error"); + if(pico_err == PICO_ERR_ENOTCONN) + DEBUG_ERROR("PICO_ERR_ENOTCONN - the socket is not connected"); + if(pico_err == PICO_ERR_ESHUTDOWN) + DEBUG_ERROR("PICO_ERR_ESHUTDOWN - cannot send after transport endpoint shutdown"); + if(pico_err == PICO_ERR_EADDRNOTAVAIL) + DEBUG_ERROR("PICO_ERR_EADDRNOTAVAIL - address not available"); + if(pico_err == PICO_ERR_EHOSTUNREACH) + DEBUG_ERROR("PICO_ERR_EHOSTUNREACH - host is unreachable"); + if(pico_err == PICO_ERR_ENOMEM) + DEBUG_ERROR("PICO_ERR_ENOMEM - not enough space"); + if(pico_err == PICO_ERR_EAGAIN) + DEBUG_ERROR("PICO_ERR_EAGAIN - resource temporarily unavailable"); + */ + + // adjust buffer + int sz = (conn->txsz)-r; + if(sz) + memmove(&conn->txbuf, (conn->txbuf+r), sz); + conn->txsz -= r; + + int max = conn->type == SOCK_STREAM ? DEFAULT_TCP_TX_BUF_SZ : DEFAULT_UDP_TX_BUF_SZ; + DEBUG_TRANS("TCP TX ---> :: {TX: %.3f%%, RX: %.3f%%, sock=%p} :: %d bytes", + (float)conn->txsz / (float)max, (float)conn->rxsz / max, (void*)&conn->sock, r); + #endif } } // namespace ZeroTier diff --git a/src/SDK_EthernetTap.hpp b/src/SDK_EthernetTap.hpp index 0f2a9b4..8629619 100644 --- a/src/SDK_EthernetTap.hpp +++ b/src/SDK_EthernetTap.hpp @@ -52,6 +52,9 @@ #include "SDK_pico.hpp" #include "SDK_jip.hpp" + #include "pico_protocol.h" + + // lwIP structs struct tcp_pcb; struct udp_pcb; diff --git a/src/SDK_pico.hpp b/src/SDK_pico.hpp index 30315b8..94036e9 100644 --- a/src/SDK_pico.hpp +++ b/src/SDK_pico.hpp @@ -46,9 +46,9 @@ #include "pico_ipv4.h" #include "pico_icmp4.h" #include "pico_dev_tap.h" +#include "pico_protocol.h" -#define PICO_STRING_TO_IPV4_SIG const char *ipstr, uint32_t *ip #define PICO_IPV4_TO_STRING_SIG char *ipbuf, const uint32_t ip #define PICO_TAP_CREATE_SIG char *name #define PICO_IPV4_LINK_ADD_SIG struct pico_device *dev, struct pico_ip4 address, struct pico_ip4 netmask @@ -58,7 +58,9 @@ // #define PICO_TIMER_ADD_SIG pico_time expire, void (*timer)(pico_time, void *), void *arg +#define PICO_STRING_TO_IPV4_SIG const char *ipstr, uint32_t *ip #define PICO_STRING_TO_IPV6_SIG const char *ipstr, uint8_t *ip + #define PICO_SOCKET_SETOPTION_SIG struct pico_socket *s, int option, void *value #define PICO_SOCKET_SEND_SIG struct pico_socket *s, const void *buf, int len #define PICO_SOCKET_SENDTO_SIG struct pico_socket *s, const void *buf, int len, void *dst, uint16_t remote_port @@ -125,6 +127,7 @@ namespace ZeroTier { int (*_pico_socket_shutdown)(PICO_SOCKET_SHUTDOWN_SIG); int (*_pico_ipv6_link_add)(PICO_IPV6_LINK_ADD_SIG); + pico_err_t (*_get_pico_err)(void); Mutex _lock; Mutex _lock_mem; @@ -183,6 +186,8 @@ namespace ZeroTier { _pico_ipv6_link_add = (int(*)(PICO_IPV6_LINK_ADD_SIG))&pico_ipv6_link_add; + _get_pico_err = (pico_err_t(*)())&get_pico_err; + #endif #ifdef __DYNAMIC_LWIP__ // Use dynamically-loaded symbols (for use in normal desktop applications) @@ -217,6 +222,8 @@ namespace ZeroTier { _pico_ipv6_link_add = (int(*)(PICO_IPV6_LINK_ADD_SIG))dlsym(_libref, "pico_ipv6_link_add"); + _get_pico_err = (pico_err_t(*)())dlsym(_libref, "get_pico_err"); + #endif } @@ -230,14 +237,15 @@ namespace ZeroTier { inline void __pico_stack_init(void) throw() { Mutex::Lock _l(_lock); _pico_stack_init(); } inline void __pico_stack_tick(void) throw() { Mutex::Lock _l(_lock); _pico_stack_tick(); } inline struct pico_device * __pico_tap_create(PICO_TAP_CREATE_SIG) throw() { Mutex::Lock _l(_lock); return _pico_tap_create(name); } - inline int __pico_string_to_ipv4(PICO_STRING_TO_IPV4_SIG) throw() { Mutex::Lock _l(_lock); return _pico_string_to_ipv4(ipstr, ip); } inline int __pico_ipv4_to_string(PICO_IPV4_TO_STRING_SIG) throw() { Mutex::Lock _l(_lock); return _pico_ipv4_to_string(ipbuf, ip); } inline int __pico_ipv4_link_add(PICO_IPV4_LINK_ADD_SIG) throw() { Mutex::Lock _l(_lock); return _pico_ipv4_link_add(dev, address, netmask); } inline int __pico_device_init(PICO_DEVICE_INIT_SIG) throw() { Mutex::Lock _l(_lock); return _pico_device_init(dev, name, mac); } inline int __pico_stack_recv(PICO_STACK_RECV_SIG) throw() { /*Mutex::Lock _l(_lock);*/ return _pico_stack_recv(dev, buffer, len); } inline int __pico_icmp4_ping(PICO_ICMP4_PING_SIG) throw() { Mutex::Lock _l(_lock); return _pico_icmp4_ping(dst, count, interval, timeout, size, cb); } + inline int __pico_string_to_ipv4(PICO_STRING_TO_IPV4_SIG) throw() { Mutex::Lock _l(_lock); return _pico_string_to_ipv4(ipstr, ip); } inline int __pico_string_to_ipv6(PICO_STRING_TO_IPV6_SIG) throw() { Mutex::Lock _l(_lock); return _pico_string_to_ipv6(ipstr, ip); } + inline int __pico_socket_setoption(PICO_SOCKET_SETOPTION_SIG) throw() { Mutex::Lock _l(_lock); return _pico_socket_setoption(s, option, value); } inline uint32_t __pico_timer_add(PICO_TIMER_ADD_SIG) throw() { Mutex::Lock _l(_lock); return _pico_timer_add(expire, timer, arg); } inline int __pico_socket_send(PICO_SOCKET_SEND_SIG) throw() { Mutex::Lock _l(_lock); return _pico_socket_send(s, buf, len); } @@ -252,6 +260,8 @@ namespace ZeroTier { 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); } + + inline pico_err_t __get_pico_err(void) throw() { Mutex::Lock _l(_lock); return _get_pico_err(); } }; } // namespace ZeroTier