Detect the operating system using UDP stack corner cases
#include <sys/socket.h> | |
#include <err.h> | |
#include <errno.h> | |
#include <netinet/in.h> | |
#include <stdio.h> | |
#include <string.h> | |
int main(void) | |
{ | |
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | |
if ( fd < 0 ) | |
err(1, "socket"); | |
if ( shutdown(fd, SHUT_RD) < 0 ) | |
{ | |
if ( errno == ENOSYS ) | |
puts("minix"); | |
else if ( errno == ENOTCONN ) | |
{ | |
struct sockaddr_in sin; | |
memset(&sin, 0, sizeof(sin)); | |
sin.sin_family = AF_INET; | |
sin.sin_addr.s_addr = 0; | |
sin.sin_port = 0; | |
if ( connect(fd, (const struct sockaddr*) &sin, sizeof(sin)) < 0 ) | |
{ | |
if ( errno == EADDRNOTAVAIL ) | |
puts("freebsd"); | |
else | |
err(1, "connect"); | |
} | |
else | |
puts("linux"); | |
} | |
else | |
err(1, "shutdown"); | |
} | |
else | |
{ | |
union | |
{ | |
sa_family_t family; | |
unsigned char bytes[3]; | |
} u; | |
memset(&u, 0, sizeof(u)); | |
u.family = AF_UNSPEC; | |
if ( connect(fd, (const struct sockaddr*) &u, sizeof(u)) < 0 ) | |
{ | |
if ( errno == EINVAL ) | |
puts("netbsd"); | |
else if ( errno == EAFNOSUPPORT ) | |
puts("openbsd"); | |
else | |
err(1, "connect"); | |
} | |
else | |
puts("dragonflybsd"); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment