2016-09-07 4 views
1

Ich habe Probleme mit einem Raw Sockets-Programm, das ich gerade zusammenstelle. Ich entwickle auf Ubuntu 16.04 und benutze die sys/sockets.h Datei. Meine Ubuntu-Box ist eine virtuelle Maschine, die über meinen physischen Windows 10-PC NAT (VMWare) zu meinem physischen Netzwerk geroutet wird.Keine Erkennung von UDP-Paketen mit Raw Sockets

Ich habe den folgenden Code geschrieben und führen Sie mein Programm als root (Raw-Socket-Berechtigungen Fehler zu verhindern). Ich erhalte keinen Fehlercode von den Befehlen socket(), setsockopt() oder sendto(). Sendto() gibt 32 zurück, was impliziert, dass ein UDP-Paket gesendet wird. Wireshark scheint jedoch keinen Hinweis darauf zu geben, dass dieses Paket jemals in das Netzwerk freigegeben wird.

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); 
} 

^^ Packet.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

Teil dessen, was mich ist verwirrend ist, dass selbst hören Mit Wireshark auf dem Ubuntu-Rechner ergeben sich keine Ergebnisse, so dass es so aussieht, als würde das Paket die Schnittstelle überhaupt nicht verlassen. Hat jemand einen Rat dafür?

+0

müssen Sie auch den Ethernet-Header ausfüllen und einen MAC-Adr des IF auf einem Socket setzen. Sehen Sie nach: https://gist.github.com/austinmarton/1922600 – Serge

+1

Bitte versuchen Sie ein Bridged VM-Netzwerk anstelle von NAT, das das Problem für mich gelöst hat. – Robert

Antwort

1

Es stellte sich heraus, dass das Ausführen des VM-Netzwerkadapters im NAT-Modus das Problem verursachte. Sobald ich zur Brücke wechselte, war alles gut.