Мой учитель хочет, чтобы мы выполнили упражнение на raw-сокете в c ++ для Windows (для изучения tcp-связи).
У меня есть проблема с этим. Я видел много документации, но я не знаю, как ее решить.
int raw()
{
WSADATA WSAData;
SOCKET sock;
SOCKADDR_IN sin,din;
WSAStartup(MAKEWORD(2, 2), &WSAData);
char datagram[MAX_PACKET_SIZE];
struct iphdr *iph = (struct iphdr *)datagram;
struct tcphdr *tcph = (struct tcphdr *)((UCHAR *)iph + sizeof(tcphdr));
char new_ip[sizeof "255.255.255.255"];
sock = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
cout << "failled init socket" << endl ;
else{
memset(datagram, 0, MAX_PACKET_SIZE); // Clear the data
setup_ip_header(iph);
setup_tcp_header(tcph);
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);
sin.sin_addr.s_addr = inet_addr("192.168.1.10"); //source ip
din.sin_family = AF_INET;
din.sin_port = htons(DEST_PORT);
din.sin_addr.s_addr = inet_addr(TARGET_SERV_IP); //ip serv to connect
tcph->port_dest = htons(DEST_PORT);
iph->ip_dest = din.sin_addr.s_addr;
iph->ip_source = sin.sin_addr.s_addr;
iph->ip_dest = inet_addr(TARGET_SERV_IP); //ip serv to connect
iph->ip_source = inet_addr("192.168.1.10"); //source ip
//iph->checksum = csum((unsigned short *)datagram, iph->tot_len >> 1);
iph->checksum = csum((unsigned short *)datagram, sizeof(struct iphdr));
int one = 1;
const int *val = &one;
if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)val, sizeof(one)) < 0)
printf("failled set socket option IP_HDRINCL");
else{
if (sendto(sock, /* our socket */
datagram, /* the buffer containing headers and data */
ntohs( iph->tot_len), /* total length of our datagram */
0, /* routing flags, normally always 0 */
(struct sockaddr *) &sin, /* socket addr, just like in */
sizeof(sin)) < 0) /* a normal send() */
cout << stderr << "sendto() error!!!.\n " << WSAGetLastError() << endl;
else
cout << "packet send\n" << endl;
}
closesocket(sock);
}
}
Моя ошибка происходит в sendto (). возвращается ошибка 10022 = WSAEINVAL
Я видел, что может быть новая защита окон?
Есть ли у вас идеи, чтобы исправить мою проблему или обойти защиту (глубже, водитель и т. Д.)
Вы не устанавливаете iph-> tot_len в своем коде.
Моя рекомендация для сетевого кода с использованием c ++ будет использовать std :: string или std :: vector:
std::vector<uint8_t> packet(MAX_PACKET_SIZE, 0);
...
packet.resize(real_size);
затем используйте адрес (&пакет [0]) для ваших манипуляций с указателями.
Других решений пока нет …