コード例 #1
0
ファイル: us_rawnet.c プロジェクト: andrew-elder/microsupport
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;
}
コード例 #2
0
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;
}
コード例 #3
0
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;
}
コード例 #4
0
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;
}
コード例 #5
0
ファイル: us_rawnet.c プロジェクト: andrew-elder/microsupport
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;
}