A scopa game in Common Lisp

This is a scopa game for 2 players, human vs pc, written in Common Lisp mostly for fun, and to put in practice what I learned about CL so far.

This is my first “real program” (if it can be called so) in Common Lisp, so just don’t expect it to be well-designed. Comments are very welcome.. and don’t strive to be polite about it. 🙂

Source code

Use (play) to play.

Example session at the REPL of GNU CLISP:
I lost against the PC :/

[1]> (load "scopa.clisp")
;; Loading file scopa.clisp ...
;; Loaded file scopa.clisp
T
[2]> (play)

On the table:    [7 OF COPPE],   [6 OF DENARI],   [2 OF DENARI],    [8 OF COPPE]
Your hand:     [5 OF BASTONI],  [9 OF BASTONI],  [2 OF BASTONI]
Stock: 30 cards.

It's PC turn.

Player PC plays [7 OF SPADE] taking [7 OF COPPE]

On the table:   [6 OF DENARI],   [2 OF DENARI],    [8 OF COPPE]
Your hand:     [5 OF BASTONI],  [9 OF BASTONI],  [2 OF BASTONI]
Stock: 30 cards.

It's HUMAN turn.

1) Play [2 OF BASTONI] taking [2 OF DENARI]
2) Play [5 OF BASTONI]
3) Play [9 OF BASTONI]
What do you want to do?
1
Player HUMAN plays [2 OF BASTONI] taking [2 OF DENARI]

On the table:   [6 OF DENARI],    [8 OF COPPE]
Your hand:     [5 OF BASTONI],  [9 OF BASTONI]
Stock: 30 cards.

It's PC turn.

Player PC plays [10 OF COPPE]

On the table:   [6 OF DENARI],    [8 OF COPPE],   [10 OF COPPE]
Your hand:     [5 OF BASTONI],  [9 OF BASTONI]
Stock: 30 cards.

It's HUMAN turn.

1) Play [5 OF BASTONI]
2) Play [9 OF BASTONI]
What do you want to do?
2
Player HUMAN plays [9 OF BASTONI]

...
...

It's PC turn.

Player PC plays [4 OF DENARI]

On the table:    [8 OF SPADE],   [4 OF DENARI]
Your hand:       [2 OF COPPE]
Stock: 0 cards.

It's HUMAN turn.

1) Play [2 OF COPPE]
What do you want to do?
1
Player HUMAN plays [2 OF COPPE]
Player HUMAN collect all the remaining cards on the table.

SCORE ASSIGNMENTS
Greatest number of cards: PC
Greatest number of denari cards: PC
Settebello: PC
Prime: PC
HUMAN
0 + 0 + 0 scopas = 0
-------
PC
0 + 4 + 0 scopas = 4

On the table:    [5 OF SPADE],   [6 OF DENARI],  [3 OF BASTONI],    [3 OF SPADE]
Your hand:     [5 OF BASTONI],    [7 OF SPADE],   [10 OF SPADE]
Stock: 30 cards.

It's HUMAN turn.

1) Play [5 OF BASTONI] taking [5 OF SPADE]
2) Play [10 OF SPADE]
3) Play [7 OF SPADE]
What do you want to do?
1
Player HUMAN plays [5 OF BASTONI] taking [5 OF SPADE]

...
...

It's PC turn.

Player PC plays [5 OF DENARI]
Player PC collect all the remaining cards on the table.

SCORE ASSIGNMENTS
Greatest number of cards: PC
Greatest number of denari cards: PC
Settebello: HUMAN
Prime: PC
HUMAN
0 + 1 + 0 scopas = 1
-------
PC
4 + 3 + 2 scopas = 9

On the table:   [4 OF DENARI],    [5 OF SPADE],   [9 OF DENARI],   [10 OF SPADE]
Your hand:     [7 OF BASTONI],    [8 OF SPADE],   [1 OF DENARI]
Stock: 30 cards.

It's HUMAN turn.

1) Play [8 OF SPADE]
2) Play [1 OF DENARI]
3) Play [7 OF BASTONI]
What do you want to do?
1
Player HUMAN plays [8 OF SPADE]

...
...

It's PC turn.

Player PC plays [6 OF SPADE] taking [2 OF SPADE], [4 OF BASTONI]
Player PC collect all the remaining cards on the table.

SCORE ASSIGNMENTS
Greatest number of cards: PC
Greatest number of denari cards: PC
Settebello: PC
Prime: HUMAN
HUMAN
1 + 1 + 1 scopa = 3
-------
PC
9 + 3 + 2 scopas = 14
The game is over!
The winner is PC with a score of 14!
NIL
[3]>

Entire session.

Lesson learned: never modify literals, quote lists only for constant data

While writing a scopa card game in Common Lisp both as a pet project and a way to practice a little lisp, I had a hard time trying to understand what was going on here:

