Estes programas mostrados até agora não rodam no Windows, mas por quê disso? Windows usa um fork de socket chamado "winsock", com umas frescuras para Windows, muitos colegas fizeram artigos só falando de winsock detalhadamente, mas aqui vou mostrar apenas para deixar seu código portável tanto para Windows como para Unix like.
Para começar você pode deixar uma condição no seu código como exemplo:
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include "windows.h"
// aqui versão do winsock 2.0...
# include "winsock2.h"
#else
# include "sys/socket.h"
#endif
Um paradigma que podemos seguir quando usamos winsock seria usar a função "WSAStartup" para iniciar nossa "winsock", e temos como exemplo:
WSADATA wsa;
// definido versão 2.0 da winsock comum em todos os windows só não sei no
// windows 7 mais deve funcionar.
WSAStartup(MAKEWORD(2,0),&wsa);
//e para declarar o uso de uma socket
SOCKET sock;
Uma ideia fascinante para melhorar a tarefa, uma função void:
#ifdef _WIN32
static void init_winsock()
{
WORD wVersion = MAKEWORD(2,2);
WSADATA wsaData;
DWORD err;
if ( (err = (DWORD)WSAStartup(wVersion, &wsaData)) != 0 )
{
fprintf(stderr, "ERROR: got err#%d from Winsock init\n", err);
exit(EXIT_FAILURE);
}
}
#endif
// podemos chamar então desta forma
#ifdef _WIN32
init_winsock();
#endif
Você vai usar winsock como se fosse socket do padrão Unix, porém usando estas condições. Bom lembrar, se for portar um exploit remoto, terá que refazer tal exploit para o sistema operacional a ser portado porque endereços de memória mudam agora para scanners, spiders, programas corporativos... seria uma boa!
Exemplo final um código portável que tem como função fazer "whois".
/* fwhois.c by Ang3ldust
* Networking code taken and modified from net.c in the finger source code
*
* Added :port notation to the hostname
*/
#include "stdio.h"
#include "string.h"
#include "ctype.h"
#include "stdlib.h"
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include "windows.h"
# include "winsock2.h"
# include "io.h"
#else
# include "sys/types.h"
# include "sys/socket.h"
# include "netinet/in.h"
# include "netdb.h"
# define __cdecl
#endif
#ifndef _WIN32
# define SOCKET int
# define closesocket(fd) close(fd)
#endif
static unsigned int portno = 43;
static char whobuf[256];
static void netfinger(char *name);
int __cdecl main(int argc, char **argv)
{
if ( argc != 2 )
{
printf("usage: fwhois user[@<whois.server> [:portno] ]\n");
exit(1);
}
strcpy(whobuf, argv[1]);
if ( strchr(whobuf, '@') == 0 )
strcat(whobuf, "@whois.internic.net");
netfinger(whobuf);
exit(EXIT_SUCCESS);
}
#ifdef _WIN32
static void init_winsock()
{
WORD wVersion = MAKEWORD(2,2);
WSADATA wsaData;
DWORD err;
if ( (err = (DWORD)WSAStartup(wVersion, &wsaData)) != 0 )
{
fprintf(stderr, "ERROR: got err#%d from Winsock init\n", err);
exit(EXIT_FAILURE);
}
}
#endif
static void netfinger(char *name)
{
int nr;
char *pport;
char iobuf[256];
register int lastc = 0;
struct in_addr defaddr;
struct hostent *hp, def;
struct sockaddr_in sin;
SOCKET s;
char *alist[1], *host;
if ((host = strrchr(name, '@')) == 0 )
{
fprintf(stderr, "ERROR: don't know what host to query\n");
return;
}
*host++ = '\0';
if ( (pport = strchr(host, ':')) != 0 )
{
*pport++ = '\0';
portno = atoi(pport);
}
#ifdef _WIN32
init_winsock();
#endif
if (!(hp = gethostbyname(host)))
{
defaddr.s_addr = inet_addr(host);
if (defaddr.s_addr == -1)
{
fprintf(stderr, "fwhois: unknown host: %s\n",host);
return;
}
def.h_name = host;
def.h_addr_list = alist;
def.h_addr = (char *)&defaddr;
def.h_length = sizeof(struct in_addr);
def.h_addrtype = AF_INET;
def.h_aliases = 0;
hp = &def;
}
if ( portno == 0 )
{
struct servent *sp;
if ( (sp = getservbyname("whois", "tcp")) == 0 )
{
fprintf(stderr, "fwhois: tcp/whois: unknown service\n");
return;
}
portno = ntohs(sp->s_port);
}
sin.sin_family = hp->h_addrtype;
memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
sin.sin_port = htons((short)portno);
#ifdef _WIN32
if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) == INVALID_SOCKET )
#else
if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0)
#endif
{
perror("fwhois: socket");
return;
}
printf("[%s]\n", hp->h_name);
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
{
perror("fwhois: connect");
closesocket(s);
return;
}
nr = sprintf(iobuf, "%s\r\n", name);
send(s, iobuf, nr, 0);
while ( (nr = recv(s, iobuf, sizeof iobuf, 0)) > 0 )
{
char *maxread = iobuf + nr;
char *p = iobuf;
while ( p < maxread )
{
int c = *p++ & 0x7F;
if (c == '\r')
{
lastc = '\r';
c = '\n';
}
else
{
if (!isprint(c) && !isspace(c))
c |= 0x40;
if (lastc != '\r' || c != '\n')
lastc = c;
else
{
lastc = '\n';
continue;
}
}
putchar(c);
}
}
if (lastc != '\n')
putchar('\n');
fflush(stdout);
}
Para testar:
./programa endereço_web