Skip to content

Instantly share code, notes, and snippets.

@allanjude
Forked from sortie/which_os.c
Created October 18, 2017 16:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save allanjude/a7d511b0531798e63a0aa603b87485a3 to your computer and use it in GitHub Desktop.
Save allanjude/a7d511b0531798e63a0aa603b87485a3 to your computer and use it in GitHub Desktop.
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