示例#1
0
void PacketSender::close_socket(SocketType type, const NetworkInterface &iface) {
    if(type == ETHER_SOCKET) {
        #if defined(BSD) || defined(__FreeBSD_kernel__)
        BSDEtherSockets::iterator it = _ether_socket.find(iface.id());
        if(it == _ether_socket.end())
            throw invalid_socket_type();
        if(::close(it->second) == -1)
            throw socket_close_error(make_error_string());
        _ether_socket.erase(it);
        #elif !defined(WIN32)
        if(_ether_socket == INVALID_RAW_SOCKET)
            throw invalid_socket_type();
        if(::close(_ether_socket) == -1)
            throw socket_close_error(make_error_string());
        _ether_socket = INVALID_RAW_SOCKET;
        #endif
    }
    else {
        if(type >= SOCKETS_END || _sockets[type] == INVALID_RAW_SOCKET)
            throw invalid_socket_type();
        #ifndef WIN32
        if(close(_sockets[type]) == -1)
            throw socket_close_error(make_error_string());
        #else
        closesocket(_sockets[type]);
        #endif
        _sockets[type] = INVALID_RAW_SOCKET;
    }
}
示例#2
0
void RadioTap::send(PacketSender &sender, const NetworkInterface &iface) {
    if(!iface)
        throw invalid_interface();

#if !defined(BSD) && !defined(__FreeBSD_kernel__)
    struct sockaddr_ll addr;

    memset(&addr, 0, sizeof(struct sockaddr_ll));

    addr.sll_family = Endian::host_to_be<uint16_t>(PF_PACKET);
    addr.sll_protocol = Endian::host_to_be<uint16_t>(ETH_P_ALL);
    addr.sll_halen = 6;
    addr.sll_ifindex = iface.id();

    const Tins::Dot11 *wlan = tins_cast<Tins::Dot11*>(inner_pdu());
    if(wlan) {
        Tins::Dot11::address_type dot11_addr(wlan->addr1());
        std::copy(dot11_addr.begin(), dot11_addr.end(), addr.sll_addr);
    }

    sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
#else
    sender.send_l2(*this, 0, 0, iface);
#endif
}
示例#3
0
void PacketSender::open_l2_socket(const NetworkInterface& iface) {
    #if defined(BSD) || defined(__FreeBSD_kernel__)
        int sock = -1;
        // At some point, there should be an available device
        for (int i = 0; sock == -1;i++) {
            std::ostringstream oss;
            oss << "/dev/bpf" << i;

            sock = open(oss.str().c_str(), O_RDWR);
        }
        if(sock == -1) 
            throw socket_open_error(make_error_string());
        
        struct ifreq ifr;
        strncpy(ifr.ifr_name, iface.name().c_str(), sizeof(ifr.ifr_name) - 1);
        if(ioctl(sock, BIOCSETIF, (caddr_t)&ifr) < 0) {
            ::close(sock);
            throw socket_open_error(make_error_string());
        }
        _ether_socket[iface.id()] = sock;
    #else
    if (_ether_socket == INVALID_RAW_SOCKET) {
        _ether_socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
        
        if (_ether_socket == -1)
            throw socket_open_error(make_error_string());
    }
    #endif
}
示例#4
0
bool PacketSender::ether_socket_initialized(const NetworkInterface& iface) const {
    #if defined(BSD) || defined(__FreeBSD_kernel__)
    return _ether_socket.count(iface.id());
    #else
    return _ether_socket != INVALID_RAW_SOCKET;
    #endif
}
示例#5
0
int PacketSender::get_ether_socket(const NetworkInterface& iface) {
    if(!ether_socket_initialized(iface))
        open_l2_socket(iface);
    #if defined(BSD) || defined(__FreeBSD_kernel__)
    return _ether_socket[iface.id()];
    #else
    return _ether_socket;
    #endif
}
示例#6
0
void Dot11::send(PacketSender &sender, const NetworkInterface &iface) {
    if(!iface)
        throw invalid_interface();
    
    #if !defined(BSD) && !defined(__FreeBSD_kernel__)
        sockaddr_ll addr;

        memset(&addr, 0, sizeof(struct sockaddr_ll));

        addr.sll_family = Endian::host_to_be<uint16_t>(PF_PACKET);
        addr.sll_protocol = Endian::host_to_be<uint16_t>(ETH_P_ALL);
        addr.sll_halen = 6;
        addr.sll_ifindex = iface.id();
        memcpy(&(addr.sll_addr), _header.addr1, 6);
        sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
    #else
        sender.send_l2(*this, 0, 0, iface);
    #endif
}
示例#7
0
void EthernetII::send(PacketSender &sender, const NetworkInterface &iface) {
    if(!iface)
        throw invalid_interface();
    #if defined(HAVE_PACKET_SENDER_PCAP_SENDPACKET) || defined(BSD) || defined(__FreeBSD_kernel__)
        // Sending using pcap_sendpacket/BSD bpf packet mode is the same here
        sender.send_l2(*this, 0, 0, iface);
    #elif defined(WIN32)
        // On Windows we can only send l2 PDUs using pcap_sendpacket
        throw std::runtime_error("LIBTINS_USE_PCAP_SENDPACKET is not enabled");
    #else
        // Default GNU/Linux behaviour
        struct sockaddr_ll addr;

        memset(&addr, 0, sizeof(struct sockaddr_ll));

        addr.sll_family = Endian::host_to_be<uint16_t>(PF_PACKET);
        addr.sll_protocol = Endian::host_to_be<uint16_t>(ETH_P_ALL);
        addr.sll_halen = address_type::address_size;
        addr.sll_ifindex = iface.id();
        memcpy(&(addr.sll_addr), _eth.dst_mac, address_type::address_size);

        sender.send_l2(*this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr));
    #endif
}