c++ - 使用原始套接字未检测到 UDP 数据包

标签 c++ linux sockets networking

我正在努力处理我正在组装的 Raw Sockets 程序。我在 Ubuntu 16.04 上开发并使用 sys/sockets.h 文件。我的 Ubuntu 盒子是一个虚拟机,它通过我的物理 Windows 10 PC 通过 NAT 路由 (VMWare) 到我的物理网络。

我编写了以下代码并以 root 身份运行我的程序(以防止原始套接字权限错误)。我没有收到来自 socket()、setsockopt() 或 sendto() 命令的错误代码。 Sendto() 返回 32,表示正在发送 UDP 数据包。但是,Wireshark 似乎没有显示任何证据表明该数据包曾被发布到网络上。

int main(){
    cout << "UDP Packet Sender\n";
    PacketArgs* p_args = new PacketArgs;
    p_args->setDestIP("192.168.204.1");
    p_args->setSrcIP("192.168.204.128");
    p_args->setDestPort(500);
    p_args->setSrcPort(500);
    p_args->setProtocol(17);
    p_args->setPacketLength(sizeof(struct ip_header)+ sizeof(struct udp_header));

    UDPArgs* udp_args = new UDPArgs;
    udp_args->setSrcPort(500);
    udp_args->setDestPort(500);
    udp_args->setLength(htons(sizeof(udp_header)));

    UDPPacket* packet = new UDPPacket(p_args,udp_args);
    for(int i = 0; i < 10; i++){    
         packet->sendPacket();
    }
}

^^ main.cpp

Packet::Packet(PacketArgs* args){
    buffer = new char[PCKT_LENGTH];
    std::memset(buffer, 0, PCKT_LENGTH);
    m_packet = (ip_header*)buffer;
    m_packet->iph_ihl = 5;
    m_packet->iph_ver = 4;
    m_packet->iph_tos = 16;
    m_packet->iph_len = args->getPacketLength();
    m_packet->iph_ident = htons(54321);
    m_packet->iph_ttl = 64;
    m_packet->iph_protocol = args->getProtocol();
    m_packet->iph_sourceip = args->getSrcIP();
    m_packet->iph_destip = args->getDestIP();

}

unsigned short Packet::calculateChecksum(size_t* buf, int nwords){
    unsigned long sum;
    for(sum=0; nwords>0; nwords--)
        sum += *buf++;
    sum = (sum >> 16) + (sum &0xffff);
    sum += (sum >> 16);
    return (unsigned short) (~sum);
}

^^ 数据包.cpp

UDPPacket::UDPPacket(PacketArgs* p_args, UDPArgs* udp_args): Packet(p_args){
    m_udp = (struct udp_header*)(buffer + sizeof(struct ip_header));
    m_udp->udph_srcport = udp_args->getDestPort();
    m_udp->udph_destport = udp_args->getSrcPort();
    m_udp->udph_len = htons(sizeof(struct udp_header));
    m_packet->iph_checksum = calculateChecksum((size_t*)&m_packet, sizeof(struct ip_header) + sizeof(struct udp_header));
}

int UDPPacket::sendPacket(){
    int sd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP);

    struct sockaddr_in src, dest;   
    src.sin_family = AF_INET;
    dest.sin_family = AF_INET;

    src.sin_port = htons(m_udp->udph_srcport);
    dest.sin_port = htons(m_udp->udph_destport);
    src.sin_addr.s_addr = m_packet->iph_sourceip;
    dest.sin_addr.s_addr = m_packet->iph_destip;

    int one = 1;
    const int* val = &one;

    int sso = setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(one));

    std::cout << "sso is: " << sso << std::endl << "sd is: " << sd << std::endl;

    int st = sendto(sd,buffer,m_packet->iph_len,0,(struct sockaddr*)&src, sizeof(src));

    std::cout << "st is: " << st << std::endl;

}

^^ UDPPacket.cpp

让我感到困惑的部分原因是,即使在 Ubuntu 机器上使用 Wireshark 进行监听也不会产生任何结果,因此数据包似乎从未真正离开过接口(interface)。有人对此有什么建议吗?

最佳答案

原来是在 NAT 模式下运行 VM 网络适配器导致了这个问题。一旦我切换到桥接,一切都很好。

关于c++ - 使用原始套接字未检测到 UDP 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39362413/

相关文章:

python - 取消接受和关闭 Python 处理/多处理监听器连接的正确方法

c++ - 快速射线和多边形相交

c++ - 多变量for循环

java - Play框架Windows v的Linux文件路径

linux根据文件名模式搜索文件

linux - Chrome 不能播放 MP4

java - 非阻塞 I/O 与使用线程(上下文切换有多糟糕?)

python - 通过socket发送wav文件

c++ - Ifstream 因未知原因失败

C++ 标准布局和引用