Programmare con le Raw Socket

When I was 16, I used to write articles under the nicknames Esorcista and XpTerminator.

The following is an article I translated from English to Italian, that got published on the 7th issue of OndaQuadra, an Italian e-zine.

 

+--------------------------------------------------------------------------+
| ONDAQUADRA ~ [MiSC]                                     #06 - 25/04/2002 |
| PR0GRAMMARE LE REW S0CKET (TRADUZi0NE)          [XpTerminator] 0x11/0x1D |
+--------------------------------------------------------------------------+
|                                                                          |
|                       -==============================-                   |
|                        | Programmare le raw socket  |                    |
|                        |                   Nitr0gen |                    |
|                       =/____________________________\=                   |
|                       | traduzione  by  XpTerminator |                   |
|                       -==============================-                   |
|                                                                          |
| Premetto innanzi tutto  che questo testo  non e` di  mia fattura, io  ho |
| effettuato la traduzione   dalla lingua  inglese  e  delle modifiche  ed |
| aggiunte  per  rendere il   testo  più chiaro;   visto   che in   lingua |
| italiana    non  si   trovano  documenti   del   genere,    ed  essendo  |
| interessante,  ho   ritenuto   utile  effettuarne  la traduzione.        |
|                                                                          |
|                         Exile 2000 International Coding Team             |
|                              (http://www.exile2k.org)                    |
|                    Documentation about native raw socket programming     |
|                            All rights reserved Exile Team                |
|                                                                          |
|                 Free to distribute this text just keep it's integrity    |
|                            Ripping is lame remember this                 |
|                                                                          |
|                                                                          |
|         Per domande e commenti:  (in english! ;)                         |
|                                                                          |
|                                     Nitr0gen                             |
|                              nitr0gen@hackersnews.com                    |
|                                                                          |
|         oppure:   (in italiano:)                                         |
|                                                                          |
|                                    XpTerminator                          |
|                             xp_terminator@katamail.com                   |
|                                                                          |
|                                                                          |
|                                                                          |
| -----[ Prefazione ]---                                                   |
|                                                                          |
|                                                                          |
|         A differenza di  come pensano  molte  persone,                   |
| programmare   le  raw  socket  non  è annoiante ed una                   |
| perdita  di tempo, anzi  è una  buona  esperienza  per                   |
| imparare  ed  a  volte è  molto utile. Programmando le                   |
| raw  socket  si ha molta più  flessibilità rispetto ai                   |
| programmi che utilizzano socket  con librerie standard                   |
| e quindi diventa facile implementare  nuovi protocolli                   |
| e  controllare cosa  sta realmente  accadendo anche al                   |
| più basso dei livelli.                                                   |
| Costruire pacchetti tramite una libreria è efficiente,                   |
| ma immagina quanto lo sia tramite  una  TUA  libreria.                   |
| Non  mi  trovo  qui  per  spiegare  quanto  sia figo o                   |
| potente   programmare   le  raw  socket,  quindi  vado                   |
| direttamente   al   dunque.  Prima   di  tutto, voglio                   |
| avvertire  che per poter comprendere al  meglio questo                   |
| testo bisogna avere una buona conoscenza del C e della                   |
| struttura della rete.                                                    |
| Nella  prima  parte del  testo introdurrò l'header ip,                   |
| l'header tcp, quello udp ed infine quello icmp, ultimo                   |
| non per importanza.                                                      |
|                                                                          |
| La seconda parte di  questa prefazione è  dedicata ai                    |
| lamer:  per favore  abbiate  rispetto dell'autore del                    |
| testo (Nitr0gen) e non rippate queso testo per vostri                    |
| scopi!                                                                   |
|                                                                          |
| Nitr0gen and Exile 2000 International Coding Team:                       |
| don't worry! i've  only  translated your document,                       |
| and i've riported this!                                                  |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| -----[ Indice ]---                                                       |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| [ Header Ip ]                                                            |
|         - Teoria                                                         |
|         - Frammentazione                                                 |
|         - Checksum                                                       |
|         - Esempi                                                         |
|                                                                          |
| [ Header Tcp ]                                                           |
|         - Teoria                                                         |
|         - Esempi                                                         |
|                                                                          |
| [ Header Udp ]                                                           |
|         - Teoria                                                         |
|         - Esempi                                                         |
|                                                                          |
| [ Header Icmp ]                                                          |
|         - Teoria                                                         |
|         - Esempi                                                         |
|                                                                          |
| [ Implementazione ]                                                      |
|                                                                          |
| [ Conclusioni ]                                                          |
|                                                                          |
| [ Appendice A ]                                                          |
|         - Strutture e Funzioni                                           |
|         - Codici sorgente                                                |
|                                                                          |
| [ Riferimenti ]                                                          |
|                                                                          |
| [ Ringraziamenti ]                                                       |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                         [ CAPITOLO 1 ]                                   |
|                           (HEADER IP)                                    |
|                                                                          |
|                                                                          |
| ---[ Teoria                                                              |
|                                                                          |
|                                                                          |
|       Bene, se sei interessato nella programmazione delle                |
| raw  socket  presumo  che  tu conosca le basi del tcp/ip.                |
| L'header IP  fa parte  del layer  di rete della  suite di                |
| protocolli tcp/ip.  Fondamentalmente  l'header ip è usato                |
| per routare i pacchetti attraverso una rete,come internet                |
| una wan o una lan.  Il metodo di  trasmissione  di questo                |
| header è inaffidabile poichè non hai garanzia dell'arrivo                |
| a  destinazione  del  pacchetto, o  meglio,  quando invii                |
| dei pacchetti, non hai la certezza che questi  arrivino a                |
| destinazione nel giusto ordine in cui li hai inviati.                    |
| Prendi per esempio i pacchetti A B. A viene inviato prima                |
| di B, ma non è garantito che A prenderà la stessa  strada                |
| (routing) di B per arrivare a destinazione.  Il risultato                |
| di ciò  è  quello che  ho detto prima,  i  pacchetti  non                |
| vengono ricevuti nello stesso ordine di partenza. Come ho                |
| ho detto dalla partenza,  questo testo non è  un corso di                |
| tcp/ip  ma  un  testo  sulla  programmazione,  quindi, mi                |
| limiterò alla programmazione.  A titolo  di informazione,                |
| quando costruisci un pacchetto  non dimenticare htons() o                |
| htonl() per rispettare il giusto ordine dei byte.                        |
| Dei lettori si staranno sicuramente  chiedendo perchè sto                |
| dicendo questo,  rispondo  dicendo  che io ho  passato un                |
| mese per risolvere questo piccolo problema.                              |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| Questa è una rappresentazione ascii dell'header ip:                      |
|                                                                          |
|                                                                          |
| 0                     15-16                    31                        |
| +-----+-----+-----------+-----------------------+  \                     |
| | Ver | IHL |    TOS    |      Total Length     |   \                    |
| | (4) | (4) |    (8)    |         (16 )         |    |                   |
| +-----+-----+-----------+--------+--------------+    |                   |
| |    Identification     |  Flags |  Frag Offset |    |                   |
| |        (16)           |   (3)  |     (13)     |    |                   |
| +-----------+-----------+--------+--------------+    |                   |
| |    TTL    |  Protocol |    Header Checksum    |   20 Bytes             |
| |    (8)    |    (8)    |         (16)          |    |                   |
| +-----------+-----------+-----------------------+    |                   |
| |               Source Ip Address               |    |                   |
| |                      (32)                     |    |                   |
| +-----------------------------------------------+    |                   |
| |             Destination Ip Address            |    |                   |
| |                      (32)                     |   /                    |
| +-----------------------------------------------+  /                     |
| <                     Options                   >                        |
| >                     (if any)                  <                        |
| +-----------------------------------------------+                        |
| >                                               <                        |
| <                      Data                     >                        |
| >                                               <                        |
|                                                                          |
|                                                                          |
|                                                                          |
| Version (4 bits):                                                        |
|                 Il campo version è usato per  indicare  la               |
|         versione del IP (Internet Protocol), quindi o IpV4               |
|          o IpV6.                                                         |
|                                                                          |
|                                                                          |
| IHL (Internet Header Length, 4 bits):                                    |
|                 Il  campo ihl indica la lunghezza dell'header            |
|         Ip. Quando non si usano opzioni, il valore di default            |
|         dovrebbe essere 5.                                               |
|                                                                          |
|                                                                          |
| TOS (Type Of Service, 8 bits):                                           |
|                 Tos è utilizzato per specificare le necessità            |
|         del servizio.                                                    |
|                                                                          |
|         Vi sono 4 opzioni per TOS:                                       |
|                                                                          |
|                 *NOME*              *Valore esadecimale*                 |
|                                                                          |
|         1- Minimize delay                   0x10                         |
|         2- Maximize throughput              0x08                         |
|         3- Maximize reliability             0x04                         |
|         4- Minimize monatary cost           0x02                         |
|                                                                          |
|          1: Questa opzione è utilizzata  da  applicazioni                |
|             che trasmettono piccole quantità  di  dati  e                |
|             necessitano di una risposta veloce.                          |
|                                                                          |
|          2: Caso opposto:  questo  è usato da  applicazioni              |
|             che trasmettono grandi quantità di dati.                     |
|                                                                          |
|          3: Non ne parlerò in questo testo.                              |
|                                                                          |
|          4: Non ne parlerò in questo testo.                              |
|                                                                          |
|         Dato che TOS è  una  caratteristica  sperimentale                |
|         dell'ip, non ci dilungheremo su di esso in questo                |
|         testo.                                                           |
|                                                                          |
|                                                                          |
| Total Length (8 bits):                                                   |
|                 Questo specifica la grandezza del datagramma,            |
|         (header + dati). Per esempio:                                    |
|         Prendiamo  un  pacchetto (ip header +  tcp header[syn])          |
|         senza dati. La  grandezza dell'header  ip è 20 e quella          |
|         dell'header tcp anche, quindi il campo tot_len sarà 40.          |
|                                                                          |
|                                                                          |
| Identification (16 bits):                                                |
|                 Id è utilizzato per identificare i frammenti.            |
|         Quando  un  pacchetto non  è frammentato questo campo            |
|         è inutile.  L'Id solitamente aumenta da  datagramma a            |
|         datagramma;  ogni  frammento  ha  lo  stesso  id  del            |
|         datagramma a cui appartiene.                                     |
|                                                                          |
|                                                                          |
| Flags (3 bits):                                                          |
|                 Questo campo dell'header ip è utilizzato dalla           |
|                 frammentazione. Ci sono 4 flag:                          |
|                                                                          |
|               *NOME*               *Valore esadecimale*                  |
|                                                                          |
|          No flags                          0x00                          |
|          More fragment                     0x01                          |
|          Don't fragment                    0x02                          |
|          More and Dont't frag              0x03                          |
|                                                                          |
|         More fragment significa che ci sono ancora frammenti             |
|         dopo questo datagramma, don't fragment  dice che il              |
|         pacchetto non è frammentato.  Quando un datagramma è             |
|         frammentato,l'ultimo frammento non ha mai il flag MF             |
|         (More Fragment) settato.                                         |
|                                                                          |
|                                                                          |
| Fragment Offset (13 bits):                                               |
|               Questo è l'offset con  il  quale  il pacchetto             |
|       è stato calcolato.  Il primo  datagramma ha  offset 0.             |
|       Questo campo è calcolato a 64 bits.  Quando si calcola             |
|       l'offset, l'ultimo offset sarà uguale a tot_len.                   |
|                                                                          |
|                                                                          |
| TTL (Time To Live, 8 bits):                                              |
|                 Questo  campo  specifica  quanti  hop  potrà             |
|         effettuare il datagramma.  Esso è  decrementato ogni             |
|         volta che viene rispedito (durante il routing:  ogni             |
|         router decrementa di 1 questo valore). Quando il TTL             |
|         raggiunge 0,  il datagramma viene ignorato  e  viene             |
|         inviato al mittente un messaggio icmp di TIME EXCEED.            |
|         Questo  avviene  per evitare che un  datagramma giri             |
|         all'infinito per la rete.                                        |
|                                                                          |
|                                                                          |
| Protocol (8 bits):                                                       |
|                 Questo campo specifica il protocollo per il              |
|         layer di trasmissione.  Il valore può essere:                    |
|                                                                          |
|           *NOME*                    *Valore esadecimale*                 |
|                                                                          |
|         IPPROTO_TCP                         0x06                         |
|         IPPROTO_UDP                         0x11                         |
|         IPPROTO_ICMP                        0x01                         |
|                                                                          |
|         Vi sono anche altri protocolli ma non saranno trattati           |
|         in questo testo.  Per maggiori informazioni osserva il           |
|         seguente file header che definisce tutte le costanti.            |
|         '/usr/include/linux/in.h'                                        |
|                                                                          |
|                                                                          |
| Header CheckSum (16 bits):                                               |
|                 Il checksum è utilizzato per verificare                  |
|         l'integrità di un datagramma. Se i dati durante                  |
|         il trasporto si sono corrotti o modificati,esso                  |
|         è in grado di capirlo. Se il checksum non viene                  |
|         specificato   nel   datagramma,   questo  viene                  |
|         scartato  senza  alcun  tipo di avvertenza. Dal                  |
|         punto  di  vista  del programmatore ciò risulta                  |
|         annoiante.Osserva l'appendice A per la funzione                  |
|         del checksum ( in_cksum() ).                                     |
|                                                                          |
|                                                                          |
| Source Ip (32 bits):                                                     |
|                 L'indirizzo ip dell'host che ha inviato il               |
|         datagramma.                                                      |
|                                                                          |
| Destination Ip (32 bits):                                                |
|                 L'indirizzo ip della  macchina a cui dovrà               |
|         essere "recapitato" questo datagramma.                           |
|                                                                          |
|                                                                          |
| Options (Variable):                                                      |
|                 Il  campo  options  non  sarà  trattato in               |
|         questo testo.                                                    |
|                                                                          |
|                                                                          |
|                                                                          |
|         Dal punto di  vista della programmazione,  costruire             |
| un header ip significa semplicemente riempire una struttura.             |
| Dato che sto utilizzando Linux, tutti i riferimenti che farò             |
| a file di sistema saranno basati su kernel 2.2.13.                       |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ Frammentazione                                                      |
|                                                                          |
|                                                                          |
|         In parole povere,  la  frammentazione   avviene                  |
| quando il MTU  (Maximum Transfert Unit)  è minore della                  |
| lunghezza   totale  del   datagramma,  quindi,  dovremo                  |
| dividere il datagramma  in  piccoli  pezzi, ed inviarli                  |
| uno alla  volta;  quando i pacchetti  saranno ricevuti,                  |
| il datagramma originale sarà ricostruito.                                |
| Quando effettuiamo la frammentazione,abbiamo bisogno di                  |
| settare campi specifici dell'header Ip.                                  |
| Il flag MF deve  essere  settato  a  tutti i frammenti,                  |
| tranne l'ultimo.L'offset del primo pacchetto sarà zero.                  |
| L'Id  dovrà essere  lo stesso  per ogni  frammento, per                  |
| identificare  a  quale  serie  di pezzi  di  datagramma                  |
| appartiene.Se l'header Ip è modificato anche in un solo                  |
| frammento  il  checksum  dovrà  essere  ricalcolato. La                  |
| lunghezza  totale dei frammenti  prenderà il valore del                  |
| MTU.                                                                     |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ Checksum                                                            |
|                                                                          |
|                                                                          |
|         Calcolare  il  checksum  di  un  header  non  è                  |
| difficile, osserva l'appendice A per vedere la funzione                  |
| responsabile di questa operazione.                                       |
| Questo è il prototipo della funzione:                                    |
|                                                                          |
| unsigned short in_cksum(unsigned short *addr, int len);                  |
|                                                                          |
|     - unsigned short *addr : E' un puntatore  all'header ip.             |
|     - int len              : E' la lunghezza dell'header ip.             |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ Esempi                                                              |
|                                                                          |
|                                                                          |
| Il nome della  sezione  dice esplicitamente  cosa                        |
| troverai qui.                                                            |
|                                                                          |
|                                                                          |
|                                                                          |
| /*******************************************************************/    |
| /*                Exile 2000 International Coding Team             */    |
| /*                     (http://www.exile2k.org)                    */    |
| /*                   All rights reserved Exile Team                */    |
| /*                    Copyright 2000 (C) Nitr0gen                  */    |
| /*                                                                 */    |
| /*             Questa funzione costruisce un header IP             */    |
| /*                      SENZA FRAMMENTAZIONE                       */    |
| /*                                                                 */    |
| /*******************************************************************/    |
|                                                                          |
| void buildip_nf(){ /*** Funzione che costruisce un Header Ip ***/        |
|                                                                          |
|         struct iphdr *ip;                                                |
|          /*** A little step for a man, a big step for human kind ***/    |
|                                                                          |
|         ip = (struct iphdr *) malloc(sizeof(struct iphdr));              |
|                 /*** Alloca la memoria dinamica ***/                     |
|                                                                          |
|  ip->ihl     = 5;    /*** Lunghezza in byte dell'Header IP ***/          |
|  ip->version = 4;    /*** Versione del protocollo IP ***/                |
|  ip->tos     = 0;    /*** Sperimentale (Vedi sopra per i dettagli) ***/  |
|  ip->tot_len = sizeof(struct iphdr) + 452 /*** Lunghezza totale del ***/ |
|                                          /***       pacchetto      ***/  |
|                                                                          |
|                                                                          |
|  ip->id      = htons(getuid());                                          |
|   /*** ID (identification) del pacchetto, inutile nel nostro caso ***/   |
|                                                                          |
|  ip->ttl      = 255;                /*** Il pacchetto può effettuare     |
|                                                           255 hop ***/   |
|  ip->protocol = IPPROTO_TCP; /*** Utilizziamo il tcp come protocollo     |
|                                                  di trasmissione ***/    |
|  ip->saddr    = inet_addr("127.0.0.1");  /*** Ip sorgente  ***/          |
|  ip->daddr    = inet_addr("127.0.0.1");  /*** Ip di destinazione ***/    |
|                                                                          |
|  ip->check    = in_cksum((unsigned short *)ip, sizeof(struct iphdr));    |
|                            /*** Checksum ***/                            |
|                                                                          |
| }                                                                        |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| /*****************************************************************/      |
| /*                Exile 2000 International Coding Team           */      |
| /*                     (http://www.exile2k.org)                  */      |
| /*                   All rights reserved Exile Team              */      |
| /*                    Copyright 2000 (C) Nitr0gen                */      |
| /*                                                               */      |
| /*                Questa funzione costruisce un header IP        */      |
| /*                    FRAMMENTAZIONE del pacchetto               */      |
| /*                           in 2 frammenti                      */      |
| /*                           MTU = 280 byte                      */      |
| /*                                                               */      |
| /*****************************************************************/      |
|                                                                          |
|                                                                          |
|                                                                          |
| void buildip_f(){                                                        |
|      /*** Funzione che costruisce un header IP frammentato ***/          |
|                                                                          |
| struct iphdr *ipf;                                                       |
|                                                                          |
| ipf = (struct iphdr *) malloc(sizeof(struct iphdr));                     |
|                                                                          |
| /**** PRIMO FRAMMENTO ***/                                               |
| ipf->ihl     = 5; /*** Lunghezza dell'header in 32 bit */                |
| ipf->version = 4; /*** Versione del protocollo IP */                     |
| ipf->tos     = 0; /*** TOS (Type of service), inutilizzato */            |
| ipf->tot_len = sizeof(struct iphdr) + 256; /* Lunghezza del              |
|                                               primo frammento */         |
| ipf->id      = htons(1); /*** Per identificare i nostri 2 frammenti */   |
| ipf->ttl     = 255;        /*** Il datagramma può effettuare 255 hop */  |
| ipf->protocol = IPPROTO_TCP; /*** uso il protocollo TCP */               |
| ipf->saddr    = inet_addr("127.0.0.1"); /*** Ip sorgente (localhost) */  |
| ipf->daddr    = inet_addr("127.0.0.1"); /*** Ip di destinazione          |
|                                                          (localhost) */  |
| ipf->frag_off = htons(0x2000); /*** Offset 0 e MF */                     |
| ipf->check  = in_cksum((unsigned short *)ipf,sizeof(struct iphdr)+256);  |
|         /*** Checksum */                                                 |
|                                                                          |
|                                                                          |
| /**** Qui dovremmo inviare il primo frammento ***/                       |
|                                                                          |
|                                                                          |
| /**** SECONDO FRAMMENTO ***/                                             |
| ipf->tot_len = sizeof(struct iphdr) + 196; /*** Aggiorno la lunghezza    |
|                                                    dei datagrammi */     |
| ipf->frag_off = htons(32); /*** Offset del frammento ***/                |
| ipf->check = in_cksum((unsigned short *)ipf,sizeof(struct iphdr)+196);   |
| /*** Ricalcoliamo il checksum dato che abbiamo cambiato dei campi */     |
|                                                                          |
|   /**** Qui dovremmo inviare il secondo frammento ***/                   |
|                                                                          |
| }                                                                        |
|                                                                          |
|                                                                          |
|                                 [ CAPITOLO 2 ]                           |
|                                  (HEADER TCP)                            |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ Teoria                                                              |
|                                                                          |
|                                                                          |
|        Diamo  ora  un'occhiata all'header tcp. Dato                      |
| he  esso fa utilizzo  di un  metodo di trasmissione                      |
| ffidabile,  prima di  effettuare lo  streaming  dei                      |
| ati c'è bisogno di creare una connessione.  Quindi,                      |
| os'è una connessione? Con il tcp noi  la  chiamiamo                      |
| hree-way-handshake ("stretta di mano" in tre fasi).                      |
| on il  primo passo  il client  invia  al  server un                      |
| acchetto  tcp SYN per  sincronizzare  (SYNchronize)                      |
| l   numero  di acknowledgment; con il secondo passo                      |
| l  server  "riconosce" (ACKnowledge) il  syn,  cioè                      |
| onferma  la sua  ricezione,  tramite  un  pacchetto                      |
| YN_ACK. Se il SYN_ACK non è ricevuto dal  client lo                      |
| tato  della connessione  tcp  rimane  in SYN_SENT e                      |
| l client  continua  l'invio   di  SYN   al  server,                      |
| inchè  esso  non lo  riceverà  e quindi  confermerà                      |
| on SYN_ACK.Dopo la conferma dell'avvenuta ricezione                      |
| el   SYN,   il  client  risponde  con  un  ACK  per                      |
| onfermare  l'avvenuta ricezione del SYN_ACK.                             |
| eoricamente  una connessione è creata tra due host,                      |
| a se il server si disconnette  prima di ricevere il                      |
| ostro  ultimo  pacchetto  (ACK),  noi  crederemo di                      |
| ssere connessi, ma in realtà non lo siamo. Questo è                      |
| no dei  problemi  del tcp. Il Tcp (Transfer control                      |
| rotocol)  come  l'Ip  ( Internet protocol )  ha  un                      |
| hecksum per  il controllo  dell'integrità  dei dati                      |
| he   fa  utilizzo  di   uno pseudo-header   di  cui                      |
| arleremo dopo.  Per essere  sicuri che un pacchetto                      |
| rovenga  realmente  dal source ip  specificato  nel                      |
| uo header, il tcp ha aggiunto la funzionalità di un                      |
| equence   number,   ciò   significa   che   durante                      |
| 'handshake, prima il client invia un Seq Number,poi                      |
| l server effettua l'acknowledgement del SYN  con il                      |
| roprio seq number. Il server attende nel successivo                      |
| acchetto del client  il seq number come specificato                      |
| el  campo ACK  dell'ultimo  pacchetto  inviato. Ciò                      |
| reviene   l'hijacking   o   lo   spoofing   di  una                      |
| onnessione da parte di utenti malintenzionati.                           |
| cco un esempio:                                                          |
|                                                                          |
|        Host A < ---- TCP CONNECTION ----> HOST B                         |
|                                                                          |
|                   ^---- HOST X (utente malintenzionato)                  |
|                                                                          |
|        Se  non  ci fosse il  sequence number,  HOST X                    |
|        potrebbe  inviare  pacchetti  a HOST B facendo                    |
|        credere  in realtà  che questi  provenghino da                    |
|        HOST A. Oggi giorno,  con la  generazione  del                    |
|        sequence number ormai casuale questa tecnica è                    |
|        quasi impossibile.                                                |
|                                                                          |
| uesto protocollo ha ancora altre  opzioni in  ambito                     |
| i  sicurezza  aggiunte  a  quelle  dell'IP,  ma  non                     |
| erranno  trattate  in  questo testo. Il Tcp permette                     |
| noltre un  buon  managing  dei pacchetti  in entrata                     |
| d in uscita. Grazie   alla   specifica nei pacchetti                     |
| elle porte sorgente e destinazione,  molti  processi                     |
| ossono  comunicare contemporaneamente.  Tutte queste                     |
| pzioni, incluse quelle  non trattate, però  hanno lo                     |
| vantaggio di diminuire la velocità di trasmissione.                      |
| i sei  mai domandato  cosa sia un socket? Il termine                     |
| ocket  nel  mondo  tcp  è  usato  spesso.  Questo  è                     |
| emplicemente un indirizzo ip combinato con un numero                     |
| i  porta, ed  una coppia di socket è la combinazione                     |
| ndirizzo Ip Sorgente + Porta Sorgente + Indirizzo Ip                     |
| i Destinazione + Porta di Destinazione.                                  |
|                                                                          |
|        Il Tcp ha 6 funzioni principali:                                  |
|                                                                          |
|                                                                          |
|        URG:        Invia  dei  dati  urgenti,  cioè  con                 |
|                    maggiore   priorità,   all'host    di                 |
|                    destinazione.                                         |
|                                                                          |
|        ACK:        "Acknowledgement" dei  dati ricevuti.                 |
|                    Come visto sopra.                                     |
|                                                                          |
|        PSH:        Invia i dati all'host di destinazione.                |
|                                                                          |
|        RST:        Resetta una connessione.                              |
|                                                                          |
|        SYN:        Sincronizza il Seq Number.                            |
|                                                                          |
|        FIN:        Nessun altro dato da  inviare da parte                |
|                    dell'host.                                            |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| chema dell'header TCP:                                                   |
|                                                                          |
|                      15-16                    31                         |
| -----------------------+-----------------------+ \                       |
|       Source Port      |    Destination Port   |  \                      |
|         (16b)          |         (16b)         |  |                      |
| -----------------------+-----------------------+  |                      |
|                 Sequence Number                |  |                      |
|                      (32b)                     |  |                      |
| -----------------------------------------------+  |                      |
|                  Acknowledgement               |  |                      |
|                      (32b)                     |  |                      |
| -------+------+--------+-----------------------+  20 Bytes               |
|  D_Off | Res  | Flags  |       Windows         |  |                      |
|   (4b) | (6b) |  (6b)  |        (16b)          |  |                      |
| -------+------+--------+-----------------------+  |                      |
|        Checksum        |    Urgent Pointer     |  |                      |
|          (16b)         |        (16b)          |  |                      |
| -----------------------+------------+----------+  |                      |
|                Options              | Padding  |  |                      |
|                 (24b)               |  (8b)    |  /                      |
| ------------------------------------+----------+ /                       |
|                       DATA                     <                         |
|                                                >                         |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ource Port (16 bits):                                                    |
|                La porta sorgente  del  pacchetto.                        |
|        I pacchetti di ritorno saranno ricevuti su                        |
|        questa porta.                                                     |
|                                                                          |
| estination Port (16 bits):                                               |
|                La  porta   di   destinazione  del                        |
|        pacchetto. Il pacchetto  sarà  ricevuto su                        |
|        questa porta dall'host di destinazione.                           |
|                                                                          |
| equence number (32bits):                                                 |
|                Il Sequence  number è una  buona                          |
|        caratteristica della sicurezza del  tcp.                          |
|        Quando un pacchetto viene  ricevuto,  il                          |
|        modulo  tcp del  kernel  verifica  se il                          |
|        numero  è   giusto.  Se  non  lo  è,  il                          |
|        pacchetto viene scartato.                                         |
|                                                                          |
|                                                                          |
|                                                                          |
| cknowledgment (32 bits):                                                 |
|                Quando il flag ACK è settato, il                          |
|        valore  di  questo  campo  è  settato al                          |
|        valore del Seq number che ci si  aspetta                          |
|        di  ricevere  nel prossimo  pacchetto da                          |
|        parte   dell'altro   peer   (capo  della                          |
|        connessione).                                                     |
|                                                                          |
|                                                                          |
| ata Offset (4 bits):                                                     |
|                L'offset dei dati espresso  a  32                         |
|        bit. Se non vi sono opzioni, il valore di                         |
|        default è 5.                                                      |
|                                                                          |
|                                                                          |
| eserved (6 bits):                                                        |
|                Riservato per un uso futuro, deve                         |
|        essere settato a 0.                                               |
|                                                                          |
| lags (6 bits):                                                           |
|                Ci sono 6 flag possibili nel tcp.                         |
|        Come visto sopra, questi sono:                                    |
|                                                                          |
|                                                                          |
|        URG:        Indicatore di urgenza                                 |
|        ACK:        Acknowledge                                           |
|        PSH:        Push                                                  |
|        RST:        Reset                                                 |
|        SYN:        Sincronizza il Seq Number                             |
|        FIN:        Nessun altro dato da inviare                          |
|                                                                          |
|                                                                          |
| indows (16 bits):                                                        |
|                Questo  specifica  il  MSS  (maximum                      |
|        segment  size) del prossimo pacchetto. Se un                      |
|        pacchetto supera  questo valore,  esso dovrà                      |
|        essere frammentato.                                               |
|                                                                          |
|                                                                          |
| hecksum (16 bits):                                                       |
|                Il    checksum     per    verificare                      |
|        l'integrità dei dati.Il checksum è calcolato                      |
|        con uno Pseudo-Header che  spiegherò. Questa                      |
|        è la  struttura,  tratta da Tcp/Ip  Volume 1                      |
|        (The  protocol)  di  W. Richard Stevens. Per                      |
|        favore  dedica  un  minuto  di  silenzio per                      |
|        questo incredibile uomo che è morto, è stato                      |
|        uno straordinario scrittore.                                      |
|                                                                          |
|        Questa è la struttura:                                            |
|                                                                          |
|                struct pseudohdr {                                        |
|                        unsigned long saddr;                              |
|                        unsigned long daddr;                              |
|                        char useless;                                     |
|                        unsigned char protocol;                           |
|                        unsigned short length;                            |
|                };                                                        |
|                                                                          |
|        L'header contiene  l'indirizzo  ip  sorgente e                    |
|        destinazione per evitare pacchetti mal-routati                    |
|        (saddr, daddr). Il carattere "useless"  esiste                    |
|        solo  per  rispettare il  limite  dei  32  bit                    |
|        (per questo "useless" = "inutile"). "protocol"                    |
|        contiene  il  protocollo,   in   questo   caso                    |
|        IPPROTO_TCP,  e  "lenght", la   lunghezza  del                    |
|        pacchetto.                                                        |
|                                                                          |
|        Il checksum è calcolato come per l'header Ip:                     |
|                                                                          |
|                                                                          |
| -------------- CUT HERE -----------------                                |
|                                                                          |
|   #define PSEUDO sizeof(struct pseudohdr)                                |
|   #define TCPHDR sizeof(struct tcphdr)                                   |
|                                                                          |
|    struct pseudohdr pseudo;                                              |
|    struct tcphdr tcp;                                                    |
|                                                                          |
|    pseudo.saddr    = inet_addr("127.0.0.1");                             |
|    pseudo.daddr    = inet_addr("127.0.0.1");                             |
|    pseudo.useless  = htons(0);                                           |
|    pseudo.protocol = IPPROTO_TCP;                                        |
|    pseudo.length   = TCPHDR + data;                                      |
|                                                                          |
|    tcp->check    = in_cksum((unsigned short *)&pseudo, PSEUDO+TCPHDR);   |
|                                                                          |
| -------------- CUT HERE ----------------                                 |
|                                                                          |
|                                                                          |
|                                                                          |
|  Urgent Pointer (16 bits):                                               |
|                  Questo campo è significante solo se il flag             |
|          URG è settato.  Esso  punta  ad un'area  dati e ciò             |
|          rende i dati urgenti dal punto di vista dei peer.               |
|                                                                          |
|                                                                          |
|  Options (24 bits):                                                      |
|                  Il  campo  options  non  verrà  trattato in             |
|          questo testo.                                                   |
|                                                                          |
|                                                                          |
|  Padding (8 bits):                                                       |
|                  Il campo padding è riempito con 0. Questo               |
|          avviene per rispettare il limite dei 32 bit: esso               |
|          parte con 32 bit e finisce con 32 bit.                          |
|                                                                          |
|                                                                          |
| ---[ Esempi                                                              |
|                                                                          |
|                                                                          |
|                                                                          |
| /******************************************************************/     |
| /*              Exile 2000 International Coding Team              */     |
| /*                   (http://www.exile2k.org)                     */     |
| /*                 All rights reserved Exile Team                 */     |
| /*                  Copyright 2000 (C) Nitr0gen                   */     |
| /*                                                                */     |
| /*                Questa funzione costruisce un header TCP        */     |
| /*                       col flag SYN settato                     */     |
| /*            e richiede una connessione telnet su localhost      */     |
| /*                                                                */     |
| /******************************************************************/     |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| #define TCPHDR                sizeof(struct tcphdr)                      |
| #define PSEUHDR                sizeof(struct iphdr)                      |
|                                                                          |
|                                                                          |
| void build_tcp(){                                                        |
|                                                                          |
| struct tcphdr *tcp;           /*** Header tcp ***/                       |
| struct pseudohdr *pseudo;  /*** Pseudo header ***/                       |
|                                                                          |
| if ((tcp = (struct tcphdr *) malloc(TCPHDR)) == NULL){                   |
|         perror("malloc()");   /*** Alloca la memoria dinamica ***/       |
|         return -1;                                                       |
| }                                                                        |
|                                                                          |
| if ((pseudo = (struct pseudohdr *) malloc(PSEUDOHDR)) == NULL){          |
|         perror("malloc()");   /*** Alloca la memoria dinamica ***/       |
|         return -1;                                                       |
| }                                                                        |
|                                                                          |
| memset(tcp,'\0',TCPHDR);     /*** Inizializza la memoria                 |
|                                             al carattere \0 ***/         |
| memset(pseudo,'\0',PSEUDOHDR);                                           |
|                                                                          |
|                                                                          |
| pseudo->saddr    = inet_addr("127.0.0.1"); /*** Ip sorgente ***/         |
| pseudo->daddr    = inet_addr("127.0.0.1"); /*** Ip di destinazione ***/  |
| pseudo->useless  = 0;      /*** Spazio riservato per rispettare il       |
|                                                          limite ***/     |
| pseudo->protocol = IPPROTO_TCP; /*** Utilizziamo tcp ***/                |
| pseudo->length   = htons(TCPHDR); /*** Dato che non abbiamo nessun       |
|                                        dato,  la  lunghezza è solo       |
|                                        quella dell'header tcp.     ***/  |
|                                                                          |
|                                                                          |
| tcp->source  = htons(5000); /*** Utilizziamo la 5000                     |
|                                         come porta sorgente ***/         |
| tcp->dest    = htons(23);   /*** Inviamo al demone telnet ***/           |
| tcp->seq     = htonl(31337); /*** Initial sequence number ***/           |
| tcp->ack_seq = htonl(0);     /*** E' significante solo se è settato      |
|                                                     il flag ack ***/     |
| tcp->doff    = 5; /*** Offset dell'header tcp a 32 bit ***/              |
| tcp->fin     = 0; /*** Flag FIN non settato durante l'handshake ***/     |
| tcp->syn     = 1; /*** Flag SYN settato, primo passo dell'handshake ***/ |
| tcp->rst     = 0; /*** Flag RST non settato durante l'handshake ***/     |
| tcp->psh     = 0; /*** Flag PSH non settato durante l'handshake ***/     |
| tcp->ack     = 0; /*** Flag ACK non settato durante l'handshake ***/     |
| tcp->urg     = 0; /*** Flag URG non settato durante l'handshake ***/     |
| tcp->window  = htons(4000); /*** Lunghezza massima del prossimo          |
|                                                       pacchetto ***/     |
| tcp->urg_ptr = htons(0);  /*** E' significativo solo se il flag URG      |
|                                                         è settato ***/   |
|                                                                          |
| tcp->check   = in_cksum((unsigned short *)pseudo,TCPHDR+PSEUDOHDR);      |
|   /*** Calcolo del checksum tcp per evitare corruzione dei dati ***/     |
| }                                                                        |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                 [ CAPITOLO 3 ]                           |
|                                  (HEADER UDP)                            |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ Teoria                                                              |
|                                                                          |
|                                                                          |
|         Arrivato fin qui, hai  superato la  parte  più                   |
| "difficile".                                                             |
| L'Udp   è   meno   complesso  del  tcp.  Esso  non  ha                   |
| caratteristiche di sicurezza e neanche di affidabilità                   |
| ma ha un maggiore transfert rate  che lo  rende utile.                   |
| Come il tcp, anche l'udp ha un checksum ed  ha bisogno                   |
| di uno pseudo header per calcolarlo.                                     |
|                                                                          |
|                                                                          |
| Schema dell'Header UDP:                                                  |
|                                                                          |
|                                                                          |
| 0                     15-16                    31                        |
| +-----------------------+-----------------------+                        |
| |     Source Port       |   Destination Port    |                        |
| |       (16 b)          |       (16 b)          |                        |
| +-----------------------+-----------------------+                        |
| |       Length          |       Checksum        |                        |
| |       (16 b)          |        (16 b)         |                        |
| +-----------------------+-----------------------+                        |
| >                     DATA                      <                        |
| <                                               >                        |
|                                                                          |
|                                                                          |
|                                                                          |
| Source Port (16 bits):                                                   |
|                 La porta sorgente  del datagramma.                       |
|         I pacchetti di ritorno saranno ricevuti su                       |
|         questa porta.                                                    |
|                                                                          |
|                                                                          |
| Destination Port (16 bits):                                              |
|              La porta destinazione del datagramma.                       |
|         Il datagramma  sarà  ricevuto  dal peer di                       |
|         destinazione su questa porta.                                    |
|                                                                          |
|                                                                          |
| Length (16 bits):                                                        |
|               Contiene la lunghezza dei datagrammi                       |
|         udp in ottetti, solitamente 8.                                   |
|                                                                          |
|                                                                          |
| Checksum (16 bits):                                                      |
|               Contiene il checksum  del  datagramma                      |
|         per   controllarne   l'integrità    e   per                      |
|         assicurare che non vi sono stati errori nel                      |
|         routing.                                                         |
|                                                                          |
|         Se  sei  curioso  circa  la  sua struttura,                      |
|         osserva l'appendice A.                                           |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ Esempi                                                              |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| /****************************************************************/       |
| /*              Exile 2000 International Coding Team            */       |
| /*                   (http://www.exile2k.org)                   */       |
| /*                 All rights reserved Exile Team               */       |
| /*                  Copyright 2000 (C) Nitr0gen                 */       |
| /*                                                              */       |
| /*                Questa funzione costruisce un header UDP      */       |
| /*                                                              */       |
| /****************************************************************/       |
|                                                                          |
|                                                                          |
| void build_udp(){                                                        |
|                                                                          |
| struct udphdr *udp;        /*** Dichiarazione delle variabili ***/       |
| struct pseudohdr pseudo;                                                 |
|                                                                          |
| if ((udp = (struct udphdr *) malloc(sizeof(struct udphdr))) == NULL){    |
|         perror("Memory exhausted"); /*** Allocazione memoria             |
|                                                          dinamica ***/   |
|         return ;                                                         |
| }                                                                        |
|                                                                          |
|                                                                          |
| /*** Pseudo-Header, utilizzato per evitare datagrammi "mal-routati" ***/ |
|                                                                          |
| pseudo.saddr    = inet_addr("127.0.0.1"); /* Inviamo da localhost **/    |
| pseudo.daddr    = inet_addr("127.0.0.1"); /* Inviamo a localhost **/     |
| pseudo.useless  = htons(0);         /* Per rispettare il limite          |
|                                                         di 32 bit*/      |
| pseudo.protocol = IPPROTO_UDP;      /* Utilizziamo il protocollo UDP */  |
| pseudo.length   = sizeof(struct udphdr); /* sizeof della                 |
|                                                    struttura udphdr  */  |
|                                                                          |
| udp->source = htons(5000);  /** Inviamo dalla porta 5000 */              |
| udp->dest   = htons(7);     /** Inviamo al server echo (porta=7) */      |
| udp->len    = htons(sizeof(struct udphdr)); /* Lunghezza di udphdr.      |
|                                                 Utilizziamo htons()      |
|                                                 per il giusto            |
|                                                 ordinamento dei byte */  |
|                                                                          |
| udp->check  = in_cksum((unsigned short *)&pseudo,sizeof(struct udphdr)); |
|                 /*** Calcoliamo il checksum ***/                         |
|                                                                          |
| }                                                                        |
|                                                                          |
|                                                                          |
|                                 [ CAPITOLO 4 ]                           |
|                                 (HEADER ICMP)                            |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ Teoria                                                              |
|                                                                          |
|                                                                          |
|         Fondamentalmente l'Internet Control Message                      |
| Protocol  (ICMP)  è utilizzato per riportare errori                      |
| come l'irraggiungibilità di un host,la scadenza del                      |
| TTL (Time to live) o "source quench" (letteralmente                      |
| "spegnimento" dell'host sorgente) che significa che                      |
| non c'è abbastanza memoria  per  proseguire l'invio                      |
| del   datagramma  in  questione.  Non   esiste   un                      |
| messaggio  icmp  per  evitare  cicli infiniti di un                      |
| pacchetto in una rete.                                                   |
|                                                                          |
|                                                                          |
|                                                                          |
|         Schema dell'Header ICMP:                                         |
|                                                                          |
|                                                                          |
| 0                     15-16                    31                        |
| +-----------+-----------+-----------------------+                        |
| |   Type    |   Code    |       Checksum        |                        |
| |   (8 b)   |   (8 b)   |        (16 b)         |                        |
| +-----------+-----------+-----------------------+                        |
| |                     UNUSED                    |                        |
| |                     (32 b)                    |                        |
| +-----------------------------------------------+                        |
| |       Internet Header + 64 bits di dati       |                        |
| |                     (32 b)                    |                        |
| +-----------------------------------------------+                        |
| Questo è il formato standard dell'header icmp.                           |
| Se però cambiano i valori dei  campi "Type"  e  "Code"                   |
| il  campo  "unused" (inutilizzato) viene  utilizzato.                    |
| Se  "unused"   rimane  inutilizzato,  settalo  a  0. A                   |
| seconda del tipo  di  messaggio icmp, alcuni campi del                   |
| header Ip possono cambiare.                                              |
|                                                                          |
|                                                                          |
|                                                                          |
|  ECHO REQUEST o ECHO REPLY                                               |
|  -------------------------                                               |
|                                                                          |
| L'Echo  viene  comunemente  chiamato  PING.  Per                         |
| generare  la  reply,  lo  stack  inverte  l'indirizzo Ip                 |
| sorgente   e   destinazione   nell'header  Ip. Il  campo                 |
| "UNUSED" è diviso  in  campi da 8 bit ciascuno, chiamati                 |
| Identifier e Sequence number, che  descriverò qui sotto.                 |
|                                                                          |
|                                                                          |
| TYPE (8 bits):                                                           |
|                 0        Per echo reply                                  |
|                 8        Per echo request                                |
|                                                                          |
| CODE (8 bits):                                                           |
|                 0        Campo inutilizzato per questo tipo              |
|                          di messaggi                                     |
|                                                                          |
| CHECKSUM (16 bits):                                                      |
|                 Il checksum è calcolato come per gli altri               |
|         header, ma il campo  checksum  deve essere 0 prima               |
|         di averlo calcolato. Per rispettare il  limite dei               |
|         32 bit, il kernel può "imbottire" il  messaggio se               |
|         la sua lunghezza totale è inaspettata, cioè minore               |
|         dei 32 bit.                                                      |
|                                                                          |
| Identifier (16 bits):                                                    |
|                 Questo campo si comporta allo  stesso modo               |
|         dell'ID nell'headers ip, ma  per gli echo e reply.               |
|         Esso aiuta a capire  quale echo reply appartiene a               |
|         quale  echo request  (come per la frammentazione).               |
|                                                                          |
| Sequence Number (16 bits):                                               |
|                 Questo campo si comporta allo  stesso modo               |
|         dell'ID nell'headers ip, ma  per gli echo e reply.               |
|         Esso aiuta a capire  quale echo reply appartiene a               |
|         quale  echo request  (come per la frammentazione).               |
|                                                                          |
|                                                                          |
| Negli  echo  request possono essere inseriti anche i dati,               |
| questi   poi  saranno rispediti dall'host  di destinazione               |
| nell'echo reply.                                                         |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| DESTINATION UNREACHABLE                                                  |
| -----------------------                                                  |
|                                                                          |
| Questo messaggio è utilizzato  per indicare                              |
| che un host o una rete è down, che un  servizio non                      |
| è  in  funzione,  che  lo  stack  non  supporta  il                      |
| protocollo, che c'è bisogno della frammentazione ma                      |
| "don't fragment" (DF) è settato, o che c'è stato un                      |
| errore durante il routing del pacchetto.  Il  campo                      |
| "UNUSED"  rimane  inutilizzato  e  dovrebbe  essere                      |
| settato a 0.                                                             |
|                                                                          |
|                                                                          |
| TYPE (8 bits):                                                           |
|         3        Destination Unreachable                                 |
|                                                                          |
|                                                                          |
| CODE (8 bits):                                                           |
|         0        Rete irraggiungibile                                    |
|         1        Host irraggiungibile                                    |
|         2        Protocollo irraggiungibile                              |
|         3        Porta irraggiungibile                                   |
|         4        Frammentazione necessaria ma DF settato.                |
|         5        Routing fallito                                         |
|                                                                          |
|                                                                          |
|                                                                          |
| CHECKSUM (16 bits):                                                      |
|                 Il  checksum  è  calcolato  come                         |
|         l'ultimo messaggio.                                              |
|                                                                          |
|                                                                          |
| UNUSED (32 bits):                                                        |
|         Rimane inutilizzato.                                             |
|                                                                          |
|                                                                          |
| INTERNET HEADER + 64 BIT DI DATI DEL DATAGRAMMA:                         |
|                 Il titolo è esplicativo.E' usato                         |
|         dai  protocolli di  livello più alto, se                         |
|         c'è una  porta  da  identificare o altri                         |
|         campi.                                                           |
|                                                                          |
|                                                                          |
|                                                                          |
| SOURCE QUENCH                                                            |
| -------------                                                            |
|                                                                          |
| Questo   messaggio   d'errore  viene                                     |
| inviato quando un host  o  un gateway non ha                             |
| abbastanza  memoria  per  mettere in coda il                             |
| pacchetto ricevuto per inoltrarlo.                                       |
|                                                                          |
|                                                                          |
| TYPE (8 bits):                                                           |
|         4        Source Quench                                           |
|                                                                          |
|                                                                          |
| CODE (8 bits):                                                           |
|         0        Inutilizzato                                            |
|                                                                          |
|                                                                          |
| CHECKSUM (16 bits):                                                      |
|                 Il checksum viene calcolato come                         |
|         l'ultimo messaggio.                                              |
|                                                                          |
|                                                                          |
| UNUSED (32 bits):                                                        |
|         Rimane inutilizzato.                                             |
|                                                                          |
|                                                                          |
| INTERNET HEADER + 64 BIT DI DATI DEL DATAGRAMMA:                         |
|                 Il titolo è esplicativo.E' usato                         |
|         dai  protocolli di  livello più alto, se                         |
|         c'è una  porta  da  identificare o altri                         |
|         campi.                                                           |
|                                                                          |
|                                                                          |
|                                                                          |
| REDIRECT                                                                 |
| --------                                                                 |
|                                                                          |
| Un  messaggio  redirect  (di redirezione) è                              |
| inviato  quando  esiste  una  strada  più corta per                      |
| arrivare alla destinazione.                                              |
| Esempio:                                                                 |
|                                                                          |
|         Johnny invia un pacchetto alla rete R. La sua                    |
|         route  table  (tabella  di  routing) dice per                    |
|         default di inviarlo al Gateway #1, ma  quando                    |
|         il Gateway #1 riceve il pacchetto  esso trova                    |
|         una  via   più   corta   per  arrivare   alla                    |
|         destinazione. Esso  quindi  invia un REDIRECT                    |
|         all'ip sorgente  specificando  l'indirizzo Ip                    |
|         del nuovo gateway nel campo UNUSED.                              |
|                                                                          |
|                                                                          |
| Vi  è  una  eccezione  quando l'"IP source routing" è                    |
| abilitato,ma di questa opzione dell'ip non ho parlato                    |
| in questo testo quindi mi fermo qui.                                     |
|                                                                          |
|                                                                          |
| TYPE (8 bits):                                                           |
|         5        Redirect                                                |
|                                                                          |
|                                                                          |
| CODE (8 bits):                                                           |
|         0        Redirige i datagrammi destinati ad una Rete             |
|         1        Redirige i datagrammi destinati ad un Host              |
|         2        Redirige i datagrammi destinati ad un TOS e             |
|                  ad una Rete                                             |
|         3        Redirige i datagrammi destinati ad un TOS e             |
|                  ad un Host                                              |
|                                                                          |
|                                                                          |
| CHECKSUM (16 bits):                                                      |
|                 Il checksum viene calcolato come                         |
|         l'ultimo messaggio.                                              |
|                                                                          |
|                                                                          |
|                                                                          |
| GATEWAY INTERNET ADDRESS (32 bits):                                      |
|                 Indirizzo Ip del gateway più vicino                      |
|         al quale inviare il pacchetto.                                   |
|                                                                          |
|                                                                          |
| INTERNET HEADER + 64 BIT DI DATI DEL DATAGRAMMA:                         |
|                 Il titolo è esplicativo. E' usato                        |
|           dai  protocolli  di  livello più alto, se                      |
|         c'è  una  porta  da  identificare o altri                        |
|         campi.                                                           |
|                                                                          |
|                                                                          |
|                                                                          |
| TIME EXCEED                                                              |
| -----------                                                              |
|                                                                          |
| Questo messaggio viene inviato quando il Time To                         |
| Live (TTL)(tempo di vita) di un pacchetto scade o quando                 |
| scade il tempo per riassemblare il pacchetto.                            |
|                                                                          |
|                                                                          |
| TYPE (8 bits):                                                           |
|         11        Time Exceed                                            |
|                                                                          |
|                                                                          |
| CODE (8 bits):                                                           |
|         0        Time To Live Scaduto (TTL)                              |
|         1        Tempo per il riassemblaggio dei frammenti               |
|                  scaduto                                                 |
|                                                                          |
|                                                                          |
| CHECKSUM (16 bits):                                                      |
|                 Il checksum viene calcolato come                         |
|         l'ultimo messaggio.                                              |
|                                                                          |
|                                                                          |
| UNUSED (32 bits):                                                        |
|         Rimane inutilizzato.                                             |
|                                                                          |
|                                                                          |
| INTERNET HEADER + 64 BIT DI DATI DEL DATAGRAMMA:                         |
|                 Il titolo è esplicativo. E' usato                        |
|         dai  protocolli di  livello  più alto, se                        |
|         c'è una  porta  da  identificare  o altri                        |
|         campi.                                                           |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| PARAMETER PROBLEM                                                        |
| -----------------                                                        |
|                                                                          |
| Il  messaggio  "Parameter  problem"                                      |
| (problemi di parametri) è inviato quando un                              |
| datagramma ha valori  errati nelle opzioni,                              |
| TOS o un campo non valido.  Il campo UNUSED                              |
| viene  riempito con  un puntatore  al campo                              |
| errato.                                                                  |
|                                                                          |
|                                                                          |
| TYPE (8 bits):                                                           |
|         12        Parameter problem                                      |
|                                                                          |
|                                                                          |
| CODE (8 bits):                                                           |
|         0        Rende il campo POINTER significativo,                   |
|                  cioè non viene ignorato                                 |
|                                                                          |
|                                                                          |
| CHECKSUM (16 bits):                                                      |
|                 Il checksum viene calcolato come                         |
|         l'ultimo messaggio.                                              |
|                                                                          |
|                                                                          |
| POINTER (8 bits):                                                        |
|                 Viene preso in considerazione  solo                      |
|         se  CODE = 0. Esso punta  all'area  dove si                      |
|         trova l'errore.                                                  |
|                                                                          |
|                                                                          |
| UNUSED (24 bits):                                                        |
|                 Rimane inutilizzato.                                     |
|                                                                          |
|                                                                          |
| INTERNET HEADER + 64 BIT DI DATI DEL DATAGRAMMA:                         |
|                 Il titolo è esplicativo. E' usato                        |
|         dai  protocolli di  livello  più alto, se                        |
|         c'è  una  porta  da  identificare o altri                        |
|         campi.                                                           |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|  TIMESTAMP REQUEST e TIMESTAMP REPLY                                     |
|  -----------------------------------                                     |
|                                                                          |
| Tramite questi messaggi  si comunica l'orario in                         |
| secondi in  cui il pacchetto è stato modificato l'ultima                 |
| volta dalla  mezzanotte UT (Universal Time).  Quando  il                 |
| pacchetto  viene  inviato,  l'orario  viene  inserito, e                 |
| quando viene inviata la risposta a questo,viene inserito                 |
| l'orario  affianco a  quello  precedente. Tramite questo                 |
| metodo possiamo calcolare  quando sia distante da noi un                 |
| host.                                                                    |
|                                                                          |
|                                                                          |
| TYPE (8 bits):                                                           |
|         13        Timestamp Request                                      |
|         14        Timestamp Reply                                        |
|                                                                          |
|                                                                          |
| CODE (8 bits):                                                           |
|         0        Rende l'ID e il Seq Num significativi                   |
|                  (non vengono ignorati)                                  |
|                                                                          |
|                                                                          |
| CHECKSUM (16 bits):                                                      |
|                 Il checksum viene calcolato come                         |
|         l'ultimo messaggio.                                              |
|                                                                          |
|                                                                          |
| IDENTIFIER (16 bits):                                                    |
|                 Significativo solo se Code = 0.  Esso                    |
|         aiuta  a determinare la  giusta  combinazione                    |
|         reply / request.                                                 |
|                                                                          |
|                                                                          |
| SEQUENCE NUMBER (16 bits):                                               |
|                 Significativo solo se Code = 0.  Esso                    |
|         aiuta  a determinare la  giusta  combinazione                    |
|         reply / request.                                                 |
|                                                                          |
|                                                                          |
|                                                                          |
|  NETMASK REQUEST e NETMASK REPLY                                         |
|  -------------------------------                                         |
|                                                                          |
| Questo   messaggio   icmp  restituisce  la                               |
| maschera di rete dell'host che invia il messaggio.                       |
| Per generare la reply, gli indirizzi Ip sorgente e                       |
| destinazione vengono invertiti, viene  inserito la                       |
| maschera di rete  nel campo, viene  ricalcolato il                       |
| checksum  e  viene  spedito  al  mittente.  Se  il                       |
| mittente non conosce il proprio Ip, egli inserisce                       |
| 0 nel campo del source ip adress, e la risposta al                       |
| pacchetto   verrà   inviata  all'indirizzo  Ip  di                       |
| broadcast.                                                               |
|                                                                          |
|                                                                          |
|                                                                          |
| TYPE (8 bits):                                                           |
|         17        Netmask Request                                        |
|         18        Netmaks Reply                                          |
|                                                                          |
|                                                                          |
| CODE (8 bits):                                                           |
|         0        Rende l'ID e il Seq Num significativi                   |
|                                                                          |
|                                                                          |
| CHECKSUM (16 bits):                                                      |
|                 Il checksum viene calcolato come                         |
|         l'ultimo messaggio.                                              |
|                                                                          |
|                                                                          |
| IDENTIFIER (16 bits):                                                    |
|                 Significativo solo se Code = 0.  Esso                    |
|         aiuta  a determinare la  giusta  combinazione                    |
|         reply / request.                                                 |
|                                                                          |
|                                                                          |
| SEQUENCE NUMBER (16 bits):                                               |
|                 Significativo solo se Code = 0.  Esso                    |
|         aiuta  a determinare la  giusta  combinazione                    |
|         reply / request.                                                 |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ Esempi                                                              |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| /****************************************************************/       |
| /*                                                              */       |
| /*           Exile 2000 International Coding Team               */       |
| /*                (http://www.exile2k.org)                      */       |
| /*              All rights reserved Exile Team                  */       |
| /*               Copyright 2000 (C) Nitr0gen                    */       |
| /*                                                              */       |
| /*         Questa funzione costruisce un header ICMP (PING)     */       |
| /*                                                              */       |
| /****************************************************************/       |
|                                                                          |
|                                                                          |
|                                                                          |
| void icmp_build(){                                                       |
|                                                                          |
| struct icmphdr *icmp;                                                    |
|                                                                          |
| icmp = (struct icmphdr *) malloc(sizeof(struct icmphdr));                |
|                                                                          |
| icmp->type = ICMP_ECHO;        /*** ECHO REQUEST */                      |
| icmp->code = 0;                /*** Campi Id e Sequence significativi */ |
| icmp->un.echo.id = 0;        /*** Per identificare la risposta al ping */|
| icmp->un.echo.sequence = 0; /*** Per identificare la risposta al ping */ |
| icmp->checksum = 0;        /*** Il campo checksum deve essere 0          |
|                                                   prima del calcolo */   |
|                                                                          |
| icmp->checksum =in_cksum((unsigned short *)icmp,sizeof(struct icmphdr)); |
|         /*** Checksum */                                                 |
|                                                                          |
| }                                                                        |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                 [ CAPITOLO 5 ]                           |
|                                (IMPLEMENTAZIONE)                         |
|                                                                          |
|                                                                          |
| ---[ Teoria                                                              |
|                                                                          |
| Dopo  questa  teoria sui vari header                                     |
| dei protocolli, dobbiamo ora  abbandonare la                             |
| teoria per passare alla implementazione vera                             |
| e propria. Fondamentalmente ciò che descrivo                             |
| in  questo  testo è  come creare  un  socket                             |
| utilizzando il  livello  raw, come  riempire                             |
| la struttura del socket e come comunicare ad                             |
| un livello così basso.                                                   |
|                                                                          |
|         Per prima cosa  osserveremo man mano                             |
| un   codice  sorgente   e   per  ogni  linea                             |
| spiegherò il suo significato. Andiamo:                                   |
|                                                                          |
|                                                                          |
|         int sock, optval;        /***  Descrittore del socket  ***/      |
|         struct sockaddr_in peer; /*** Struttura usata da sendto() ***/   |
|                                                                          |
|                                                                          |
| Se  non  capisci  qualcosa, credo sia meglio                             |
| che tu prenda un libro  sulla programmazione                             |
| dei socket su sistemi unix.                                              |
|                                                                          |
|         if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_TCP)) == -1){        |
|                 perror("Errore nella creazione del socket");             |
|                 return -1;                                               |
|         }                                                                |
|                                                                          |
|                                                                          |
|  Queste linee creano  un socket utilizzando                              |
|  il  TCP  come  protocollo di trasporto. Il                              |
|  socket è SOCK_RAW per permettere l'accesso                              |
|  raw.   E'  utilizzato  AF_INET  poichè  ci                              |
|  troviamo su internet. Da  ora, se socket()                              |
|  restituisce     un      errore,   perror()                              |
|  visualizzerà il contenuto di errno  e  ciò                              |
|  che ha restituito la funzione.                                          |
|                                                                          |
|         setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&optval,sizeof(int));      |
|                                                                          |
|                                                                          |
|                                                                          |
| Questa  funzione dice  al  socket  sock che                              |
| lavoriamo al livello IPPROTO_IP e  che  noi                              |
| includeremo  l'header ip  (IP_HDRINCL)  nei                              |
| pacchetti inviati. optval  e    sizeof(int)                              |
| non sono  importanti  per  questa  opzione,                              |
| quindi non parlerò di loro.                                              |
|                                                                          |
|                                                                          |
|         peer.sin_family      = AF_INET;                                  |
|         peer.sin_port        = htons(23);                                |
|         peer.sin_addr.s_addr = inet_addr("127.0.0.1");                   |
|                                                                          |
|                                                                          |
| Qui  riempiamo  la   struttura  sockaddr_in                              |
| (peer) utilizzata da sendto().Diciamo che è                              |
| un protocollo di famiglia Internet(AF_INET).                             |
| La   porta   di   destinazione   è   la  23.                             |
| Utilizziamo htons() per la  giusta sequenza                              |
| dei  byte,  come  detto   all'inizio. Nella                              |
| linea  successiva  settiamo  l'indirizzo di                              |
| destinazione  utilizzando  inet_addr()  per                              |
| convertire l'indirizzo in formato binario.                               |
|                                                                          |
| A questo punto dovremmo costruire il nostro                              |
| pacchetto.  Prenderò  per scontato le  cose                              |
| di cui ho parlato nella teoria.                                          |
|                                                                          |
|                                                                          |
|         sendto(sock, packet, strlen(packet),0,                           |
|         (struct sockaddr *)&peer,sizeof(struct sockaddr));               |
|                                                                          |
|                                                                          |
|                                                                          |
| Inviamo il   pacchetto packet  sul socket sock                           |
| per la lunghezza strlen(packet). Nel parametro                           |
| successivo settiamo 0, poichè  non  indichiamo                           |
| alcun flag. Vi sono 4 flag:                                              |
|                                                                          |
|                 MSG_OOB                Questo  invia  un pacchetto       |
|                                 Out  Of  Bound,  aumentando la sua       |
|                                 priorità.                                |
|                                                                          |
|                 MSG_DONTROUTE        Non osserva  la  tabella di         |
|                                 routing   e  invia  direttamente         |
|                                 all'interfaccia.                         |
|                                                                          |
|                 MSG_DONTWAIT        Normalmente   sendto()  può          |
|                                 trattenere un pacchetto, ma con          |
|                                 questo  flag,  non  lo  farà  e          |
|                                 restituirà EAGAIN.                       |
|                                                                          |
|                 MSG_NONSIGNAL        Chiede  di  non  inviare  il        |
|                                 segnale SIGPIPE quando uno stream        |
|                                 orientato     alla    connessione        |
|                                 fallisce cioè genera  un errore o        |
|                                 si disconnette.                          |
|                                                                          |
|                                                                          |
| Poi, con ((struct sockaddr *)&peer), chiediamo                           |
| al   peer   di   specificare  la   famiglia di                           |
| protocolli,  e  la  porta   e  l'indirizzo  di                           |
| destinazione  poichè  sendto  si   aspetta  di                           |
| avere  un  puntatore  alla struttura sockaddr.                           |
| Infine  specifichiamo   la   lunghezza   della                           |
| struttura          sockaddr            tramite                           |
| (sizeof(struct sockaddr))  e  il  datagramma è                           |
| inviato!!                                                                |
|                                                                          |
| Per essere sicuro  di  aver  capito, scrivi                              |
| questo  esempio  e  prova  a   ricevere  il                              |
| pacchetto  e  stamparne  il  risultato.  Ho                              |
| creato  dei  programmini   nella   seguente                              |
| sezione in modo che tu possa  verificare di                              |
| aver capito bene.                                                        |
|                                                                          |
| Suggerimento:     man recv                                               |
|                                                                          |
|         buona fortuna                                                    |
|                                                                          |
|                                                                          |
| -----[ Conclusioni ]---                                                  |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| Ho fatto il meglio  che  potevo  per  creare                             |
| un testo completo e buono sulla  programmazione delle                    |
| raw socket. Spero che il testo ti sia piaciuto e sono                    |
| sicuro che ti abbia aiutato  nel capire  come  codare                    |
| con le raw socket.  Questo  documento  mi  ha aiutato                    |
| a capire delle  cose  di cui  non  ero  sicuro  e  ad                    |
| imparare delle cose che non avevo  mai sentito prima.                    |
| Infine, vorrei  approfittare  di  questo momento  per                    |
| dire ufficialmente  che in breve  tempo  rilascerò un                    |
| portscanner simile a nmap. Sto provando a migliorarne                    |
| la velocità e lo stile di codifica  per  renderlo più                    |
| leggibile  a  persone  "ordinarie"  come  me.  Questo                    |
| progetto è chiamato ESCAN ed include  molte  funzioni                    |
| come:  connect  scan,  stealth,  half  open,  decoys,                    |
| logging. Una versione beta dovrebbe essere rilasciata                    |
| il prima possibile. Per seguire lo sviluppo:                             |
|         http://www.exile2k.org                                           |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                         [ Appendice A ]                                  |
|                      (Strutture e Funzioni)                              |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ STRUTTURA HEADER IP                                                 |
|                                                                          |
|                                                                          |
|                                                                          |
| struct iphdr {                                                           |
|                                                                          |
| #if __BYTE_ORDER == __LITTLE_ENDIAN                                      |
|     unsigned int ihl:4;                                                  |
|     unsigned int version:4;                                              |
| #elif __BYTE_ORDER == __BIG_ENDIAN                                       |
|     unsigned int version:4;                                              |
|     unsigned int ihl:4;                                                  |
| #else                                                                    |
| # error        "Please fix <bits/endian.h>"                              |
| #endif                                                                   |
|     u_int8_t tos;                                                        |
|     u_int16_t tot_len;                                                   |
|     u_int16_t id;                                                        |
|     u_int16_t frag_off;                                                  |
|     u_int8_t ttl;                                                        |
|     u_int8_t protocol;                                                   |
|     u_int16_t check;                                                     |
|     u_int32_t saddr;                                                     |
|     u_int32_t daddr;                                                     |
|     /*The options start here. */                                         |
| };                                                                       |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ STRUTTURA PSEUDO HEADER                                             |
|                                                                          |
|                                                                          |
|                                                                          |
| struct pseudohdr {                                                       |
|         unsigned long saddr;                                             |
|         unsigned long daddr;                                             |
|         char useless;                                                    |
|         unsigned char protocol;                                          |
|         unsigned short length;                                           |
| };                                                                       |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ STRUTTURA HEADER TCP                                                |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| struct tcphdr {                                                          |
|         __u16        source;                                             |
|         __u16        dest;                                               |
|         __u32        seq;                                                |
|         __u32        ack_seq;                                            |
| #if defined(__LITTLE_ENDIAN_BITFIELD)                                    |
|         __u16        res1:4,                                             |
|                 doff:4,                                                  |
|                 fin:1,                                                   |
|                 syn:1,                                                   |
|                 rst:1,                                                   |
|                 psh:1,                                                   |
|                 ack:1,                                                   |
|                 urg:1,                                                   |
|                 res2:2;                                                  |
| #elif defined(__BIG_ENDIAN_BITFIELD)                                     |
|                 __u16        doff:4,                                     |
|                 res1:4,                                                  |
|                 res2:2,                                                  |
|                 urg:1,                                                   |
|                 ack:1,                                                   |
|                 psh:1,                                                   |
|                 rst:1,                                                   |
|                 syn:1,                                                   |
|                 fin:1;                                                   |
| #else                                                                    |
| #error        "Adjust your <asm/byteorder.h> defines"                    |
| #endif                                                                   |
|         __u16        window;                                             |
|         __u16        check;                                              |
|         __u16        urg_ptr;                                            |
| };                                                                       |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ STRUTTURA HEADER UDP                                                |
|                                                                          |
|                                                                          |
|                                                                          |
| struct udphdr {                                                          |
|         __u16        source;                                             |
|         __u16        dest;                                               |
|         __u16        len;                                                |
|         __u16        check;                                              |
| };                                                                       |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ STRUTTURA HEADER ICMP                                               |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| struct icmphdr {                                                         |
|   __u8          type;                                                    |
|   __u8          code;                                                    |
|   __u16         checksum;                                                |
|   union {                                                                |
|         struct {                                                         |
|                 __u16   id;                                              |
|                 __u16   sequence;                                        |
|         } echo;                                                          |
|         __u32   gateway;                                                 |
|         struct {                                                         |
|                 __u16   __unused;                                        |
|                 __u16   mtu;                                             |
|         } frag;                                                          |
|   } un;                                                                  |
| };                                                                       |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ---[ FUNZIONE PER IL CALCOLO DEL CHECKSUM                                |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| /*                                                                       |
|  * in_cksum --                                                           |
|  *      Checksum routine for Internet Protocol                           |
|  *        family headers (C Version)                                     |
|  */                                                                      |
| unsigned short in_cksum(unsigned short *addr, int len)                   |
| {                                                                        |
|     register int sum = 0;                                                |
|     u_short answer = 0;                                                  |
|     register u_short *w = addr;                                          |
|     register int nleft = len;                                            |
|                                                                          |
|     /*                                                                   |
|      * Our algorithm is simple, using a 32 bit accumulator (sum), we add |
|      * sequential 16 bit words to it, and at the end, fold back all the  |
|      * carry bits from the top 16 bits into the lower 16 bits.           |
|      */                                                                  |
|     while (nleft > 1)                                                    |
|       {                                                                  |
|           sum += *w++;                                                   |
|           nleft -= 2;                                                    |
|       }                                                                  |
|                                                                          |
|     /* mop up an odd byte, if necessary */                               |
|     if (nleft == 1)                                                      |
|       {                                                                  |
|           *(u_char *) (&answer) = *(u_char *) w;                         |
|           sum += answer;                                                 |
|       }                                                                  |
|     /* add back carry outs from top 16 bits to low 16 bits */            |
|     sum = (sum >> 16) + (sum & 0xffff);  /* add hi 16 to low 16 */       |
|     sum += (sum >> 16);                /* add carry */                   |
|     answer = ~sum;                /* truncate to 16 bits */              |
|     return (answer);                                                     |
| }                                                                        |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| ----[ Codici sorgente                                                    |
|                                                                          |
|                                                                          |
| /********************************************************************/   |
| /*                                                                  */   |
| /*           Exile 2000 International Coding Team                   */   |
| /*                (http://www.exile2k.org)                          */   |
| /*              All rights reserved Exile Team                      */   |
| /*               Copyright 2000 (C) Nitr0gen                        */   |
| /*                                                                  */   |
| /*         Questa funzione costruisce un pacchetto ICMP (PING)      */   |
| /*                     includendo l'header IP                       */   |
| /*                                                                  */   |
| /*                                                                  */   |
| /*                                                                  */   |
| /*                                                                  */   |
| /********************************************************************/   |
|                                                                          |
|                                                                          |
| #include <stdio.h>                                                       |
|                                                                          |
| #include <linux/ip.h>                                                    |
| #include <linux/icmp.h>                                                  |
| #include <netinet/in.h>                                                  |
| #include <sys/types.h>                                                   |
| #include <sys/socket.h>                                                  |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| unsigned short in_cksum(unsigned short *addr, int len);                  |
|                                                                          |
|                                                                          |
| int main(){                                                              |
|                                                                          |
| int sock, optval;                                                        |
| char *packet, *buffer;                                                   |
|                                                                          |
| struct icmphdr *icmp;                                                    |
|                                                                          |
| struct sockaddr_in peer;                                                 |
| struct iphdr *ip;                                                        |
|                                                                          |
|                                                                          |
| ip = (struct iphdr *) malloc(sizeof(struct iphdr));                      |
| icmp     = (struct icmphdr *) malloc(sizeof(struct icmphdr));            |
| packet= (char *) malloc(sizeof(struct iphdr) + sizeof(struct icmphdr));  |
| buffer= (char *) malloc(sizeof(struct iphdr) + sizeof(struct icmphdr));  |
|                                                                          |
|                                                                          |
| ip = (struct iphdr *) packet;                                            |
| icmp = (struct icmphdr *) (packet + sizeof(struct iphdr));               |
|                                                                          |
|                                                                          |
| ip->ihl     = 5;                                                         |
| ip->version = 4;                                                         |
| ip->tos     = 0;                                                         |
| ip->tot_len = sizeof(struct iphdr) + sizeof(struct icmphdr);             |
| ip->id      = htons(getuid());                                           |
| ip->ttl      = 255;                                                      |
| ip->protocol = IPPROTO_ICMP;                                             |
| ip->saddr    = inet_addr("127.0.0.1");                                   |
| ip->daddr    = inet_addr("127.0.0.1");                                   |
|                                                                          |
|                                                                          |
| sock = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);                            |
| setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&optval,sizeof(int));              |
|                                                                          |
| icmp->type = ICMP_ECHO;                                                  |
| icmp->code = 0;                                                          |
| icmp->un.echo.id = 0;                                                    |
| icmp->un.echo.sequence = 0;                                              |
| icmp->checksum = 0;                                                      |
|                                                                          |
| icmp->checksum = in_cksum((unsigned short *)icmp,sizeof                  |
|      (struct icmphdr));                                                  |
|                                                                          |
| ip->check    = in_cksum((unsigned short *)ip, sizeof(struct iphdr));     |
|                                                                          |
|                                                                          |
|                                                                          |
| peer.sin_family = AF_INET;                                               |
| peer.sin_addr.s_addr = inet_addr("127.0.0.1");                           |
|                                                                          |
| sendto(sock,packet,ip->tot_len,0,(struct sockaddr *)&peer,sizeof         |
|       (struct sockaddr));                                                |
|                                                                          |
| recv(sock,buffer,sizeof(struct iphdr)+sizeof(struct icmphdr),0);         |
| printf("Ricevuto l'ECHO REPLY\n");                                       |
|                                                                          |
| close(sock);                                                             |
| return 0;                                                                |
| }                                                                        |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| /********************************************************************/   |
| /*                                                                  */   |
| /*            Exile 2000 International Coding Team                  */   |
| /*                 (http://www.exile2k.org)                         */   |
| /*               All rights reserved Exile Team                     */   |
| /*                Copyright 2000 (C) Nitr0gen                       */   |
| /*                                                                  */   |
| /*              Questa funzione csotruisce un pacchetto UDP         */   |
| /*     includendo l'header IP ed inviandlo al server echo locale    */   |
| /*                                                                  */   |
| /*  Per far funzionare il programma abilita il server echo:         */   |
| /*                                                                  */   |
| /*     - pico /etc/inetd.conf                                       */   |
| /*     - Elimina i simboli del commento dalla riga                  */   |
| /*       dell'echo server (udp one)                                 */   |
| /*     - killall -HUP inetd                                         */   |
| /*                                                                  */   |
| /*                                                                  */   |
| /*                                                                  */   |
| /*                                                                  */   |
| /********************************************************************/   |
|                                                                          |
|                                                                          |
| #include <stdio.h>                                                       |
|                                                                          |
| #include <linux/ip.h>                                                    |
| #include <linux/udp.h>                                                   |
| #include <netinet/in.h>                                                  |
| #include <sys/types.h>                                                   |
| #include <sys/socket.h>                                                  |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
| unsigned short in_cksum(unsigned short *addr, int len);                  |
|                                                                          |
|                                                                          |
|                                                                          |
| int main(){                                                              |
|                                                                          |
| int sock, optval;                                                        |
| char *packet, *buffer;                                                   |
|                                                                          |
| struct udphdr *udp;                                                      |
| struct pseudohdr {                                                       |
|         unsigned long saddr;                                             |
|         unsigned long daddr;                                             |
|         char useless;                                                    |
|         unsigned char protocol;                                          |
|         unsigned short length;                                           |
| }pseudo;                                                                 |
|                                                                          |
| struct sockaddr_in peer;                                                 |
| struct iphdr *ip;                                                        |
|                                                                          |
|                                                                          |
| ip = (struct iphdr *) malloc(sizeof(struct iphdr));                      |
| udp     = (struct udphdr *) malloc(sizeof(struct udphdr));               |
| packet  = (char *) malloc(sizeof(struct iphdr) +                         |
|           sizeof(struct udphdr) + 12);                                   |
| buffer  = (char *) malloc(sizeof(struct iphdr) +                         |
|           sizeof(struct udphdr) + 12);                                   |
|                                                                          |
|                                                                          |
| ip = (struct iphdr *) packet;                                            |
| udp = (struct udphdr *) (packet + sizeof(struct iphdr));                 |
|                                                                          |
|                                                                          |
| ip->ihl     = 5;                                                         |
| ip->version = 4;                                                         |
| ip->tos     = 0;                                                         |
| ip->tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) +12;          |
| ip->id      = htons(getuid());                                           |
| ip->ttl      = 255;                                                      |
| ip->protocol = IPPROTO_UDP;                                              |
| ip->saddr    = inet_addr("127.0.0.1");                                   |
| ip->daddr    = inet_addr("127.0.0.1");                                   |
|                                                                          |
|                                                                          |
| sock = socket(AF_INET,SOCK_RAW,IPPROTO_UDP);                             |
| setsockopt(sock,IPPROTO_IP,IP_HDRINCL,&optval,sizeof(int));              |
|                                                                          |
| pseudo.saddr    = inet_addr("127.0.0.1");                                |
| pseudo.daddr    = inet_addr("127.0.0.1");                                |
| pseudo.useless  = htons(0);                                              |
| pseudo.protocol = IPPROTO_UDP;                                           |
| pseudo.length   = sizeof(struct udphdr) + 12;                            |
|                                                                          |
|                                                                          |
| udp->source = htons(5000);                                               |
| udp->dest   = htons(7);                                                  |
| udp->len    = htons(sizeof(struct udphdr) + 12);                         |
| udp->check  = in_cksum((unsigned short *)&pseudo,sizeof(struct udphdr)   |
|      + sizeof(struct pseudohdr) + 12);                                   |
|                                                                          |
| ip->check    = in_cksum((unsigned short *)ip, sizeof(struct iphdr));     |
|                                                                          |
|                                                                          |
| strcpy((packet+sizeof(struct iphdr) + sizeof(struct udphdr)),            |
|         "Hello World");                                                  |
|                                                                          |
| peer.sin_family = AF_INET;                                               |
| peer.sin_addr.s_addr = inet_addr("127.0.0.1");                           |
| peer.sin_port = htons(7);                                                |
|                                                                          |
| sendto(sock,packet,ip->tot_len,0,(struct sockaddr *)&peer,sizeof         |
|       (struct sockaddr));                                                |
|                                                                          |
| recv(sock,buffer,sizeof(struct iphdr)+sizeof(struct udphdr)+13,0);       |
|                                                                          |
| buffer += (sizeof(struct iphdr)+sizeof(struct udphdr));                  |
| printf("Reply from Echo server:\t%s\n",buffer);                          |
|                                                                          |
| close(sock);                                                             |
| return 0;                                                                |
| }                                                                        |
|                                                                          |
|                                 [ Riferimenti ]                          |
|                                                                          |
|                                                                          |
|                                                                          |
| Tcp/Ip Illustrated Volume 1 (The Protocol)                               |
| By W. Richard Stevens (Addison Wesley)                                   |
|                                                                          |
| Tcp/Ip Illustrated Volume 2 (The implementation)                         |
| By Gary R. Wright and W. Richard Stevens (Addition Wesley)               |
|                                                                          |
| Dai un'occhiata qui:                                                     |
|                                                                          |
|         http://www.exile2k.org                Exile Team home page       |
|         http://www.hexedit.com                HNS home page              |
|         http://www.eEyes.com                  eEyes home page            |
|                                                                          |
|                                                                          |
|                                                                          |
|                                 [ Ringraziamenti ]                       |
|                                                                          |
|                                                                          |
|                                                                          |
| Special thanx to:                                                        |
|         My Exile team bro's: Mayhem(Tutu rose emulator),                 |
|                                    Rix(Assembly wh0re),                  |
|                                    Kraken(Saleter dhypee),               |
|                                    Ehoba(Pas toi!!!),                    |
|                                    Liks(Erm...)                          |
|                                                                          |
|                 or Europeen wh0res kinda synonyms =]                     |
|                  ---> keep it kool guys!                                 |
|                                                                          |
|         #rhino9 peeps: Colonwq(Gotta learn you howto drink),             |
|                        Hexedit(Lucky to be yourself),                    |
|                        Binf(Mon mentor de hacking y0),                   |
|                        Klog(Bleh j00),                                   |
|                        zorkeres(Still sickshit addict?),                 |
|                        RcLocal(The french skill0rz),                     |
|                        and others                                        |
|                                                                          |
|         People who supported me even if i was newbie: Utopiste,          |
|                                                       Wyzeman...         |
|                                                                          |
| ~ My parents who made it possible during 1982's night... ~               |
|                                                                          |
|                 God bless people i forget...                             |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|                                                                          |
|         Nitr0gen     Exile Team 2000     Rock on!                        |
|                  nitr0gen@hackersnews.com                                |
|                                                                          |
|                                                                          |
| Tradotto da XpTerminator:                                                |
|                                                                          |
|     spero  proprio  di  aver  tradotto bene...                           |
| per  qualunque  genere  di  errore  segnalate  a:                        |
|                                                                          |
|                                   xp_terminator@katamail.com             |
|                                   http://xpterminator.cjb.net            |
|                                                                          |
| Ciao a tutti!                                                            |
|                                                                          |
|                                                                          |
+--------------------------------------------------------------------------+