1
我正在努力處理我正在放在一起的原始套接字程序。我正在開發Ubuntu 16.04並使用sys/sockets.h文件。我的Ubuntu盒子是一臺虛擬機器,它通過我的物理Windows 10 PC,通過NAT路由(VMWare)到我的物理網絡。使用原始套接字沒有檢測到UDP數據包
我已經寫了下面的代碼並以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);
}
^^ 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
什麼困惑我的部分原因是,在聽在Ubuntu機器上使用Wireshark不會產生任何結果,因此看起來數據包根本就不會真正離開接口。有沒有人對此有任何建議?
您還需要填寫以太網報頭,並在套接字上設置outg IF的MAC地址。看看:https://gist.github.com/austinmarton/1922600 – Serge
請嘗試橋接虛擬機網絡,而不是NAT,這解決了我的問題。 – Robert