Skip to content

Instantly share code, notes, and snippets.

@sortie
Created October 15, 2017 23:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sortie/94b302dd383df19237d1a04969f1a42b to your computer and use it in GitHub Desktop.
Save sortie/94b302dd383df19237d1a04969f1a42b 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;
}
@krytarowski
Copy link

$ ./a.out                                                                                                                    
openbsd
$ uname -a
NetBSD chieftec 8.99.4 NetBSD 8.99.4 (GENERIC) #0: Sat Oct 14 16:12:26 CEST 2017  root@chieftec:/public/netbsd-root/sys/arch/amd64/compile/GENERIC amd64

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment