int us_rawnet_socket(us_rawnet_context_t *self, uint16_t ethertype, const char *interface_name, const uint8_t join_multicast[6]) { int fd = socket(AF_PACKET, SOCK_RAW, htons(ethertype)); if( join_multicast ) { memcpy( self->m_default_dest_mac, join_multicast, 6 ); } if (fd >= 0 && interface_name) { int i; struct ifreq ifr; strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name) - 1); if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { close(fd); return -1; } self->m_interface_id = ifr.ifr_ifindex; if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { close(fd); return -1; } for (i = 0; i < 6; ++i) { self->m_my_mac[i] = (uint8_t)ifr.ifr_hwaddr.sa_data[i]; } self->m_fd = fd; self->m_ethertype = ethertype; if (join_multicast) { us_rawnet_join_multicast(self, join_multicast); } us_net_set_socket_nonblocking(fd); } return fd; }
int us_socket_collection_add_multicast_udp( us_socket_collection_t *self, const char *local_addr_name, const char *local_port_name, const char *multicast_addr_name, const char *multicast_port_name, const char *network_port_name, void *context ) { struct addrinfo *local_addr; struct addrinfo *multicast_addr; int fd; local_addr = us_net_get_addrinfo( local_addr_name, local_port_name, SOCK_DGRAM, true ); multicast_addr = us_net_get_addrinfo( multicast_addr_name, multicast_port_name, SOCK_DGRAM, false ); fd = us_net_create_multicast_rx_udp_socket( local_addr, multicast_addr, network_port_name ); if ( fd != -1 ) { us_net_set_socket_nonblocking( fd ); if ( !us_socket_collection_add_fd( self, fd, context ) ) { closesocket( fd ); fd = -1; } } return fd; }
int us_socket_collection_add_tcp_client( us_socket_collection_t *self, const char *remote_addr_name, const char *remote_port_name, void *context ) { int fd = -1; // make sure we have room before trying anything if ( self->num_sockets < US_SOCKET_COLLECTION_MAX_SOCKETS ) { // get the address of the remote struct addrinfo *remote_addr; remote_addr = us_net_get_addrinfo( remote_addr_name, remote_port_name, SOCK_STREAM, false ); // create the tcp client socket for this kind of address fd = us_net_create_tcp_socket( remote_addr, false ); // did it work? if ( fd != -1 ) { // yes, try initiate a connect int con_result; // we are doing a non blocking connect us_net_set_socket_nonblocking( fd ); // try connect, ignore signals during this time do { con_result = connect( fd, remote_addr->ai_addr, remote_addr->ai_addrlen ); } while ( con_result == -1 && errno == EINTR ); // If the connect succeeded or it is in progress, then track this fd if ( con_result == 0 || ( con_result == -1 && errno == EINPROGRESS ) ) { // Add the fd to the collection if ( !us_socket_collection_add_fd( self, fd, context ) ) { // unable to add the fd to the collection, close the socket closesocket( fd ); fd = -1; } } } } return fd; }
int us_socket_collection_add_tcp_server( us_socket_collection_t *self, const char *local_addr_name, const char *local_port_name, void *context ) { int fd; fd = us_net_create_tcp_socket_host( local_addr_name, local_port_name, true ); if ( fd != -1 ) { us_net_set_socket_nonblocking( fd ); if ( !us_socket_collection_add_fd( self, fd, context ) ) { closesocket( fd ); fd = -1; } } return fd; }
int us_rawnet_socket(us_rawnet_context_t *self, uint16_t ethertype, const char *interface_name, const uint8_t join_multicast[6]) { int r = -1; char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *p; self->m_ethertype = ethertype; if( join_multicast ) { memcpy( self->m_default_dest_mac, join_multicast, 6 ); } p = pcap_open_live(interface_name, 65536, 1, 1, errbuf); self->m_pcap = (void *)p; if (!p) { us_log_error("pcap open error on interface '%s': %s", interface_name, errbuf); } else { int dl = pcap_datalink(p); if (dl != DLT_EN10MB && dl != DLT_IEEE802_11) { us_log_error("Interface %s is not an Ethernet or wireless interface", interface_name); } else { pcap_if_t *d=0; self->m_interface_id = -1; if( us_rawnet_alldevs==0 ) { if (pcap_findalldevs(&us_rawnet_alldevs, errbuf) != 0 || us_rawnet_alldevs==0) { us_log_error("pcap_findalldevs failed"); pcap_close(p); return -1; } atexit(us_rawnet_cleanup); } { for (d = us_rawnet_alldevs; d != NULL; d = d->next) { self->m_interface_id++; /* find the interface by name */ if (strcmp(interface_name, d->name) == 0) { /* now find the MAC address associated with it */ #if defined(_WIN32) PIP_ADAPTER_INFO info = NULL, ninfo; ULONG ulOutBufLen = 0; DWORD dwRetVal = 0; if (GetAdaptersInfo(info, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { info = (PIP_ADAPTER_INFO)malloc(ulOutBufLen); if (info != NULL) { if ((dwRetVal = GetAdaptersInfo(info, &ulOutBufLen)) == NO_ERROR) { ninfo = info; while (ninfo != NULL) { if (strstr(d->name, ninfo->AdapterName) > 0) { if (ninfo->AddressLength == 6) memcpy(self->m_my_mac, ninfo->Address, 6); break; } ninfo = ninfo->Next; } } else us_log_error("Error in GetAdaptersInfo"); free(info); } else { us_log_error("Error in malloc for GetAdaptersInfo"); } } #else pcap_addr_t *alladdrs; pcap_addr_t *a; alladdrs = d->addresses; for (a = alladdrs; a != NULL; a = a->next) { #if defined(__APPLE__) /* Apple AF_LINK format depends on osx version */ if (a->addr->sa_family == AF_LINK && a->addr->sa_data != NULL) { struct sockaddr_dl *link = (struct sockaddr_dl *)a->addr->sa_data; uint8_t mac[link->sdl_alen]; memcpy(mac, LLADDR(link), link->sdl_alen); if (link->sdl_alen == 6) { /* older mac os x */ memcpy(self->m_my_mac, &mac[0], 6); } else if (link->sdl_alen > 6) { /* newer mac os x */ memcpy(self->m_my_mac, &mac[1], 6); } break; } #elif defined(__linux__) if (a->addr->sa_family == AF_PACKET) { struct sockaddr_ll *link = (struct sockaddr_ll *)a->addr; memcpy(self->m_my_mac, link->sll_addr, 6); break; } #endif } #endif break; } } if (self->m_interface_id == -1) { us_log_error("unable to get MAC address for interface '%s'", interface_name); } else { /* enable ether protocol filter */ us_rawnet_join_multicast(self, join_multicast); self->m_fd = pcap_fileno(p); if (self->m_fd == -1) { us_log_error("Unable to get pcap fd"); } else { r = self->m_fd; } } } } } if (r == -1) { if (p) { pcap_close(p); self->m_pcap = 0; } } else { us_net_set_socket_nonblocking(r); } return r; }