WebSocketTransport::WebSocketTransport(websocketpp::connection_hdl hdl, websocket::Server& server, time::milliseconds pingInterval) : m_handle(hdl) , m_server(server) , m_pingInterval(pingInterval) { const auto& sock = m_server.get_con_from_hdl(hdl)->get_socket(); this->setLocalUri(FaceUri(sock.local_endpoint(), "ws")); this->setRemoteUri(FaceUri(sock.remote_endpoint(), "wsclient")); if (isLoopback(sock.local_endpoint().address()) && isLoopback(sock.remote_endpoint().address())) { this->setScope(ndn::nfd::FACE_SCOPE_LOCAL); } else { this->setScope(ndn::nfd::FACE_SCOPE_NON_LOCAL); } this->setPersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND); this->setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT); this->setMtu(MTU_UNLIMITED); this->schedulePing(); NFD_LOG_FACE_INFO("Creating transport"); }
bool IpAddr::isPrivate() const { if (isLoopback()) { ERROR("IpAddr::isPrivate: %s LOOPBACK", toString().c_str()); return true; } switch (addr.addr.sa_family) { case AF_INET: uint8_t b1, b2; b1 = (uint8_t)(addr.ipv4.sin_addr.s_addr >> 24); b2 = (uint8_t)((addr.ipv4.sin_addr.s_addr >> 16) & 0x0ff); // 10.x.y.z if (b1 == 10) return true; // 172.16.0.0 - 172.31.255.255 if ((b1 == 172) && (b2 >= 16) && (b2 <= 31)) return true; // 192.168.0.0 - 192.168.255.255 if ((b1 == 192) && (b2 == 168)) return true; return false; case AF_INET6: { const pj_uint8_t* addr6 = reinterpret_cast<const pj_uint8_t*>(&addr.ipv6.sin6_addr); if (addr6[0] == 0xfc) return true; return false; } default: return false; } }
bool IPEndpoint::V4::isPrivate () const { return ((value&0xff000000)==0x0a000000) || // Prefix /8, 10.##.#.# ((value&0xfff00000)==0xac100000) || // Prefix /12 172.16.#.# - 172.31.#.# ((value&0xffff0000)==0xc0a80000) || // Prefix /16 192.168.#.# isLoopback(); }
//--------------------------------------------------------------------------- void IPAddress::getIPv4(sockaddr_in &outAddress) const throw(IPAddress::Exceptions::NotIPv4) { memset(&(outAddress), 0, sizeof(outAddress)); #ifdef HAVE_SOCKADDR_IN_LEN outAddress.sin_len = sizeof(outAddress); #endif // HAVE_SOCKADDR_IN_LEN outAddress.sin_family = AF_INET; #ifdef _WIN32 if (isLoopback()) outAddress.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK); // loopback is a special case since it could be stored as ::1 in IPv6 else outAddress.sin_addr.S_un.S_addr = htonl(getIPv4AddressAsDWORD()); #else if (isLoopback()) outAddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK); // loopback is a special case since it could be stored as ::1 in IPv6 else outAddress.sin_addr.s_addr = htonl(getIPv4AddressAsDWORD()); #endif //_WIN32 outAddress.sin_port = mPort; }
InterfaceIndexTable *getInterfaceIndexTableInt( BOOL nonLoopbackOnly ) { DWORD numInterfaces, curInterface = 0; int i; IFInfo *ifInfo; InterfaceIndexTable *ret = 0; HANDLE tcpFile; NTSTATUS status = openTcpFile( &tcpFile, FILE_READ_DATA ); if( NT_SUCCESS(status) ) { status = getInterfaceInfoSet( tcpFile, &ifInfo, &numInterfaces ); TRACE("InterfaceInfoSet: %08x, %04x:%08x\n", status, ifInfo->entity_id.tei_entity, ifInfo->entity_id.tei_instance); if( NT_SUCCESS(status) ) { ret = (InterfaceIndexTable *) calloc(1, sizeof(InterfaceIndexTable) + (numInterfaces - 1) * sizeof(DWORD)); if (ret) { ret->numAllocated = numInterfaces; TRACE("NumInterfaces = %d\n", numInterfaces); for( i = 0; i < numInterfaces; i++ ) { TRACE("Examining interface %d\n", i); if( !nonLoopbackOnly || !isLoopback( tcpFile, &ifInfo[i].entity_id ) ) { TRACE("Interface %d matches (%d)\n", i, curInterface); ret->indexes[curInterface++] = ifInfo[i].if_info.ent.if_index; } } ret->numIndexes = curInterface; } tdiFreeThingSet( ifInfo ); } closeTcpFile( tcpFile ); } return ret; }
static DWORD getNumInterfacesInt(BOOL onlyNonLoopback) { DWORD numEntities, numInterfaces = 0; TDIEntityID *entitySet; HANDLE tcpFile; NTSTATUS status; int i; status = openTcpFile( &tcpFile, FILE_READ_DATA ); if( !NT_SUCCESS(status) ) { WARN("getNumInterfaces: failed %08x\n", status ); return 0; } status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities ); if( !NT_SUCCESS(status) ) { WARN("getNumInterfaces: failed %08x\n", status ); closeTcpFile( tcpFile ); return 0; } for( i = 0; i < numEntities; i++ ) { if( isInterface( &entitySet[i] ) && (!onlyNonLoopback || (onlyNonLoopback && !isLoopback( tcpFile, &entitySet[i] ))) ) numInterfaces++; } TRACE("getNumInterfaces: success: %d %d %08x\n", onlyNonLoopback, numInterfaces, status ); closeTcpFile( tcpFile ); tdiFreeThingSet( entitySet ); return numInterfaces; }
void rxpacket(int sock) { Packet pkt; memset(&pkt, 0, sizeof(pkt)); // using recvmsg int size; // size of the received data struct msghdr msg; memset(&msg, 0, sizeof(msg)); struct sockaddr_in from; int fromlen=sizeof(from); msg.msg_name = &from; msg.msg_namelen = fromlen; char anciliary[2048]; msg.msg_control = anciliary; msg.msg_controllen = sizeof(anciliary); struct iovec iov[1]; memset(iov, 0, sizeof(iov)); iov[0].iov_base = &pkt.data; iov[0].iov_len = sizeof(pkt.data); msg.msg_iov = iov; msg.msg_iovlen = 1; struct cmsghdr *cmsg; unsigned int ifindex; // interface index struct in_addr hdraddr; // destination IP address in IP header size = recvmsg(sock, &msg, 0); if (size == -1) { ASSERT(0); rcpLog(muxsock, RCP_PROC_RIP, RLOG_ERR, RLOG_FC_RIP, "cannot read data on socket, attempting recovery..."); exit(1); } // verify packet size int sz = size - 4; if (sz<= 0 || (sz % sizeof(RipRoute)) != 0) { rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "Invalid RIP packet size"); return; } int routes = sz / sizeof(RipRoute); int found = 0; for(cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { // struct in_pktinfo { // unsigned int ipi_ifindex; /* Interface index */ // struct in_addr ipi_spec_dst; /* Local address */ // struct in_addr ipi_addr; /* Header Destination // address */ // }; hdraddr = ((struct in_pktinfo*)CMSG_DATA(cmsg))->ipi_addr; ifindex = ((struct in_pktinfo*)CMSG_DATA(cmsg))->ipi_ifindex; found = 1; } } if (!found) return; pkt.ip_source = ntohl(from.sin_addr.s_addr); pkt.ip_dest = ntohl(hdraddr.s_addr); pkt.if_index = ifindex; // is the source ip address one of our addresses? RcpInterface *rxif = rcpFindInterface(shm, pkt.ip_source); if (rxif) { // on Linux, packets we send to the multicast group will be received back on the socket return; } char *cmd[] = {"", "request", "response"}; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "Receiving RIP packet of size %d, from %d.%d.%d.%d, destination %d.%d.%d.%d, RIP %s, protocol version %d", size, RCP_PRINT_IP(pkt.ip_source), RCP_PRINT_IP(pkt.ip_dest), cmd[(pkt.data.command <= 2) ? pkt.data.command: 0], pkt.data.version); // update neighbor list RipNeighbor *neigh = neighbors; while (neigh != NULL) { if (neigh->ip == pkt.ip_source) { neigh->rx_time = 0; break; } neigh = neigh->next; } if (neigh == NULL) { RipNeighbor *newneigh = malloc(sizeof(RipNeighbor)); if (newneigh != NULL) { memset(newneigh, 0, sizeof(RipNeighbor)); newneigh->ip = pkt.ip_source; newneigh->next = neighbors; neighbors = newneigh; neigh = newneigh; } else { ASSERT(0); rcpLog(muxsock, RCP_PROC_RIP, RLOG_ERR, RLOG_FC_RIP, "cannot allocate memory, attempting recovery..."); exit(1); } } // do we have a valid interface? rxif =rcpFindInterfaceByKIndex(shm, pkt.if_index); if (rxif == NULL) { neigh->errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid interface, dropping..."); return; } // do we have a configured neighbor? RcpRipPartner *rxnetwork = NULL; RcpRipPartner *net; int i; for (i = 0, net = shm->config.rip_neighbor; i < RCP_RIP_NEIGHBOR_LIMIT; i++, net++) { if (!net->valid) continue; // matching both source and destination addresses if (net->ip == pkt.ip_source && rxif->ip == pkt.ip_dest) { rxnetwork = net; break; } } // if no configured neighbor was found, try to find a configured network if (rxnetwork == NULL) rxnetwork = find_network_for_interface(rxif); // no network or neighbor configured, just drop the packet if (rxnetwork == NULL) { neigh->errors++; // the network can get disabled while receiving packets rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid network or neighbor, dropping..."); return; } // the source of the datagram must be on a directly-connected network if ((pkt.ip_source & rxif->mask) != (rxif->ip & rxif->mask)) { neigh->errors++; // interface ip addresses are changing dynamically via CLI rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid source IP address, dropping..."); return; } // drop invalid command packets if (pkt.data.command > 2) { neigh->errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid RIP command, dropping..."); return; } if (pkt.data.command == 1) { rxnetwork->req_rx++; // force a response in one second rxif->rip_timeout = 1; return; } else rxnetwork->resp_rx++; ASSERT(sizeof(RipAuthMd5) == sizeof(RipAuthSimple)); ASSERT(sizeof(RipAuthSimple) == sizeof(RipRoute)); RipRoute *ptr = &pkt.data.routes[0]; int rt = 0; // if md5 auth configured, and the packet is missing the auth header, drop the packet if (rxif->rip_passwd[0] != '\0') { if (ptr->family != 0xffff || ntohs(ptr->tag) != 3) { neigh->md5_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " missing MD5 authentication header"); return; } } // checking auth header and calculate md5 if (ptr->family == 0xffff) { // we don't care about simple auth if (ntohs(ptr->tag) == 3 && rxif->rip_passwd[0] != '\0') { RipAuthMd5 *md5 = (RipAuthMd5 *) ptr; uint16_t offset = ntohs(md5->offset); uint32_t seq = ntohl(md5->seq); rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " MD5 auth offset %u, key id %d, auth_len %d, seq %u", offset, md5->key_id, md5->auth_len, ntohl(md5->seq)); // check offset if ((offset + sizeof(RipRoute)) != size) { neigh->md5_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid offset"); return; } // check seq if (seq != 0 && seq < neigh->auth_seq) { neigh->md5_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid sequence number"); return; } neigh->auth_seq = seq; // calculate md5 uint8_t secret[16]; memset(secret, 0, 16); memcpy(secret, rxif->rip_passwd, strlen(rxif->rip_passwd)); MD5_CTX context; uint8_t digest[16]; MD5Init (&context); MD5Update (&context, (uint8_t *) &pkt, size - 16); MD5Update (&context, secret, 16); MD5Final (digest, &context); #if 0 { int i; uint8_t *p = digest; printf("rx digest:\n"); for (i = 0; i < 16; i++,p++) printf("%02x ", *p); printf("\n"); } #endif // compare md5 if (memcmp((uint8_t *) ptr + offset, digest, 16) != 0) { neigh->md5_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid MD5 digest"); return; } } ptr++; rt++; routes--; // the last route is the digest } // parsing routes while (rt < routes) { uint32_t metric = ntohl(ptr->metric); uint32_t mask = ntohl(ptr->mask); uint32_t ip = ntohl(ptr->ip); uint32_t gw = ntohl(ptr->gw); // if (trace_prefix == 0 || // (trace_prefix != 0 && trace_prefix == ip)) { // if (gw == 0) // rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, // " %d.%d.%d.%d/%d metric %u", // RCP_PRINT_IP(ip), // mask2bits(mask), // metric); // else // rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, // " %d.%d.%d.%d/%d metric %u next hop %d.%d.%d.%d", // RCP_PRINT_IP(ip), // mask2bits(mask), // metric, // RCP_PRINT_IP(gw)); // } // only AF_INET family is supported if (ntohs(ptr->family) != AF_INET) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid route family"); goto next_element; } // check destination for loopback addresses if (isLoopback(ip)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid loopback route prefix"); goto next_element; } // check destination for broadcast addresses if (isBroadcast(ip)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid broadcast route prefix"); goto next_element; } // check destination for multicast addresses if (isMulticast(ip)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid multicast route prefix"); goto next_element; } // validate route metric else if (metric > 16 || metric == 0) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid metric"); goto next_element; } // validate route entry if (ip == 0 && mask == 0) { rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " received default route metric %d", metric); } else if (pkt.data.version == 2 && mask == 0) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid RIP route"); goto next_element; } else if (pkt.data.version == 1 && mask != 0) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid RIP route"); goto next_element; } // check if the mask is contiguous if (mask != 0 && !maskContiguous(mask)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid mask"); goto next_element; } // validate next hop if (gw) { if (isLoopback(gw) || isMulticast(gw) || isBroadcast(gw)) { neigh->route_errors++; rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, " invalid next hop"); goto next_element; } } // manufacture mask for rip v1 if (pkt.data.version == 1) mask = classMask(ip); // RFC metric = metric + interface cost // we assume a cost of 1 for each interface metric++; // add the route in the database if (metric < 16) { //RFC //- Setting the destination address to the destination address in the // RTE // // - Setting the metric to the newly calculated metric (as described // above) // // - Set the next hop address to be the address of the router from which // the datagram came // // - Initialize the timeout for the route. If the garbage-collection // timer is running for this route, stop it (see section 3.6 for a // discussion of the timers) // // - Set the route change flag // // - Signal the output process to trigger an update (see section 3.8.1) // a next hop of 0 means send the packets to me if (gw == 0) gw = pkt.ip_source; ripdb_add(RCP_ROUTE_RIP, ip, mask, gw, metric, pkt.ip_source, rxif); } else { // a next hop of 0 means send the packets to me if (gw == 0) gw = pkt.ip_source; ripdb_delete(RCP_ROUTE_RIP, ip, mask, gw, pkt.ip_source); } next_element: ptr++; rt++; } }