1
2
3
4
5
6
7
8
9
10
11
(defun prime-points-of-card (card)
  (let ((prime-points '((7 21) (6 18) (1 16) (5 15) (4 14) (3 13) (2 12) (10 10) (9 10) (8 10))))
    (cadr (assoc (card-rank card) prime-points))))
 
(defun prime-points (deck)
  (let ((scores '((denari 0) (coppe 0) (bastoni 0) (spade 0))))
    (loop for card across deck do
         (let ((suit (card-suit card)))
           (setf (cadr (assoc suit scores)) (max (cadr (assoc suit scores))
                                                 (prime-points-of-card card)))))
    (apply #'+ (mapcar #'cadr scores))))

I was expecting prime-points to return the prime points of a sequence of cards, but it kept returning what seemed to me just meaningless numbers.

I added a couple of prints to inspect what was going on:
(yeah I still need to learn how to debug effectively with lisp)

(defun prime-points (deck)
  (let ((scores '((denari 0) (coppe 0) (bastoni 0) (spade 0))))
    (print scores)
    (loop for card across deck do
         (let ((suit (card-suit card)))
           (setf (cadr (assoc suit scores)) (max (cadr (assoc suit scores))
                                                 (prime-points-of-card card)))))
    (print scores)
    (apply #'+ (mapcar #'cadr scores))))

and this is what I found:

[3]> (prime-points #())
 
((DENARI 0) (COPPE 0) (BASTONI 0) (SPADE 0))
((DENARI 0) (COPPE 0) (BASTONI 0) (SPADE 0))
0
[4]> (prime-points #())
 
((DENARI 0) (COPPE 0) (BASTONI 0) (SPADE 0))
((DENARI 0) (COPPE 0) (BASTONI 0) (SPADE 0))
0
[5]> (prime-points (deck 'stock))
 
((DENARI 0) (COPPE 0) (BASTONI 0) (SPADE 0))
((DENARI 21) (COPPE 21) (BASTONI 21) (SPADE 21))
84
[6]> (prime-points #())
 
((DENARI 21) (COPPE 21) (BASTONI 21) (SPADE 21))
((DENARI 21) (COPPE 21) (BASTONI 21) (SPADE 21))
84

scores was keeping its value at each call to prime-points!
Wasn’t let supposed to create a new lexical scope?
Yes, it is and in fact it is what let does.
The problem is to understand that

(quote (foo bar baz))

and its shortcut

'(foo bar baz)

are just list literals the same way as

#(1 2 3) ; Literal array
"literal string"

This means that

(quote (foo bar baz))

is not equivalent to

(list 'foo 'bar 'baz)

In the first case, the list is literal, in the second it is generated by code.
When the list is literal, the compiler could copy it into write-protected memory or share it among more functions (or more calls to the same function) hence the consequences are undefined if it is modified.

As HyperSpec’s QUOTE page states:

Special Operator QUOTE

Syntax:
quote object => object

Arguments and Values:
object—an object; not evaluated.

Description:
The quote special operator just returns object.

The consequences are undefined if literal objects (including quoted objects) are destructively modified.

Ok. This may seem trivial for anybody else, but it was not for me.

This is the same thing that happens in other languages.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
 
void foo() {
  char string[] = "Fresh new at every call";
 
  printf("%s\n", string);
  string[0]++;
  printf("%s\n", string);
}
 
void bar() {
  char* string = "I could be in read-only memory";
 
  printf("%s\n", string);
  string[0]++; // Possible segmentation fault
  printf("%s\n", string);
}
 
int main(int argc, char **argv) {
  foo();
  foo();
  foo();
 
  bar();
  bar();
  bar();
 
  return 0;
}

This is what happens with gcc:

dom@dom-laptop:~/Progetti/c$ gcc -o test test.c && ./test
Fresh new at every call
Gresh new at every call
Fresh new at every call
Gresh new at every call
Fresh new at every call
Gresh new at every call
I could be in read-only memory
Errore di segmentazione
dom@dom-laptop:~/Progetti/c$

So if you need to define a data structure the way I did, use list or just copy-tree the literal data:

(defun prime-points (deck)
  (let ((scores (copy-tree '((denari 0) (coppe 0) (bastoni 0) (spade 0)))))
    (loop for card across deck do
         (let ((suit (card-suit card)))
           (setf (cadr (assoc suit scores)) (max (cadr (assoc suit scores))
                                                 (prime-points-of-card card)))))
    (apply #'+ (mapcar #'cadr scores))))

I need to thank people at comp.lang.lisp for always being friendly and very didactic to lurk at.

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!                                                            |
|                                                                          |
|                                                                          |
+--------------------------------------------------------------------------+

Guida al Pascal

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

The following is a tutorial on the Pascal programming language that got published on the 4th issue of OndaQuadra, an Italian e-zine.

 

+-------------------------------------------------------------------------------+
| ONDAQUADRA MAGAZINE ~ [C0DiNG]                               #03 - 17/09/2001 |
| iNTR0DUZi0NE ALLA PR0GRAMMAZi0NE (PASCAL)           [Xp Terminator] 0x10/0x29 |
+-------------------------------------------------------------------------------+



+--+-+-+-++--++-+-+++--++-+-+-+-++-+--+-+-++--+-+-+-+-+-+-+-+-++-+-+--+-++--+
                              GUIDA AL PASCAL
                                           by Xp Terminator
+--+-+-+-++--++-+-+++--++-+-+-+-++-+--+-+-++--+-+-+-+-+-+-+-+-++-+-+--+-++--+

oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO
Ne io ne lo staff di oq si assume responsabilità su ciò che farete con le
informazioni di questo tutorial, anche se credo che non si possa fare nulla
di male...
oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO


Premetto che con questa guida non si diventerà di certo guro della programmazione
ma è una buona introduzione ai concetti principali della programmazione, se poi 
si vuole passare a linguaggi più complicati.
Ho scelto come linguaggio il pascal, poichè è semplice, ed in rete si può trovare
veramente tanto materiale su di esso.

Il pascal e` un linguaggio di programmazione straordinario, ed a differenza
di come la pensano in molti e` anche molto potente, grazie anche alla
possibilita` di utilizzare file object compilati con altri linguaggi,
e di inserire frammenti di codice assembler, un linguaggio a bassissimo
livello con il quale e` possibile fare qualunque cosa. Magari in futuro
scrivero` una guida anche per l`assembler.
Il pascal e` un linguaggio ad alto livello, cioe` e` ben lontano dal linguaggio
macchina. I linguaggi di programmazione possono essere divisi in due categorie,
quelli che vengono eseguiti direttamente (come per esempio il basic, o i file
batch del dos), e quelli che per essere eseguiti hanno prima bisogno di essere
compilati (tramite la compilazione viene creato un file .obj) e linkati
(con il link viene creato il file eseguibile).
Il pascal fa parte di questi ultimi, ed e` un pregio, perche` i file che vengono
eseguiti direttamente sono molto + lenti e gli errori non vengono segnalati,
ma si scoprono man mano che si esegue il programma.
Esistono vari compilatori per il pascal, e tra di loro vi sono poche differenze.
Io consiglierei il Borland Pascal 7.0, l'ultima versione rilasciata, prima
dell`avvento del Delphi, il "pascal visuale" un po` come il visual basic, che
e` il basic visuale. Io sinceramente consiglierei il Delphi x chi ha intenzione
di programmare sotto so windows con interfaccia grafica; con il pascal, si
possono creare non solo applicazioni che girano sotto dos o sotto windows in
interfaccia in modalita` testo, ma addirittura si possono creare sistemi
operativi! come per esempio, Menuet, scritto con 25000 righe in turbo pascal,
+ quasi 2000 scritte in Assembler. Il borland pascal 7.0 e` downloadabile
dall`url http://www.computertemple.com nella sezione utility.
Ecco un semplicissimo programma in Pascal:

program prova;
{questo e` un commento!}
uses crt;
var stringa : string;

begin
     stringa := 'Hello world!!!';
     writeln(stringa);
     repeat until keypressed;
end.

provate a compilarlo ed eseguirlo, otterrete come output:

Hello world!!!

Ora esaminiamo questo piccolo frammento di codice sorgente:

program prova;   ---> questa riga non fa altro che dichiarare il nome del
                      programma che scriviamo; questa riga e` omettibile;
                      il nome del programma non puo` contenere spazi, io
                      consiglierei di sostituirli con gli underline _ .

{questo e` un commento} ---> Servono commenti? :))) spero di no, cmq
                             tra parentesi graffe possono essere
                             inseriti i commenti; cio` e` molto utile
                             quando il programma diventera` + complesso,
                             e dovremo rivederlo, cosi` potremo commentare
                             a cosa servira` una riga

uses crt;   ---> il pascal come qualunque altro linguaggio di programmazione
                 permette di inserire librerie nel proprio programma. Le
                 librerie specificamente in pascal sono chiamate "unit".
                 Queste sono molto utili, per diminuire il codice sorgente
                 del programma; infatti, procedure e funzioni (spieghero`
                 dopo cosa sono + approfonditamente) possono essere scritte
                 in unit; queste quando vengono compilate, creano un file
                 con estensione .tpu , quindi poi bastera` inserire nel
                 proprio programma "uses libreria,libreria2,nlibrerie;"
                 (ricordate che il file libreria si dovra` trovare nella
                 stessa directory del file sorgente, oppure nelle directory
                 tpu del nostro compilatore pascal). Spesso le librerie
                 vengono utilizzate a scopo commerciale, infatti vengono
                 dati gratuitamente i file .tpu (dai quali non si puo` vedere
                 il codice sorgente della unit), e i file sorgenti ,invece,
                 vengono dati solo in cambio di soldi. (In verita` dalle tpu
                 si puo` risalire ai codici sorgenti delle librerie in un
                 modo non molto legale detto Reverse engineering :) ).
                 Con questa riga non abbiamo fatto altro quindi che includere
                 la libreria "crt" nel nostro programma. Questa libreria e`
                 insieme a quella "dos", la + utilizzata, per l`utilita` delle
                 procedure incluse.

var striga : string;   ---> leggi + avanti...

begin   --->  con il comando begin si dichiara l`inizio del programma,
             di un ciclo, di una procedura o di una funzione.
             In questo caso abbiamo dichiarato l`inizio del programma
             vero e proprio.

stringa := 'Hello world!!!';   ---> leggi + avanti...

writeln(stringa);   ---> con il comando writeln viene stampato a video
                         un testo, od una variabile come in questo caso.
                         Il testo viene stampato sul punto attuale del cursore.

repeat until keypressed;   ---> Questo e` un ciclo, e la sua sintassi e`:
                                repeat comando1 comando2 ... until condizione;
                                cioe` vengono ripetuti i comandi finche`
                                non avviene la condizione. In questo caso
                                come vedete viene ripetuto " " finche` non
                                viene premuto un tasto. Cioe` non avviene
                                un bel niente finche` non viene premuto un
                                tasto. Altri cicli li vedremo + avanti...

end.    ---> End e` l`equivalente dell`opposto di begin, infatti esso
             dichiara la fine di una procedure, di un ciclo, di una funzione
             o del programma vero e proprio. In questo caso dichiara la fine
             del programma essendo seguito da un punto . Quando ,invece,
             dichiara la fine di un`altra delle ipotesi suddette viene seguito
             da una virgola, .


Come avete notato alla fine di ogni riga e` obbligatorio inserire un ";", se
no viene considerato come un errore. Le uniche eccezioni sono il begin,
i commenti, e l`end finale, che come avete visto e` seguito da punto.
Inoltre, avrete sicuramente notato che il codice dopo il begin e spostato
con una tabulazione a destra. Questo non e` obbligatorio ma e` molto utile
per rendere il programma facilmente "leggibile".

Come premesso ora parlero` approfonditamente delle variabili, della loro
funzione e dichiarazione.
Le variabili non sono altro che dei "cassetti" infatti, quando dichiariamo
una variabile non facciamo altro che assegnare ad una parte della nostra
memoria ram il compito di contenere un valore. Le variabili vengono dichiarate
con questa sintassi:
var nomevariabile : tipovariabile;
Il nome della variabile puo` essere qualunque basta che non sia una parola
chiave. Le parole chiave variano da compilatore a compilatore.
I tipi di variabili possono essere del testo : "string", un singolo carattere
della tabella ASCII : "char", booleano cioe` con valori true o false "boolean",
od un numero. I tipi di variabili numero sono molti,
ecco i maggiori:
"byte" : valori da 0 a 255
"integer" : valori da -32768 a 32767
"real" : valori in virgola mobile

I valori delle variabili devono essere dichiarati dopo il begin, con questa
sintassi:
nomevariabile := valore;
Quando la variabile e` numerica la sintassi e` come in questo esempio:

numero:=6378;

mentre quando si tratta di un testo o di un carattere:

stringa:='Hello world!!!';
carattere:='d';

Le variabili sono utili per ottenere degli input da colui che esegue il
programma, vedete per esempio questo codice:

uses crt;

var input1,input2 : string;
    input3 : byte;

begin
        clrscr;
        writeln;
        write('Qual e'' il tuo nome? ');
        readln(input1);
        write('Qual e'' il tuo cognome? ');
        readln(input2);
        write('Quanti anni hai?');
        readln(input3);
        writeln;
        writeln(input1,' ',input2,' ha ', input3, ' anni.');
        repeat until keypressed;
end.

eseguendo questo programma otterrete:


        Qual e' il tuo nome? Xp
        Qual e' il tuo cognome? Terminator
        Quanti anni hai? 16

        Xp Terminator ha 16 anni.

Analizziamolo:
le righe fino al begin le abbiamo tutte gia` visto precedentemente.
clrscr;   ---> questa procedura si trova nella libreria crt, e non fa
               altro che fare pagina pulita.

writeln;   ---> come visto in precedenza writeln serve per stampare
                a video qualcosa, in questo caso lasciamo solo una riga vuota.

write('Qual e'' il tuo nome?');   ---> write ha lo stesso utilizzo di writeln,
                                        ma al termine della scrittura a video
                                        non va a capo. Come avete visto inoltre
                                        per far visualizzare un apice ' bisogna
                                        digitarlo due volte, se no sarebbe un
                                        errore. Cio` vale anche per writeln.

readln(input1);    ---> readln e` l`opposto di writeln, infatti a posto
                        di inviare un output alla periferica standard (video),
                        riceve un input dalla periferica standard (tastiera).
                        In effetti, questa riga non fa altro che aspettare che
                        l`utente dgt qualcosa, e poi assegna cio` che e` stato
                        digitato alla variabile.

write('Qual e'' il tuo cognome?');---\
readln(input2);    ----------------\
write('Quanti anni hai?');   -----| tutti questi comandi sono stati gia` visti
readln(input3);   ----------------/
writeln;   -------------------------/

writeln(input1,' ',input2,' ha ', input3, ' anni.');  ---> Con questa riga
                                                        scriviamo le variabili
                                                        ottenute + uno spazio
                                                        tra di loro e "ha"
                                                        e "anni.", in modo da
                                                        ottenere: "Nome Cognome
                                                        ha num_anni anni."

repeat until keypressed; ---> gia` visti
end.            ----------------/\

Tramite la spiegazione e gli esempi spero di aver chiarito cosa sia una
variabile, come dichiararla, come assegnargli un valore.

Spesso quando si scrive un programma si incontra il problema di dover scrivere
+ volte una stessa serie di comandi; a questo punto vengono in aiuto le
procedure. Infatti queste non sono nient`altro che una serie di comandi che
possono essere chiamati con una sola riga. Ecco un esempio:

uses crt;

var ancora : string;
label prova2;


procedure prova1;
var addendo1, addendo2, risultato : integer;

begin
        clrscr;
        writeln;
        writeln;
        writeln;
        write('Inserisci il primo addendo : ');
        readln(addendo1);
        write('Inserisci il secondo addendo : ');
        readln(addendo2);
        risultato := addendo1 + addendo2;
        writeln;
        writeln('Il risultato e'' ',risultato); 
end;
         
begin

        prova2:
                prova1;
                writeln;
                write('Un''altra addizione? (s/n)');
                readln(ancora);
                if ancora='s' then goto prova2;
end.


come vedete e` un semplice programma che fa un`addizione. La procedura
non era strettamente necessaria, ma era solo per esempio.
Analizziamo le cose nuove all`interno del semplice programma:

label prova2;   --->con questa riga abbiamo dichiarato un`"etichetta".
                    Queste sono molto utili per rimandare il programma
                    ad una certa riga in qualsiasi momento. E` un po` come
                    quando col basic vi era "then goto numeroriga", e` la
                    stessa cosa qui, solo che si rimanda al nome della label.

procedure prova1;   --->Vedi + avanti...

risultato := addendo1 + addendo2;   --->Come abbiamo detto in precedenza in
                                        questo modo si assegnano dei valori
                                        alle variabili. In questo caso
                                        abbiamo assegnato a risultato il
                                        valore della somma del valore di
                                        addendo1 e del valore di addendo2.
                                        Quel + tra le variabili viene detto
                                        operatore. Ve ne sono altri, ecco i
                                        + diffusi:

                                        + (gia` visto) per la somma
                                        - per la sottrazione
                                        / per la divisione
                                        * per la moltiplicazione

prova2:    ---> Assegniamo l`inizio della label, dichiarata in precedenza.
                Quando chiameremo la label, il programma continuera` ad
                eseguire i comandi da qui in poi.

prova1;   ---> Con questa riga richiamiamo la procedura scritta in precedenza.

if ancora='s' then goto prova2;  ---> controlla se ("if" = "se") la variabile
                                      ancora e` uguale a "s"; se e` uguale
                                      allora ("then" = "allora")
                                      vai alla ("goto" = "vai a") label prova2.



Come avete visto le procedure sono come dei veri e propri programmi
all`interno del nostro programma che possono essere chiamati quando si vuole.
Ecco la sintassi:

procedure nomeprocedura(eventuali_variabili : tipo);
eventuali_variabili_2 : tipo;
begin
        comando1;
        comando2;
        comando3;
        ...
end;

Come avete visto dopo il nome della procedura tra parentesi e` possibile
inserire dei valori da poi utilizzare all`interno del programma.
Inoltre prima del begin della procedura si possono anche dichiarare delle
variabili da utilizzare, basta che il loro nome non sia lo stesso di quello
tra parentesi dopo il nome della procedura. Non e` possibile creare
concatenazioni di procedure, cioe` non si possono inserire altre procedure
all`interno delle procedure.
Come detto in precedenza vi sono anche le funzioni. Queste sono molto simili
alle procedure, l`unica differenza e` che restituiscono un valore.
Ecco la sintassi:

function nomefunzione(variabili : tipo):tipo_funzione;
eventuali_variabili : tipo;
begin
        comando1;
        comando2;
        comando3;
        ...
        nomefunzione:=valore;
end;


in cui:

tipo_funzione ---> i tipi sono gli stessi delle variabili
nomefunzione:=valore ---> con la penultima riga non facciamo altro
                          che assegnare alla funzione il valore da restituire.

Ecco subito un esempio chiarificatore:

uses crt;

var a1,a2:integer;


function somma(addendo1,addendo2:integer):integer;
begin
        somma:=addendo1+addendo2;
end;
         
begin
                writeln;
                write('Inserisci il primo addendo: ');
                readln(a1);
                write('Inserisci il secondo addendo: ');
                readln(a2);
                writeln;
                writeln('Il risultato e'' ',somma(a1,a2));
                repeat until keypressed;
end.

Come vedete, la funzione somma non fa altro che addizionare le variabili
che gli vengono inviate.

In precedenza, abbiamo visto il comando if. Spieghiamolo meglio; questo e`
molto semplice infatti e` il corrispondente in inglese di come diremmo in
italiano:
se variabile1='Ciao' allora fai questo;.
Cosi` in inglese, e quindi in pascal, faremo:
if variabile1='Ciao' then comando1;
Come vedete, cosi` eseguiamo un solo comando, per eseguire + comandi,
ecco la sintassi:

if variabile=2 then begin
        comando1;
        comando2;
        comando3;
        ...
end;

Inoltre, e` possibile inserire anche "else" il corrispondente dell`italiano
"se no, invece, fai questo". Ecco un esempio di sintassi:

if (questione=false) and (anni=16) then begin
        comando1;
        comando2;
        comando3;
        ...
end else begin
        comando1;
        comando2;
        comando3;
        ...
end;

In questo codice, oltre ad usare else, abbiamo introdotto anche l`utilizzo
di + di una condizione con AND che equivale ad e. Quindi se questione=false
e anni=16 esegue i comandi. Inoltre, oltre ad AND esiste anche OR che equivale
ad o.
Spieghiamo invece ora gli altri cicli, oltre a repeat ... until.
For , ecco la sua sintassi:
for nomevariabile:=numero to numero2 do begin
        comando1;
        comando2;
        comando3;
        ...
end;

Grazie a questo ciclo si possono ripetere un determinato numero di volte
dei comandi. Ecco un esempio:

uses crt;

var i : integer;


begin
        for i:=1 to 10000 do begin
                write('Hello World! ',i);
                clrscr;
        end;                
end.

Questo esempio scrive Hello world! 1 , poi pulisce la pagina e scrive
Hello world! 2, fino ad arrivare a 10000

Un altro ciclo e` While (che corrisponde a "finche`"), ecco la sintassi:

while condizione do begin
        comando1;
        comando2;
        comando3;
        ...
end;

Finche` si verifica la condizione si ripetono i comandi.

Bene, come direbbe il grande Michael Bakunin: Ex Claro?
Credo di aver spiegato chiaramente i concetti base del pascal, ora potete
gia` iniziare a divertirvi con la vostra fantasia a creare nuovi programmi.

Cerco di spiegare ora qualcosa in + sul pascal.
Come ho detto all`inizio all`interno del pascal e` possibile inserire codice
assembler. Questo e` possibile con asm ... end;
Scrivendo asm si dice al compilatore che da li` fino al primo end; le
istruzioni sono in assembler. Esempio:

begin
        asm
                mov al, 07h
        end;
end.

Questo programma e` un esempio e non fa assolutamente niente, inserisce solo
il valore 07 in esadecimale nella parte bassa del registro ax.
Naturalmente, non posso spiegarvi l`assembler in questa guida, sarebbe troppo
lunga, vi consiglio di leggere la guida all'asm di Michael Bakunin
downloadabile da http://go.to/tankcommandos . Magari in futuro ne scrivero`
una anch`io. Se si conosce bene sia l`assembler che il pascal, si puo` fare
qualunque cosa dal sistema operativo al videogioco tridimensionale.

Inoltre, ho detto in precedenza che all`interno del pascal si possono utilizzare
funzioni scritte in altri linguaggi, basta compilarli ed ottenere il file
con estensione obj. Per inserire questo file bisogna scrivere all`inizio del
programma la riga:
{$L nomefile.obj}
in questo modo si potranno richiamare funzioni e procedure scritte nel file
object. Naturalmente per ogni linguaggio esistono alcuni altri provvedimenti
da prendere, di cui io non parlo in questa guida. Per esempio, per inserire
l'object di un file assembler, bisognera` dichiarare nel file asm le procedure
come public, e poi inserire nel nostro codice le procedure del file object
che useremo in questo modo:
procedure nomeprocedura; external;
Dicendo external; il compilatore cerchera` direttamente la funzione nel file
object.

Infine, sfrutto quest`ultima parte della guida per parlare dei colori.
Nella unit crt, vi sono infatti le procedure textcolor(colore) e
textbackground(colore). Queste dichiarano il colore del testo e dello sfondo
in modalita` testo. Per esempio:

textcolor(white);
textbackground(blue);
clrscr;
writeln('Hello world!');

non fa altro che mettere sfondo blu e testo bianco e scrivere Hello world!

Ecco infine un piccolo programma di esempio:

program prova_arcobaleno;

uses crt;

var coloretesto,coloresfondo : integer;
    i : byte;


procedure arcobaleno;
begin
        if coloretesto > 20 then begin
        coloretesto:=0;
        coloresfondo:=1;
        end else begin
        coloretesto := coloretesto + 1;
        coloresfondo := coloresfondo + 1;
        end;
        textcolor(coloretesto);
        textbackground(coloresfondo);
        clrscr;
        writeln;
        writeln('               HELLO WORLD!!!');
        delay(10);
end;

begin
        coloretesto:=1;
        coloresfondo:=0;
        repeat
        arcobaleno;
        until keypressed;
        textcolor(15);
        textbackground(1);
        clrscr;
        writeln;
        writeln('               Tabella ASCII');
        writeln;
        writeln('   premi il pulsante PAUSA per bloccare la lista');
        writeln('   premi qualsiasi tasto per ricominciare a far scorrere la lista o per uscire');
        delay(2000);
        i:=0;
	readln;
	repeat
        writeln(i,' = ',chr(i));
        i:=i+1;
	delay(100);
	until keypressed;
end.


Questo esempio che ho scritto prima visualizza la scritta hello world
(la tipica scritta che viene visualizzata di solito quando si scrive
per la prima volta un programma) con effetto arcobaleno, e poi visualizza
la tabella ascii. Ecco i comandi nuovi che ho inserito in questo esempio:

delay ---> questo comando attende un determinato periodo di tempo,
           la sintassi e`: delay(ms) . Tra parentesi va il tempo da
           attendere in millesimi di secondo, quindi 1000 = 1 secondo.
chr --->   questa funzione restituisce il carattere del numero inserito
           tra parentesi. Sintassi: chr(numero) . Per esempio se scriviamo
           write(chr(21)); otterremo scritto : § .Infatti, se tenendo premuto
           l`alt sinistro della vostra tastiera digitate 21 sui numeri sulla
           destra della vostra tastiera otterrete: §.
Inoltre come avrete notato questa volta dopo l`if al posto di uguale =
abbiamo utilizzato >. > sta a significare maggiore, < minore ed <> diverso.

Siamo giunti agli sgoccioli della guida, perche` non so + cosa spiegare...

Ecco un esempio di un altro programma:

{$M 65000,0,65000}

program esegui;

uses dos,crt;

var file_da_eseguire : string;


begin
        clrscr;
        writeln;
        write('Path del file da eseguire : ');
        readln(file_da_eseguire);
        swapvectors;
        exec('c:\command.com',' /c ' + file_da_eseguire);
        swapvectors;
	writeln;
	writeln('Premi un tasto per uscire dal programma');
	repeat until keypressed;
end.

La prima riga fa utilizzare 65000 byte di memoria, in modo da permettere
l`esecuzione di programmi. Swapvectors, deve essere sempre usato prima e dopo
exec. Exec ,infine, non fa altro che eseguire un file. Ecco la sintassi:
exec(interprete_dei_comandi,parametri);
L`interprete dei comandi del dos e di windows e` il command.com, quindi
bastera` scrivere il suo path. Come parametri /c indica di eseguire un file,
od un comando come ad esempio dir.

Ora sapete quindi anche come eseguire un file.
Ecco discusse qui altre procedure utili, di cui non ho avuto la possibilta`
di parlare:

gotoxy(y,x); ---> sposta il cursore alla x ed alla y data (x e` la riga dello
                  schermo, mentre y e` la colonna) (in modalita` testo normale
                  vi sono 20 righe ed 80 colonne)

random(numero); ---> sceglie casualmente un numero da 1 fino al numero inserito
		     fra parentesi. Per esempio :
		     write(random(100));
		     scrivera` a video un numero casuale da 1 a 100.

initgraph(drivergrafico,modografico,pathdeldriver) ---> inizializza il modo
						grafico. Questa funzione per
						essere eseguita ha bisogno
						della unit graph (quindi
						dovremo inserire graph
						dopo uses), e del path
						della directory bgi che si
						trova nella cartella del nostro
						pascal.

Ecco un esempio di utilizzo della modalita` grafica:

uses Graph;

var Driver_grafico,Modo_grafico,Errore: Integer;

begin
	Driver_grafico := Detect;
	InitGraph(Driver_grafico, Modo_grafico,'qui va il path dei file bgi'); {per es. c:\tp\bgi\ }
	Errore := GraphResult;
	if Errore = grOk then begin
        	Line(0, 0, GetMaxX, GetMaxY);
     		Readln;
     		CloseGraph;
        end else Writeln('Errore grafico:', GraphErrorMsg(Errore));
end.



Vediamo un po`:

Driver_grafico := Detect;  ---> Determina automaticamente il driver grafico giusto per la nostra
				scheda video, e lo assegna alla variabile Driver_grafico

InitGraph(Driver_grafico, Modo_grafico,'qui va il path dei file bgi'); ---> Questa riga
							inizializza la modalita` grafica,
							utilizzando il driver determinato
							precedentemente. Nel terzo parametro
							va inserito il path dei file grafici
							con estensione .bgi. Per esempio, il mio e`
							'c:\progra~1\borlan~1\bgi\'

Errore := GraphResult;   ---> Questa riga controlla il risultato ottenuto dopo essere stata
			      inizializzata la grafica.

if Errore = grOk then begin  ---> se non vi e` errore allora:

Line(0, 0, GetMaxX, GetMaxY);   ---> disegna una linea che va dall`angolo in alto a sinistra sullo
				     schermo, fino all`angolo in basso a destra. GetMaxX e GetMaxY
				     sono delle costanti che indicano l`ultima riga e l`ultima colonna
				     dello schermo.

Readln;    ---> aspetta che si prema un tasto (proprio come repeat until keypressed)

CloseGraph;   ---> chiude la modalita` grafica

end else Writeln('Errore grafico:', GraphErrorMsg(Errore));  ---> se, invece, vi sono stati errori nella
								inizializzazione, scrive a video:
								Errore grafico: ed il codice dell`errore

end.   ---> fine programma



L'articolo e` finito e spero vi sia piaciuto.
Per critiche, per domande, per mandarmi affCENSUREDulo o per presentarmi vostra sorella :))
scrivetemi all'email xp_terminator@katamail.com

Xp Terminator

XP Tel ‘N Chat

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

The following is a tutorial on how to write a “telnet” client in Visual Basic and how to extend it to send e-mails with a spoofed sender.

This tutorial got published on the 4th issue of OndaQuadra, an Italian e-zine.

 

+-------------------------------------------------------------------------------+
| ONDAQUADRA MAGAZINE ~ [L'APPRENDiSTA STREG0NE]               #03 - 17/09/2001 |
| XP TEL 'N CHAT                                      [Xp Terminator] 0x22/0x29 |
+-------------------------------------------------------------------------------+


oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO
Ne io ne lo staff di oq si assume responsabilità su ciò che farete con il
programma allegato
oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoO



SALUTI: saluto tutti i miei amici di #hack , free.it.hacker.virus e soprattutto BigAlex!!
THX: ringrazio me stesso per aver creato il programma e visual basic per non essersi crashato mai durante lo sviluppo (che mazzo! :) (cmq, caso rarissimo, non tentate di imitarlo... ;)
FUCK: un grande vaffxxxulo a tutti i lamerz!
DEDICATED TO: dedico questa guida a tutti quelli che mi conoscono!
WHERE : potete trovarmi su #chihackerare o #hack di irc.azzurranet.org o sul ng free.it.hacker.virus
SITE : due giorni fa ho pubblicato il mio sito, visitatelo! http://xpterminator.cjb.net
Time: 22:58:52
Date: 24/07/01



Tramite questo tutorial cercherò nel modo più semplice possibile di spiegare come sia possibile
tramite visual basic, realizzare un proprio telnet, oppure un proprio client irc, ecc,ecc,
utilizzando come esempio il programma da me realizzato Xp Tel 'n chat. Questo è in allegato
con onda quadra, e funge da telnet, chat, inviatore di mail anonime, e prende pagina http o ftp
tramite proxy....



oOoOoOoOoOoOoOoOo REALIZZIAMO IL NOSTRO TELNET PERSONALE!!! oOoOoOoOoOoOoOoOoOoOoO

[premetto che utilizzeremo il protocollo tcp...]

In visual basic, l'invio e la ricezione dei dati in rete, è gestito da un controllo ocx, 
chiamato Microsoft Winsock Control. Esso non è inserito come controllo standard, quindi
non lo troveremo nella barra standard. Per aggiungerlo seguiamo questi passi:
click col tasto destro sulla barra dei controlli (dove si trovano picture, label, textbox, ecc...)
e scegliamo dal menu "Components..." (la mia versione di vb è inglese, ma credo che voi riusciate a capire i relativi corrispondenti in italiano...)
Si aprirà una finestra; scendiamo fino ad arrivare al controllo Microsoft Winsock Controll [ver] (ver è il numero di versione),
spuntiamo la casella corrispondente e clicckiamo sul tasto ok. Ora noteremo che sarà stato
aggiunto il nuovo controllo winsock.
Siamo pronti!
Facciamo doppio click sul nuovo controllo per inserirlo nel form.
Ora tramite esso possiamo effettuare qualsiasi operazione in internet...
decidete, cosa volete fare?
mmmmm, la mia prima idea è stata quella di realizzare un semplice programma telnet,
poichè non è detto che ognuno debba per forza usare il telnet di winzoz, che per altro non è
neanche ben fatto... (cmq, vi dico subito che il telnet che realizzeremo non permetterà di connettersi,
per esempio, al server www.server.com sulla porta telnet, poichè non è compatibile con il tipo di terminale...,
cmq non rattristitevi! tutte le altre operazioni le potremo fare! come inviare mail più o meno anonime, ecc....)
Allora, pronti per la vostra versione personalizzata di telnet?
Per prima cosa dovremo creare due textbox che chiameremo textbox1 e textbox2.
In queste l'utente inserirà rispettivamente server e porta per la connessione.
Quindi, creiamo un pulsante e cambiamo la caption in "Connetti! / Disconnetti!"
Nell'evento click del pulsante inseriamo il codice:

0101010100011010101010101010010101011010101010101010110

    If Winsock1.State <> sckClosed 'controlla se il winsock e' gia' connesso
    	Winsock1.Close		   'quindi chiude la connessione
    	Exit Sub 		   'ed esce dalla routine
    End If
  
    Winsock1.RemoteHost = Text1.Text        'imposta il contenuto di text1 come host remoto a cui connettersi
    Winsock1.RemotePort = Text2.Text        'imposta il contenuto di text2 come porta dell'host a cui connettersi
    Winsock1.Connect			    'si connette

0101010100011010101010101010010101011010101010101010110

In questo momento, il winsock tenta di connettersi alla porta tot del server tot, quindi avviene il three-way-handshake.
Quando questo sarà terminato cosa succede? Se la connessione e' andata a buon fine
il server ci inviera' una stringa che varia da porta a porta, ovvero da demone a demone.
Come possiamo ricevere questo messaggio e visualizzarlo?
Per prima cosa creiamo un'altra textbox, textbox3.
Impostiamo le proprietà del textbox : multiline deve essere true, e scrollbars sul valore 3 (both).
Ma ora come facciamo a capire quando riceviamo i dati?
Nel momento in cui il server ci risponde, il winsock genera un evento chiamato dataarrival, quindi inseriamo nel codice:

0101010100011010101010101010010101011010101010101010110

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
   Dim dati As String                   'dichiariamo la viariabile
   Winsock1.GetData dati, vbString      'inseriamo i dati inviati dal server nella variabile
   Text3.Text = text3.text & dati       'inseriamo i dati nel textbox, in modo che siano leggibili dall'utente
End Sub

0101010100011010101010101010010101011010101010101010110

Quindi, da come si vede, inseriamo ciò che ci invia il server nella nuova textbox.
Ora però che programma sarebbe se non possiamo rispondere al server?
Creiamo una nuova textbox, text4, ed un nuovo bottone.
Nel textbox saranno inseriti i dati da inviare, mentre col nuovo tasto li invieremo..
Quindi nella routine dell'evento click del nuovo tasto inseriamo:

0101010100011010101010101010010101011010101010101010110

    Winsock1.SendData text4.text & vbCrLf            'inviamo al server il testo contenuto nel text4, seguito da un carattere che fa capire al server che la stringa da inviare è finita, e che quindi può rispondere...
    text3.text = text3.text & text4.text & vbCrLf    'inseriamo i dati anche nella textbox precedente

0101010100011010101010101010010101011010101010101010110

Come vedete ora inviamo i dati al server, ed inseriamo gli stessi anche nella stessa
textbox nella quale inseriamo le risposte del server, in modo tale da avere sotto
controllo tutta la sessione telnet...
Ed ora cos'altro dobbiamo aggiungere per poter correre a dire agli amici di aver creato un telnet?
Niente! :)
Hiihihih

Certo non permette operazioni troppo complesse, ma rimane sempre un telnet più che buono! sopratutto paragonato ai programmi della microzoz...



Con ciò abbiamo realizzato un buon telnet, usando la stessa procedura che ho usato per realizzare il mio.
Ma come si può chattare? 
Facilissimo direte voi! Basta connettersi ad una porta prescelta del computer di un amico e comunicare!
Sii! Pero' per connetterci alla porta del nostro amico, c'e' bisogno che lui sia in ascolto!
Ok, allora, togliamoci questo atroce problema, ed aggiungiamo i componenti che possano
permettere alla nostra applicazione di fungere da server...
Aggiungiamo quindi, una textbox, text5, ed un bottone.
Nella text5 dovrà essere inserita la porta sulla quale mettersi in ascolto;
cambiate la caption in "Mettiti in ascolto!" e, all'evento click del nuovo bottone inseriamo:

0101010100011010101010101010010101011010101010101010110

    Winsock1.LocalPort = text5.text    'Impostiamo il valore contenuto in text5 come porta locale d'ascolto
    Winsock1.Listen		       'Mettiamo in ascolto il winsock

0101010100011010101010101010010101011010101010101010110

Ok! Ora e' tutto fatto vero? No!
Come possiamo sapere quando qualcuno sta tentando di connettersi sulla nostra porta in ascolto?
Semplice, esiste come prima un altro evento che avviene in tal caso: connectionrequest.
Quindi inseriamo questa routine nel codice:

0101010100011010101010101010010101011010101010101010110

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
   If Winsock1.State <> sckClosed Then Winsock1.Close     'Se la connessione è aperta la chiude
   Winsock1.Accept requestID 				  'Accetta la richiesta di connessione  
End Sub

0101010100011010101010101010010101011010101010101010110

Ora basta che o noi o il nostro amico si metta in attesa su una determinata porta, 
e l'altro ci si connetta e si puo' chattare! :)
L'unica pecca e' che colui che si connette ha bisogno di sapere l'ip del computer al quale connettersi!

Ora il gioco è veramente fatto!
Abbiamo tra le nostre mani un ottimo programma!
Ma non sarebbe meglio aggiungere qualche optional?
Ok, potremmo aggiungere un form per inviare le mail anonime.

Creiamo un nuovo form, form2, ed inseriamo all'interno tre textbox normali, ed una
quarta nella quale settiamo le proprieta' : multiline = true, e scrollbars = 3 (both)
Ora aggiungiamo un pulsante, un timer, ed un controllo winsock.
Nei rispettivi textbox inseriremo: mittente, destinatario, oggetto e messaggio da inviare...
Impostiamo la proprieta' delay del timer1 su 1000 ed enabled su false.
Ora nell'evento click del bottone inseriamo:

0101010100011010101010101010010101011010101010101010110

    Winsock1.RemoteHost = "193.70.192.50"    'imposta mail.libero.it come host remoto
    Winsock1.RemotePort = "25"               'imposta 25 come porta remota (smtp)
    Winsock1.Connect                         'avvia la connessione al server
    Timer1.Enabled = True                    'attiva il timer1 (cioè avvia il conto alla rovescia del valore impostato precedentemente ovvero 1000 ms, alla fine dei quali viene eseguita la ruotine timer relativa al timer)

0101010100011010101010101010010101011010101010101010110

ora facciamo doppio click sul timer ed inseriamo nell'evento timer:

0101010100011010101010101010010101011010101010101010110

If Winsock1.State = 7 Then                                  'se e' avvenuta la connessione
   
    Winsock1.SendData "helo xp_trmntr.net" & vbCrLf                  'saluta il server
    Winsock1.SendData "mail from: <" & Text1.Text & ">" & vbCrLf     'indica al server il mittente (falso!)
    Winsock1.SendData "rcpt to: <" & Text2.Text & ">" & vbCrLf       'indica al server il destinatario
    Winsock1.SendData "data" & vbCrLf                                'indica al server che inizia il messaggio da inviare
    Winsock1.SendData "From: <" & Text1.Text & ">" & vbCrLf          'inserisce nelle intestazioni della mail il mittente
    Winsock1.SendData "To: <" & Text2.Text & ">" & vbCrLf            'inserisce nelle intestazioni della mail il destinatario  
    Winsock1.SendData "Subject: " & Text3.Text & vbCrLf              'inserisce nelle intestazioni della mail l'oggetto
    Winsock1.SendData vbCrLf                                         'invia una riga vuota      
    Winsock1.SendData Text4.Text & vbCrLf                            'invia il messaggio
    Winsock1.SendData vbCrLf                                         'invia una riga vuota         
    Winsock1.SendData "." & vbCrLf                                   'indica al server che la mail e' finita
    Winsock1.SendData "quit" & vbCrLf                                'chiude la comunicazione con il server  
    MsgBox "Invio completato!"					     'avverte l'utente che l'invio e' stato completato   
    
Else                                                         'se invece non ci si e' connessi al server
    
    MsgBox "Impossibile connettersi al server per l'invio dell'e-mail!"  'avverte l'utente dell'errore
    
End If

0101010100011010101010101010010101011010101010101010110

Ora torniamo al form1, e creiamo un pulsante, inserendo come caption "Invia email anonima!"
ed inserendo come codice della routine click:

0101010100011010101010101010010101011010101010101010110

form2.show

0101010100011010101010101010010101011010101010101010110

in modo tale da visualizzare il form per inviare l'email anonima.


Bhe' cos'altro c'e' da dire!
Spero che da oggi in avanti vi creerete le cose da soli! poiche' come avete
visto non e' affatto difficile! e' spero che quindi non andiate piu' ingiro a chiedere
tutto gia' pronto...cio' che non avete realizzatevelo! :)

Per critiche, per domande, per mandarmi affCENSUREDulo o per presentarmi vostra sorella :))
scrivetemi all'email xp_terminator@katamail.com

Ciauz :)
Xp Terminator