diff options
author | Joseph Henry <joseph.henry@zerotier.com> | 2015-09-15 14:15:59 -0400 |
---|---|---|
committer | Joseph Henry <joseph.henry@zerotier.com> | 2015-09-15 14:15:59 -0400 |
commit | 8ea83c9548f0e100ba56619e461b896e81295c02 (patch) | |
tree | d97b093dc649405b6439aeb4caacfb7084dc1f60 | |
parent | 8189b2ba919f2c8276cf3e5b3df3643830350669 (diff) | |
download | infinitytier-8ea83c9548f0e100ba56619e461b896e81295c02.tar.gz infinitytier-8ea83c9548f0e100ba56619e461b896e81295c02.zip |
netif code hooked up
-rwxr-xr-x | netcon/Intercept.h | 3 | ||||
-rw-r--r-- | netcon/LWIPStack.hpp | 30 | ||||
-rw-r--r-- | netcon/NetconEthernetTap.cpp | 120 | ||||
-rw-r--r-- | netcon/NetconEthernetTap.hpp | 78 | ||||
-rwxr-xr-x | netcon/liblwip.so | bin | 224696 -> 213704 bytes | |||
-rw-r--r-- | osdep/Arp.cpp | 2 |
6 files changed, 192 insertions, 41 deletions
diff --git a/netcon/Intercept.h b/netcon/Intercept.h index 5c154e6e..7a8864aa 100755 --- a/netcon/Intercept.h +++ b/netcon/Intercept.h @@ -176,6 +176,7 @@ struct shutdown_st /* LWIP error beautification */ +/* const char *lwiperror(int n) { switch(n) @@ -216,6 +217,6 @@ const char *lwiperror(int n) return "UNKNOWN_RET_VAL"; } } - +*/ #endif diff --git a/netcon/LWIPStack.hpp b/netcon/LWIPStack.hpp index 14edd1d5..38bb8547 100644 --- a/netcon/LWIPStack.hpp +++ b/netcon/LWIPStack.hpp @@ -29,6 +29,7 @@ #include "lwip/mem.h" #include "lwip/pbuf.h" #include "lwip/ip_addr.h" +#include "lwip/netif.h" /* #include "lwip/timers.h" @@ -78,9 +79,6 @@ typedef ip_addr ip_addr_t; #define TCP_LISTEN_SIG struct tcp_pcb * pcb #define TCP_LISTEN_WITH_BACKLOG_SIG struct tcp_pcb * pcb, u8_t backlog #define TCP_BIND_SIG struct tcp_pcb * pcb, struct ip_addr * ipaddr, u16_t port -//#define NETIF_SET_DEFAULT_SIG struct netif *netif -//#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 -//#define NETIF_SET_UP_SIG struct netif *netif //#define TAPIF_INIT_SIG struct netif *netif //#define TAPIF_INPUT_SIG LWIPStack* ls, struct netif *netif #define PBUF_FREE_SIG struct pbuf *p @@ -91,6 +89,13 @@ typedef ip_addr ip_addr_t; #define ETHARP_OUTPUT_SIG struct netif *netif, struct pbuf *q, ip_addr_t *ipaddr #define ETHERNET_INPUT_SIG struct pbuf *p, struct netif *netif +#define TCP_INPUT_SIG struct pbuf *p, struct netif *inp +#define IP_INPUT_SIG struct pbuf *p, struct netif *inp + +#define NETIF_SET_DEFAULT_SIG struct netif *netif +#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 +#define NETIF_SET_UP_SIG struct netif *netif + class LWIPStack{ @@ -116,9 +121,6 @@ public: struct tcp_pcb * (*tcp_listen)(TCP_LISTEN_SIG); struct tcp_pcb * (*tcp_listen_with_backlog)(TCP_LISTEN_WITH_BACKLOG_SIG); err_t (*tcp_bind)(TCP_BIND_SIG); - //void (*netif_set_default)(NETIF_SET_DEFAULT_SIG); - //struct netif* (*netif_add)(NETIF_ADD_SIG); - //void (*netif_set_up)(NETIF_SET_UP_SIG); void (*etharp_tmr)(void); void (*tcp_tmr)(void); //err_t (*tapif_init)(TAPIF_INIT_SIG); @@ -130,6 +132,12 @@ public: char* (*ipaddr_ntoa)(IPADDR_NTOA_SIG); err_t (*etharp_output)(ETHARP_OUTPUT_SIG); err_t (*ethernet_input)(ETHERNET_INPUT_SIG); + void (*tcp_input)(TCP_INPUT_SIG); + err_t (*ip_input)(IP_INPUT_SIG); + + void (*netif_set_default)(NETIF_SET_DEFAULT_SIG); + struct netif * (*netif_add)(NETIF_ADD_SIG); + void (*netif_set_up)(NETIF_SET_UP_SIG); @@ -158,9 +166,6 @@ public: tcp_listen = (struct tcp_pcb*(*)(TCP_LISTEN_SIG))dlsym(libref, "tcp_listen"); tcp_listen_with_backlog = (struct tcp_pcb*(*)(TCP_LISTEN_WITH_BACKLOG_SIG))dlsym(libref, "tcp_listen_with_backlog"); tcp_bind = (err_t(*)(TCP_BIND_SIG))dlsym(libref, "tcp_bind"); - //netif_set_default = (void(*)(NETIF_SET_DEFAULT_SIG))dlsym(libref, "netif_set_default"); - //netif_add = (struct netif*(*)(NETIF_ADD_SIG))dlsym(libref, "netif_add"); - //netif_set_up = (void(*)(NETIF_SET_UP_SIG))dlsym(libref, "netif_set_up"); etharp_tmr = (void(*)(void))dlsym(libref, "etharp_tmr"); tcp_tmr = (void(*)(void))dlsym(libref, "tcp_tmr"); //tapif_init = (err_t(*)(TAPIF_INIT_SIG))dlsym(libref, "tapif_init"); @@ -172,6 +177,13 @@ public: ipaddr_ntoa = (char*(*)(IPADDR_NTOA_SIG))dlsym(libref, "ipaddr_ntoa"); etharp_output = (err_t(*)(ETHARP_OUTPUT_SIG))dlsym(libref, "etharp_output"); ethernet_input = (err_t(*)(ETHERNET_INPUT_SIG))dlsym(libref, "ethernet_input"); + + tcp_input = (void(*)(TCP_INPUT_SIG))dlsym(libref, "tcp_input"); + ip_input = (err_t(*)(IP_INPUT_SIG))dlsym(libref, "ip_input"); + + netif_set_default = (void(*)(NETIF_SET_DEFAULT_SIG))dlsym(libref, "netif_set_default"); + netif_add = (struct netif*(*)(NETIF_ADD_SIG))dlsym(libref, "netif_add"); + netif_set_up = (void(*)(NETIF_SET_UP_SIG))dlsym(libref, "netif_set_up"); } }; diff --git a/netcon/NetconEthernetTap.cpp b/netcon/NetconEthernetTap.cpp index e7e38939..ecfca72d 100644 --- a/netcon/NetconEthernetTap.cpp +++ b/netcon/NetconEthernetTap.cpp @@ -34,7 +34,6 @@ #include "NetconEthernetTap.hpp" #include "../node/Utils.hpp" -#include "../node/Node.hpp" // for //TRACE #include "../osdep/OSUtils.hpp" #include "../osdep/Phy.hpp" @@ -43,6 +42,7 @@ #include "lwip/ip.h" #include "lwip/ip_addr.h" #include "lwip/ip_frag.h" +#include "lwip/tcp.h" #include "LWIPStack.hpp" #include "NetconService.hpp" @@ -53,6 +53,7 @@ namespace ZeroTier { + NetconEthernetTap::NetconEthernetTap( const char *homePath, const MAC &mac, @@ -120,7 +121,7 @@ bool NetconEthernetTap::addIp(const InetAddress &ip) } // TODO: alloc IP in LWIP - //netif_set_addr(netif, ipaddr, netmask, gw); + fprintf(stderr, "ASSIGNING IP = %s\n", ip.toIpString().c_str()); } return true; // TODO: what is exapected? } @@ -152,7 +153,6 @@ std::vector<InetAddress> NetconEthernetTap::ips() const void NetconEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) { - fprintf(stderr, "put\n"); if (!_enabled) return; @@ -164,30 +164,48 @@ void NetconEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType Mutex::Lock _l2(_arp_m); _arp.processIncomingArp(data,len,arpReplyBuf,arpReplyLen,arpReplyDest); if (arpReplyLen > 0) + fprintf(stderr, "ARP reply generated\n"); _handler(_arg,_nwid,_mac,from,ZT_ETHERTYPE_ARP,0,arpReplyBuf,arpReplyLen); - } else if (etherType == ZT_ETHERTYPE_IPV4) { - - // Pass IPV4 packets to LWIP + } + else if (etherType == ZT_ETHERTYPE_IPV4) { + // Copy data into a pbuf chain struct pbuf *p, *q; - u16_t len; - char *bufptr; + //u16_t len; + char buf[1514]; + char *bufptr; - // allocate a pbuf chain of pbufs from the pool - p = lwipstack->pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + // We allocate a pbuf chain of pbufs from the pool. + p = lwipstack->pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - if(p != NULL) { - // We iterate over the pbuf chain until we have read the entire packet into the pbuf. - bufptr = (char*)data; + if(p != NULL) { + /* We iterate over the pbuf chain until we have read the entire + packet into the pbuf. */ + bufptr = &buf[0]; for(q = p; q != NULL; q = q->next) { - // read data into(q->payload, q->len); - memcpy(q->payload, bufptr, q->len); - bufptr += q->len; - } - // acknowledge that packet has been read(); - } else { - fprintf(stderr, "packet dropped\n"); - } + /* Read enough bytes to fill this pbuf in the chain. The + available data in the pbuf is given by the q->len + variable. */ + /* read data into(q->payload, q->len); */ + memcpy(q->payload, bufptr, q->len); + bufptr += q->len; + } + /* acknowledge that packet has been read(); */ + } else { + /* drop packet(); */ + } + + // Assemble ethernet header and call netif->output + struct eth_hdr *ethhdr; + ethhdr = (struct eth_hdr *)p->payload; + from.copyTo(ethhdr->src.addr, 6); + _mac.copyTo(ethhdr->dest.addr, 6); + ethhdr->type = ZT_ETHERTYPE_IPV4; + + if(interface.input(p, &interface) != ERR_OK) + { + fprintf(stderr, "IP error (netif->input)\n"); + } } } @@ -285,19 +303,36 @@ void NetconEthernetTap::closeConnection(NetconConnection *conn) } +/*------------------------------------------------------------------------------ +------------------------ low-level Interface functions ------------------------- +------------------------------------------------------------------------------*/ + + void NetconEthernetTap::threadMain() throw() { fprintf(stderr, "starting threadMain()\n"); + static ip_addr_t ipaddr, netmask, gw; char ip_str[16] = {0}, nm_str[16] = {0}, gw_str[16] = {0}; - IP4_ADDR(&gw, 192,168,0,1); - IP4_ADDR(&netmask, 255,255,255,0); - IP4_ADDR(&ipaddr, 192,168,0,2); + + if(_ips.size() == 0) { + fprintf(stderr, "no IP assigned. Exiting.\n"); + exit(0); + } + + IP4_ADDR(&gw,0,0,0,0); + ipaddr.addr = *((u32_t *)_ips[0].rawIpData()); + netmask.addr = *((u32_t *)_ips[0].netmask().rawIpData()); + strncpy(ip_str, lwipstack->ipaddr_ntoa(&ipaddr), sizeof(ip_str)); strncpy(nm_str, lwipstack->ipaddr_ntoa(&netmask), sizeof(nm_str)); strncpy(gw_str, lwipstack->ipaddr_ntoa(&gw), sizeof(gw_str)); + fprintf(stderr, "ip_str = %s\n", ip_str); + fprintf(stderr, "nm_str = %s\n", nm_str); + fprintf(stderr, "gw_str = %s\n", gw_str); + unsigned long tcp_time = ARP_TMR_INTERVAL / 5000; unsigned long etharp_time = IP_TMR_INTERVAL / 1000; unsigned long prev_tcp_time = 0; @@ -307,6 +342,37 @@ void NetconEthernetTap::threadMain() unsigned long since_etharp; struct timeval tv; + /* set up the faux-netif for LWIP's sake */ + fprintf(stderr, "netif_add\n"); + lwipstack->netif_add(&interface,&ipaddr, &netmask, &gw, NULL, tapif_init, lwipstack->ethernet_input); + + + fprintf(stderr, "initializing interface\n"); + struct tapif *tapif; + tapif = (struct tapif *)mem_malloc(sizeof(struct tapif)); + if (!tapif) { + //return ERR_MEM; + } + //interface.state = tapif; + interface.state = this; + interface.name[0] = 't'; + interface.name[1] = 'p'; + interface.output = lwipstack->etharp_output; + interface.linkoutput = low_level_output; + interface.mtu = 1500; + /* hardware address length */ + interface.hwaddr_len = 6; + tapif->ethaddr = (struct eth_addr *)&(interface.hwaddr[0]); + interface.flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP; + low_level_init(&interface); + + fprintf(stderr, "netif_set_default\n"); + lwipstack->netif_set_default(&interface); + fprintf(stderr, "netif_set_up\n"); + lwipstack->netif_set_up(&interface); + fprintf(stderr, "complete\n"); + + while (_run) { gettimeofday(&tv, NULL); curr_time = (unsigned long)(tv.tv_sec) * 1000 + (unsigned long)(tv.tv_usec) / 1000; @@ -325,7 +391,8 @@ void NetconEthernetTap::threadMain() lwipstack->etharp_tmr(); } fprintf(stderr, "_run\n"); - _phy.poll(min_time / 1000); // conversion from usec to millisec, TODO: double check + _phy.poll(100); // conversion from usec to millisec, TODO: double check + } // TODO: cleanup -- destroy LWIP state, kill any clients, unload .so, etc. } @@ -704,7 +771,7 @@ void NetconEthernetTap::handle_connect(NetconClient *client, struct connect_st* // that's it! // - Most instances of a retval for a connect() should happen // in the nc_connect() and nc_err() callbacks! - fprintf(stderr, "failed to connect: %s\n", lwiperror(err)); + //fprintf(stderr, "failed to connect: %s\n", lwiperror(err)); send_return_value(client, err); } // Everything seems to be ok, but we don't have enough info to retval @@ -717,6 +784,7 @@ void NetconEthernetTap::handle_connect(NetconClient *client, struct connect_st* void NetconEthernetTap::handle_write(NetconConnection *c) { + fprintf(stderr, "handle_write"); if(c) { int sndbuf = c->pcb->snd_buf; float avail = (float)sndbuf; diff --git a/netcon/NetconEthernetTap.hpp b/netcon/NetconEthernetTap.hpp index c1c667aa..f48f9e80 100644 --- a/netcon/NetconEthernetTap.hpp +++ b/netcon/NetconEthernetTap.hpp @@ -48,6 +48,14 @@ #include "NetconService.hpp" #include "NetconUtilities.hpp" +#include "netif/etharp.h" + +struct tapif { + struct eth_addr *ethaddr; + /* Add whatever per-interface state that is needed here. */ + int fd; +}; + namespace ZeroTier { class NetconEthernetTap; @@ -86,6 +94,9 @@ public: throw(); LWIPStack *lwipstack; + uint64_t _nwid; + void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); + void *_arg; private: @@ -136,9 +147,6 @@ private: return conn_addr; } - void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); - void *_arg; - // Client helpers NetconConnection *getConnectionByThisFD(int fd); NetconConnection *getConnectionByPCB(struct tcp_pcb *pcb); @@ -146,12 +154,14 @@ private: void closeClient(NetconClient *client); void closeConnection(NetconConnection *conn); + Phy<NetconEthernetTap *> _phy; PhySocket *_unixListenSocket; std::vector<NetconClient*> clients; + netif interface; + - uint64_t _nwid; MAC _mac; Thread _thread; std::string _homePath; @@ -171,6 +181,66 @@ private: volatile bool _run; }; + +/*------------------------------------------------------------------------------ +------------------------ low-level Interface functions ------------------------- +------------------------------------------------------------------------------*/ + + static void low_level_init(struct netif *netif) + { + } + + static err_t tapif_init(struct netif *netif) + { + return ERR_OK; + } + + static err_t low_level_output(struct netif *netif, struct pbuf *p) + { + struct pbuf *q; + char buf[1514]; + char *bufptr; + //struct tapif *tapif; + int tot_len = 0; + + //tapif = (struct tapif *)netif->state; + ZeroTier::NetconEthernetTap *tap = (ZeroTier::NetconEthernetTap*)netif->state; + + #if 0 + if(((double)rand()/(double)RAND_MAX) < 0.2) { + printf("drop output\n"); + return ERR_OK; + } + #endif + /* initiate transfer(); */ + + bufptr = &buf[0]; + + for(q = p; q != NULL; q = q->next) { + /* Send the data from the pbuf to the interface, one pbuf at a + time. The size of the data in each pbuf is kept in the ->len + variable. */ + /* send data from(q->payload, q->len); */ + memcpy(bufptr, q->payload, q->len); + bufptr += q->len; + tot_len += q->len; + } + + // signal that packet should be sent(); + // Split ethernet header and feed into handler + struct eth_hdr *ethhdr; + ethhdr = (struct eth_hdr *)p->payload; + + ZeroTier::MAC src_mac; + ZeroTier::MAC dest_mac; + + src_mac.setTo(ethhdr->src.addr, 6); + dest_mac.setTo(ethhdr->dest.addr, 6); + + tap->_handler(tap->_arg,tap->_nwid,src_mac,dest_mac,ZT_ETHERTYPE_IPV4,0,buf,p->tot_len); + return ERR_OK; + } + } // namespace ZeroTier #endif // ZT_ENABLE_NETCON diff --git a/netcon/liblwip.so b/netcon/liblwip.so Binary files differindex 18c04c3d..75b8f0a0 100755 --- a/netcon/liblwip.so +++ b/netcon/liblwip.so diff --git a/osdep/Arp.cpp b/osdep/Arp.cpp index f71dfb54..2ca00f0d 100644 --- a/osdep/Arp.cpp +++ b/osdep/Arp.cpp @@ -65,7 +65,7 @@ uint32_t Arp::processIncomingArp(const void *arp,unsigned int len,void *response responseLen = 0; responseDest.zero(); - if (len > 28) { + if (len >= 28) { if (!memcmp(arp,ARP_REQUEST_HEADER,8)) { // Respond to ARP requests for locally-known IPs _ArpEntry *targetEntry = _cache.get(reinterpret_cast<const uint32_t *>(arp)[6]); |