I want to send a UDP packet using the raw socket. If that works, next, I'd like to send by my own protocol using raw socket at e.g 89 instead of 17. Unfortunately nothing happens when I try to send a UDP packet on the Windows.There is no error code, so it should be sent but not... In the wireshark, I don't see any traffic during the program launch. The Windows firewall is off, so there's nothing to block. App also running with admin privileges.
I'll add that the same program works without problems on linux. The only difference is that there is no "WSAStartup", and I use "errno.h" to get error codes, besides the whole code is identical.
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <stdint.h>
#include <WinSock2.h>
#pragma comment(lib, "Ws2_32.lib")
#include <ws2ipdef.h>
#include <WS2tcpip.h>
#include <BaseTsd.h>
#include <inaddr.h>
typedef SSIZE_T ssize_t;
#define MAXHOSTNAMELEN 256
#define MSGSIZE 64
#define TTL 23
#define MESSAGE "azertyuiopqsdf"
static char source_addr[INET_ADDRSTRLEN];
static int protocol = 17;
static int port = 572;
static char progname[MAXHOSTNAMELEN + 1];
struct ip {
u_char ip_hl : 4, /* header length */
ip_v : 4; /* version */
u_char ip_tos; /* type of service */
short ip_len; /* total length */
u_short ip_id; /* identification */
short ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
struct udphdr {
u_short uh_sport; /* source port */
u_short uh_dport; /* destination port */
short uh_ulen; /* udp length */
u_short uh_sum; /* udp checksum */
};
struct udp_pseudo_header {
struct in_addr ip_src, ip_dst; /* source and dest address */
u_char mbz, ip_p;
u_short length;
};
struct opacket4 {
struct ip ip;
struct udphdr udp;
char payload[MSGSIZE];
};
uint16_t checksum(const void* buf, size_t buflen) {
uint32_t r = 0;
size_t len = buflen;
const uint16_t* d = reinterpret_cast<const uint16_t*>(buf);
while (len > 1) {
r += *d++;
len -= sizeof(uint16_t);
}
if (len) {
r += *reinterpret_cast<const uint8_t*>(d);
}
while (r >> 16) {
r = (r & 0xffff) + (r >> 16);
}
return static_cast<uint16_t>(~r);
}
char* text_of(struct sockaddr *address) {
char *text = (char*)malloc(INET_ADDRSTRLEN);
struct sockaddr_in *address_v4;
struct sockaddr_in6 *address_v6;
if (address->sa_family == AF_INET) {
address_v4 = (struct sockaddr_in *) address;
inet_ntop(AF_INET, &address_v4->sin_addr, text, INET_ADDRSTRLEN);
} else if (address->sa_family == AF_INET6) {
address_v6 = (struct sockaddr_in6 *) address;
inet_ntop(AF_INET6, &address_v6->sin6_addr, text, INET_ADDRSTRLEN);
} else {
strcpy(text, "Unknown address family");
}
return text;
}
int main(int argc, char **argv) {
char c;
char hostname[MAXHOSTNAMELEN + 1] = "31.24.11.66";
char message[MSGSIZE];
int status;
struct addrinfo hints_numeric, hints;
struct addrinfo *result, *source;
size_t packetsize, headersize, extraipheadersize;
struct opacket4 op4;
struct sockaddr_in *sockaddr4;
struct sockaddr_in6 *sockaddr6;
void *packet;
int on = 1;
strncpy(progname, argv[0], MAXHOSTNAMELEN);
progname[MAXHOSTNAMELEN] = 0;
int sd; // Socket Descriptor */
ssize_t num;
strcpy(message, MESSAGE);
strcpy(source_addr, "");
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR)
printf("Initialization error.\n");
int protocol = 17;//UDP
memset(&hints_numeric, 0, sizeof(hints_numeric));
hints_numeric.ai_flags = AI_NUMERICHOST;
hints_numeric.ai_socktype = SOCK_RAW;
hints_numeric.ai_protocol = IPPROTO_RAW;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_RAW;
hints.ai_protocol = IPPROTO_RAW;
result = (addrinfo*)malloc(sizeof(struct addrinfo));
status = getaddrinfo(hostname, NULL, &hints_numeric, &result);
if (status && status == EAI_NONAME) { // It may be a name, but it is * certainly not an address
status = getaddrinfo(hostname, NULL, &hints, &result);
if (status) {
fprintf(stderr, "Nothing found about host name %s\n", hostname);
abort();
}
}
fprintf(stdout, "Connecting to %s...\n", text_of(result->ai_addr));
sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (sd == SOCKET_ERROR) {
printf("Cannot create raw socket: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
if (setsockopt(sd, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) == SOCKET_ERROR) {
printf("Cannot set IP_HDRINCL: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
sockaddr4 = (struct sockaddr_in *) result->ai_addr;
memset(&op4.ip, '\0', sizeof(op4.ip));
op4.ip.ip_v = 4;
op4.ip.ip_hl = sizeof(op4.ip) >> 2;
op4.ip.ip_dst = sockaddr4->sin_addr;
op4.ip.ip_p = protocol;
op4.ip.ip_ttl = TTL;
headersize = sizeof(op4.ip) + sizeof(op4.udp);
packetsize = headersize + strlen(message);
op4.ip.ip_len = htons(packetsize);
memset(&op4.udp, '\0', sizeof(op4.udp));
op4.udp.uh_dport = htons(port);
op4.udp.uh_sport = htons(port);
op4.udp.uh_ulen = htons(strlen(message) + sizeof(op4.udp));
//Checksum
udp_pseudo_header uph;
memset(&uph, 0x00, sizeof(uph));
uph.ip_src = op4.ip.ip_src;
uph.ip_dst = op4.ip.ip_dst;
uph.mbz = 0x00;
uph.ip_p = op4.ip.ip_p;
uph.length = strlen(MESSAGE);
char* buff = new char[sizeof(uph) + sizeof(op4.udp) + strlen(message)];
memset(buff, 0x00, sizeof(uph) + sizeof(op4.udp) + strlen(message));
memcpy(buff, &uph, sizeof(uph));
memcpy(&buff[sizeof(uph)], &op4.udp, sizeof(op4.udp));
memcpy(&buff[sizeof(uph) + sizeof(op4.udp)], message, strlen(message));
op4.udp.uh_sum = checksum(buff, sizeof(uph) + sizeof(op4.udp) + strlen(message));
delete[] buff;
memset(op4.payload, '\0', MSGSIZE);
strcpy(op4.payload, message);
packet = &op4;
extraipheadersize = 0;
fprintf(stdout, "Sending %i bytes (%i for the headers)...\n", (int)packetsize, (int)headersize);
num = sendto(sd, (char*)packet, packetsize + extraipheadersize, 0, result->ai_addr, result->ai_addrlen);
if (num <= 0) {
printf("Cannot send message: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
return (0);
}