_______ __ __________ \ \ _____/ |\______ \__ __ ____ ____ ___________ ______ / | \_/ __ \ __\ _/ | \/ \ / \_/ __ \_ __ / ___/ / | \ ___/| | | | \ | / | \ | \ ___/| | \|___ \ \____|__ /\___ >__| |____|_ /____/|___| /___| /\___ >__| /____ > \/ \/ \/ \/ \/ \/ \/(r) 4 0 4 -------------------------------------------------------------------------- FrOm Spp to tHe NeT NumEro UnDiCi -------------------------------------------------------------------------- Sommario: --------- Editoriale ---------- By -=F14m3r=-® Pager ----- By Master Metereologia ------------ By wuRZel Lo Stack TCP/IP e i socket --------------- By LuRkIn' TOP Trojan ---------- By x-h4ck3r Mirc 5.51 - Seconda parte ------------------------- Linux: piu' semplice di quanto sembra ------------------------------------- By -=F1m3r=-® -=HTML SECTION=- Superato il sistema di protezione del DVD ---------------------- By ADaM ========================================================================================== Editoriale -------------- by -=F14m3r=-® -------------- Bene bene, siamo arrivati al numero undici. Ok, ok... ammetto che di tempo dall'uscita del numero precedente ne e' passato fin troppo (quasi 3 mesi), e a questo proposito devo ammettere che la colpa e' mia. Mi cospargo il capo di cenere, e chiedo perdono. Comunque, ora eccolo qua. Ci troverete un articolo un po' fuori dai soliti canoni ma a mio parere interessante (fatemi sapere che ne pensate!). Per il resto... tutto secondo norma. Ah... quasi dimenticavo! Approfitto di questo editoriale per dare il benvenuto al nuovo membro del gruppo SPP: Quequero, che gia' aveva contribuito in passato a questa rivista con molta disponibilita'. Ok, penso sia abbastanza... visto che gli editoriali nove volte su dieci vengono saltati a pie' pari direi che posso risparmiare la fatica a chi e' arrivato fin qua e lasciarvi alla lettura di questa e-zine. Have fun! -=F14m3r=-® - flamer@freemail.it ========================================================================================== Pager --------- by Master --------- _ _ 8a Q 1#_, _ _#B B##B" g##b_ ####, ""#9 a####@ Q""" `@ ,W####Bg ,@ B /######W J9 ,ggggWggg_ [g [####### B _qg#ggggq ,##IN######@q @_########9[" ,d#########@g #####G#######p,l&########&W p############## J######I##M####@`@##NS###Q@j##############@ 4#######RU#I####@Q##O#U###@Q###############B T#########MUS###N##C##M#N##NI###########M ` "@######NOC##T###I#RIG#########" ####" "M#TEE###MU###" Y###@ ###BL `"#########" ####c + """ _,gM#137#Mg_ """ END #___#___# "4#######" -= Master =- ##SATOR## _ k####@ ,a SPP MEMBER *** #AREPO# #pg___d@###@____g#L www.spippolatori.com #TENET# @#################L master@spippolatori.com #OPERA# *###""`##P "@##@ ######### ########### #ROTAS# ### ################################################################################### ############## E TU VOLEV 'O PAGER .. 'O PAGER .. 'O PAGER ################# ################################################################################### . - . Meglio la pizza senza dubbio. :)) Cmq dopo una latitanza forzata dal vb ho pensato di continuare con questo articolo che puo' essere visto come il continuo naturale dei due precedenti tutorial sulla programmazione del winsock. Prologo: Una delle principali preoccupazioni per gli psicotici della rete e' sempre stata quella di poter comunicare (chissa' quali tremendi segreti) in tutta serenita' avendo la certezza dell'anonimato e soprattutto del fatto che nessuno (echelon e rispettivi providers compresi) possano intromettersi spulciando all'interno delle conversazioni frasi e battute maliziose. Relativamente a questa legittima preoccupazione si trovano qua e la in rete programmi per poter chattare in maniera privata ed alcuni di questi permettono di ricevere e trasmettere i dati in maniera cifrata: ovvero codificati con un certo algoritmo all'atto dell'uscita e quindi successivamente decodificati all'atto della ricezione. Quasi tutti quelli che ho visto funzionavano sulla base della chat privata e due programmi per costruirsi una chat privata sia in chiaro che cifrata sono gia stati trattati nei tutorial precedenti... anche multiutente! Chat privata significa che due o piu' persone si connettono tra di loro comunicando in linea diretta con un determinato ip che puo' a sua volta mandare messaggi ad uno o a tutti i suoi interlocutori. Invece una cosa che non ho ancora visto da nessuna parte e di facile implementazione e' un vero e proprio servizio pager. Nel caso specifico l'ip al quale tutti si collegano diventa un vero e proprio server attivo che non solo cessa di essere l'oggetto delle attenzioni ma diventa il nucleo che reindirizza i messaggi in provenienza da un utente a tutti gli altri, esegue i comandi, ecc.. Praticamente cio' che fa un server icq o un server irc. si passa quindi da una situazione dove : IP1 monta il programma multichat in listen | | +----+----+--- ... ---+ | | | | IP2, IP3, IP4, IPX si connettono a IP1 per chattare con quest'ultimo. ad un'altra situazione dove IP2-----\ /---------IP3 IP1 IP4-----/ \---------IPX IP2, IP3, IP4, ... IPX sono tutti connessi tra di loro tramite IP1. Ip1 come avevamo detto prima diventa un interlocutore passivo ed invisibile ma anche un attivo reindirizzatore di messaggi su comandi. E' necessario come prima cosa stabilire un protocollo per le comunicazioni. ----------*************** Cosa e' tenuto a fare IP1 come server? 1. stabilire le connessioni per ogni nuovo utente 2. ricevere i messaggi da un utente e reindirizzarli a tutti gli altri 3. eseguire il particolare comando di un utente 4. specificare a tutti gli utenti la provenienza di ogni singolo messaggio attribuendo a ciascuno un numero o un nick di appartenenza che lo renda facilmente identificabile 5. fornire ad ogni utente strumenti di base per l'identificazione in ogni momento di tutte le connessioni attive 6. fornire all'attivazione della connessione e/o su richiesta la lista di tutti gli utenti connessi 7. creare delle aree specifiche (rooms) dove gruppi di utenti possano discutere di argomenti differenziati. ecc.. ci sarebbero anche altre cose importanti ma la base e' questa e per ora sara' la nostra meta da raggiungere col minimo sforzo programmatorio. ;-) Abbiamo detto allora che IP1 riceve dati da ogni utente connesso e deve poter interpretare questi dati in anticipo per poter eseguire correttamente il lavoro che gli viene richiesto. Ad esempio un utente potrebbe semplicemente voler mandare un messaggio a tutti ma anche cambiare il proprio nick .. nel caso la stringa inviata nel primo caso avrebbe le stesse connotazioni di quella inviata nel secondo. ************ Come fare allora per far capire al server le nostre intenzioni? Occorre studiarsi un protocollo comune. Esattamente come il protocollo usato da i server irc o da i server icq. Nel caso specifico ho optato per il protocollo letterale simil-IRC piuttosto che quello numerico di ICQ per via di una piu' facile comprensione. Mai provato durante una sessione irc con telnet a a digitare "/ping utente" ? Si ottiene il ping sull'utente selezionato come se la cosa fosse fatta da noi in prima persona. Questo lo si deve allo speciale protocollo IRC. Inviando la stringa "/ping utente" il server irc a cui siamo commessi leggera' come prima cosa lo slash sapendo cosi' che quello che segue e' un comando. Di seguito prendera' tutto il testo che si trova tra lo slash e il carattere spazio: "ping" avra' cosi' la conferma che il comando che intendiamo usare e' appunto il -ping-. Leggera' poi (sempre nella stringa di testo inviatagli) i dati che si trovano dopo il carattere spazio sino al prossimo spazio o alla fine della stringa.. ed ecco l'ip o il nome dell'utente da verificare. Ancora di seguito il server IRC fara' un PING inviandoci a sua volta una stringa di dati contenente i risultati della sua azione. Il nostro protocollo sara' molto semplice .. ho inserito in effetti solo 4 azioni possibili (dato il semplice sistema di implementazione ne potrete inserire a vostra volta anche a centinaia costruendovi un protocollo-personalizzato) + ******************************************************************* + | 1. ( < ... > ) spedizione di un messaggio sulla lista pubblica | | 2. ( ) richiamo della lista degli utenti connessi | | 3. ( ) cambio del proprio nick | | 4. ( ) ping di un utente | + ******************************************************************* + *************** Passiamo quindi alla descrizione dei vari programmi. Ci sara un server ed un client ovviamente.. nella versione non cifrata il client potra' essere sostituito volendo sia da telnet che da netcat. . - . //---------------------------------------------------------------------------------------- IL SERVER NON CIFRATO: //---------------------------------------------------------------------------------------- Per il form vedere i programmi allegati. ' /////////////////////////////////////////////////////////////// ' si stabilisce il numero massimo di connessioni ' /////////////////////////////////////////////////////////////// Const limite = 30 ' /////////////////////////////////////////////////////////////// ' lista dei nick ' /////////////////////////////////////////////////////////////// Dim nomi(limite) ' /////////////////////////////////////////////////////////////// ' buffer per le stringhe inviate da ogni utente ' /////////////////////////////////////////////////////////////// Dim parole(1 To limite) As String ' /////////////////////////////////////////////////////////////// ' Si attiva il server sulla porta 666 :)) ' ' Ovviamente potra' essere usata una qualunque altra porta ' e si potranno usare server multipli su porte diverse per ' aprire ROOM di dibattito semplicemente sapendo che su una ' determinata porta si parlera' di quello specifico argomento ' ' I nick vengono inizialmente dichiarati tutti secondo lo schema ' ' Primo sock aperto -> nick == 001 ' Secondo sock aperto -> nick == 002 ' ecc.. ecc.. ' ' /////////////////////////////////////////////////////////////// Private Sub Form_Load() For trova = 0 To limite nomi(trova) = "00" + CStr(trova) Next trova TCP(0).Protocol = scktestoProtocol TCP(0).LocalPort = 666 TCP(0).Listen End Sub ' /////////////////////////////////////////////////////////////// ' ' Se un utente ricerca una connessione si controlla se la cosa e' ' fattibile e lo si aggiunge alla lista. ' Immediatamente gli si invia la lista completa di tutti gli altri ' utenti connessi. ' ' /////////////////////////////////////////////////////////////// Private Sub TCP_ConnectionRequest(Index As Integer, ByVal requestID As Long) Dim trova As Long ' /////////////////////////////////////////////////////////////// ' ' Si tenta di connettere i nuovi arrivati su un sock precedentemente aperto ' ed attualmente chiuso o disponibile.. ' ' /////////////////////////////////////////////////////////////// For trova = 1 To TCP.UBound If TCP(trova).State = sckClosed Then parole(trova) = "" TCP(trova).Accept requestID lista$ = "LISTA: " For trova2 = 1 To TCP.UBound lista$ = lista$ + nomi(trova2) + " " Next trova2 manda trova, "CONNESSO -> " & nomi(trova) & " " & lista$ Exit Sub End If Next trova ' /////////////////////////////////////////////////////////////// ' ' Nel caso non ci si riesca si carica un altro winsock e si usa quello ' a meno che non si sia gia superato il limite massimo imposto ' ' /////////////////////////////////////////////////////////////// If TCP.UBound < limite Then trova = TCP.UBound + 1 Load TCP(trova) parole(trova) = "" TCP(trova).Accept requestID lista$ = "LISTA: " For trova2 = 1 To TCP.UBound lista$ = lista$ + nomi(trova2) + " " Next trova2 manda trova, "CONNESSO -> " & nomi(trova) + " " + lista$ For y = 1 To TCP.UBound TCP(y).SendData "Si e'connesso:(" + nomi(trova) + ") -> IP: " + TCP(Index).RemoteHostIP + vbCrLf Next y End If End Sub ' /////////////////////////////////////////////////////////////// ' ' Con l'evento DataArrival .. il cuore del server.. si provvede al reindirizzamento ' di ogni messaggio e all'effettiva trattazione del protocollo da noi studiato. ' ' ' /////////////////////////////////////////////////////////////// Private Sub TCP_DataArrival(Index As Integer, ByVal bytesTotal As Long) Dim passa As String Dim trova As Long If TCP(Index).State = sckConnected Then ' /////////////////////////////////////////////////////////////// ' ' Si acquisiscono le stringhe parziali in arrivo dai vari utenti ' ' /////////////////////////////////////////////////////////////// TCP(Index).GetData passa parole(Index) = parole(Index) & passa Do ' /////////////////////////////////////////////////////////////// ' ' Si aspetta ad elaborare le stringhe parziali fino a quando non si trova ' all'interno di queste un carattere LF ..comunque presente all'atto dell'invio ' Se si usa il CLIENT qui riportato si avra' a fine riga un CRLF esattamente come ' se si usasse un TELNET. Nel caso di NETCAT o di altri programmi specifici per ' UNIX il carattere finale sara' soltanto LF. ' ' /////////////////////////////////////////////////////////////// trova = InStr(parole(Index), vbLf) - 1 If trova < 1 Then Exit Do ' /////////////////////////////////////////////////////////////// ' ' Necessario per l'uso di NETCAT o di altri analoghi tools di UNIX ' ' /////////////////////////////////////////////////////////////// If InStr(parole(Index), vbCrLf) = 0 Then trova = trova + 1 End If passa = Left$(parole(Index), trova - 1) parole(Index) = Mid$(parole(Index), trova + 2) ' /////////////////////////////////////////////////////////////// ' ' Abbiamo la stringa completa da interpretare ' e possiamo passare alla formalizzazione delle varie procedure del ' protocollo ' ' /////////////////////////////////////////////////////////////// ' /////////////////////////////////////////////////////////////// ' ' Si tenta di eseguire un comando solo se se questo rientra effettivamente ' nelle procedure inserite ' ' /////////////////////////////////////////////////////////////// If InStr(1, "nick: lista:ping: ", Mid$(passa, 1, 6)) Then ' /////////////////////////////////////////////////////////////// ' ' CAMBIO DI NICK ' ' ' /////////////////////////////////////////////////////////////// If InStr(1, passa, "nick: ") Then TCP(Index).SendData "Il tuo nick e' stato modificato " + CStr(Index) + " -> " nomi(Index) = Mid$(passa, 6, Len(passa) - 5) Mid$(nomi(Index), 1, 1) = "@" TCP(Index).SendData nomi(Index) + vbCrLf mostra Index, "Esecuzione comando da " + CStr(Index) + " -> " + nomi(Index) End If ' /////////////////////////////////////////////////////////////// ' ' PING DI UN UTENTE CONNESSO ' E' possibile avere piu' ping insieme dichiarando solo parte del nome ' o parti facenti parte di piu' nick contemporaneamente.. ' ad esempio dichiarando PING: a ' si avra' il ping di tutti nick che contengono la lettera "a" ' ' /////////////////////////////////////////////////////////////// If InStr(1, passa, "ping: ") Then For trova = 1 To TCP.UBound If InStr(1, nomi(trova), Mid$(passa, 7, Len(passa) - 4)) Then TCP(Index).SendData "PING " + nomi(trova) + " IP:" + TCP(trova).RemoteHostIP + " SH:" + CStr(TCP(trova).SocketHandle) + vbCrLf End If Next trova mostra Index, "Esecuzione comando da " + CStr(Index) + " -> " + nomi(Index) End If ' /////////////////////////////////////////////////////////////// ' ' LISTA DEGLI UTENTI CONNESSI ' ' ' /////////////////////////////////////////////////////////////// If InStr(1, passa, "lista:") Then lista$ = "LISTA_UTENTI: " For trova = 1 To TCP.UBound lista$ = lista$ + nomi(trova) + " " Next trova lista$ = lista$ + "|- fine lista." TCP(Index).SendData lista$ + vbCrLf End If ' /////////////////////////////////////////////////////////////// ' ' Si invia un punto di riscontro come dichiarazione di comando eseguito ' ' ' /////////////////////////////////////////////////////////////// TCP(Index).SendData "." + vbCrLf Else ' /////////////////////////////////////////////////////////////// ' ' Nel caso la stringa inviata non contenesse nessuno comando tra quelli ' implementati il server dovra' interpretare quest'ultima come un messaggio ' semplice da far visualizzare pubblicamente.. ' ..lo inviera' quindi a tutti gli utenti connessi escludendo il mittente ' che avendolo gia' scritto sul proprio client se lo ritroverebbe altrimenti ' doppio. ;-) ' ' ' /////////////////////////////////////////////////////////////// mostra Index, passa End If Loop End If End Sub ' /////////////////////////////////////////////////////////////// ' ' Procedura per mostrare sulla lista del server i vari messaggi ' e reindirizzarli alla procedure -manda- per la spedizione ' a tutti gli utenti connessi ' ' ' /////////////////////////////////////////////////////////////// Private Sub mostra(ByVal Index As Integer, ByVal testo As String) If List1.ListCount > 100 Then List1.RemoveItem 0 List1.AddItem CStr(Index) & ": " & testo List1.ListIndex = List1.NewIndex For trova = 1 To TCP.UBound If trova <> Index Then manda trova, nomi(Index) & ": " & testo End If Next trova DoEvents End Sub ' /////////////////////////////////////////////////////////////// ' ' Invia i messaggia tutti gli utenti connessi meno che al mittente ' ' ' /////////////////////////////////////////////////////////////// Private Sub manda(ByVal Index As Integer, ByVal testo As String) Do Until TCP(Index).State = sckConnected Or TCP(Index).State = sckClosed DoEvents Loop If TCP(Index).State = sckConnected Then TCP(Index).SendData testo & vbCrLf DoEvents End If End Sub ' /////////////////////////////////////////////////////////////// ' ' Alla disattivazione del server si scaricano dalla memoria ' tutti i winsock attivati prima di chiudere il programma ' Altrimenti il VB lascerebbe delle risorse occupate ' ' /////////////////////////////////////////////////////////////// Private Sub Form_Unload(Cancel As Integer) TCP(0).Close For trova = 1 To TCP.UBound TCP(trova).Close Unload TCP(trova) Next trova End Sub ' /////////////////////////////////////////////////////////////// ' ' Se un utente chiude la propria connessione si libero il relativo ' sock e si informa gli altri utenti della sua 'dipartita'. :)) ' (Si resetta il suo nick che altrimenti verrebbe passato al prossimo utente) ' ' ' /////////////////////////////////////////////////////////////// Private Sub TCP_Close(Index As Integer) If Len(parole(Index)) > 0 Then mostra Index, parole(Index) parole(Index) = "" End If For trova = 1 To TCP.UBound If trova <> Index Then manda trova, nomi(Index) & ": DISCONNESSO" End If Next trova TCP(Index).Close nomi(Index) = CStr(Index) End Sub ' /////////////////////////////////////////////////////////////// ' ' Stessa cosa della chiusura. Se interviene un qualche durante il collegamento con ' un particolare utente. Lo si disconnette liberando il suo sock ed avvertendo ' pubblicamente tutti gli altri. ' (Si resetta il suo nick che altrimenti verrebbe passato al prossimo utente) ' ' /////////////////////////////////////////////////////////////// Private Sub TCP_Error(Index As Integer, ByVal Number As Integer, Description As String, _ ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, _ CancelDisplay As Boolean) If Len(parole(Index)) > 0 Then mostra Index, parole(Index) parole(Index) = "" End If For trova = 1 To TCP.UBound If trova <> Index Then manda trova, nomi(Index) & ": DISCONNESSO" End If Next trova TCP(Index).Close nomi(Index) = CStr(Index) End Sub //---------------------------------------------------------------------------------------- . - . //---------------------------------------------------------------------------------------- IL CLIENT NON CIFRATO: //---------------------------------------------------------------------------------------- Per il form vedere i programmi allegati. Dim linea As Integer ' /////////////////////////////////////////////////////////////// ' ' Invia al server il comando per la visualizzazione di tutti gli ' utenti connessi. ' ' ' /////////////////////////////////////////////////////////////// Private Sub aggio_Click() TCP1.SendData "lista:" + vbCrLf End Sub ' /////////////////////////////////////////////////////////////// ' ' CAMBIO DI NICK. (invio diretto di comando al server) ' ' ' /////////////////////////////////////////////////////////////// Private Sub Cambia_Click() a$ = InputBox("Scrivi il tuo nick:", "CAMBIA") If a$ <> "" Then TCP1.SendData "nick: " + a$ + vbCrLf End If End Sub ' /////////////////////////////////////////////////////////////// ' ' Si connette al server alla porta prefissata ' ' ' /////////////////////////////////////////////////////////////// Private Sub Command1_Click() linea = 0 On Error Resume Next TCP1.Connect Text1, Text2 Label3 = "Connessione aperta" End Sub ' /////////////////////////////////////////////////////////////// ' ' Visualizza su una text box i vari messaggi provenienti dagli altri utenti ' E le dichiarazioni del server. ' ' ' /////////////////////////////////////////////////////////////// Private Sub Command2_Click() On Error Resume Next Label3 = "Invio dei dati" Text4 = Text4 + "I> " + Text3 & vbCrLf Text4.SelStart = Len(Text4) linea = linea + 1 TCP1.SendData Text3 & vbCrLf Text3.SetFocus Text3.SelStart = 0 Text3.SelLength = Len(Text3) End Sub Private Sub Command3_Click() On Error Resume Next TCP1.Close Label3 = "Connessione chiusa" End Sub Private Sub TCP1_DataArrival(ByVal bytesTotal As Long) TCP1.GetData dalserver, vbString parole$ = dalserver If InStr(1, parole$, "LISTA_UTENTI:") Then List1.Clear parti = 1 su: pri = InStr(parti, parole$, " ") sec = InStr(pri + 1, parole$, " ") utente$ = Mid$(parole$, pri + 1, sec - pri - 1) If utente$ = "|-" Then GoTo fine List1.AddItem utente$ parti = sec - 1 GoTo su End If Text4 = Text4 + "R> " + parole$ linea = linea + 1 Text4.SelStart = Len(Text4) ' SendKeys ("^{END}") fine: Text3.SetFocus End Sub Private Sub TCP1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, _ ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) Label3 = Str$(Number) & "," & Description End Sub Private Sub Text3_Click() Text3 = "" End Sub Private Sub Text3_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then Command2_Click End Sub //---------------------------------------------------------------------------------------- Credo non sia sfuggito ai piu' attenti che per fare il client ho riutilizzato di sana pianta il programmino per fare un Telnet in vb creato appositamente per i tutorial precedente. Il riciclaggio in questo caso era doveroso. :)) Per l'utlizzo anche fuori connessione potete provare cosi'.. 1. Attivate sulla vostra macchina il server .. 2. Aprite 4 o 5 client e connettetevi con ognuno all'indirizzo 127.0.0.1 alla porta 666 3. Fate qualche prova cambiano i nick, chiedendo i ping, la lista, spedendo messaggi, ecc... La stessa cosa potra' essere fatta con amici direttamente in rete aprendo sulla macchina di qualcuno il server e specificando a tutti l'ip di quest'ultimo. L'ip potra' ovviamente anche essere trovato con un portscan. :) La differenza con il pager e il client che trasmettono in codice cifrato e' assolutamente minima. E' stato infatti sufficiente cifrare tutti i dati in invio TCP1(INDEX).SENDDATA dato_da_inviare con l'apposita funzione di codifica: TCP1(INDEX).SENDDATA CODIFICA(dato_da_inviare) ed analogamente decodificare tutti i dati in arrivo sull'evento Data_Arrival con la procedura di DECODIFICA TCP1(INDEX).GETDATA dato_ricevuto -> TCP1(INDEX).GETDATA DECODIFICA(dato_ricevuto). Le due procedure per la codifica e la decodifica sono un equivalente del DECO SPP per la cifratura a chiave di battitura random con l'aggiunta di una sotto procedura per la trasformazione dei cifrati in random-time. Ovvero la stessa stringa di testo inviata piu' volte sara' cifrata sempre in maniera diversa. . - . Le procedure sono queste: //---------------------------------------------------------------------------------------- ' ' CODIFICA modo = 0 cifrato deco ' modo = 1 cifrato deco random-time ' ' Private Function codifica(testo$, modo) a$ = "kdfjfdsgnbcvxjhbfyewrygsdfjhbfgkjeripsjjasbgfvads" a$ = a$ + "sdlkasdmnzxbcvdfgqwpweoerhrtrqewueirotinymbn" a$ = a$ + "dfkmsdfnjnrtyqwepoqiwejhdgbncvbyertbvsbvashs" a$ = a$ + "dmcnnxcbxchhdfyueroqwerpkfdsglkncbgjhwjskfhd" a$ = a$ + "dfllfkfgnnmzxcpoeriuteyfdjhsdasdbzxcnvbjfguj" a$ = a$ + "ldkqsdcbcvvczsfcdefcrerfjygrfvughdfkjhtghjty" a$ = a$ + "acbaucbafpaoafadfjhsjhsdfbrethijdfgjhgwretjh" a$ = a$ + "sdfdfmnncvjnbfgyuretygsdfhhdfhrywyywywywhsdf" a$ = a$ + "sdkjsdkjfvnbvcbjhrtuertjhgsdfjygsdfplupljhkh" a$ = a$ + "fdghlkfglhknmlghlkfghopfghlkgfhmgfhodfgidfgu" a$ = a$ + "asdbsansanbasdnbasdhhqherusdfjhcxvhjdsfuhsdf" a$ = a$ + "qweiueuytergftyewrytfqwetfasdgfwqetfyqweruyg" a$ = a$ + "dsfmsdfnmxcvbasdfhjsdfuygwetrpoqwelkjqwemzxv" a$ = a$ + "dfkmvnbhufrhbsvsawvdyfrygsetferuyfuihrdeioeq" a$ = a$ + "sdklsdfjhdfhuisdfeqwytfqwedsfygrgnufgoidfsdf" inizio = 1 b$ = testo$ c$ = "" For n = 1 To Len(b$) e$ = Mid$(b$, n, 1) If e$ >= "a" And e$ <= "z" Then pri = Asc(e$) - Asc("a") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri + sec) Mod 26 c$ = c$ + Chr$(Asc("a") + cif) GoTo ok End If If e$ >= "A" And e$ <= "Z" Then pri = Asc(e$) - Asc("A") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri + sec) Mod 26 c$ = c$ + Chr$(Asc("A") + cif) GoTo ok End If If e$ >= "0" And e$ <= "9" Then pri = Asc(e$) - Asc("0") sec = (Asc(Mid$(a$, inizio, 1)) - Asc("a")) Mod 10 cif = (pri + sec) Mod 10 c$ = c$ + Chr$(Asc("0") + cif) GoTo ok End If c$ = c$ + e$ ok: inizio = inizio + 1 If inizio > Len(a$) Then inizio = 1 Next n If modo = 1 Then codifica = recod(c$) Else codifica = c$ End If End Function ' ' DECODIFICA modo = 0 cifrato deco ' modo = 1 cifrato deco random-time ' ' Private Function Decodifica(testo$, modo) a$ = "kdfjfdsgnbcvxjhbfyewrygsdfjhbfgkjeripsjjasbgfvads" a$ = a$ + "sdlkasdmnzxbcvdfgqwpweoerhrtrqewueirotinymbn" a$ = a$ + "dfkmsdfnjnrtyqwepoqiwejhdgbncvbyertbvsbvashs" a$ = a$ + "dmcnnxcbxchhdfyueroqwerpkfdsglkncbgjhwjskfhd" a$ = a$ + "dfllfkfgnnmzxcpoeriuteyfdjhsdasdbzxcnvbjfguj" a$ = a$ + "ldkqsdcbcvvczsfcdefcrerfjygrfvughdfkjhtghjty" a$ = a$ + "acbaucbafpaoafadfjhsjhsdfbrethijdfgjhgwretjh" a$ = a$ + "sdfdfmnncvjnbfgyuretygsdfhhdfhrywyywywywhsdf" a$ = a$ + "sdkjsdkjfvnbvcbjhrtuertjhgsdfjygsdfplupljhkh" a$ = a$ + "fdghlkfglhknmlghlkfghopfghlkgfhmgfhodfgidfgu" a$ = a$ + "asdbsansanbasdnbasdhhqherusdfjhcxvhjdsfuhsdf" a$ = a$ + "qweiueuytergftyewrytfqwetfasdgfwqetfyqweruyg" a$ = a$ + "dsfmsdfnmxcvbasdfhjsdfuygwetrpoqwelkjqwemzxv" a$ = a$ + "dfkmvnbhufrhbsvsawvdyfrygsetferuyfuihrdeioeq" a$ = a$ + "sdklsdfjhdfhuisdfeqwytfqwedsfygrgnufgoidfsdf" inizio = 1 If modo = 1 Then b$ = redec(testo$) Else b$ = testo$ End If c$ = "" For n = 1 To Len(b$) e$ = Mid$(b$, n, 1) If e$ >= "a" And e$ <= "z" Then pri = Asc(e$) - Asc("a") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri - sec) If cif < 0 Then cif = cif + 26 c$ = c$ + Chr$(Asc("a") + cif) GoTo ok2 End If If e$ >= "A" And e$ <= "Z" Then pri = Asc(e$) - Asc("A") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri - sec) If cif < 0 Then cif = cif + 26 c$ = c$ + Chr$(Asc("A") + cif) GoTo ok2 End If If e$ >= "0" And e$ <= "9" Then pri = Asc(e$) - Asc("0") sec = (Asc(Mid$(a$, inizio, 1)) - Asc("a")) Mod 10 cif = (pri - sec) If cif < 0 Then cif = cif + 10 c$ = c$ + Chr$(Asc("0") + cif) GoTo ok2 End If c$ = c$ + e$ ok2: inizio = inizio + 1 If inizio > Len(a$) Then inizio = 1 Next n Decodifica = c$ End Function ' ' ' Decodifica con estrapolazione della chiave aggiunta ' ' Function recod(testa As String) As String Dim aggiunta As Byte Dim chiave As Byte Dim L1, L2 As Integer Dim OrgInp As String Randomize aggiunta = Int((255 * Rnd) + 1) chiave = Int((255 * Rnd) + 1) L1 = chiave L2 = 1 While L2 < Len(testa) Mid(testa, L2, 1) = Chr((Asc(Mid(testa, L2, 1)) + L1) And 255) L1 = (L1 + aggiunta) Mod 256 L2 = L2 + 1 Wend testa = Chr(chiave) & testa & Chr(aggiunta) recod = testa End Function ' ' Codifica con chiave aggiunta ' ' ' Function redec(testa As String) As String Dim aggiunta As Byte Dim chiave As Byte Dim L1, L2 As Integer aggiunta = Asc(Right(testa, 1)) chiave = Asc(Left(testa, 1)) testa = Mid(testa, 2, Len(testa) - 2) L1 = chiave L2 = 1 While L2 < Len(testa) Mid(testa, L2, 1) = Chr((Asc(Mid(testa, L2, 1)) - L1) And 255) L1 = (L1 + aggiunta) Mod 256 L2 = L2 + 1 Wend redec = testa End Function //---------------------------------------------------------------------------------------- La chiave random specifica che ho inserito e' a$ = "kdfjfdsgnbcvxjhbfyewrygsdfjhbfgkjeripsjjasbgfvads" a$ = a$ + "sdlkasdmnzxbcvdfgqwpweoerhrtrqewueirotinymbn" a$ = a$ + "dfkmsdfnjnrtyqwepoqiwejhdgbncvbyertbvsbvashs" a$ = a$ + "dmcnnxcbxchhdfyueroqwerpkfdsglkncbgjhwjskfhd" a$ = a$ + "dfllfkfgnnmzxcpoeriuteyfdjhsdasdbzxcnvbjfguj" a$ = a$ + "ldkqsdcbcvvczsfcdefcrerfjygrfvughdfkjhtghjty" a$ = a$ + "acbaucbafpaoafadfjhsjhsdfbrethijdfgjhgwretjh" a$ = a$ + "sdfdfmnncvjnbfgyuretygsdfhhdfhrywyywywywhsdf" a$ = a$ + "sdkjsdkjfvnbvcbjhrtuertjhgsdfjygsdfplupljhkh" a$ = a$ + "fdghlkfglhknmlghlkfghopfghlkgfhmgfhodfgidfgu" a$ = a$ + "asdbsansanbasdnbasdhhqherusdfjhcxvhjdsfuhsdf" a$ = a$ + "qweiueuytergftyewrytfqwetfasdgfwqetfyqweruyg" a$ = a$ + "dsfmsdfnmxcvbasdfhjsdfuygwetrpoqwelkjqwemzxv" a$ = a$ + "dfkmvnbhufrhbsvsawvdyfrygsetferuyfuihrdeioeq" a$ = a$ + "sdklsdfjhdfhuisdfeqwytfqwedsfygrgnufgoidfsdf" Ovviamente potra' essere cambiata a piacere inserendo al posto delle lettere minuscole altre lettere minuscole battute a caso. Spero non sia necessario specificare che sia il server che il tutti client impegnati nel lavoro dovranno contenere obbligatoriamente la stessa chiave. ;-) . - . Esempio di server e client Cifrati: //---------------------------------------------------------------------------------------- SERVER CIFRATO //---------------------------------------------------------------------------------------- Private Const limite = 30 Dim nomi(limite) Private parole(1 To limite) As String Private Sub Form_Load() On Error Resume Next For trova = 0 To limite nomi(trova) = "00" + CStr(trova) Next trova TCP(0).LocalPort = 666 TCP(0).Protocol = scktestoProtocol TCP(0).Listen End Sub Private Sub TCP_ConnectionRequest(Index As Integer, _ ByVal requestID As Long) On Error Resume Next Dim trova As Long For trova = 1 To TCP.UBound If TCP(trova).State = sckClosed Then parole(trova) = "" TCP(trova).Accept requestID lista$ = "LISTA: " For trova2 = 1 To TCP.UBound lista$ = lista$ + nomi(trova2) + " " Next trova2 manda trova, "CONNESSO -> " & nomi(trova) & " " & lista$ Exit Sub End If Next trova If TCP.UBound < limite Then trova = TCP.UBound + 1 Load TCP(trova) parole(trova) = "" TCP(trova).Accept requestID lista$ = "LISTA: " For trova2 = 1 To TCP.UBound lista$ = lista$ + nomi(trova2) + " " Next trova2 manda trova, "CONNESSO -> " & nomi(trova) + " " + lista$ For y = 1 To TCP.UBound TCP(y).SendData codifica("Si e'connesso:(" + nomi(trova) + ") -> IP: " _ + TCP(Index).RemoteHostIP, 1) + vbCrLf Next y End If End Sub Private Sub TCP_DataArrival(Index As Integer, _ ByVal bytesTotal As Long) On Error Resume Next Dim passa As String Dim trova As Long If TCP(Index).State = sckConnected Then TCP(Index).GetData passa parole(Index) = parole(Index) & passa Do trova = InStr(parole(Index), vbCrLf) If trova < 1 Then Exit Do passa = Decodifica(Left$(parole(Index), trova - 1), 1) parole(Index) = Mid$(parole(Index), trova + 2) If InStr(1, passa, "nick: ") Then nomi(Index) = Mid$(passa, 6, Len(passa) - 5) Mid$(nomi(Index), 1, 1) = "@" TCP(Index).SendData (codifica("Il tuo nick e' stato modificato " & CStr(Index) _ & " -> " & nomi(Index), 1) & vbCrLf) mostra Index, "Esecuzione comando da " + CStr(Index) + " -> " + nomi(Index) Else If InStr(1, passa, "lista:") Then lista$ = "LISTA_UTENTI: " For trova = 1 To TCP.UBound lista$ = lista$ + nomi(trova) + " " Next trova lista$ = lista$ + "|- fine lista." TCP(Index).SendData codifica(lista$, 1) + vbCrLf Else mostra Index, passa End If End If Loop End If End Sub Private Sub mostra(ByVal Index As Integer, _ ByVal testo As String) On Error Resume Next Dim trova As Long If List1.ListCount > 100 Then List1.RemoveItem 0 List1.AddItem CStr(Index) & ": " & testo List1.ListIndex = List1.NewIndex For trova = 1 To TCP.UBound If trova <> Index Then manda trova, nomi(Index) & ": " & testo End If Next trova DoEvents End Sub Private Sub manda(ByVal Index As Integer, ByVal testo As String) On Error Resume Next Do Until TCP(Index).State = sckConnected Or TCP(Index).State = sckClosed DoEvents Loop If TCP(Index).State = sckConnected Then TCP(Index).SendData codifica(testo, 1) & vbCrLf DoEvents End If End Sub Private Sub Form_Unload(Cancel As Integer) On Error Resume Next Dim trova As Long TCP(0).Close For trova = 1 To TCP.UBound TCP(trova).Close Unload TCP(trova) Next trova Set Form1 = Nothing End Sub Private Sub TCP_Close(Index As Integer) On Error Resume Next If Len(parole(Index)) > 0 Then mostra Index, parole(Index) parole(Index) = "" End If For trova = 1 To TCP.UBound If trova <> Index Then manda trova, nomi(Index) & ": DISCONNESSO" End If Next trova TCP(Index).Close nomi(Index) = CStr(Index) End Sub Private Sub TCP_Error(Index As Integer, _ ByVal Number As Integer, Description As String, _ ByVal Scode As Long, ByVal Source As String, _ ByVal HelpFile As String, ByVal HelpContext As Long, _ CancelDisplay As Boolean) If Len(parole(Index)) > 0 Then mostra Index, parole(Index) parole(Index) = "" End If For trova = 1 To TCP.UBound If trova <> Index Then manda trova, nomi(Index) & ": DISCONNESSO" End If Next trova TCP(Index).Close nomi(Index) = CStr(Index) End Sub Private Function codifica(testo$, modo) On Error Resume Next a$ = "kdfjfdsgnbcvxjhbfyewrygsdfjhbfgkjeripsjjasbgfvads" a$ = a$ + "sdlkasdmnzxbcvdfgqwpweoerhrtrqewueirotinymbn" a$ = a$ + "dfkmsdfnjnrtyqwepoqiwejhdgbncvbyertbvsbvashs" a$ = a$ + "dmcnnxcbxchhdfyueroqwerpkfdsglkncbgjhwjskfhd" a$ = a$ + "dfllfkfgnnmzxcpoeriuteyfdjhsdasdbzxcnvbjfguj" a$ = a$ + "ldkqsdcbcvvczsfcdefcrerfjygrfvughdfkjhtghjty" a$ = a$ + "acbaucbafpaoafadfjhsjhsdfbrethijdfgjhgwretjh" a$ = a$ + "sdfdfmnncvjnbfgyuretygsdfhhdfhrywyywywywhsdf" a$ = a$ + "sdkjsdkjfvnbvcbjhrtuertjhgsdfjygsdfplupljhkh" a$ = a$ + "fdghlkfglhknmlghlkfghopfghlkgfhmgfhodfgidfgu" a$ = a$ + "asdbsansanbasdnbasdhhqherusdfjhcxvhjdsfuhsdf" a$ = a$ + "qweiueuytergftyewrytfqwetfasdgfwqetfyqweruyg" a$ = a$ + "dsfmsdfnmxcvbasdfhjsdfuygwetrpoqwelkjqwemzxv" a$ = a$ + "dfkmvnbhufrhbsvsawvdyfrygsetferuyfuihrdeioeq" a$ = a$ + "sdklsdfjhdfhuisdfeqwytfqwedsfygrgnufgoidfsdf" inizio = 1 b$ = testo$ c$ = "" For n = 1 To Len(b$) e$ = Mid$(b$, n, 1) If e$ >= "a" And e$ <= "z" Then pri = Asc(e$) - Asc("a") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri + sec) Mod 26 c$ = c$ + Chr$(Asc("a") + cif) GoTo ok End If If e$ >= "A" And e$ <= "Z" Then pri = Asc(e$) - Asc("A") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri + sec) Mod 26 c$ = c$ + Chr$(Asc("A") + cif) GoTo ok End If If e$ >= "0" And e$ <= "9" Then pri = Asc(e$) - Asc("0") sec = (Asc(Mid$(a$, inizio, 1)) - Asc("a")) Mod 10 cif = (pri + sec) Mod 10 c$ = c$ + Chr$(Asc("0") + cif) GoTo ok End If c$ = c$ + e$ ok: inizio = inizio + 1 If inizio > Len(a$) Then inizio = 1 Next n If modo = 1 Then codifica = recod(c$) Else codifica = c$ End If End Function Private Function Decodifica(testo$, modo) On Error Resume Next a$ = "kdfjfdsgnbcvxjhbfyewrygsdfjhbfgkjeripsjjasbgfvads" a$ = a$ + "sdlkasdmnzxbcvdfgqwpweoerhrtrqewueirotinymbn" a$ = a$ + "dfkmsdfnjnrtyqwepoqiwejhdgbncvbyertbvsbvashs" a$ = a$ + "dmcnnxcbxchhdfyueroqwerpkfdsglkncbgjhwjskfhd" a$ = a$ + "dfllfkfgnnmzxcpoeriuteyfdjhsdasdbzxcnvbjfguj" a$ = a$ + "ldkqsdcbcvvczsfcdefcrerfjygrfvughdfkjhtghjty" a$ = a$ + "acbaucbafpaoafadfjhsjhsdfbrethijdfgjhgwretjh" a$ = a$ + "sdfdfmnncvjnbfgyuretygsdfhhdfhrywyywywywhsdf" a$ = a$ + "sdkjsdkjfvnbvcbjhrtuertjhgsdfjygsdfplupljhkh" a$ = a$ + "fdghlkfglhknmlghlkfghopfghlkgfhmgfhodfgidfgu" a$ = a$ + "asdbsansanbasdnbasdhhqherusdfjhcxvhjdsfuhsdf" a$ = a$ + "qweiueuytergftyewrytfqwetfasdgfwqetfyqweruyg" a$ = a$ + "dsfmsdfnmxcvbasdfhjsdfuygwetrpoqwelkjqwemzxv" a$ = a$ + "dfkmvnbhufrhbsvsawvdyfrygsetferuyfuihrdeioeq" a$ = a$ + "sdklsdfjhdfhuisdfeqwytfqwedsfygrgnufgoidfsdf" inizio = 1 If modo = 1 Then b$ = redec(testo$) Else b$ = testo$ End If c$ = "" For n = 1 To Len(b$) e$ = Mid$(b$, n, 1) If e$ >= "a" And e$ <= "z" Then pri = Asc(e$) - Asc("a") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri - sec) If cif < 0 Then cif = cif + 26 c$ = c$ + Chr$(Asc("a") + cif) GoTo ok2 End If If e$ >= "A" And e$ <= "Z" Then pri = Asc(e$) - Asc("A") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri - sec) If cif < 0 Then cif = cif + 26 c$ = c$ + Chr$(Asc("A") + cif) GoTo ok2 End If If e$ >= "0" And e$ <= "9" Then pri = Asc(e$) - Asc("0") sec = (Asc(Mid$(a$, inizio, 1)) - Asc("a")) Mod 10 cif = (pri - sec) If cif < 0 Then cif = cif + 10 c$ = c$ + Chr$(Asc("0") + cif) GoTo ok2 End If c$ = c$ + e$ ok2: inizio = inizio + 1 If inizio > Len(a$) Then inizio = 1 Next n Decodifica = c$ End Function Function recod(testa As String) As String On Error Resume Next Dim aggiunta As Byte Dim chiave As Byte Dim L1, L2 As Integer Dim OrgInp As String Randomize aggiunta = Int((255 * Rnd) + 1) chiave = Int((255 * Rnd) + 1) L1 = chiave L2 = 1 While L2 < Len(testa) Mid(testa, L2, 1) = Chr((Asc(Mid(testa, L2, 1)) + L1) And 255) L1 = (L1 + aggiunta) Mod 256 L2 = L2 + 1 Wend testa = Chr(chiave) & testa & Chr(aggiunta) recod = testa End Function Function redec(testa As String) As String On Error Resume Next Dim aggiunta As Byte Dim chiave As Byte Dim L1, L2 As Integer aggiunta = Asc(Right(testa, 1)) chiave = Asc(Left(testa, 1)) testa = Mid(testa, 2, Len(testa) - 2) L1 = chiave L2 = 1 While L2 < Len(testa) Mid(testa, L2, 1) = Chr((Asc(Mid(testa, L2, 1)) - L1) And 255) L1 = (L1 + aggiunta) Mod 256 L2 = L2 + 1 Wend redec = testa End Function //---------------------------------------------------------------------------------------- . - . //---------------------------------------------------------------------------------------- CLIENT CIFRATO //---------------------------------------------------------------------------------------- Dim linea As Integer Private Sub aggio_Click() TCP1.SendData codifica("lista:", 1) + vbCrLf End Sub Private Sub Cambia_Click() a$ = InputBox("Scrivi il tuo nick:", "CAMBIA") If a$ <> "" Then TCP1.SendData codifica("nick: " + a$, 1) + vbCrLf End If End Sub Private Sub Command1_Click() linea = 0 On Error Resume Next TCP1.Connect Text1, Text2 Label3 = "Connessione aperta" End Sub Private Sub Command2_Click() On Error Resume Next Label3 = "Invio dei dati" Text4 = Text4 + "I> " + Text3 & vbCrLf Text4.SelStart = Len(Text4) linea = linea + 1 TCP1.SendData codifica(Text3, 1) & vbCrLf Text3.SetFocus Text3.SelStart = 0 Text3.SelLength = Len(Text3) End Sub Private Sub Command3_Click() On Error Resume Next TCP1.Close Label3 = "Connessione chiusa" End Sub Private Sub TCP1_DataArrival(ByVal bytesTotal As Long) TCP1.GetData dalserver, vbString If InStr(dalserver, vbCrLf) Then parole$ = Decodifica(Mid$(dalserver, 1, Len(dalserver) - 2), 1) If InStr(1, parole$, "LISTA_UTENTI:") Then List1.Clear parti = 1 su: pri = InStr(parti, parole$, " ") sec = InStr(pri + 1, parole$, " ") utente$ = Mid$(parole$, pri + 1, sec - pri - 1) If utente$ = "|-" Then GoTo fine List1.AddItem utente$ parti = sec - 1 GoTo su End If Text4 = Text4 + "R> " + parole$ + vbCrLf linea = linea + 1 Text4.SelStart = Len(Text4) ' SendKeys ("^{END}") fine: Text3.SetFocus End If End Sub Private Sub TCP1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, _ ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) Label3 = Str$(Number) & "," & Description End Sub Private Sub Text3_Click() Text3 = "" End Sub Private Sub Text3_KeyPress(KeyAscii As Integer) If KeyAscii = 13 Then Command2_Click End Sub Private Function codifica(testo$, modo) a$ = "kdfjfdsgnbcvxjhbfyewrygsdfjhbfgkjeripsjjasbgfvads" a$ = a$ + "sdlkasdmnzxbcvdfgqwpweoerhrtrqewueirotinymbn" a$ = a$ + "dfkmsdfnjnrtyqwepoqiwejhdgbncvbyertbvsbvashs" a$ = a$ + "dmcnnxcbxchhdfyueroqwerpkfdsglkncbgjhwjskfhd" a$ = a$ + "dfllfkfgnnmzxcpoeriuteyfdjhsdasdbzxcnvbjfguj" a$ = a$ + "ldkqsdcbcvvczsfcdefcrerfjygrfvughdfkjhtghjty" a$ = a$ + "acbaucbafpaoafadfjhsjhsdfbrethijdfgjhgwretjh" a$ = a$ + "sdfdfmnncvjnbfgyuretygsdfhhdfhrywyywywywhsdf" a$ = a$ + "sdkjsdkjfvnbvcbjhrtuertjhgsdfjygsdfplupljhkh" a$ = a$ + "fdghlkfglhknmlghlkfghopfghlkgfhmgfhodfgidfgu" a$ = a$ + "asdbsansanbasdnbasdhhqherusdfjhcxvhjdsfuhsdf" a$ = a$ + "qweiueuytergftyewrytfqwetfasdgfwqetfyqweruyg" a$ = a$ + "dsfmsdfnmxcvbasdfhjsdfuygwetrpoqwelkjqwemzxv" a$ = a$ + "dfkmvnbhufrhbsvsawvdyfrygsetferuyfuihrdeioeq" a$ = a$ + "sdklsdfjhdfhuisdfeqwytfqwedsfygrgnufgoidfsdf" inizio = 1 b$ = testo$ c$ = "" For n = 1 To Len(b$) e$ = Mid$(b$, n, 1) If e$ >= "a" And e$ <= "z" Then pri = Asc(e$) - Asc("a") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri + sec) Mod 26 c$ = c$ + Chr$(Asc("a") + cif) GoTo ok End If If e$ >= "A" And e$ <= "Z" Then pri = Asc(e$) - Asc("A") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri + sec) Mod 26 c$ = c$ + Chr$(Asc("A") + cif) GoTo ok End If If e$ >= "0" And e$ <= "9" Then pri = Asc(e$) - Asc("0") sec = (Asc(Mid$(a$, inizio, 1)) - Asc("a")) Mod 10 cif = (pri + sec) Mod 10 c$ = c$ + Chr$(Asc("0") + cif) GoTo ok End If c$ = c$ + e$ ok: inizio = inizio + 1 If inizio > Len(a$) Then inizio = 1 Next n If modo = 1 Then codifica = recod(c$) Else codifica = c$ End If End Function Private Function Decodifica(testo$, modo) a$ = "kdfjfdsgnbcvxjhbfyewrygsdfjhbfgkjeripsjjasbgfvads" a$ = a$ + "sdlkasdmnzxbcvdfgqwpweoerhrtrqewueirotinymbn" a$ = a$ + "dfkmsdfnjnrtyqwepoqiwejhdgbncvbyertbvsbvashs" a$ = a$ + "dmcnnxcbxchhdfyueroqwerpkfdsglkncbgjhwjskfhd" a$ = a$ + "dfllfkfgnnmzxcpoeriuteyfdjhsdasdbzxcnvbjfguj" a$ = a$ + "ldkqsdcbcvvczsfcdefcrerfjygrfvughdfkjhtghjty" a$ = a$ + "acbaucbafpaoafadfjhsjhsdfbrethijdfgjhgwretjh" a$ = a$ + "sdfdfmnncvjnbfgyuretygsdfhhdfhrywyywywywhsdf" a$ = a$ + "sdkjsdkjfvnbvcbjhrtuertjhgsdfjygsdfplupljhkh" a$ = a$ + "fdghlkfglhknmlghlkfghopfghlkgfhmgfhodfgidfgu" a$ = a$ + "asdbsansanbasdnbasdhhqherusdfjhcxvhjdsfuhsdf" a$ = a$ + "qweiueuytergftyewrytfqwetfasdgfwqetfyqweruyg" a$ = a$ + "dsfmsdfnmxcvbasdfhjsdfuygwetrpoqwelkjqwemzxv" a$ = a$ + "dfkmvnbhufrhbsvsawvdyfrygsetferuyfuihrdeioeq" a$ = a$ + "sdklsdfjhdfhuisdfeqwytfqwedsfygrgnufgoidfsdf" inizio = 1 If modo = 1 Then b$ = redec(testo$) Else b$ = testo$ End If c$ = "" For n = 1 To Len(b$) e$ = Mid$(b$, n, 1) If e$ >= "a" And e$ <= "z" Then pri = Asc(e$) - Asc("a") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri - sec) If cif < 0 Then cif = cif + 26 c$ = c$ + Chr$(Asc("a") + cif) GoTo ok2 End If If e$ >= "A" And e$ <= "Z" Then pri = Asc(e$) - Asc("A") sec = Asc(Mid$(a$, inizio, 1)) - Asc("a") cif = (pri - sec) If cif < 0 Then cif = cif + 26 c$ = c$ + Chr$(Asc("A") + cif) GoTo ok2 End If If e$ >= "0" And e$ <= "9" Then pri = Asc(e$) - Asc("0") sec = (Asc(Mid$(a$, inizio, 1)) - Asc("a")) Mod 10 cif = (pri - sec) If cif < 0 Then cif = cif + 10 c$ = c$ + Chr$(Asc("0") + cif) GoTo ok2 End If c$ = c$ + e$ ok2: inizio = inizio + 1 If inizio > Len(a$) Then inizio = 1 Next n Decodifica = c$ End Function Function recod(testa As String) As String Dim aggiunta As Byte Dim chiave As Byte Dim L1, L2 As Integer Dim OrgInp As String Randomize aggiunta = Int((255 * Rnd) + 1) chiave = Int((255 * Rnd) + 1) L1 = chiave L2 = 1 While L2 < Len(testa) Mid(testa, L2, 1) = Chr((Asc(Mid(testa, L2, 1)) + L1) And 255) L1 = (L1 + aggiunta) Mod 256 L2 = L2 + 1 Wend testa = Chr(chiave) & testa & Chr(aggiunta) recod = testa End Function Function redec(testa As String) As String Dim aggiunta As Byte Dim chiave As Byte Dim L1, L2 As Integer aggiunta = Asc(Right(testa, 1)) chiave = Asc(Left(testa, 1)) testa = Mid(testa, 2, Len(testa) - 2) L1 = chiave L2 = 1 While L2 < Len(testa) Mid(testa, L2, 1) = Chr((Asc(Mid(testa, L2, 1)) - L1) And 255) L1 = (L1 + aggiunta) Mod 256 L2 = L2 + 1 Wend redec = testa End Function //---------------------------------------------------------------------------------------- E questo e' tutto. ;-) . - . ****************************************************************************************** ****************************************************************************************** ****************************************************************************************** Per i piu' pigri tutti i sorgenti, i files necessari alle prove e i programmi gia' compilati sono acclusi di seguito in formato mime. L'attach contiene un file compresso con RK .. attualmente il migliore compressore in assoluto tra tutti quelli esistenti. Chi ancora non lo avesse lo puo' trovare assieme a tanti altri qui: http://www.geocities.com/SiliconValley/Park/4264/ alla sezione archivio files per ms-dos. emh.. come si fa ad estrarre archivio.rk dall'attach mime?? :)) Se dovete fare domande come queste non dovreste leggere questo tipo di riviste! .. cmq per la cronaca se non avete un decoder mime o non avete mai usato Windows Commander al posto di Gestione Risorse (dovreste proprio farlo!) basta semplicemente estrarre l'attach tagliandolo dove indicato e scrivendo l'interno in un file di testo chiamandolo AddioCore.eml ( :)) ) .. cliccandoci sopra il vostro Outlook Express aprira' un form contenente come attach decodificato appunto l'archivio "archivio.rk" che potrete salvare dove volete. ;-) [ MI SEMBRA DI AVERLO GI ASCRITTO DA QUALCHE PARTE! :)) HA HA .. ] ****************************************************************************************** ****************************************************************************************** ****************************************************************************************** . - . ----------------------- ATTACH MIME - TAGLIA QUI ----------------------------- MIME-Version: 1.0 Content-Type: application/octet-stream; name="programmi.rk" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="programmi.rk" VMZBLUV11rmzZkO8Jzpvrq95Iz8AM6E6Bi8OOxT71TL4JNTUExW6NDeRFe7EB0508EjG+gTpoVVV UllXKiFdrEqYP22JByq/jBHck+qxX6TB4EZao/YtVIwXuGizYYm32E2OGjd6CgIQPK321Gmntz2B Bx1lfrQe86zApPcPGW/3B/B5oilxKfHYtWf5X/yovUJe+Ccg6HUwr6Moe6cXGVDq2wC3yj4I55lM C8VcPQ1vgJiojN9a/RnwM+uUgkBiBbj7M8iOmZttSeB3IJUt/a8o92aGjsv1Cdout3hGtySqR8e/ /ABr8ObGGycdVe5fSfdntk4c8l+1RLK9a8XH9+Z1joBRjSf4uH6wZ8V28d7wWRQRFgawwuQ1Csgh 1O/tzJybzQanFhjzmBrkepcBAZUl5yC0YQIHng8QynvbYFIaRxpTH/mNhm/MUAeKFwshMW/2YMy9 ///8Np0WOJ03a9bmm/RcXLecNGvbMaseY8ZUrCDyFB2KZJHK5pJrAxKywjj8jZWh44Q01LbcR4CF REoym9gMW5cNjw3dr7asdXm08iP3soxgsi4UPd78jj1LYT+PoLzyaJxyQTPqweUgmp1f2OReqD3b Xu1nX9aoAwNenc9FOyxUFxW6hl5Qke0aGtuvASXh6ZsVgp8KrEqg8Dz8Sr9f5t7TUoAttw6jzTtB Z1VBCu9Ub5FR/y1+/RgcYIlrkNCeb5U1gaACXensghi3dvTc2ZgOvTCAiGbr1nWZ0iFQbdaRpydR W5gOOp0/kgcPl0HEO3Wz8M6JocULwlCe3p+Uk1yPkFNQL+l5trgwEWlHw+XE+omhDVHBEaasv4vR RlyOF0bVtLRzoRuCD2iNupNGlbnoLIbJiMey5XAUb0c9YdTL7yli/NrEYNErNxhvE/wXV/d7Vs8N gSSpMTzW6IYpfAzGuQzAp8f5vyTxz+m7iYeyyyx+4Vw3xtBnWVNnPSOak8mmyswUuQIcCUkPzG+h ALdlQj5A+uDa1/GgJG/RTq5oBM8jwi70mXGtXbRRCQKl/nflDLsyLeOpEgdG+dPGDidLebpR/9NV TyMv36HKqNOGvmxWownJhC5O/Uygwbf1KtyuWYK4ro0VoHcKXq/9WkXqmrMpPd71nztoDAPP2lJf n5m7hq/cNQ2M+L9rbcKm4WwqL2ycaxGlnv//+vF+zKHGXlKYRkWO2rN/m2y0ORPEzrgHUIxN7Qr1 zl/xFbmYXj/Swuu0hm6H3YSAlQe4IHfw971s1KxpNhcoNCYRVyKtAJhCYnBa/m0EoCMENE/fml7S NmLb5GmlnuqOKC97agpxv/MZpkhl7lH/125RiJCVQg3Jpr4Szy6PQ8+ol11n5IT2zksHBrU/uoeX 2fL3AoIOXSLWXMvQ+j42muxSGNQcLYjDsBiB3Ow8LlDLmeQSSaAZJ57VsgVRtt4g/Dkr4n8sREvn S/cEvurKip7CVFKZ/n+2Ct5aZFUI4yCS99Pts5UaILZp1zpXhojPtDSQHhwe3Ke9IX3PN5BLQ9C9 xAv3CpdqoMs15xQD0BB8XoP3EwmOT26XseNMSt9j2pl/GdaNjkSFkTeRvCZOexI+rwllsp33rIU6 cTNsaLWPAzI3qDsj/GJiclr4gJFZ2B4lFKPJ0MfZy4r5W58uuJjJiaG2eH51XE5YSRjREQtlMKIs XriCbOcalAYaEbJc0c2hOY9hqIKDl0Kuzzn2Vz6CWe6q5fCN/V5+Y2PejIROFhp0Zuhyf6XEGcGW kUe0y8HwfN+Q+bcLCSxCo9J94Iew1B8z/bTB/IU+DYM6s2xTPUYhBEB1mlyy8jvFRikBnWR4iFkK 0d2viz/KigbvkZXrIjrlx/rfct2e5ZMDnADdt1FzJkz0XU9R/akbniaNk9HxyggJKniD8YDxINbe T1yxELnDgZyUBJpT1yimK+VWwfDqyqtqd7HVKLjV8aQZfpr50C2xLeE8nuExeaWgNo/X10iI7JfI fFXC6dZK30rl4hMr8aboz/mWskOjiQrdYBCM76s4IwvNtUPaTyTBikbrDsR0buZQTClcuX6GOu62 E85Ovu8uTvWN+Ju+UPCB0zrUE3ORrylOLIPGBkxhkwllvIYjV55Gcm76nG6xbYTtouS+KD2iYgtn b+KA7haB0xSZxIGtz9xbecrvQjn9D5EM+ATPww4KWFWySF8TO5dUc0AG5+fkNtO9Hcv+eIKfkfXJ MkmNYMLCSlW3H9zd/zgaziNFpgeKrbqgMmRBRtMiTkIqKH4yIpKSGRSLb1WYaslxq7lk4JRK9EAT 8lNX3XDInWDUJLZ7xggZWi4L1f69gca7w6LbO/SuWSvcohsnNtb5KGsTBRo+nSfJLiYBwenCd1xr 2Rc97HAP0kITKwEM89Ql5SJawoBYdpTYe/fIhuZFwZx+mx1lmH9YfyzyBAz0Gu4UDdy2bFGqy9AJ 3xrIFSbdMbBOq+AbiSqEJdmRum9ats3tULaynrsyuYsLheGd6VWsFjvBWDFeKAOS6Dkow1cDExF7 vl/RtvEtPgIsLn5x3lqlXS6uTAGtQQA9m6B5QHlN2ajObmW3Nm1/ftDM40/dNEplT40pO8O+Ad+X hh3tnbhxcfJqveHPcVCJkN84ibXrpAZNNurzCKCMAkFoCx/8/WjpTX1WiihsObnrK/lklN/4j8PY +xfH/3oDQmkvvqaaFGb1+PoGCA4QCxEpoxUIvm6/DT6MOYFXFOpIoNivONTAoQFE1/4hOpNliINM r3EuJ6ARWx01VHfWegE3FI2wNXtmEnBFyDEKu//EF/UYmcI7/1bNYcpiJztw4GFAOG9zYUkBOreu NRCAPZoFcQ3Flkz/0Bx3pRC6+2WYaBDae39D74/K93Jox+MvdkYYBEejWCOcmVjGdQIVqhYvT2SI liLamMOG2fe/YXeQDyi5ioA7ANItvOwNAHv5CaQpPwAgGKP0ramk6p79uX04uTsYYwFHVTLhoqFc nyiz5/bhHW65vx2c/q+JfwxOSyy4O1ZL6IxpmEtr4QTQe2WHxs8ve1i/p20u+BVwblVopySJAP3F KypNZ1CaGaLvmJPO+Oy9Eumbk4YYTyAuyg3sc3H6vsEuxqFrtBfxOWxbIBdbA9ytv4e6uM2K9utM O8EDHitRRRYL+LsD3rxrGHOaSuac8cOlE0Gpj0cmEyuEjQIdwVqlMaO51JqOuFukvn2Ttbpvza4n Y+u6ozK1dUI23er23IPDuxS1gBSL65sruvdVrls6uGtxXMpTVOtwmFhcMpPdgFDg2CwW9nksqeA/ 23M7v/kNyEGkrzwezISGwnfTNpDMjfdDZgdJeUACu5b9ZCxFZlkA/OHPWyiPIbV+e+tgfjPnLO/U TT/1rcOXWxR8Xck59DKTWFq+TKhpnvcfhMh5VtNgx+rYh3ELmZH/542HXU0spO9k4oxS9y6/6j1j WiL4GvuRdYfEl3oIVSyRFovQP5H0mG+nPuspOTmCjx/3l/+OKMK/O7P4BpL/9egUO2bG9doiflGF Oub/+4suY370CLthmY0MswhDO/lbFB7XceGeqwroTX+xCLbw/JbGpgcmq7YjtqQUcIEhV6lYId6t FQuirJ1x5zg22R3Qhu78YdRu3jymaLjacJOsc/acesPalQ7GlJQXIhfIuh434d+q1VMod+U6qjuf wfAT6n7sVIm/nptqfLR6S9O8P9obL8mguFe1S6vvGyVIF5TUr6/tHtnOHj0PZ6Eil0QiUgHhl3xa bFBiB4bRnv0BbnPzxSPDOGRB26/PnehvS3ESwvZ3ueBOcVxnRl/hxuWbRC7B4NL2fSWlkNKDduRy X4WcA3bkzpzEoxOOtRZ+Kpcj/ejG5ssuumge/bZRkKX+lyS6LvB/ysPxuDqiCvidXQ4lPeSNrSYK aDpgrWh9FyPjOckJiIRFhvInNHVZA+z1vX2HvuEsMDrBszFNo9nalsxl9YQQlmxcRcuyC8EXeuu8 yjJ/WytAqQY1ltbQryiXb59YTVVXxCSz8KJbGa1XL4j+CiikrU4vY/0P98ZIIIGl/bQswy4atAOd mJapOwteVOubsRPxxxv9ZKWpR77YS7/IxK3zcRiwc4oeVXgq8lKcLr1eNIcd/8Zl5rYC8KctwRxg A32MPUDGOM4Nn7IH4ba1xmX66pXf0Pb5UGIX3O50zNcXPiUuzXID+TT3cXBuHFR1vdcA3L4jX9eE 3Sjv4LJUCwWzWlusD+Y1UfvmxI14UvdEOXRzClrysRKuJBZKeXKWWht/vJGxczfN385Maovwv1Rr 1UOKypugoayWzZWI/sQwxdP9lLqSlTsLhOB30v6xgFyv8AZEN040X/YzaTp1OHynTdz3+pK1v4Zr ghF0TbZZTYsmzM1x8DweCet4w/uD8kOPW0SuLMk22ht2eok6MKN/Z5zoTtjXa3YX19OWl+/IHGeN 4XX7XplQqJQwCxb3r2OVz+2PRhpHt7CYICwqUrz5lkjQbQZ+UCxyAyXMKgq0ZpjSUPgGbUBi4XB2 yhBnRgMeR4Iwbp/AD3pY9h2PSF3oGRNKtx7n9Ka6uw0DdqaamMaE/6iXtq/r2krvozTnWHqZUp8E qv9gkBnm4QNYpF5nu7rn5c8fXIEtP2mIyAkWE9pJlbrglJ5ceaRIcw6I5ikTExPzypoNg+82GwBU 4FFC5dyuwI+yT2WJ/yYeePu+9AUhYMVplwmHbhJ9c0IDH2X0rsXNiQa3FQdZv3eKlg/mNnON/w+0 AxPWnPW3I68z8A6r28KnO9qkKBjE5Lsjis2KoF8WUAFtZQm+Q9kcb6iX69TrD3+ck3LbgJke6A3O dH45AKhxOHscOm4puLPblCP3o0Dn3e97Npx5wL4mIQMLV1xTflMbq++297bbbsNks5cNqn9OzWuq gO88htBcZZ21v5yI82SonBBtHQSA/Z593We9AOTSTAdONVAJvuVUpO1y+melWiC6lOAqPmoQCL2a XIBTghP/oeDDubcZ86DOp/mkEJhmH35ufLrUsp5DJTouMcLwYR9FUfMdAbCxyx79zBE6jYEd5Fil KzBnNlFAEPAYeswQSUJNgkYJzDGv3/btpnN1RXUBSx1CcWjO+U0wG6vqHn5pWoI2M1Ybd04Kx8jn 8XxyT9415hgQCupgZjS3lyouFnayy8dvuqMwFMygExqRhO2o3nKHsnXrGCV8J2kcqwihM48dErh4 M5uGCTINccNXLQ62he3YJ+ybRDdlzrfkzrtZ9b1eO1n7exc0dFRv+rK9sMX4num0RYyIJobMIN2i qQYwXFHcITjt83TWd1Fb5nu3vWTqy59ePppmNWFvZEk0bD22I+kiRsyV65i9DqURxw02x2GRJdk5 j3jc0yLKd7vN7ig0AskX7Hu4Nv7gIPr4q3q8iD28Y+FyqZdn3ngdLk+IXPq5lhQXVugT1cON14dD kH8KHzcVFa+DcQCziZS9mt4vazw3Ojax5iZNkWEV4kcB4/voglN/N8dtC3wbxzZEfunyiJVCE7u1 eXmIgeLQgHkS2T7Kpc2+vhbrflcz2zUQ3wgQA+Tw29pEbhVtpTlGiwa8KHFoll7pHm/2o+roh0pq 2yg29DUJRlZK2Np2jR8CyHgHtooVdUnZpROGmjMojLVQui27dlCb2SE4GFZLOnFHXUdyhylsoUWZ vmQdegHMlUM9HUCpF82Tp0Ycm64wxwwLSa4ixsIBo9MK9u4aoASiweDgWBK+zeYARNZWburKmzRl b6H3q8IpFuTFQNEEwCwhwuMg2Zed+D47bUIVZdhWtaFEE420eDuCBNNGXEQBrVjShEX8D0wLLBwH znI9cC5ndkJpDBwJX0FgjFguarwlFPWdGlICCiVNl42ZGjBQ+hW6JEM83LSQzyG2bF0avHSHFxey ABDXULaFs/lk7owFWUE5BYX5QtgnBjSHMa9NJ89vnN1+wxWhyStL492ol1ogvStuajn+ODeXmP06 kguCGv290FxuYDuj74uiqJWobVywqUEk2fU5nnvJujqEJrcaCBOb/+m8NxgtOcep6QIBb2kmDun1 g0nPsrVlNualo094HZeBb4qNYwXbh67w3qcbpGntzvljpq+dSHnKBFe48SE2dqEETTlsPbhgvIOI kn6Cyb1Ysbvgf+wLojKhOz6LVibX/kAhurCCbaa4sHywtG5UXb9292iTA5QSEW2/TFnrhrC524fB AAAATci/GrEqgmpiQMvp/z4Bjjq8B3ipBnxUpJlCeCirvxTMQgvO/fXv2oEpYB5EiEicDUac5jpi DdoIH726e9otEIAjXpqr/rtIFSijF7itMZjYzEG4fQ9p+kdwwQLJd0wbBtmNh6OS8xrP1UsOvKf7 p89Wg5eYd0u+18tkQ/XsP8P9Av1gS2WeytoKelduHUocbTTju1Qy4uZpZ+o43RW6DUKGhywJPQtb wzvUg/u7fyr49oz/zhE+zFRNC0yi5SGtk+ROWfVxAgn5GJn4teDCzs8rBZbWmpJhaslJLwhjYdHo u8v2WmJHjrujJ68Vd9Qns9ud7L1tKp124B/1V51GEnDKps2+Sk7xTw6DUSVuqXtOdrxfFPY1tMZs cMNoT0jHO2wRYa3OqXfq7u0eNQXBnH/mE1Hfr6SXdHuklvTgz9acwkEy6q22Wb7smSEwzweXAxwW BHdiKyg3vRUqzGCJjjB8Wyjadz0M85C7DTyQU9wPIljyYrW+W5r19Xjk89Vi//6DJPZGIis0u0X0 fl5qZz89OEOCsfB3b4SrN8bNGarqFq/5IdqWbDyJ+Hs8TI+a7NIPa7zQOuZeEZEcg4eJQKyDnC3P wVYxNjSIHFv95ubHNaPABOKw0EpUYlF61NT0NJNEikCx6fcgZdGJqtWzl8Hp1tGqRR7OMWq5bC/e c7AsilfQfBw1z8xIVHTrPOQkPwSnIdsGiU7fF6vJ4kFL47r+yBtlgQTXUopWrzC6+mLVVSjoP1OJ 4s8b409rwC0MEkunrSD9Bpv/OOasNE33pj6AuNiUDvzZWUvNzHtjjlDcfmS6tjdLCH7oqYUGKrKZ bhNGU3ZRih2hZXf9xcE2iu/HKf/6Mhu+txGJL9mEIUSb0P3QNIML/ShpR8pSE6GNtI0+7EWIhxfy UUZY/OYRieDZgdgP6ITHadI7oxt6oeaZeOkva+PZbbLXxHdVPSOmfFmxSV4A3Jfn79rOjmzZILCG gwyVJdhRZRFEN78TdFwXpU0rnMOk/G2XZUSH/ed0vGuzBCbhU396+SfeizM/BgxNKFQpYSkwOLau nVwc52g+1QXiFp0ZqLKx5cDQPj/DWLDNWCrcC8s1Crpprd7z2awaiHW/z8RYWUUPK2FNK8tCDJL+ 9uG7JP8SjAimsSDtbMZQUq9JcaCTxFdXsHcSlIxLFQgd88fhJfJP+NiqAKETrQNEXnlyMIDBICRy zxI28NmU5/TGDzTT03Ne95ZT736QAkeB/hz+LShRJrNj8fTfuvugvUEzKpc82RgrRB8kcjK/AiHg oTK2WaC5yqefHj47w2mKhznJq48esTxogvzNcALLm+44jPxGcU1N9C9sUxp5h174Cn+Jav85lj7z M6ZObut3n/zscJqX6tLQO4STmN2vARkOtSSCf6MYJw7PK1Rz9MvCxjo4d+wERh2xr5Jfge8Lrfwv m6iIciwpzL+EdL9YKtiN3DDCnicbBWGnNhxGkldIaZ6Kiu+EOGEAoaYAV9Abf3Dt2MX/qKFvIchO /QB0IIKZbZItX2bjXpJsrhX/6VoeOHNwTMXGMTDuYFajFiqV/ZELkUlobHFEVl/VNjcei51tEtnm bB/X8ruNfHw1s/5sJrTv+rdY8XrCNxBRBlSLEjSUR8m32jkncu10NC7CzShDVCVImJ3nwK8OUsAK HIiGtIMYVjyVuUVzlmtJL6xiKw9lqh6wC+EsQxpArxhbUkgVJgulW8RtFJHEEuFGaIknXTr3xgdL KI/X032QEk186zXPlCnKTMrXcnuAHsGDFTXX29eb/6hpKw7P7gzCAu6Gto8lPCiWIUBgIcppG2xK ETjF0xGtA20UW4yxqDwM++5tYfQZ2BjVDMZNtssxzQsXiyAHxWQU1GbVClTMb27XNvZVf3deRGbP IdESEttNMW5pdw53Hy0cHkVVBBdZ8/ZCrAKLo+cVHjlDFyBfx+S2xwJ1mj5vhpugZ/c1flrGe63B NcZxgXaMHldBodkKdGmh4EP70dKcFESp2UZDyrr//29lpTneKd2wL47tdz9k4uoh9IKarEitBu9r 5pqjuFNkf9GQX6mf86/Z8ZLvBaRAqqctpNkR5dAuefz1h41p5T4VSjMXTgqKQNs07OCbVnWa3mVd jvctpXdJRIlh8QbE29Bf8yzqGk9uUgCFsYuQAHELjWxY0viHH2eJNBxV2H8OvhAHuDEukpsptbN3 apMcPI1tBAnDm78EAlPiqOzIaitxEB8HAsRHpcBOIff7dP+vv3cEHWAFpRMONXkiCHYocGNhsY4g 3nbpl9X3qCYtDXCPAfU4HqzQ8fOgofH/z/ok+xrRSG5K9oITcIWO95IELWo/Y8AuwhCEwKPItvqy xu3AXommPnwBEXncJLCMWR3TKDBKvadAhiLEHgUP7iOkVR49lF7pgf/1yNcNj/ls+8Xrq0846Oot a2c9E3myODZDv9iScoKj92+nScbUblLG9X7O2MoCihV5Ixu0E00pN+FhpwejePyEd257QKLkImPw 1POlf8G3jUBRkYxplWdtYdNAgThTnN60pcXSWu86BHNdO8un74oeAGIc9BUkAwP7DgSKAjWCaCaf vWgLAWPF0jvdGRmMuEZU4fmzgn4czPXL0bnK5LtpUQo3ihe9jkVxr0mrr7W7Wbu2DC4+WC/WqJZS qvE8FHzCNRxJRk1ZLTNJ/hGyi8pmgpXt1bwwGcxlG70Txh7WzGzKZE0CajWekk8Fyg2QHcQ4NO8F A7zL/e3DrXuajhAZsDxajw5lGgYwWjfLWTrg7NBR59jkLscaW7xFgybqyBBi8i2nBBXLqBpu0i7E VHixntSbeEQsfiLIW3rOzYl/sY+dnBIC210cp/LLxM4/pErPvIYb+gpPtr1u8OfcdGdtBnVthVbI TFM7yuekQSIVerEkz01p1cp6/2pD8I45uKirNWjAn1zI9o9y8MnVMOaHCqcFRu05fbIEYzy1JGX3 BEcICQ0UNB/krcUtPZ2/TLskunFrES2lkyNyHCH77e4W2ClZ1nX1kGJRAsBbkIe6fpxp19OHVS00 Fi39F6eve/nsviNtN0xIIQDsEYmKr7xHWCe41EAp1dvcuAIaRmB3CFxm+0ATw98VTpgIuDsSc6LN q/2INqrIAZ2gKDCSSr7lKJFVsnA64Hud6fsrq/Fd6FmMidF9AXzHjf5GqQMcRY1WSl1Kak1VkFZ9 kwmqZNlVAbU1E9oCCW1lXL8smeGgeiV+6/4UlvfGDB0EeUDLkoTgnK+4kcJaSlAmpR7UbwsA7m39 1WorIiF6X5dJ+N4oFZT5aJLG1HVUZjh3atgHu8bFczGjLHP3U2a1O4TfoJV/bZZvQCb//9UZQmkx kjnPnXcGIRC04RV6OgzJy0vGGaXcGsny3fpYk1t/OyDrPhj9mzaKKzxrag+lSf8v9jd/3+TV4+/N uLWduV3jyhRpx6ftVjNByzMN4dkbC0Y3Sq2valyyVv4epaGGFWb/8mWzztW7m+NeWEhzuDKvV1gh aSPpabtjXmXuCv76qOdzAPcPqpmL7TNLM9g67W7E8roqY+c+SIPyOjHEkrwM3Mc57w1/cVe5MxWn LmTr79n8GOjEuCR3hnc8JSV71lG0mCiMZs70LdKgZwpozd1SdP3NjC6InbF67NjDY4TUHL4kcu7+ 4i2gWXUB7zS9Kz5cl2Jr0RbvlFKL7Ih3Vl2qCA+qYHbah/gWswBAIvHeLE7QAS7z/cgnAPLePsvK G4vUOwnZ2W6JLRmrtuCu/acQ+euV/e5ppewI35Zz/k/Q/RBsavn9C0KX6QwQwWo63kAtty10VcnI CMd11JgVwxwGnYcmjkIZbrBg17BkYeCk/8lj/iqP/t0ZlQsfSX7PtUY3YZESu2Xm6FaZoxWJcT+Y B3EzU7Q1Zy5SSIgMiJYS1tchmp2v8NUCb78Sp7hrpQWjic4jbttX/fgDRuEyjgXu7TR4ZzpidpNz +rUf9bps0ByYhMxtIIONf2ZpekBZS8oLsYZpK0Wk5GVazmkdWULbOk1uE6j/fwhSkEfyUi5jjfNN FsnYmdgfox3qB2g0J1Hi+xBd9UJ4jsspxHCoomnM7nuGJuG9O5MalfOMb2FN2wj/1VUi//lLIM+u siqLsgt8p+d5MLq7mm0lDFBHbIuQXv6dO+PlBzZXcw5AnCbdgeMm4IY+SHjUFNSy8RduzsyXd2WZ +hwBiXmzHfBN/1V3ipthJ+QlofGz7yzX4/ve+f4nVe1RYunWVdZHV6RjaHyjjn416lDYcg7D0+iZ ZCd8+SZV2c6TXcVPkNCSLTKPf8Zy747aM0znNkC7V+xURiIUFsM9/zou/SDjwSuQV3VMhrO5Kjm7 +5WWpIvsTXj2VxxekNXh8bz7QvhvQ5DlBDVXkfZfHxinG1IBhBrNVjGISmwTuMI5tb6QpNs4aU5T 5esHKc+c1FraT19mrIiKuO0zkevZAHzHAMBK2WRxjCUkiSVy7iZNE1USSn5McrXIqOu6HUycQfI7 OtlDqdjUX32uzEzIDUSqVsEIzi/u/wizJUptzJ2/6ZBISoHjI1ehHSv+c/ScyJRqd4O7UdLGIBmv fTAxLyKE0hgOFZZkq8uDKL9cueidhbKM4ViPRO2zjWulbJnrZzS7xueAvtzffcsCxv8NZRmRoecQ WGNcLBsOr9exrCRpamq7vLvSMcKsrlYAW2Ws/TtYdFVwVRY/XqCMR8HHLXhjyJ0nlzyZ7ivFen7d ijiLcIZurzLStC4Kn73QL0tpVVhqdkihx7H0/sxm6z663SwNvtS5B5ypxG9nidFJ6VJB8nqp+0CQ RcwVTeIocTVccBo67LYY0pus78muAH3yZsb28NHvGumcAbQ8mZnbtbwF7EZDWnqPnXAEM4IeGawj ZAyA0Kc4z3pGF1BdcvyLmRuAUWCCdm4dnv3KFrIKoetrbB+QFZzAZvCtODtYCPio4Vendv7j2Jkg 57X9Jj2a7BsjMqwVoGpNqfo+5DUH8FsM6Qih3u1gSNHbUCAUrWe98uGLmVAGSGDd6IZpoGVYvOEC oqcxT7pdYv8PWOiMkGnsilU9XEvFSqMVUT2vPe646FZTm2rN8TaDS7kXD/jnDAgBjkI7yTfIcQ7g KOA1MP/XIo2ZKr3pp3KhwoQDr+CDadKap1v6I7Hh9//qHHVSHKhVO/aFh88hGBdBpdSUCVCCKRdc MeyRieNwghtum7A8oH9rtIGw49aOZRuz+w6LM2V/fmQL0X30zxkszTwGxjPc2CFAu4iWFJmS/tcE UNYvYH6yTLtIeJ/BITXDhBMtwHIlaPKrG2+vFBksoRGAelTrAULT7s7OVUOh3NQ5xi9cRu5vRXcq zlwUqfsMzaNWywMWbGQlk7BZWZg3mNAzBAIlVZeUPOyPNxmTxRGcW07IwlafSHCFvi/cq+TvNlRf tOGKVFeLh2F8Pjevv2eCyNt4ohu4/vQWCdq4QpeM6iLL3T1U9ahirBqWlIUMJZeES0HHcW+o7UUe x+C58mXaMwQVdlXCBIRTJu7ObRCsqSRTCI4BPLB6A2619m7eUl2t1JLH12nAZz6+OjlPqtgWls0a Wn7mvMWg6bhK58yHE2mpvYadSSnKIDW7gpQ6Y7LQkg7lAf8L7BXEscghRGLWlTXPgPDCkYG9DaSc Au2IqU3Y0eyQJ84B5K0hprOpG8pFgWYEOuOZTmE7nSVgcYkEeDsuZVLhHyYkPEGP2eOq9Hb6bd33 XK/PYshUC4o2/nHMM46bYAaTDMlh+WDLUOyMLRsgQsns1S7xR6VvlgZXvxB9wMFH1KlcjvH1nazV TITSP4Zz41Ytuq4tQZ7q0WgCG/43nnWDkR7PYfxKO7zVGzW2yANtH+uO0uDE/Iav55JlzM3qBi3J pT0UM07qffg7yMZ4R2HxK4RArabLzeTI2MWFoCgjXU9mpIJhEaBgq8h0/KLrg9MBLPU/hmdXYJnC eQBikKR+4CRnKmYPWL5NzcZm0Xs3kXY9gTUAUNqyU2S4wJJOtRV9qSw/H6tC+ckShGRM7f5gjCoY +YLIXC3Lp2sUDkZB2/mSqQI22p4mFc+aF61tEW+I51/nfOrzi8ZwViJIFosmeLAwFSrYbOIujqW8 SWZ5xTQ4QdqUlFmPb28kMmEhULX+WovYmO1gMu4h0XJX7CNqJ/b/+EExLjj6JlEW5Mukpjy5Kzug sARrQCfApiH7/gVI4t4PAnsHxZqUOuLnge6TBkVcjpGaD+uxT+4T9q1Cp8D8JMZ+OYO7qObTrRgw 4daSZZvhjIdtqMXGGiRfjj6BovjT5w4AZr4VZ/iAsnWlSzG+RqIMknABB6xv5M2do12iW5ZDTeeV paA6qh0EMuLtw+knAqQoab27T1hQPs4ALVshAkodC38t6mL5SPG9cBlj7GqmpNnTF0sgxrvm3Kpo nQ2O2xnTWdTxt6I9ITXePfYwpDkMw9flVIKnJdqoIFfOYFek8769EVFjCVNActtrQPQnjHoWH5T2 CFVveGp3lyeQ9rlep7d4wk5TWwI7ZqBlyzdjPgOBkU7HY1PcatVDblUVdKGsWes4ez7SLBgcBDRQ WchLrsXg9BgM1zevYnaSeIioF50HNWnGHvM8f6Nz+zMhlXgHHgChXrKIS3SQer7iGUFOfePpGLp5 epV6N49YS2QlfNk7Y9+CcMT/g0ttebUqcGfifw4zSr7o8RkNJSKJ93a8Z6uf4ffc36QBdXimaet5 GkKBb1PiYgGD37ayuh35u4z+pNUDM4SMGfAuA9Evyz7LochGbq3Bf7IpFDmctnkm4Rh1CpmcQZE6 IdF8E+SZKQEDttyJH61zjGRL0k8bImgmrN3IiAUj/xtphrQAuSwgMacGcRkJPoaNxlRTPvqk43v0 KWh7Ulw4rnYgVrYcnD/XMfiAKlti1H6Ww14qKa86gSDzwc9b9GGLUdRS3kjdsYCbjesYFR1XN3/R rq6jw2wBKB0VaD6eqTorGAHyUcu96GW3eO6mzYFvc+IyBEaFYghJMbPT1ObhYg91PXWNBfNGosF8 wINVeOLUlAmvQSUa62HvJt81nTyMdjcY8K4kpdf6fBzqAuy+fn8nDF2I8orovV9VRx3O5gKXBVPh KTxQ3krFtstdwWlRQUCdDxxO3SaE0/GDnXFW2Zv5u1GobguoKt8o4Yu5/XJXjxyD8p0B7LV3NP+A Dglr9J6rj2TJCXDs32q93i96xHry+V10VK+4fmTVe9NWnk7cRBEMHhQDIdFN5n9ttngrauB99rxz ok+bPRyLRCPzlzx40JpoV0xXftcdWyKXuGBxaGLHezXC5Lc/kOqMbLTw7jMdKS13JrhZTt8jSFYl NCT59d1Yu0LwoG0mgR4TJakp962RV/C7xzmgQ/5eCkPF5tl027o/zVClcuhpaMxOWUo7e91KH42C 6I3RD/Ddi+AwbohG1f0ZbJaWXP35iP5p2XJXR22avuCaraHLp4ZR3fPxP91Vgv2kzk+Wl+l/O/A+ J/YbhWIK3b9kTNAzonsoJLDoRlBKJEn9J5dVnZPxBwylEdQJWazKc7MeZUzBlE2y3RJnQtitZpi0 Q3zvEDuHFDcuCSb6z4nGbPbfsDyKUI+ITaMDgQRV29DYXxcEoPdGMrRXZciIodvAwiwAzjndKfoL Eg5uk3t8RkfJcYs/6CSzUXx6OUTOxmUNzpt4I5/U6TnmzhLSByguceWHx9UrBRiDEYRZQUuJsaL7 IMe6tBzzgfQq8ThjY2jyLebMN/zuGLYS1ZPQZvzSBmNUrIBhYr82GN0fl6HAwvUZqnBEFJIXjD7s MfrMNWel5ymGx5T6EJKr4OkubuZr44iuIXXwiWjXwKQdaBSlajwD/KvvUIN6DHi4UXh/B8NW/0zq +FLNz7djXpS3M29dOE+8KuI4ih7Ck+e1geA1parNLEemwWj+deBfOli2tsP547xrW3s+wyJ21HnF nQL609Kamzafw8A/0Eu7/Baudong/Yl1tJtiko85GzWl7pMKFcf9VkBw0CC/+5pFM1hBqvujCE3u 3GO68IFZG9LZImLTeVjj6x0dXSvL2wrZ2ZTu3Fbfh5uXxjoCcEThrEbWXzhRt4haZkA+kpeLYlNg NNj2RNWyw/Mjf76MhOQtpuCiYJrYGJ5mKYDNzjfIw63Fi81oJ8pYET4M8998flJDO62QEUf97RW+ efc/8rvEkm4drul/aYxBMcHj78Sk+0xdOSufrxqAHvf69xf8NmFIPNKQnZ3fiN8iA+oNj8Icg5K3 qrWDOKN8JUyMtutp6EkRe0lVnFNHMSFi2Tm0gmu/mfGJ/jSP0oYrC7n5SmTyOCV0yPt4LReXGIV3 HihevmpEDJ/WppAUABd//3IXLWH6SF0+w142r6svFRufR4fgIZ6St0x/EzhIYgJDV+W0ZkKlF2lx mo4i6pb+3Rf3EFKUpNUNWMU3JSPdrfxRqEKYQejhShq65BgU6WQJ7rSRwssM4vcNC8SPyUGQo5aO 2UZkrBjSZYwA74ZD4+psmmh+Jp+L6VVQG007BADjzQLIznu4M02UAsD6e8BXc0UC9zSanPHQ889m RT7o7pvUEbBZDymq4Ct3tA1cvfe11LKtXQYSHB7nQRT8jWC+wT8oqaWy062QQQlc01gASfOysWwA +QwWygdq4EB32h0qGhrr7gM+/COKq2RCyWvwWufOExI3ajGIopPGwBEmPAvJ7FNyJrKgqN7juL37 YjZ3zzhf9ff7Lk1sWerbgv2mxHncw+aRHVzd+Yp/4SibImaH/e3inV9pBVBK/WcKXgXeK1XTDiI2 8Wzy4CWJMrcOKpYgBkKHtkGkXgMC+zFWWrT0w+ue8W0MG/Ndy4eAvIlqS9n/E1GUWbDIRSLmaxAV vRWOylS4PsQptynCLZPUNgertFudot6T0bpbkuJuey/EkRTos22bG/qvEi2a5kJtXaV+Spy4JC5f rqAqWHHsZyRleEXlgPUPU+uGbHaiH9ZS3BU1JFEUXS5GXPCwpVybcr+l+OPJc7QzTt8Mi5HYK4qF z9jP+UirvPONhoL50mWmqzE/OzGdi/3Bkp9BEWoyKAb65iAx0qSZgvIHUqUCWhIcAT6LOKST7I5P 1DV/amKPB9kuZ0VpsXFf9AHlr0Yzth0mzDOZHnLmszn/2MYsIavtuGjnGyd5HG+0tVPLj8IuX79s LzhqFe2hOpX6umFGSswYamqKAQ1FYVJdBV+z79wrPeKdZI786OZvVLlFRwPdS6ZH/ZaqBVSc7gg1 KI8wWdnnHQ/OOCxgfTh8cANwHdzl5+KdLu4UqJ4EQJKyYoLsPx7ugvC/+PEnscl7HGszXRPRq1f1 CJKsjhCuzNr/apvptr1Nk3FwX8C7fn0efCo4n4FpnI8gVznmp87e0qEC2AD8f7yoBSO+bVmO1lyt cTZ4dYiig2E1EHkA89I6CVPPjEyiSrNXpRtzQvahvaKae7Q4X+PdULVsItatZ+/hjaIF2VqGKG/R haJEpsVqi4jQCWQ2jwXXPolkOCcW8SFRKDOpkFJLbzu6m8akyGiCVqoSV03eC6IrjKkegUEZp5G+ IHM0W1lfknMYGcRfALAesUnLiuYGLDdPysNhbYCXQPQVEou5hNtGKkOTZMOaG7Rt9sDnm208EmBB 5LfXgfcN/Ph0NMo7uUws42rnpzdte2ID7kLjKj1QmIPqbheXFDa8MmVjWuWsjrTCZMqd/TK89fBT 0W6bRYeaf9sv/+2Jg+fTRVwi5R9m6MwsOvlIU3E+e2tS+yMscQLk70o+4CnL3sGzN87QvIXFYi/V +NeQ87aKZOgXPquc2xnnXTvE2cPm88RToYItT4K5Qp2JYtsT9JtDax8l/fmZnWreyX/ON6ElDYrS rNuqB3xUVSaFLc5t2z59rj5bB4kQPLY/JLveGVaFSAEVuMDqKc1GM4vsZKmgS9BTo6cc8hTKJlQ6 QEZorhMeG67nFsF5I3aT/855ABsZ/1+a/F9h3qNOosMVhW4nAM1xo+ExLpprA9wPClX84NQ6WiTy 393gdI7CwVOCi2s4jGILtIiAcTvPUFXFJfEYOgazMkmHFZgWwjz9WtHY/A+5fVrIYNOOnZIKkBkH jmIWxCWe7emk8TsdvQ6I84QTO/yGSX+SmwM40vXKbfbZmX3jkXnCX9JRaTgn04otmgRmy9ZvqLy/ L5zsjo+0dgAFafZfNalXmKelXivhH74WSv2bKBH5IFp1dusJgntBna0ZMANePJSHahIjXWG7FuIT NGate3FZxYFt6sgu1IlsTKbYNSE2HegPCDbsnArlam6TkJePr8AwPFDb7rpNMUb37pe9ru4ugwKF uvfycyIrVYE76eTarcvpxdENXQIpwlSrpsbY2vRgO4VNuDnMnhBgmSk7aoHGvyntr4B9ojyiIQ2l ZQUZueGY6L8qd0ZNAn7YwUtQwZZWJHa5c4qoDkZu0pSWTZIJQSnrpYgcqbO+Hcpg5AwR/FMc4pUo DRw9zopzYCb/Yo7HnTXhx32PcCoGPvXNswSLJxtDaYGfGjpfcF6SpJX78viZQUczubI9Y7UwONwT WqN6OhO3T3ET7R+kqIj0KZaKQPQgwh57rI+O354bg4aZabGKRYjnWMl1dNAmwRbcFAvxMzZhwNiI dINyXFi6M0oufDT2f/E7zw3WBwxGPXyOzZTtl/hNEsFV/HTfRC15znp1G4VYSoA+tFEymg+YxNQl wd6hi2J79XUFJfhElWWEoiRhkNQ+chsXhl/FeEnSf5lWG03JJK5AFz5wXWJ4TagDrJIejTNP7JWj ldI+Z9/z16HiNkt1lllgYt6lCgHvZINhtIJn7VQ6C2awqRBd4suOrUP4nJL2ZElxduKc0i33ngqY jFa8+tAhvHcVzwh6k/AHvtA5Jb3FwwGXrX6TIgelAP8sL3ZopJ+4ulQCD1InQcn/ZxOVdsRasA7z sL97EZk8RCO9AczAlYkBj+mK1TdcL/WpbDRBcV3kwxYmezqMk9UHEoTVB7G5nOy6B8ymYMHr/6tt 0BZG2ZBiiaZHtCLTWksZNT/rtowpUlLbnbtuzzwFj4cvTPF3QMUv+M+nkgbkNSmUgwINXAeGFlJM 7sHCbaAJzoqogj6py4jP7eyF8TFkhX1Sx0d/L4ARs2UUiGQsuJxlXJNjZmPQb7e/IGnwWgo+dz+q RKVukq5pMioj2mahcN//+dt15Hb0Iqsbznu2ChbU76HtLjUQKsiPEiOxssajqBWPLaABZOBumUhN VB4F5v2KQZAU/VFucXlwFIhEioCCtlc1FsiHOX/Hh/unBACeXyAzAnPOQodGTSHsVnOY6J6UVyqG v5Z1OYChy/4+cF0naCH/SNhftYXVitT3xngVGyWHgsTWzriGot3L1fFWWInKSPRWu90vBAmMpdA9 MeG6OUjh8kMi35uLAxscVj0cI0s8Dl0mwM6XLqu/DQ26JzfiEU8M2pvWkMCaYVCUaYGVTl9/3sy6 moQ2rk6PsVc194um/KRRgeoNQ1CkMV1waDWOLHdrRDBsJNmGlyiq2zbFl7QU3AaO7J5cWtamN51L Fowv/LgMXIoj2taWcbLSgKWXtKDguE56Fv1KCdt/qnhYHZnmxPHmflcXeZVVZk1MtEV+zw3sWfuj DCzOsTBoY+B78QG4N+RT+mlqfULy8DxtNu+lEimPd8m0YCdvdfj7MdOQzbNy/VY9C9qtZoqYOmDG xSurilYak03StxBM++hTkKAgKXi9kIiSMrx53l0ueBzc2DgJ7TiRxhEF/KKpOME1ILH7OHP8sgaf AhKFIKKn4WgyGBQnrZmxiIB++bfpz5VT2kZGUvfmrCFEbY4Y0C/Kcf385MokBAswJSu0V9pi1bco DNSGFKeOi3eU5ISyvwmq2x+o4OPDeDz//hdnPR56SxVr+OnZpn49X3IzWjUulSMNYXXnjv7X9zxt FUBA8fxh+YnS0wC39xrdBm8kNp2Oe8EIPOj17GPvqi/0muRbfzsh0vTBuPs5f7SKkNfOHud+lrUO HTHxwndWNSU3PGqeJrNrhHi2J3wOaroU90sH9wqCcUMHW5iIrwNImFk6TAY6GsV59SwHwwfHh061 YEGDs3he0RWyoNBK5KXl3qDHVfu52ZDOkSaSvybjyxdZOvYr49wKGok/KN06E0MVFp0mQBXeKqdj jEahJ0kYiZOuIM3l/cnQ+60hlOsM3yWSSfh7OUgBsGZbGIhURH17HkizB0lDYvTr5ywXTI2Wo0Z5 2IufriV+qgXgu/8069kSwV+lU9CHB5BbwDwWSV+fO9A8Y52poWvzO8tnIhqyNzSSZw9A3yqO5SWf sz4zcJRxKQm/XOuHBRf8BbQ0YI2JUyKlM1SkYdIE1t6TeqELqVHyTvX2xNrSF3N2P76fQE+Ki0M2 fOPQ+ojkDR83cSlvMDFqZxT6c9IEYLXz4OPl0+Valh4DDFaGNrEc8wcxEh2gB96cOt8mNYELDinD /Sa27ETeyg8UmWmRple0ZdFi2hSvKSrwzjNfd1G1bLihKzyeFUjfTcT27qMoOznAt8UlO5fvRGGO FFkGD4FIDQhylqIV7khk4zxZEVxiHso4joN4mk2fddcF7yjnl0MbsNRm4yvlHq0Go/dEh5B/CWaS Ro43CYfG0QumkECGZnnNeu6D1ntiGrl5SzKRuVeloJMtYUx5oxRIzwJPHuvNKxqENbAgpAfO4PWj HaMn5/3KE3AT2QRq2ZiUb5RmlxL2e81CCuMOSYsElR/4Dg/smJPhoRr22Md4saNjPoqemMjhnChc szgH4UUBX4y5WaSvn7IYLoauoYB5gjZYJIwEE3GtjcJ4bnYa6Yli7qy6lQBJz0wjTggaXhkQSHaK RCdVY2IH4Q6hNBpY3+q48LxZXceVg2+xo21ND80Fkb3XxYBds9VWgPXHTjzjMwzHVLEbqzpf0frp VzxycoUBDUeF/1ClJYlqB1OyZnNn87bMw909p9rSCWy2ELyYRPMoOKC6dIYecc2TqNuA8QbZl7rN 0D6ERlZWvoqZSepzgyQ4tS6JBBjS4ppVRYfrb9Ew1O2SRkTkpcAxmv75JoVRB3QfddF9GLTd+gtP t7+Do1SzGgZw/GSS6Z2594euFKDQKX1zVuWldAFieaohjXJb+fUJlSEKT/7Qi+Z2eiEt5M5fJQrg 0a+5plTU/SbEcP9VDJbh7wr5yoA5ZbdoThwG4bXoJkgoCszBjMgMNOTpukNt8biJaITaE7VKaSJf Lp3BoEn3KX9v4nFLy2fPUrNBxBOvNNlpJg1TMUAnK8H+qdLOVhntlQnNG/76kU/Cmj6N01/fU5er 8ZwyJLXJLHWOTn6huvI1jAwMNdecGroeBNbEPX+paY5kIwLI4VKtM8jQpbSk7rJ669tL6n0mIupR sWUoOSHV4WgIwj+FM0tRXcSw+YoRkRRAPZq6u76C5OAznCW9ZZRgcQybyos/FcN1xttE31ystK10 Pz5EWGyHtfdHA1fGi/XdZ0M5HFTTXw8gikjEiKBXJjkRSoypdpSQg33u3ZiUPm7Ep4GeXQOCpziz XlOg1hKyaf76mi71bdkuxyuhzPPR8zM2TbBdU6U//5qmg9W+GfdmIv82n7qQMB/RNmms85Fl5k2x 7qzLaSKaqyPmTboRnxYr0nLac6ntKcqA9R/2dgWKMhYpyInWZkRbfrEFPLiM6gTjSPuYfkfINpbz /8JoyBKoa/q8fkVfPtBumX/8VMMdTccIgs0R6yt2Vo3Wi41Jr7YEb/pOpuU5YRq5T+zjJjV+8YwP 0knv//uC/WskuoyVzRMla9WMfeUOWato8lftV8F7FQxLsCZ+4Rc20/vbIDAb1ExUspUuBwoZ7Bx9 ugsHF0AT4GrLQ70U2T6p4zzfyJ9xt1iSG7X6quVxnpJuL2wFiq4CZvbdlcQkXOcBcCzLB3mxTHde uPtheprkpE3qE5/Yn9AFEvTNGskwtWrRc2TLRiIzLMjkvElbisBNYiU9SJrIkb2s/KRVF/IMZbti kxmCalOCLig8kth122LOKjyKLToMIjT9neuYK/Ll0DHyWkG5MShXBOzHU9rcFth7qx9GwaA3lFoe GRpoFQP+NH2S9XKZpUp46C3CyS7wjGekZE6T+YBsX5E7r9m4k70+xmnPC30/war4UsQCEIDmCoSK 0lNLGkhoFZM1aWVjUNoodoyymLpTmfs1KWbZ60jGa/e7lUr/LyyGr5jw08HievQWrpflHKflY+cH CcSiCN/xG7sA+P/92/S+vEKApUsg8MSAKcBn3o5c8DUpJ0KKpLaCJfUl/qUXazBbtOuz5JB+l0w/ 2wtHe8pTeI6gG94eZVOKtayu1kk9trtfAK1CPrmOKp4j9l/tV8YBfcg8uVyypLK9MnJpOPkFc+b9 Fm77/4v9veXAZPpdfFpCpf5p3KAnUZ6szIfm+wHJiSnultoqzwsxhocFDG04wNu8WITjmB6UiHp3 L8Bjls88TiYgIZGalP6P7pOEpJe8uV8ONFkZkEWw/XhgZhrPs0iCLQlt9KLMK9yUtbQOBYFn10+q i52k7s8hRlfXR9AlvdTxyw31VKE7p1ZjLUfUqamDE/vka0UIk8disuRb0sVi/LvCptC6ImPpz8r2 I8hYhTkH0UnVOncAtkAR1z2l2L6Cg2l21OVQFUM/jNAwoSAFiU8D8gpsieCMKv23vKIutyk46NYX nTw2GJoqnp7C5f21jhIR8byuhTJ+KudXI03pDVRGnNAPNdQWEQEMoA+teRRJOpjxv4t4Ff/kXSne ozbisb05I3zvi93V92JQb33arJMw9/py4wlcHGr5ZEPJfRO+q0eQntv3IB7BO6uWyIBcxwM1BWgp Mo4Edmlgyy0DTwYVO60VEp5hXG4GmuQ9V/VZA/n4jfnMIh1DJMH4xdMtu3Zb8EHCeMM5Y1rHDcNv yDzefOex/EVDUKyl4QHhgekswRmihc5dNLHaUJbd5796rJRVLNsn36uwUi+ey6vJGmmUgqpLezwG CVFSeDYdfzZDvG8mRGvelc1bqzFqm/tF24czfCr85adbjskOgVK2ntFR1GDQjj7XXxHvrla5Bjpu AmWNpnh9ZStJlpDUBXVJx4OY/8liPSGTCXzBkHTwfkPE3FGaqudm6xuDaIKshYLGo2DGgsPl1IWB 9+L3kGmCHyVpqBp6FtE1PZwOG2xU/3VwqXNDS2+ylGudyNI1Vn7uUKUxS+36L+CbaPv59LltqGhA n/k6GYla926/sJ1bVdcwsrjQhPEMG5yIhGXYShBQFsVlVnEludhER2zH8Kgpj2jA6emfRoYJQXzP Cv8BuXifbz5ADDnEBBZDZw9A3j9ec+FqUYtgfoZSxSq8iUskyhvvvUapbUGCq0rCUVVckBGb698g aiFP7WvRXpTPNKfaVPTd7j+jtzf7BsY1DAFo+FRiyU54C1ErhzHI5sbVVwdNqwmDaq2Y5GeMoPlp gjdJ+/C6XCEnPSkq/3XwkELubhim4QcURjsUeOvg3tyDY8CBMXCl/wVQ7RUlMFvBzEZxed8YrHGc QK/ijPWwITnURi0PTI4b5PMqNM2r0SwHa+5ApvuwKTeJzjqxW3l6xQvyJGKBc40/7I8wXniySq8q i30ySL8VgXvkeBcTpDML3XPMTtJSTEeqyPPxxaCmAGhaGeVqbVfV5+uABPALHpoel0UaavG18SKp WpfAEX/cv7POvpCo1rwmyZxlCu769dx8kDd0jD1/zvsIXCLWVkWDocdQFGUU4xZSsr6PvjC3Tmk1 5Qr4BSzZvKfy1md3CLtFqKHRb8lfuPqzTZh/uDeGe6WGFh7LWALGuKysm+L5bhjY8kkVyQv6vh7S BVsmPMNB6MlmLvXs0QsGQrD0oRkjWU+beQPV0RP52h9uBLz8OCR5md2aane2MW6ULwPhVZr7t7OJ 5dAC1VYdZV6yNNpw7HUsyIw1aSmREF7n/7DEcximavqOzwYJPZjH7WIUXyNJDRZapzlNiS6yQ6He jsTKxFUEVmKb4Sf3qPCr/R9mc8NXYQSoaX8E0fgFn289JFOxCpZO2xw3xudP+wwoRh/GGH3jY20a kYKjgZFdr5scK2XVVeOlb5n+A1YyzpG0Q2K6TQ7d5t3sukjTLT+wC4AzQMnOqmScjw4Wbq3dQIzH wnqLmBqS4qFOoHelT72Po3kf1F72ZlkrtbSF3ZfRZQj6Bg7BG/9Ld5HEMM0ij/JxA8X5nTNm7Mea TqbTrcXQrKAq4rutVvCcsb1g91yDqhhSHwtDq5jw3JZla2tZJaL4KeTHvnYDEywoDthg5PF4VhTL CdF1nM9EzYOPawJTmiITG9uzyf10bqP5AoZ8nbwdEIIkZBLmnKhjFpiRErKQh56asCHGg/OQfrUT t1hwdvExnBSUzSRzrZG686WFBNRH9+at0xHo32hQh0E8ebrtcnAsoYHTBaQsJsTKEMloYGlufeoI VYA6AlBOoP1nQLRLqeE30Te+gG97CwWKQTuiWpGLuwSaXaGz7V1hy0l9JPKY02VLqpBerbtc0FXr rMx+liH7Qqit08mUTb4WRRNnhKSYvl36c6QxgbvqAayMwAv9tJocF2445Vk74ueGOQlj8S7yGR8X e/6KJ6fo1YwhUD2lGZg+IArnHH3KWeN5acJWINvd1cGYN+oWDp0zJmLbVmg4k5pQMnTo6qnZ3xyC XMZZMIkZxA//uyPjXszUkGtBtawukVa4ZOw0YrdQgRqV4UMIRhwBelBGXlv6dwKJNldt/efbpFrR eImfzAFYJRx0WXI4Cdj6y314JCZ9b0qy+tppWbUK30IgYjNVCHY0jQnjNUUbuGv6HxTSx9eoKeFH mXvHwCkxotJFUDEO1NFghyCxoAt8ukOdVMn2XeQQzemnlZTMeN1mgNl0aeDycwBkNhhCHkX0/c0/ Yd8RZvPsDIOy95dhVeK47/cPCX/LVWyzqEEkN5UUOU4RZ1ZEfr8wpHnvmN0buN+HdkaSn0U3IptZ XJFyYWFWY5RKntsC6EuZPAXzNsCLpmGzlRtMRsKL2vf+T1/D5h+rEvGYpT2xBgTr9XF2XobGScf3 F4kSI5qSjJvEnwsxiEtLBVUcNgytYpJqop5pB8TpHXByn2WuQ4Ketr7MPcBsC6lGgX4CZrGWYQiQ ZzHG+MnaHOeFB7f81yT/JcVDHNQkoED5YXcVWjdByvfbpPoViy/na/BLdZpkDvDG1Y/F52QJsAxf 2YfzKOP9prRKNBAkn1dye2w5x+GAkDaXAFg1YvoWxdVJvwER0ICAfzfbXXLquDjRtEi9LagkW9ic zEwUAkq6xSyvEKJslwH2ILv3XObTEkjVyme6w/u5KDVs6EZI87GLz66yv6FGEEQsVoUGXrbSGJhN Y8blT9gS4JZY09BD2/Z8xNAEScy7BY7v2o7Ak2N7Z8FzUq+uUBx6DZDi3A4zFrOr72y1DrekkYAj Cw2LHtmPjIRRHsB5NfUZf2UYCMTviFZAIemBB9oE7JjF0/4pJb93nyLOAadW0g804Kl9IGVBjK7V Xm6g0Iu3sKDMOqMtw0gol2v6VPPyu4OwtuknA+qxDMEMUSt5yVduWoxFBzX9NIn+ioGku8Gt5q6x RPQHh5INEAR1i2e9vrI8zGFETAwVP5/lCPvbOylnJxjeq3rF9jhq/7UZTqseK3t4fpL/9yqANgt/ Tx2+9+TtzeENwPYZegt8jZvAsXYbDQwdCUeP4NA0EVx5oBEIP0p8ShsLvxw1E66fA0Rz+qkOdHtj iUYcuiJTRzhNqM5YTOSZ9tX0OKY+spYgNmQTzdDgdGqUzkrwCQF+//CNGPT/s2aOGBnpfMY6jpeL Yl/fotB+fobtqVC9rq9iHZbM3+TxLDL3CwR6w5klbdQMogl7kxIUOEjykgYbEqT0j7AisDHDxybk 8zcyI8idBAUfqWnnavONMNUVz0kv/ktd2bRv0qhZqfgd3ONhbSEIOqHEusl/KjS0PdcX5hLh/GC0 ZrCARnv9YljRdhl32jswELwb8NDZYcttLbtQoKnN/2a/vr4ehIpNHgWfQFKsVC94cvOHpS8xPSBc 507l4LG6gXFdgwR/ZzUq1d5dgavQEtaFt7+iPsdZQujRXFabbsa1mhOE8JDkw57W8mlMIz7f280G gmw2SDlc1SZCg5rfqToTBYu68SkjY+bmq5Xly1Q3QssjicAKg4CEk25xdxFkYWRiiSvwe1IoqOU4 +FmhJIaO50qHke2RuTm960617vuDVGmTP3EbKzxLpWQyfLZe5fYaue6xgLBfQbwZQLmWr76VTMgt oKZVB0vcToXwrjsDLv6uyxP+mXyW4oOGOZARG2e9/A1kVQvj0ggb8LReeFPCDbnagNIkY6sYklmQ qry3dpN82tEIWgeRP07AjPNFCNLu9nUnuwE7xxSw99vIRYILBfF0Yma7LDXWoK227/vn+QJA5L/C 5hk+PZT52cbKjK2YwzHUO1aK72q0jdZk5LgVAmKGAr1ErvZlQv4vovkwZ1UVuaMZQK1uKK7etms5 v3AO8QJrpDoY9XFQDM6si4o6wmkk/Xdy6ovOyAMzM2y7GlYGIZajtLDD7uoZEZpdQx9qgQzLY8G0 Fb0QJR9ZHdx6xpew7tQmauOZc8O6PSvJ84E/zebD/7LtEd+tPyMilFgkvIg7WJQjcx78C2uILZIc zwXRKVYFSi/1R2nXl6VVDlqt9/ZQSDKObbM3mOjmfDnR0qiDl3LN+S2ACED9VrUv6nL0e5kC6rzd CqLRP19UNbFhbtStlTxlBa1tmZLldHq97UlQXGyjPR/izUHhV9xDHrBkca40F7yF3hj9TR6ziMuK J+EuAvaYfNy8N9fmbtWO6gzgIj0Br5MOcMTWQ7FdBEVb58OjIiHoYbYVN8nULapALJjVSQQaF+dX ArmnrHjaoDjygCNWZGRY18P4aYn1Jpti3V2QCNnMhimHByAvLEmMEa2F9rxIWIxVRrhPnXljm3Gl g61UvRaATH/mdqX3jrMzJpEP3h7YoVcSSuR1MBGG+tC5BsQdddd50d0CuFurM/WBMHmHPOIUBHeK P3WJ/wq71hlE2w6SJkmgxnuxB+FzSF+51TuvAcqphxv7y5Dqyo7WZeVtkeR6CwEc4uqvVoynxuD9 L5RnAUw+BCYIZlFmC6JEbPb1uRETGvI5wzoxl7jYvcc3Sce5+HAVCG1694SexqKkM8nckq0Rj30T 1VUpJl9bykjdGaL5SOw87qlDrfmTRxjZnSL4bgdWuuqB/KtZNYk1Mxz/LimUKjEwqJuuKTZtiNTE npgK1IOkl1MJT2YSc/BRh+enqaiDRUvHrE5Y3L8nwdXWd4wxUR180qYzRawnTKdrEQZzm1eS3gkt uXDYAS0y6E7dq70+/31OQ9R9hcmFu9d3DKhpFTyJZBaYWQ2cDQooVm9ID/chjVi4Ff8dmHM55xZ4 3Uil2UZmGAJO0WubQBDzlMIKwtQmsJYdZPbpHiWb2iKaqAzC00hXWIgaAgurE6my5kaV5RY4AIAx HQMPa3nCN1CJELrhXuwo/tTLx5tjWSpenFVCXMmoTNnsPCLkKBDp3Fa6TFfOk/j23tGO5ZgpJ2Th w61ZNH0JcG0riErRZyNsiZoVPUuxry9K0LIoyQ1f2/r9sRqyL1AzYAUBYbOZf2L4YTugJa8cFht8 Ny6RqJD7llJYM/qZvpAghxS9/nG6/mIro7QalpniWQ6YGiEvPAAAAAAAAAALKmRdhcEhloj57Urt WjtWSIAU0uAAAHrd3GvOxI7guK6VNSiN5B31rchWPIcQ8+bXiy/YNjNT5TunLg0KLZOB80cUtMXq gMLo6znQO5osfJgwCtjnNEbThHPxhflOY0aipqQl6AsbbpgjkOWsmcEmGQb1EVBVc2a+GlAsxVF8 9bhxgtGDm8Q+QGvxweo3S4NKzduPULP/80jIN5+GtADkWQ/1kSjqEmRNcnAsQLF80oj3LEYiRcGD WbJ4xSkdK4zK0P450eQEzosxYXOda6UHVYoXDLMf4wqLKXLg45aX3Z7SX0DG+zsi3ne8VyTZvl4r EksaCYZZbAMBX6bim20RWXPPXS4oCxM62ayMqyWcgxq22XUWiTZBLm6Qg0SqT1cuEng4IwUzbSEq 0b2AB3+/S7scOBMPXF0PXbeq+VOg5T32bUHGMDnK/rJ3PeBlMNhvoDHpPNgppUhbDCaOOjgcljl8 3bOQAbrJN1woyc1Ipm+GgpFNEcbrKRAeR9E22WSKnyHUi0C18l4wQSWVhT/kH5wbogAAAAABpPIo cHhrgOFVyyPh5Oc4wjdOkGNYe0yniCL5IvuvGUa51WNzqFpQJL/4/WpcUXXvgjbxkCoAYzhSAGM3 PnfD2F5f8Sr+X/Eq/l/xKv5f8SwT05Y1BDRaDK+eu2KnxdclOonZKagAAAAAAAAbAAAAAEuEAAAA AwAAAABLaAAAAAAAAAAAgQIBUks= ----------------------- ATTACH MIME - TAGLIA QUI ----------------------------- ========================================================================================== Meteo --------- by wuRZel --------- Come ho già esposto agli amici SPP, non essendo io un profondo conoscitore di linguaggi, backdoor, phreaking, hacking, ecc. (anzi..), non sarei in grado di contribuire a questa e-zine con articoli di un certo livello informatico. Allora mi è venuta un'idea, quella di scrivere una serie di articoli sulla Meteorologia, campo in cui lavoro e in cui sicuramente tutti si sono imbattuti: ..sarà bello domenica o pioverà?, ..cadrà neve in montagna?, ..c'è nebbia in autostrada: corro o non corro? (in questo caso dipende se si ha voglia di morire oppure no!!!). Questi miei excursus non faranno sicuramente diventare esperti meteorologi: quello che spero è di gettare i semi per far germogliare un qualche minimo interesse. Sono ovviamente pronto a ricevere commenti ed osservazioni, anche che non ve ne frega una mazza! voster semper voster wuRZel Per cominciare bisogna parlare dell'ambiente in cui si svolgono gli eventi meteorologici, ovvero L'ATMOSFERA L'atmosfera è costituita da un miscuglio di gas di vario genere (anche di quelli emessi dopo una sostanziosa pasta e fagioli ;-) ), alcuni in quantità costanti, altri in quantità variabili, oltre a polveri, sali, prodotti chimici, microrganismi, ecc.. Si estende dalla superficie in poi, e non ha un limite preciso (circa 60000/70000 Km). Questo perché l'aria diventa sempre più rarefatta a mano a mano che aumenta la distanza dalla superficie terrestre, ovvero perché la sua densità diminuisce con l'aumentare della quota, fino ad annullarsi completamente. Suddivisioni verticali dell'atmosfera L'atmosfera, in relazione alle proprie caratteristiche (specialmente la temperatura), si distingue verticalmente in diversi strati (vedi figura 1): Ozonosfera (comprendente Troposfera, Tropopausa, Stratosfera, Stratopausa, Mesosfera), Ionosfera (comprendente Mesosfera, Mesopausa, Termosfera, Esosfera). Di queste zone, quella che a noi interessa maggiormente è la Troposfera, perché è la zona in cui avvengono la maggior parte dei fenomeni meteorologici. Troposfera A causa della forza centrifuga generata dalla rotazione della terra, si estende per circa 8 Km ai poli, e per circa 18 Km all'equatore. Mediamente la temperatura diminuisce di circa 0,6° ogni 100 m di altitudine, tranne nei casi di inversione termica, cioè quando la temperatura aumenta con la quota. I movimenti verticali sono responsabili della formazione delle nubi. La Troposfera è caratterizzata da un andamento medio in cui la temperatura diminuisce con l'aumentare della quota, e dalla concentrazione di vapore acqueo. VAPORE ACQUEO E UMIDITA' Sappiamo che la materia può essere in tre stati diversi: solido, liquido o gassoso. Per passare da uno stato ad un altro (ad una data pressione) c'è bisogno di una certa quantità di energia per poter rompere le forze che tengono unite tra loro le molecole. Per quanto riguarda l'acqua, la quantità di energia per passare da uno stato all'altro è: -------------<------------SUBLIMAZIONE------------------------- | | | 670 cal/g | | | | ----<----EVAPORAZIONE---- ------<------FUSIONE------- | _|___|_ __|___|__ __|__|__ fig.1 | GAS | 580cal/g | LIQUIDO | 90cal/g | SOLIDO | |_______| |_________| |________| | | | | | | | ---CONDENSAZIONE--->----- ---SOLIDIFICAZIONE--->--- | | | | 670cal/g | | | --------------------BRINAMENTO/DEPOSIZIONE--------->---------- Maggiore è la temperatura dell'aria, maggiore sarà la quantità di vapore che potrà contenere; maggiore la quantità di vapore, maggiore sarà la tensione di vapore (cioè la pressione dovuta al vapore acqueo). La tensione di saturazione è invece la quantità massima di vapore che può essere contenuta, ad una certa temperatura, in una certa massa d'aria. Quindi, se ad una massa d'aria viene aggiunta una quantità di vapore che eccede quella relativa alla massa stessa, la quantità di vapore eccedente condensa. Poiché ad ogni temperatura corrisponde un valore di massa d'acqua contenuta in una massa d'aria, vediamo che il vapore è funzione della temperatura: | P / es | / P= pressione in milliBar (o ettoPascal) | -/ fig.2 | --/ T= temperatura | ---/ | ----/ es= tensione di vapore satura |__----/________________________ T Ogni 10° di aumento, la pressione di saturazione raddoppia. L'umidità relativa è il rapporto tra una massa di vapore acqueo presente rispetto alla massa di vapore acqueo in saturazione. Se l'umidità dell'aria supera il punto di saturazione relativo ad una certa temperatura o se la temperatura si abbassa al di sotto del punto di rugiada (temperatura a cui una massa d'aria diventa satura) il vapore condensa Quando il vapore acqueo condensa si formano le nubi, costituite quindi non da vapore, bensì di piccolissime goccioline o aghi di ghiaccio (qualche centesimo di millimetro). NUBI Le nubi sono classificate in vari generi, a seconda della loro morfologia, del modo in cui si formano o della loro altitudine. Riguardo all'altitudine, le nubi si dividono in Alte, Medie e Basse, mentre riguardo alla forma si dividono in Cumuliformi e Stratiformi. | denominazione | abbreviazione | altitudine ---------|-----------------|---------------|---------------------------------- | Cirri | CI | Alte | Cirrocumuli | CC | Oltre i 6 km | Cirrostrati | CS | ---------|-----------------|---------------|---------------------------------- | Altocumuli | AC | fig.3 Medie | Altostrati | AS | Tra 2 e 6 km | Nembostrati | NS | ---------|-----------------|---------------|---------------------------------- | Stratocumuli | SC | Basse | Strati | ST | Dal livello del mare fino a 2 km | Cumuli | CU | ---------|-----------------|---------------|---------------------------------- | Cumulonembi | CB | Da pochi metri fino a 15 km Le nubi alte sono in genere formate da cristalli di ghiaccio. Cirri: sono nubi fibrose e 'leggere'. Cirrocumuli: hanno generalmente uno speesore limitato e costituiscono estesi banchi ondulati. Cirrostrati: hanno l'aspetto di veli sottili e trasparenti, e a volte formano aloni iridescenti intorno al sole e alla luna. Le nubi medie hanno aspetto stratiforme o cumuliforme. Altostrati: come i cirrostrati, ma più spessi. Altocumuli: sono più estesi dei cirrocumuli, e sono formati da cristalli di ghiaccio e da goccioline d'acqua. Nembostrati: più spesse e scure degli strati, sono cariche di pioggia e/o neve. Le nubi basse si formano a quote prossime al suolo. Stratocumuli: di aspetto irregolare, spesso a banchi ondulati. Strati: nubi leggere di colore grigio e consistenza simile alla nebbia, possono dar luogo a precipitazioni continue. Cumuli: a forma di ammassi tondeggianti, meno imponenti dei cumulonembi, generalmente non danno luogo a precipitazioni (si può dire che sono sintomo di bel tempo); si formano nelle ore calde del giorno in estate, e tendono a dissolversi alla sera. Cumulonembi: a forma di torre, possono produrre violenti temporali e a volte anche trombe d'aria; nella parte più alta si espandono orizzontalmente, assumendo una caratteristica forma ad incudine. Le nubi sono classificate anche in base ai movimenti dell'aria. Nubi stratiformi: caratterizzate da dimensioni orizzontali prevalenti su quelle verticali. Sono caratteristiche di aria stabile (quando i movimenti verticali presenti nell'aria sono nulli, cioè quando l'aria non tende a mescolarsi), e hanno una struttura piuttosto uniforme, con goccioline di piccole dimensioni. Si possono formare per un sollevamento lento e graduale di una vasta porzione d'aria oppure per un rimescolamento di strati d'aria pure di grandi dimensioni. Nubi cumuliformi: hanno dimensioni verticali notevoli, e sono caratteristiche di aria instabile ( quando si è in presenza di forti correnti verticali), animate da correnti verticali ascendenti e discendenti. I diametri delle goccioline presentano uno spettro molto ampio, e vi abbondano le goccie di grandi dimensioni. Nubi orografiche: sono causate dal movimento ondulato che assume l'aria quando scavalca una catena montuosa. Nella fase di salita l'aria si espande raffreddandosi e, se vi è sufficente umidità, questa condenserà formando le gocciline delle nubi. Nella fase di discesa l'aria si comprime riscaldandosi, provocando così l'evaporazione delle goccioline d'acqua. Il risultato è la formazione di nubi di forma lenticolare: queste nubi appaiono stazionarie, mentre in effetti, nel flusso dell'aria, sono sempre nuove nubi che si formano. ========================================================================================== Lo stack tcp/ip e i socket -------------------------- By LuRkIn' -------------------------- INDICE 1 INTRODUZIONE 2 LO STACK TCP/IP 2.1 L'architettura di rete 3 I PROTOCOLLI DI RETE 3.1 I protocolli del livello di trasporto 3.1.1 Il protocollo TCP 3.1.2 Il protocollo UDP 3.2 I protocolli del livello internet 3.2.1 Il protocollo IP 3.2.2 Il protocollo di controllo ICMP 3.2.3 Il protocollo di controllo IGMP 3.2.4 Il protocollo ARP 4 IL LIVELLO DELLE APPLICAZIONI: I SOCKET 4.1 Le applicazioni socket 4.1.2 Definizioni 4.1.3 Storia del socket 4.2 Elementi costitutivi 4.2.1 Tipi di socket 4.2.2 Altri tipi di socket 4.3 Funzionamento del socket 4.3.1 Definizioni del linguaggio C/C++ 4.4 Le chiamate alle funzioni 4.5 Comunicazione di rete orientata alla connessione 4.5.1 Funzione socket() 4.5.2 Funzione connect() 4.5.3 Funzione bind() 4.5.4 Funzione listen() 4.5.5 Funzione accept() 4.6 Comunicazione di rete non orientata alla con connessione 4.7 Riepilogo 4.8 Il winsock 5 CONCLUSIONE 1 INTRODUZIONE Quando leggo gli articoli di BFI provo contemporaneamente meraviglia e sgomento. Lo sgomento nasce dal fatto che, in quella e-zine, spesso mi mancano le informazioni per poter capire quella massa di dati forniti con estrema disinvoltura. Lo stesso è avvenuto per l'articolo "Guida newbie all'IP spoofing" che altro non era che la seconda parte del progetto "0N0S3NDAi" elucubrata dal pur ottimo FuSyS. Lì per i veri newbie c'era ben poco da spolpare. Al momento non avevo sottomano la prima parte del progetto e così scartabellai libri, manuali, ezines, e quant'altro mi potesse fornire la conoscenza per avvicinarmi al livello richiesto da FuSyS. Letture disordinate, sul letto o in cucina, nei ritagli di tempo che a volte, invece, arrivavano ad inglobare buona parte della giornata. Quindi le ho organizzate in piccoli appunti, collegandoli tra loro come chiazze d'olio nell'acqua. Ma ecco quello che ne è uscito. 2) LO STACK TCP-IP Esiste un'ampia letteratura sui modelli di organizzazione della rete e sulla descrizione dei protocolli utilizzati per la trasmissione dei dati. I principali modelli prevedono la suddivisione della rete in livelli, ad ognuno dei quali sono associati determinati protocolli di comunicazione. I due modelli di suddivisione od organizzazione della rete più noti sono il modello ISO-OSI ed il modello di rete TCP-IP. 2.1 L'architettura di rete Il modello di organizzazione ISO-OSI suddivide la rete in sette livelli o strati (stack). Nato tra il 1977 e il 1984 ad opera dell'organismo internazionale ISO (International Standard Organization), questo modello si basa su un procedimento standardizzato per il collegamento dei sistemi, chiamato modello standard di riferimento OSI (Open Systems Interconnection). La descrizione di questa architettura venne poi chiamata modello di organizzazione ISO-OSI. Invece, secondo il modello di rete TCP-IP, la rete viene suddivisa in quattro strati: lo strato dell'Applicazione (dove opera il software applicativo), lo strato del Trasporto, lo strato Internet e lo strato della Rete. Il termine protocollo viene usato per indicare un procedimento di trasmissione standardizzato dei dati tra le applicazioni di rete. I vari protocolli sono caratterizzati dal tipo di dati trasmessi e dalla modalità di trasmissione. I dati vengono trasmessi in segmenti di byte, chiamati pacchetti. Nella manualistica sulle comunicazioni di rete è frequente trovare ancora il termine ottetto al posto di byte. L'ottetto, che ha il significato di insieme di otto bit, sostituiva la parola byte perché al momento della progettazione del protocollo TCP esistevano sistemi con byte formati da nove bit. Oggi, pur con la quasi totalità dei sistemi che utilizzano byte di otto bit, questo termine viene ancora utilizzato anche se è anacronistico. L'organizzazione del modello di rete TCP/IP prevede che i diversi protocolli operino nello strato del trasporto, nello strato internet e nello strato della rete. Nel livello dell'applicazione, i programmi di rete trasmettono i dati al livello del trasporto o di internet utilizzando determinate interfacce software, chiamate API socket. 3 I PROTOCOLLI DI RETE A livello dello strato del trasporto operano due protocolli: TCP e UDP. Il protocollo TCP (Transport Control Protocol), esegue il trasporto di una sequenza di dati a livello dello strato del trasporto utilizzando un flusso byte-stream (la spiegazione di byte stream è più avanti). Nello stesso strato opera il protocollo UDP, che trasmette i dati mediante l'invio di datagrammi. Ad un livello più basso, nello strato della rete operano tre protocolli diversi: il protocollo IP, che si occupa di frammentare i dati e di trasportare i datagrammi attraverso la rete ed i protocolli ICMP e IGMP, che vengono chiamati protocolli di controllo in quanto servono ad inviare dati di controllo della connessione. Questi protocolli saranno l'oggetto della presente trattazione. Come abbiamo già detto, nello strato dell'applicazione operano i programmi di rete. Verranno descritte le modalità in cui questi programmi inviano e ricevono i dati, interagendo con lo strato del trasporto e utilizzando dei programmi di interfaccia (API) che permettono la creazione di una connessione tra due host in rete (socket). Saranno definiti i vari tipi di socket e le chiamate alle varie funzioni che i programmi effettuano durante l'instaurarsi della comunicazione. 3.1 protocolli del livello di trasporto 3.1.1 Il protocollo TCP RFC 793 In una sessione TCP, tra i due host si stabilisce una connessione full-duplex, cioè un trasferimento di dati bidirezionale, in cui l'host destinatario conferma il ricevimento dei pacchetti di dati all'host mittente. Ma come avviene, in pratica, la connessione con il protocollo TCP? L'host client comunica al proprio sistema operativo che intende aprire una sessione con l'host server, e pertanto si fa assegnare una porta. L'assegnazione viene effettuata dinamicamente dal s.o., con porte casuali i cui numeri assumono un valore minimo di 1024 fino a 65.535. Per chi non lo sapesse, le porte da 1 a 256 sono definite porte ben note e vengono associate ad applicazioni o servizi distinti. La descrizione delle porte si trova sotto win nel file C:\windows\services, mentre su linux in /etc/services. A questo punto, l'host mittente si connette all'indirizzo IP dell'host server, specificando il numero di porta dell'applicazione con la quale intende comunicare. Ora l'host server, ricevuta la richiesta di apertura della sessione, comunica al proprio s.o. che si deve stabilire un'apertura passiva della porta, la quale si dice che è in stato d'ascolto. A questo punto si è aperta una sessione di comunicazione punto-punto tra i due host. Tale sessione viene anche definita circuito virtuale. L'indirizzo IP del server, unitamente al protocollo usato per il trasporto ed il numero della porta al quale il protocollo si connette, costituisce l'indirizzo socket. Prima avevamo detto che TCP invia e riceve i dati utilizzando un flusso byte-stream. Ma che significa? Significa che il protocollo trasmette tutti i dati come un'unica sequenza di byte, come se le informazioni facessero parte di un unico flusso seriale. La trasmissione byte-stream (anche definita a flusso di dati), utilizzata da TCP si differenzia dalla trasmissione dei protocolli UDP e IP, che segmentano i dati in datagrammi, unità di informazioni indipendenti trasmesse non sequenzialmente. Il flusso dei dati TCP può essere di due tipi: flusso di massa (ftp, news) e flusso interattivo (telnet, rlogin). Il meccanismo di trasmissione byte-stream adottato da TCP appare a prima vista più farraginoso ed è più lento di quello usato da UDP, ma ha il vantaggio di essere estremamente affidabile perché, a differenza di quest'ultimo, TCP si assicura che i dati giungano effettivamente all'applicazione ricevente, nella sequenza corretta. Inoltre, TCP ha anche il compito di ottimizzare l'ampiezza di banda della rete, controllando che il flusso di dati trasmesso non sia eccessivo e non mandi in overflow il buffer di dati nell'host di destinazione. In questo caso TCP induce l'host mittente a ridurre la velocità di trasmissione. Ma come fa il protocollo a garantire la ricezione dei pacchetti di dati TCP? Per capirlo dobbiamo esaminare com'è fatto un segmento TCP. Un segmento di dati TCP può essere diviso in 18 campi. 1) Porta di origine: tale campo, a 16 bit, definisce la porta di protocollo usata dall'applicazione trasmittente. 2) Porta di destinazione: campo a 16 bit che identifica la porta di protocollo dell'applicazione ricevente. 3) SEQ o numero di sequenza: campo a 32 bit che indica l'ordine di riassemblaggio dei segmenti. 4) Numero di acknowledgment (numero della conferma): campo a 32 bit che specifica il numero successivo nella sequenza che l'host ricevente si aspetta di ricevere. 5) Offset dei dati: campo a 4 bit che specifica la lunghezza dell'intestazione TCP in parole a 32 bit. 6) Reserved: è un campo a 6 bit riservato, che verrà utilizzato in impieghi futuri; il valore deve essere impostato su 0. 7) Flag URG (bit del controllo urgente): campo di un bit che, se ha il valore impostato a 1, significa che il campo "puntatore urgente" punta a dati urgenti. 8) Flag ACK (Acknowledgment Control Bit o bit del controllo delle conferme): campo di un bit che, se ha il valore impostato a 1, significa che il numero di acknowledgement è valido e deve essere letto. 9) Flag PSH (Push Control Bit o bit del controllo di lancio): campo di un bit che, se impostato ad 1, il segmento chiede di essere inviato immediatamente, senza attendere che l'applicazione riempia il proprio buffer di trasmissione. 10) Flag RST (Reset Control Bit o bit del controllo del reset): campo di un bit che, se impostato ad 1, il segmento richiede che la connessione TCP sia reinizializzata. 11) Flag SYN (Syncronize Control Bit o bit del controllo della sintonia): campo di un bit che, allo stabilirsi di una sessione TCP, imposta il suo valore a 1 e chiede al modulo TCP ricevente di sincronizzare i numeri di sequenza. 12) Flag FIN (Finish Control Bit o bit del controllo di fine invio): campo di un bit che, se impostato ad 1, l'host mittente comunica che non vi sono più dati da trasmettere. 13) Dimensione Finestra: campo a 16 bit che indica il numero di ottetti di dati che l'host mittente accetterà. Questo numero definisce la grandezza delle finestre scorrevoli. 14) Checksum (somma di controllo): campo a 16 bit che permette al modulo TCP ricevente di rilevare eventuali alterazioni sui dati; l'operazione di controllo è calcolata tramite una tecnica definita "complemento ad uno". 15) Puntatore urgente: campo a 16 bit che punta all'ultimo byte di dati urgenti nell'area dati TCP. 16) Opzioni: campo di lunghezza di bit variabile, che può contenere tre opzioni diverse anche contemporaneamente; queste sono End of Option List=0, No Operation=1, Maximum segment size=2. 17) Padding (riempitivo): campo che, riempito da una serie di 0, assicura che l'intestazione TCP termini al limite dei 32 bit. 18) Data: i dati reali inclusi nel segmento. L'instaurazione di una sessione TCP, detta anche handshacking a tre vie, si attiva con l'host mittente che invia il primo segmento con il flag SYN impostato ad 1, unitamente ad un numero sequenziale a 32 bit, SEQ, scelto a caso. E' da sottolineare, tuttavia, che il numero di sequenza identifica un byte nel flusso di dati e rappresenta un valore di spostamento (offset) rispetto al primo segmento inviato, come se fosse un contatore. Quindi, i successivi SEQ sono aumentati dell'esatto numero di byte inviati. L'host ricevente, se accetta la connessione, invia due segmenti. Il primo è in risposta al segmento ricevuto e contiene il flag ACK impostato a 1, oltre al numero di acknowledgement. Questo numero viene impostato su prossimo valore di SEQ che il server si aspetta di ricevere. Tale conferma instaura una connessione TCP in una direzione. A sua volta, l'host ricevente trasmette un segmento di dati con il flag SYN impostato a 1, e con il proprio numero sequenziale, anche in questo caso scelto casualmente. L'host trasmittente trasmetterà a sua volta un messaggio di acknowledgement, con il flag ACK impostato a 1 e il numero di acknowledgement uguale al SEQ del server aumentato di 1. Ciò crea la comunicazione anche nell'altro senso. Questa connessione viene definita full-duplex. I dati che scorrono in una direzione sono indipendenti da quelli che scorrono nell'altra. Es. di handsnake a tre vie tra l'host client A e l'host server B: A-----> SYN 1, SEQ 2616666351 -----> B A invia la richiesta di connessione B-----> ACK 1, SEQ 2616666352 -----> A B conferma ricezione dati B-----> SYN 1, SEQ 6465455251 -----> A B stabilisce connessione altro senso A-----> ACK 1, SEQ 6465455252 -----> B A si sincronizza con B A-----> SYN 1, SEQ 2616666352 -----> B A invia il secondo pacchetto dati Nell'instaurarsi della sessione avviene un altro fatto: l'host mittente imposta le dimensioni della finestra di trasmissione e lo comunica all'host ricevente, che imposta la finestra di ricezione sulle stesse dimensioni. Ma cosa indica la dimensione di queste finestre? Essa indica il numero massimo di segmenti che si possono inviare ogni volta. In pratica, quando l'applicazione posta al livello superiore passa i dati al protocollo TCP, questo li suddivide in pacchetti o segmenti. Allo stabilirsi della sessione, l'host mittente invia contemporaneamente tanti segmenti quanti ne può contenere la finestra di trasmissione. Mettiamo che l'host mittente debba inviare 20 segmenti ed imposti la propria finestra di trasmissione in modo da inviare quattro segmenti per volta. L'host mittente invia i segmenti SYN1, SYN2, SYN3 e SYN4. L'host ricevente, per qualche problema della rete, riceverà solo i pacchetti 1, 2 e 4. La risposta dell'host ricevente sarà che ha ricevuto solo i segmenti 1 e 2 e trasmetterà i segmenti ACK1 e ACK2. L'host mittente, ricevuta l'informazione ritrasmetterà i segmenti SYN3 e SYN4, ma contemporaneamente trasmetterà i segmenti SYN5 e SYN6, riempiendo così la finestra di trasmissione. E così via. Questo tipo di trasmissione viene chiamato metodo delle finestre scorrevoli o sliding windows. In questo modo, l'host ricevente può inviare una sola risposta di conferma per una ricezione di più segmenti contemporaneamente. Ma come fa l'host mittente a sapere con esattezza quali pacchetti sono giunti a destinazione? Inserendo un temporizzatore di ritrasmissione in ogni segmento trasmesso. Quando il temporizzatore raggiunge il valore di 0, l'host mittente invia nuovamente il segmento, impostando il temporizzatore ad una durata doppia di prima. Questo metodo viene usato in quanto l'host ricevente può comunicare solo l'avvenuta ricezione dei segmenti e non anche il contrario. La connessione termina mediante un handsnake a due sensi. In pratica, sia il client che il server, possono decidere di terminare la comunicazione, inviando il flag FIN impostato a 1. L'host che invia il flag FIN effettua la chiusura attiva della connessione, mentre l'altro host effettua la chiusura passiva della connessione TCP. Mettiamo che il client invii FIN. Il server risponderà con un flag ACK, che starà ad indicare di avere ricevuto la richiesta di termine della connessione e, generalmente, invierà a sua volta un flag FIN, effettuando la chiusura passiva. Ma che cosa succede se il server non invia il flag FIN? In questo stato viene ancora mantenuta la connessione nell'altro senso. Questo stato di chiusura intermedia viene chiamato Half-Close. E' un evento che avviene raramente perché pochissime applicazioni TCP hanno bisogno di utilizzare questo tipo di chiusura. Una sessione TCP, pertanto, si può trovare in diverse condizioni, a seconda che la sessione stia per iniziare, sia iniziata o terminata. Durante una connessione, con il comando netstat -na si possono visualizzare tutti gli stati della sessione TCP. Ecco gli stati possibili: - LISTEN: l'host attende una richiesta di connessione da parte di qualsiasi host remoto; - SYN-SENT: l'host che si trova in questo stato, ha inviato una richiesta di connessione ad un host ricevente e sta aspettando la richiesta di ritorno per instaurare la connessione full-duplex; - SYN-RECEIVED: è lo stato dell'host ricevente che ha ricevuto ed inviato a sua volta una richiesta di conferma per la connessione e sta aspettando la conferma; - ESTABLISHED: significa che la connessione tra i due host è aperta; - FIN-WAIT1: è lo stato di attesa di una richesta di termine della sessione o di una conferma di una richiesta di termine della sessione precedente; - FIN-WAIT2: è lo stato di attesa per una richiesta di termine della sessione dall'host remoto; - CLOSE-WAIT; stato che rappresenta il lasso di tempo in cui la connessione TCP attende la richiesta di termine della sessione da parte dell'applicazione posta nel livello superiore dello stack TCP-IP; - CLOSING; è lo stato dell'attesa della conferma della richiesta di termine della connessione da parte dell'host remoto; - LAST-ACK: è lo stato dell'attesa della conferma della richesta di termine della connessione che l'host ha inviato all'host remoto; - TIME-WAIT: l'host è in attesa di chiudere la connessione, dopo l'invio della conferma della sua richiesta di termine della connessione; - CLOSED: la connessione tra i due host è terminata. 3.1.2 Il protocollo UDP RFC 768 E' un protocollo che permette una consegna non garantita, ma più veloce dei dati, trasmessi mediante l'invio di datagrammi. Una seconda caratteristica di tale protocollo è che l'host mittente, durante la trasmissione dei dati, non deve aprire una sessione con l'host di destinazione. Infatti si parla di di comunicazione senza connessione, per distinguerla dalla comunicazione con connessione del protocollo TCP. In questo caso il client effettuerà un'apertura attiva della porta, mentre il server effettuerà un'apertura passiva, ricevendo i dati senza comunicare l'avvenuta ricezione. La mancanza di questo meccanismo di controllo rende meno affidabile, ma sicuramente più veloce, la trasmissione dei dati. Pertanto, ogni applicazione che voglia utilizzare questo protocollo, come ad es. le applicazioni Realaudio, deve occuparsi di ritrasmettere i dati smarriti e di effettuare direttamente il controllo del flusso dei dati con un apposito buffer, evitando eventuali congestioni del flusso. Inoltre essa dovrà provvedere alla frammentazione e riassemblggio dei dati voluminosi. Con UDP è comunque possibile una verifica dell'integrità dei dati trasmessi e viene permesso l'invio dei dati in broadcasting e in multicasting, cosa non permessa al protocollo TCP. Ma come è fatto il datagramma UDP? Esso è composto da un header di 4 byte, contenente quattro campi, e un'area dati. I primi due campi indicano la porta sorgente e la porta destinazione del protocollo. Il terzo campo è il message lenght ed indica la lunghezza in byte del datagramma. Il campo di checksum o somma di controllo, utilizza la tecnica del complemento ad uno sull'header e sui dati per la verifica dell'integrità delle informazioni. L'area dati è di lunghezza variabile e contiene i dati che provengono dall'applicazione posta nel livello superiore. Nella trasmissione dei dati, l'host mittente non stabilisce una connessione con l'host ricevente, ma invia i datagrammi UDP dopo averli incapsulati in un datagramma IP. L'host ricevente, se avrà una porta in listening, accetterà il pacchetto eliminando l'incapsulazione IP. L'analisi del datagramma UDP permetterà all'host ricevente di verificare le informazioni del datagramma. Poiché il volume dei dati inviati tramite il protocollo UDP può essere elevata, i datagrammi UDP tendono ad essere frammentati in più pacchetti. Un controllo della velocità può essere effettuato con la produzione da parte dell'host server di datagrammi denominati "source quench", che non sono altro che ICMP di tipo 4; generalmente, la trasmissione dei dati inizia lentamente, per aumentare sempre più finchè il server non risponde con un messaggio soure quench. 3.2 I protocolli del Livello Internet 3.2.1 Il protocollo IP RFC 791 L'Internet Protocol (IP) è il principale protocollo utilizzato per la trasmissione dei dati in rete. Tutti i protocolli provenienti dal livello superiore dello stack, come TCP ed UDP, o provenienti dallo stesso livello, come i protocolli di controllo ICMP e IGMP, vengono incapsulati nei datagrammi IP e inviati nel livello inferiore, chiamato link layer, pronti per il successivo invio nella rete. Il pacchetto IP viene chiamato datagramma. Che cosa significa questo termine? Significa unità di dati autocontenente e, solitamente, specifica il tipo di consegna dei dati, per distinguerlo dalla trasmissione dei dati byte-stream. Pertanto, si può comprendere che il datagramma IP, pur utilizzando lo stesso metodo di trasmissione, è diverso dal datagramma UDP. Il datagramma IP contiene uno header e l'area dati. Quest'ultima, a sua volta consiste nel pacchetto incapsulato. L'header IP ha la lunghezza fissa di 20 byte. Ma ecco, di seguito, i campi dell'header. - Version number (VERS): campo di 4 bit che identifica la versione dell'IP usata per creare il datagramma. - Header lengh (HLEN): campo di 4 bit che specifica la lunghezza dell'header IP in parole di 32 bit. - Type of service (TOS): campo di 8 bit che specifica la priorità di consegna dei dati e le decisioni progettuali. Tuttavia, il TOS non viene supportato da parecchi host e router. Questo campo è a sua volta suddiviso in 5 sottocampi. Il primo sottocampo (precedence) viene utilizzato dalle applicazioni o dai protocolli per specificare l'importanza dei loro dati, mediante un valore che va da 0 a 7. Sebbene sia utile nel controllo delle congestioni in rete, viene scarsamente utilizzato. Il secondo sottocampo (delay), così come gli altri tre, definisce una priorità non generale come il primo, ma dipendente dalle applicazioni. Delay indica che si vogliono minimizzare i ritardi. Il terzo sottocampo (throughput) indica che si vuole massimizzare il throughput. Il quarto sottocampo (reliability) indica che si vuole massimizzare l'affidabilità. L'ultimo sottocampo (cost) indica che si vuole massimizzare il costo. - Packet length: campo di 16 bit che specifica la lunghezza totale dell'intero pacchetto IP. - Identification: campo di 16 bit, utilizzato per l'identificazione del datagramma IP quando questo viene frammentato. - Flags: campo di 3 bit utilizzato per il controllo della frammentazione. Se l'applicazione intende prevenire la frammentazione del datagramma, essa attiva il primo bit del campo. Tuttavia questo metodo viene scarsamente utilizzato poiché in caso di una sua attivazione che sia in contrasto con il MTU il pacchetto viene distrutto. L'ultimo bit del campo indica "altri frammenti". Questo bit viene attivato da IP in tutti i frammenti creati, eccetto l'ultimo frammento, che avrà valore uguale a 0. - Fragment offset: campo di 13 bit che indica la distanza o punto di rottura dall'inizio del datagramma in caso di frammentazione. Questo valore verrà utilizzato da IP per la ricostruzione dei frammenti. Dato che la lunghezza massima di un datagramma è di 65535, questo campo deve poter puntare in qualsiasi punto del pacchetto e deve poter contenere valori che vanno da 1 a 65535. - Time-to-Live (TTL): campo di 8 bit che indica quanto tempo potrà vivere il pacchetto durante il suo viaggio nella rete. Questo campo viene decrementato di un'unità ad ogni passaggio in un router. Il router che riceva un pacchetto scaduto prima del suo arrivo a destinazione, lo distruggerà ed invierà un pacchetto ICMP di avvertimento all'host mittente. - Protocol: campo di 8 bit che indica quale protocollo ha creato il pacchetto trasportato da IP. A titolo di esempio, il protocollo ICMP ha valore 1, l'IGMP 2, il TCP 6, mentre UDP 17. dell'header IP. La checksum non comprende l'area dati, il cui controllo di integrità viene gestito dal protocollo che ha creato il pacchetto. - Indirizzi IP di partenza e di arrivo: source IP address è un campo di 32 bit che contiene l'indirizzo IP dell'host mittente. Destination IP address è un campo di 32 bit che contiene l'indirizzo IP dell'host ricevente. - IP options: campo di 8 bit utilizzato per testare e correggere le applicazioni di rete. Questo campo è suddiviso in tre sottocampi: copia, classe opzione e numero opzione. Non tutti i router ed host supportano l'IP options. In rete si indica per MTU il valore di unità massima di trasferimento del pacchetto che si vuol trasferire. Quando un programma di rete cerca di inviare un pacchetto più grande della MTU di quella rete, esso viene frammentato in più parti. La frammentazione può avvenire anche durante il tragitto, se il router ha una MTU di rete più piccola di quella della rete da dove è partito il pacchetto. Come si è già detto, il riassemblaggio dei pacchetti avviene per mezzo dei tre campi Identification, Flags e Fragment Offset. 3.2.2 Il protocollo di controllo ICMP RFC 792 L'internet Control Message Protocol viene definito protocollo di basso livello, in quanto opera nello strato della rete, unitamente al protocollo IP. Tuttavia, pur operando nello stesso livello, anche ICMP si affida al protocollo IP per la trasmissione in rete dei propri pacchetti. Tutti i programmi che utilizzano l'ICMP devono creare un'interfaccia software particolarmente rudimentale, chiamata socket raw. Ma di cosa si occupa questo protocollo? L'ICMP svolge essenzialmente due compiti: il primo è di trasportare i messaggi d'errore della rete; il secondo è di trasportare i messaggi di richiesta, i quali contengono sia richieste di informazione che risposte, relative sia alla rete che all'host. La progettazione di ICMP fu resa necessaria dal fatto che il protocollo IP non contemplava la possibilità di fornire notifiche di errori nel trasporto dei dati. I progettatori decisero di semplificare l'attività di IP e di affidare questo compito al nuovo protocollo ICMP, con alcuni limiti. Infatti ICMP non è in grado di risolvere i problemi scaturiti durante il trasporto dei dati, e non può comunicare il verificarsi di un errore ai router intermedi, ma solo all'host che ha generato il pacchetto. Una particolarità che è utile menzionare è che un messaggio di errore non può generare altri messaggi di errore. Ciò evita la produzione di messaggi a catena, che provocherebbero le cosiddette "tempeste broadcast). Ma ecco la descrizione del pacchetto ICMP. L'header ICMP è formato da tre campi, di cui due a 8 bit e il terzo a 16 bit, per un totale di 32 bit. Il pacchetto che contiene ICMP comprende inoltre l'header IP con i primi 8 byte di dati del datagramma che ha generato l'errore (se si tratta di messaggi di errore) o con i dati contenenti il messaggio di richiesta. Ciò avviene perché il pacchetto del protocollo ICMP, per il trasporto nella rete, viene incapsulato in un datagramma IP. Il primo campo contiene il valore Type ed è di 8 bit. Questo valore indica i 15 tipi diversi di messaggio ICMP. Il secondo campo contiene il valore Code ed è anch'esso di un byte (1 byte= 8 bit). Questo valore contiene i codici o le categorie esistenti per ogni messaggio. Ad esempio, l'ICMP di tipo 3 è un messaggio di errore che significa destinazione irraggiungibile. Questo messaggio comprende a sua volta 16 diverse categorie che contemplano i vari tipi di errore per una destinazione irraggiungibile. Il terzo campo da 2 byte, contiene il valore Checksum. Ma ecco una tabella riassuntiva. Tipo 0 messaggio di richiesta descrizione: risposta echo Tipo 3 messaggio di errore descrizione: destinazione irraggiungibile Tipo 4 messaggio di errore descrizione: estinzione della fonte Tipo 5 messaggio di errore descrizione: reindirizzamento Tipo 8 messaggio di richiesta descrizione: echo Tipo 9 messaggio di richiesta descrizione: annuncio al router Tipo 10 messaggio di richiesta descrizione: sollecito al router Tipo 11 messaggio di errore descrizione: tempo superato Tipo 12 messaggio di errore descrizione: problema dei parametri Tipo 13 messaggio di richiesta descrizione: richiesta di un timestamp Tipo 14 messaggio di richiesta descrizione: invio di un timestamp Tipo 15 messaggio di richiesta descrizione: rich. informazioni (obsoleto) Tipo 16 messaggio di richiesta deccrizione: invio informazioni (obsoleto) Tipo 17 messaggio di richiesta descrizione: rich. maschera d'indirizzo Tipo 18 messaggio di richiesta descrizione: invio maschera d'indirizzo Come si può vedere, ICMP comprende 5 messaggi di errore e 10 messaggi di richiesta. Specifichiamo i vari messaggi. - MESSAGGI DI ERRORE 1) errori di destinazione irraggiungibile (tipo 3) Lo scopo principale del protocollo ICMP è proprio il messaggio di errore del tipo 3, cioè destinazione irraggiungibile. Questa peculiarità di ICMP serve per ovviare al fatto che il protocollo IP non garantisce la consegna dei datagrammi. Questo messaggio di errore viene prodotto dal router ed inviato all'host sorgente ogni volta che non gli è possibile consegnare il pacchetto dei dati. L'impossibilità di consegna dei dati può dipendere da un problema nel trasferimento dei dati o da un problema di routing. Nel primo caso il codice di errore è di host irraggiungibile, mentre nel secondo caso viene prodotto un codice di errore di rete irraggiungibile. I codici di errore per l'ICMP di tipo 3 sono 16: codice 0: rete irraggiungibile codice 1: host irraggiungibile codice 2: protocollo irraggiungibile codice 3: porta irraggiungibile codice 4: necessaria frammentazione e disattivazione del bit "don't fragment" codice 5: tragitto di origine fallito codice 6: rete di destinazione sconosciuta codice 7: host di destinazione sconosciuto codice 8: host di origine isolato (non più usato) codice 9: rete di destinazione vietata dall'amministrazione codice 10: host di destinazione vietato dall'amministrazione codice 11: rete irraggiungibile per il tipo di servizio (TOS) codice 12: host irraggiungibile per il tipo di servizio (TOS) codice 13: comunicazione proibita dall'amministrazione tramite filtri codice 14: violazione della precedenza da parte dell'host codice 15: scorciatoia in vigore 2) Errori di indirizzamento (tipo 5) Essi vengono prodotti dai router. Ogni router di una rete fisica ha il compito di indirizzare i pacchetti verso l'hop successivo del percorso, seguendo la via più breve. Esso ha una propria tabella di routing in cui vengono memorizzate le informazioni sui percorsi ottimali verso una rete di destinazione. La tabella di routing viene costantemente aggiornata mediante un continuo scambio di informazioni tra i router. Quando un computer host invia dei dati in rete utilizzando un percorso non ottimale, il router che è situato nel primo nodo dove inizia il percorso non ottimale informa l'host di ciò con un messaggio di errore di indirizzamento del tipo 5. Questi messaggi di reindirizzamento possono essere inviati solo dai router. I codici di errore per gli ICMP di tipo 5 sono 4: codice 0: reindirizzamento per rete codice 1: reindirizzamento per host codice 2: reindirizzamento per tipo di servizio (TOS) e rete codice 3: reindirizzamento per tipo di servizio (TOS) e host 3) Errori di superamento del tempo (tipo 11) Gli header dei datagrammi IP contengono un campo che definisce la vita del pacchetto. Questo campo è chiamato "time to live" (TTL). Se il TTL raggiunge lo zero, il software di rete scarta il pacchetto ed invia all'host sorgente un messaggio di errore. Esistono due codici di errore per questo tiipo di messaggio. Il codice 0 indica che il TTL ha raggiunto lo 0 durante il passaggio. In genere ciò è dovuto ad un errore nelle tabelle di routing che produce un ciclo di routing, cioè un ciclo di loop continui tra due router che si scambiano lo stesso pacchetto, aspettandosi che l'altro router si incarichi dell'hop. Il codice 1, invece, indica che il timer di riassemblaggio dei frammenti di un host ha raggiunto il suo limite prima che tutti i frammenti fossero giunti. Infatti, quando l'host client invia un datagramma contenente il flag "More Fragment" settato, l'host di destinazione innesca un timer per il riassemblaggio, entro il quale tutti i frammenti devono giungere, pena lo scarto dei frammenti. 4) errori relativi a problemi dei parametri (tipo 12) Questo tipo di errore può essere generato dall'host ogni qualvolta ci sia una condizione di errore sconosciuta o quando un datagramma non contiene tutte le informazioni richieste dal protocollo. Nel primo caso l'ICMP di tipo 12 avrà il codice 0 ( cattivo header IP), mentre nel secondo caso avrà il codice 1 (opzione richiesta mancante) 5) errori di estinzione della fonte (tipo 4) I protocolli orientati alla connessione come TCP contengono un controllo del flusso dei dati, per impedire l'intasamento del buffer dell'host server. Un protocollo non orientato alla connessione, come IP, è privo di questo controllo del flusso. Poiché i router utilizzano datagrammi IP, senza un adeguato controllo del flusso dei dati, essi si potrebbero intasare, congestionando a sua volta il traffico di rete. Quando si crea una congestione, i router iniziano a scartare i pacchetti ed inviano questo tipo di messaggio di errore, informando l'host mittente che è necessario rallentare la velocità del flusso. Questo tipo di ICMP contiene un solo codice, settato a 0. MESSAGGI ICMP DI RICHIESTA 1) Richieste ai router (tipi 9 e 10) Come specificato nella RFC 1256, il protocollo ICMP effettua due tipi di richiesta al router: il messaggio di sollecito al router (tipo 10) e il messaggio di annuncio del router (tipo 9). Innanzi tutto è bene ricordare che lo smistamento dei pacchetti si chiama routing. Gli host preposti allo smistamento di questi pacchetti si chiamano router (o anche gateway). Il routing può essere diretto od indiretto: nel primo caso il routing avviene tra due host connessi direttamente alla stessa rete o sottorete; nel secondo caso, i dati vengono trasmessi ad almeno un router, cioè un host che si occupa del successivo smistamento ad un altro router o all'host ricevente. Ogni router ha una sua tabella di routing, che non è altro che una tabella, contenente tra le altre cose, una serie di indirizzi di destinazioni successive, con a fianco un valore numerico (metrica) che indica la qualità della destinazione. La tabella di routing può essere statica e descritta in un file o dinamica. Ora possiamo tornare ai messaggi ICMP di richiesta al router. Il messaggio di sollecito viene prodotto dall'host al suo avvio, e la risposta del router viene chiamato messaggio di annuncio. Il messaggio di annuncio viene utilizzato dall'host per inizializzare dinamicamente la propria tabella di routing, in modo da non dover utilizzare un file statico come tabella. La particolarità del messaggio di annuncio è che il router può inserire nel pacchetto ICMP più di un indirizzo di router. Ogni indirizzo di router è corredato di un campo, chiamato Preference Level, che indica all'host ricevente quale router utilizzare per primo o con maggior frequenza. Questo pacchetto contiene anche il campo Timelife, che indica il numero di secondi per cui l'indirizzo rimane valido, che di norma è di 1800 secondi. 2) Richieste di timestamp (tipi 13 e 14) Questi tipi di richieste permettono di misurare il tempo impiegato dai pacchetti nel passare da un host a un altro. Questo datagramma contiene due campi particolari: il campo identificatore ed il numero di sequenza. Questi campi vengono utilizzati per distinguerli tra le varie richieste di timestamp che, generalmente, vengono utilizzate per analisi statistiche del tempo di trasferimento. 3) Richieste di maschera di indirizzo (17 e 18) La richiesta di maschera di indirizzo viene generalmente utilizzata da una workstation senza disco per poter ottenere la propria maschera di sottorete. La richiesta viene effettuata in broadcast e gli host in rete risponderanno con un datagramma contenente l'invio della maschera di indirizzo. I campi del datagramma ICMP di tipo 17 e 18 sono gli stessi del datagramma timestamp. 4) Messaggi di richiesta e risposta echo (tipi 0 e 8) Questo tipo di messaggio ICMP viene utilizzato da programmi come ping (packet internet grouper) per verificare se l'host di destinazione è raggiungibile e per misurare il tempo che la richiesta di echo impiega a tornare. L'ICMP di tipo 0 viene inviato dall'applicazione verso l'host di destinazione e questi risponde con un messaggio di tipo 8. L'utilizzo di questo tipo di ICMP è utile per la verifica della connettività. Per la conferma che i protocolli TCP/IP sono stati installati correttamente, generalmente si effettua un ping al proprio host, mediante l'utilizzo dell'indirizzo di riciclo o loopback, che è 127.0.0.1. Se il pacchetto torna indietro, i protocolli sono installati correttamente. Un ping all'indirizzo IP assegnato al proprio host, invece, ci permette di verificare la corretta configurazione di questo IP sul proprio host. Un ping all'indirizzo IP di gateway predefinito della propria rete, ci permette di verificare la corretta configurazione della maschera di sottorete. E' evidente che in una buona configurazione dei firewall a filtro di pacchetti, deve essere permessa la ricezione di pacchetti ICMP di errore di tipo 3, mentre è utile bloccare gli ICMP di tipo 0 e 8. 3.2.3 Il protocollo IGMP RFC 1112 Una piccola premessa per ricordare che gli indirizzi IP si distinguono in unicast, broadcast e multicast. Gli indirizzi di classe A, B e C si dicono indirizzi unicast, in quanto sono assegnati ad un singolo host. L'Internet Network Information Center (InterNIC) ha il compito di garantire che ogni rete abbia un identificatore univoco. Questo ente utilizza gli indirizzi di classe D per indirizzi di tipo multicast. Quando i pacchetti inviati da un host mittente devono raggiungere più host destinatari, si possono utilizare due metodi di trasmissione: la trasmissione broadcasting, e la trasmissione multicasting. Il metodo broadcasting comporta che il pacchetto di dati venga analizzato da tutti gli host della rete, i quali verificheranno che esso non sia destinato a loro. Il problema è che diversi router sono configurati per non inoltrare i pacchetti con la modalità broadcasting. Il metodo di trasmissione multicasting, invece, permette di specificare come destinazione uno specifico gruppo di host, evitando che i pacchetti debbano essere analizzati da tutti i router della rete. I dati multicast vengono trasmessi mediante datagrammi UDP. Gli host possono entrare od uscire dinamicamente da questi gruppi multicast. Quando ne fanno parte, assumono degli indirizzi IP di classe D, che vanno da 224.0.0.1 a 239.255.255.255. Se viene indicato come destinazione l'indirizzo IP 224.0.0.1, significa che il gruppo broadcast è formato da tutti gli host e i router che partecipano a un multicasting IP su una sezione della rete. Il pacchetto IGMP è formato da cinque campi. - Version: campo che indica la versione del protocollo utilizzato. Con IGMP è settato sul valore di 1 - Type: può avere due valori; il valore 1 significa che il messaggio IGMP è il prodotto di un'interrogazione di un router multicast; il valore impostato a 2 significa che il pacchetto origina da una risposta di un host IP - Checksum: campo che contiene un valore numerico corrispondente alla somma di controllo, per la verifica dell'integrità del dato. - Group address: campo che contiene l'IP del gruppo di host multicast. Questo tipo di protocollo viene utilizzato generalmente da applicazioni interattive, che permettono di fare arrivare le informazioni a più host. L'Internet Assigned Number Autority (IANA) assegna alcuni indirizzi multicast come indirizzi noti, i quali rappresentano gruppi di host permanenti. A causa di un bug nello stack TCP/IP nelle piattaforme win95/98, i pacchetti IGMP frammentati possono essere utilizzati per effettuare attacchi D.o.S. Recentemente è stata rilasciata dalla Microsoft una patch che risolve il problema. 3.2.4 Il protocollo ARP RFC 826 L'Address Resolution Protocol è un protocollo che viene utilizzato per risolvere un indirizzo IP di un host client nel relativo indirizzo MAC. No, nulla a che vedere con la gloriosa casa Apple. Il MAC (media access control) è l'indirizzo fisico dell'host, detto anche indirizzo hardware della scheda di rete. Il processo in cui opera tale protocollo è il seguente: innanzi tutto il client verificherà se il server fa parte della stessa rete o di una rete remota; l'indirizzo IP del server sarà confrontato con la maschera di sottorete del client mediante il processo di messa in AND. Gli indirizzi IP dell'origine e della destinazione sono confrontati con la maschera di sottorete dell'origine. Se il server si trova nella stessa rete avverrà qwuanto segue: l'host client, prima di inviare i dati al server, controlla nella propria cache ARP se vi sia l'indirizzo del server. In caso negativo, il client invia un pacchetto ARP al server, con il quale chiede l'indirizzo MAC di quest'ultimo. Nel pacchetto, il client inserisce il proprio IP e indirizzo MAC, che andranno nella cache ARP del server. Il pacchetto è inviato all'indirizzo broadcast e, quindi, a tutti gli host del segmento i quali esamineranno il pacchetto. Gli host a cui non è diretto il pacchetto, lo ignoreranno dopo averlo esaminato. L'host a cui è destinato il pacchetto, inserirà le informazioni nella propria cache ARP ed invierà il proprio indirizzo MAC all''host mittente. Dopo questo passaggio, può avere inizio la comunicazione tra il client ed il server. Quando il server si trova in una rete remota, il client controllerà nella propria cache ARP se ha l'indirizzo MAC del router predefinito. In caso negativo, esso invierà un pacchetto ARP contenente il proprio indirizzo IP e indirizzo MAC, con il quale richiederà l'indirizzo MAC del router. Quindi invierà il pacchetto al router. Il processo è identico, da router a router, fino al server. Il pacchetto ARP si compone di 9 campi. - Hardware type: campo che indica il tipo di hardware usato nella rete - Protocol type: campo che indica il tipo di indirizzo di protocollo - Hardware address lenght: campo che indica la lunghezza in bit dell'indirizzo hardware - Protocol Address Lenght: campo che indica la lunghezza dell'indirizzo di protocollo - Op code: campo che indica se il pacchetto è una richiesta od una risposta ARP - Sender's hardware Address: campo che indica l'indirizzo hardware dell'host mittente - Sender's Protocol Address: campo che indica l'indirizzo IP dell'host mittente - Target's Hardware Address: campo che indica l'indirizzo hardware dell'host destinatario - Target's Protocol Addres: campo che indica l'indirizzo hardware dellìhost destinatario 4 Il livello delle applicazioni e i socket 4.1 Le applicazioni socket Immediatamente soprastante a tale livello, nello strato dell'applicazione lavorano le applicazioni che si possono suddividere in due categorie: - applicazioni socket - applicazioni netbios Le applicazioni socket sono dei programmi di rete (ftp, telnet ecc.) che utilizzano le API socket. Le applicazioni NetBios utilizzano altri tipi di API per comunicare e condividere i dati tra due host remoti. Questa nota è improntata alla descrizione delle applicazioni socket, e quindi non parlerò del NetBios. 4.1.2 Definizioni Socket: quando due host si scambiano dati sulla rete, i due capi in cui avviene la comunicazione si dicono punti di arrivo; i socket sono i punti di arrivo tra due computer che comunicano in rete. Secondo una convenzione, definita modello client-server, i programmi che comunicano in rete, a seconda che inviino o ricevino i dati, si distinguono rispettivamente in programmi client e programmi server. Pertanto in una comunicazione ci saranno due socket, uno nel lato client e uno nel lato server. Tecnicamente su usa pure dire che un socket è una rappresentazione astratta di un punto di arrivo. Le API (Application Program Interface), sono un gruppo di funzioni o interfacce software utilizzate dai programmatori per sviluppare applicazioni in determinati ambienti. L'API socket quindi si può definire come un'interfaccia tra le applicazioni che comunicano in rete e lo stack di protocolli TCP-IP. 4.1.3 Storia del socket Ed ora, consentitemi una piccola digressione sull'interfaccia socket. Negli anni '80, sull'onda del rapido sviluppo di internet, su richiesta dell'ARPA, gli uomini dei laboratori dell'università di Berkeley, svilupparono un software particolare che interfacciava tutte le applicazioni di rete che giravano sul sistema operativo Unix, con i protocolli TCP-IP. Essi progettarono un programma d'interfaccia, denominato API socket, chiamato anche socket Berkeley, che si implementava con i protocolli TCP-IP su macchine Unix. Anche win ha le sue API sockets, chiamate windows sockets o anche winsock. Le funzioni del winsock sono praticamente le stesse di quelle dei socket Berkeley, ma implementano una serie di funzioni specifiche per l'utilizzo sotto windows. Si dice che il winsock è progettato come un componente WOSA (Windows Open Service Architecture). Nel 1991 nacque il Winsock Group, una società formata da produttori e sviluppatori di applicazioni per le reti e di software per sistemi operativi windows. Nel 1993 fu prodotto WinSock versione 1.1, che permetteva l'utilizzo di applicazioni a 16 bit. Dopo il rilascio di windows 95, sono state pubblicate le specifiche delle Windows Sockets versione 2.0, a 32 bit, con nuove funzionalità. Oggi siamo alle 2.2. Diversamente dalla versione 1.1, che era focalizzata interamente progettato sul TCP/IP, la nuova API è indipendente dal protocollo di trasporto. Il winsock32.dll consiste di due interfacce standard , una tra il winsock stesso e le Application Programming Interface (API), l'altra tra il WinSock e i service providers, Service Providers Interface (SPI). All'interno delle Windows Sockets 2 sono inseriti TCP/IP, IPX/SPX, OSI e altri protocolli minori. 4.2 Elementi costitutivi 4.2.1 Tipi di socket Il funzionamento del socket non è particolarmente complesso, ma per capirlo ci sono alcuni termini che dovrete memorizzare. Ogni socket host è costituito da cinque elementi informativi: il protocollo utilizzato, l'indirizzo IP dell'host locale o client, l'indirizzo IP dell'host remoto o server, una porta di protocollo per il processo client e una porta di protocollo per il processo server. Il protocollo utilizzato, permette di distinguere i programmi client o server orientati alla connessione o programmi client o server non orientati alla connessione. I client o server orientati alla connessione utilizzano un protocollo di trasmissione affidabile, come il Tcp, mentre quelli non orientati alla connessione si servono di protocolli la cui trasmissione non è garantita, come IP e UDP. Quanto abbiamo detto sopra, ci permette di distinguere i tipi di comunicazione che vengono definiti in tutto dall'interfaccia socket. - Comunicazione di rete orientata alla connessione: I dati viaggiano in un unico flusso di byte (byte-stream); nel linguaggio di programmazione, si dice che l'interfaccia (API) socket utilizza la costante simbolica SOCK_STREAM ed si avvale del protocollo TCP. - Comunicazione senza connessione: I dati viaggiano in pacchi ben distinti (datagrammi). L'API socket utilizza, in questo caso, la costante simbolica SOCK_DGRAM e usa il protocollo UDP. Oltre ai due tipi di comunicazione sopra descritti, esistono altri tre tipi di comunicazione dell'API socket. - Comunicazione raw socket: Il terzo tipo, più rudimentale, viene chiamato "raw socket", da raw=grezzo. L'API socket utilizza la costante simbolica SOCK_RAW. Un raw socket viene normalmente utilizzato dal programma per poter adottare protocolli diversi da TCP e UDP. Nel modello dello stack dei protocollo TCP-IP, è come dire che il raw socket mette in comunicazione direttamente il livello delle applicazioni con il livello di rete, saltando il livello del trasporto. Un esempio di tale tipo di comunicazione è quando un'applicazione crea un socket raw per gestire l'ICMP, un protocollo di controllo di basso livello, che opera nello strato della rete, come IP e IGMP. Per chi si vuole dilettare nella creazione dei pacchetti, è opportuno ricordare che i winsock inferiori alla versione 2.0 non contemplano la comunicazione raw socket, mentre le versioni successive la supportano con diverse limitazioni. Questa limitazione non esiste, invece, per i socket unix che utilizzano normalmente i raw socket. Sotto win, un uso meno limitato della comunicazione socket raw puo' essere effettuato utilizzando un winsock diverso da quello di default fornito dalla Microsoft, ad esempio usando il Trumpet Winsock, versione 3.0d che però, a detta di alcuni esperti, rende il sistema instabile in alcune situazioni. 4.2.2 Altri tipi di socket Gli ultimi due tipi di socket, sono: - socket di pacchetto in sequenza: SOCK_SEQPACKET - socket di messaggio consegnato affidabilmente (non implementato): SOCK_RDM. Dei due tipi di socket, solo il primo viene utilizzato raramente, mentre il secondo non è implementato, e vengono qui citati solo per completezza di esposizione. 4.3 Funzionamento del socket Ora passiamo ad una breve descrizione tecnica di ciò che avviene quando un programma comunica con un altro in rete. Credo che ciò sia utile anche per chi non si intende di programmazione, se non altro perchè potrà fornirgli l'input a sviluppare i concetti qui espressi. Per costoro, è utile almeno riassumere quanto segue. 4.3.1 Definizioni del linguaggio C/C++ Nel codice sorgente di un programma possono esistere delle sezioni di codice distinte, che sono chiamate funzioni. Le funzioni hanno un nome, un valore o argomento e un tipo di restituzione. Le funzioni possono essere chiamanti o chiamate. Le funzioni chiamanti sospendono l'esecuzione della sezione di codice in esse contenuto in seguito ad una chiamata di funzione. Ciò permetterà l'esecuzione della sezione di codice della funzione chiamata. Per fare un esempio, un nome di una funzione che vedremo più avanti è "socket". I valori (cioè argomenti o chiamati anche parametri) della funzione sono facoltativi, e sono indicati all'interno di una coppia di parentesi tonde, poste dopo il nome della funzione. Nel caso di una chiamata ad una funzione che, ad esempio, ha nome "che_palle()", con le parentesi prive di contenuto, avremmo una funzione priva di argomenti. Il tipo di restituzione dice al compilatore (programma che traduce il sorgente in codice macchina) che tipo di dati la funzione chiamata restituisce alla funzione chiamante. Variabile: è la rappresentazione che il linguaggio di programmazione usa per definire dei dati, che possono essere numeri o stringhe di caratteri. Quando ad una variabile non è stato assegnato un valore, si dice che la variabile non è stata inizializzata. Ad una stessa variabile possono essere assegnati valori diversi. Header file o file d'intestazione: è un file che contiene delle definizioni d'interfaccia di classe e/o dichiarazioni di funzione. Ha estensione .h. Un esempio è il file iostream.h che, tra le altre cose, dice al compilatore come utilizzare i comandi di imput ed output (<< >>). Quando nel sorgente l'header è compreso in due parentesi acute () significa che il file si trova nella directory predefinita dal compilatore. Se invece l'header è compreso in due doppi apici ("vector.h"), significa che esso si trova nella stessa directory del file sorgente. Puff, pant. Se volete un corso di C alla Bignami avete sbagliato tutorial ma, soprattutto, avete riposto troppa fiducia nell'autore. 4.4 Le chiamate alle funzioni Ora veniamo ai dettagli. Se utilizziamo un programma di rete (browser web, ftp), questo viene definito come programma client. Quando un programma client vuole comunicare con un programma server in rete, il client si limita a creare un'interfaccia socket, chiamando la funzione "socket()", con tre parametri: int socket( int famiglia, int tipo, int protocollo ). A questo punto, l'applicazione, prima di poter utilizzare il socket creato, deve prima configurarlo nella giusta maniera. Se ricordate ciò che abbiamo detto più sopra, possiamo raggruppare i socket in due tipi principali: quelli connessi e quelli non connessi. Il metodo di configurazione, pertanto, varia a seconda del tipo di socket. 4.5 Comunicazione di rete orientata alla connessione Se il programma client utilizza il protocollo TCP si dice che è orientato alla connessione. L'applicazione crea inizialmente un socket, con la chiamata alla omonima funzione. Per la configurazione del socket, il programma chiama una seconda funzione, definita "connect()". Ma procediamo con ordine e vediamo come sono strutturate le funzioni chiamate. 4.5.1 Funzione Socket() La funzione socket contiene i parametri che specificano la famiglia di protocolli (protocol_family), il tipo di socket (socket_type) e il protocollo utilizzato (protocol_type). Definiamo i tre parametri. Protocol_family: l'interfaccia socket puo effettuare comunicazioni su più tipi di reti e, quindi, può utilizzare diversi protocolli come TCP/IP, XNS ed i protocolli interni di unix. XNS è uno stack di protocolli simile a TCP/IP, sviluppato dai laboratori Xerox, che viene implementato nelle reti Netware di Nowell e VINES di Banyan. Questo parametro comprende quindi delle costanti simboliche per definire la famiglia di protocolli supportata. Quella utilizzata per le comunicazioni internet è la costante simbolica PF_INET, che identifica lo stack TCP/IP. PF_UNIX identifica la famiglia di protocolli interni di unix, i quali vengono utilizzati per le comunicazioni interne tra i vari processi del s.o.; PF_NS identifica la famiglia di protocolli XEROX. Quando il parametro identifica non le famiglie di protocolli, ma le famiglie di indirizzi, i quali variano da rete a rete, esso utilizza le stesse costanti simboliche con il prefisso AF_ al posto di PF. Pertanto avremo AF_INET, AF_UNIX e AF_NS. Socket_type: come abbiamo già visto esistono cinque tipi di socket, dei quali solo tre sono comunemente implementati: SOCK_STREAM, che indica che verrà utilizzato la comunicazione byte stream; SOCK_DGRAM che indica che verrà utilizzata la comunicazione con invio di datagrammi; SOCK_RAW, che indica che verrà utilizzato un protocollo di basso livello, come ICMP e IGMP. Protocol_type: la costante simbolica viene specificata con un prefisso IPPROTO_ seguita dal tipo di protocollo: ad es. IPPROTO_UDP, IPPROTO_TCP ecc. 4.5.2 Funzione connect() Questa funzione contiene tre parametri: socket_handle, remote_socket_address e address_lenght. Come si può notare, anche intuitivamente, dai nomi dei parametri, è' la funzione connect a memorizzare le informazioni del punto di arrivo locale e di quello remoto. In questo caso, il protocollo utilizzato permette una connessione diretta con il server, attraverso l'invio di dati byte-stream. Anche il programma server, dopo un procedimento analogo di creazione del socket, chiama alcune funzioni: 4.5.3. Funzione bind() La prima, relativa alla configurazione delle informazioni locali, è chiamata funzione "bind()"; il socket del server viene informato su quale porta deve stare in ascolto da questa funzione. Una piccola digressione sulla funzione bind(). La chiamata a bind può essere utilizzata in 3 modi diversi: 1. I server registrano il loro indirizzo, ben noto, nel sistema. In pratica dicono al sistema: "Questo è il mio indirizzo e qualsiasi messaggio ricevuto ad esso indirizzato deve essere consegnato a me!". Questa procedura deve essere fatta prima di accettare richieste da un client sia dai server orientati alla connessione sia da quelli che non lo sono. 2. Un client può registrare un indirizzo specifico per se stesso, in modo che il server risponda alle richieste su quel indirizzo. 3. Un client senza connessione deve accertarsi che il sistema assegni un certo indirizzo unico, affinchè l'altra estremità abbia un indirizzo di ritorno valido su cui inviare le risposte. Terminata la digressione, definiamo i parametri. I parametri sono: ( int sockfd, struct sockaddr*mioindir, int lunghindr). 1. sockfd: descrittore di socket precedentemente creato con la chiamata di sistema socket. 2. mioindr: è un puntatore all'indirizzo specifico della struttura del protocollo. 3. lunghdir: dimensione della struttura del protocollo. Come? Ah, c'è qualcuno che non conosce le definizioni descrittore e puntatore? Puntatore: è un indirizzo di memoria associato ad un tipo di dato, dove l'associazione viene indicata con il simbolo *. Es: Tipo_di_dato*puntatore Descrittore: E' un tipo particolare di puntatore. In C, uno dei modi per manipolare il contenuto di un file consiste nell'aprire uno stream, cioè un "canale di flusso" col file stesso mediante un'apposita funzione, che restituisce il puntatore ad una struttura i cui campi sono utilizzati poi da altre funzioni, per compiere operazioni sul file stesso. Tale puntatore è detto "descrittore" del file. Se qualcuno non ha capito nulla, ecco un altro esempio di ripasso: (Borland C++ 3 ed. Apogeo, lire 64 mila)*puntatore. Le altre due chiamate, relative alle informazioni remote sono le funzioni "listen()" e "accept()". 4.5.4 Funzione listen() Questa chiamata di sistema è usata da un server orientato alla connessione per indicare che è disposto a ricevere le connessioni, cioè si trova in stato di attesa. Solitamente è eseguita dopo le chiamate di sistema socket e bind ed immediatamente prima della chiamata accept. Quando arrivano più richieste di connessione, il server usa la funzione listen() per gestire le richieste multiple e simultanee per il socket. I parametri sono: int listen( int sockfd, int backlog ); 1. sockfd: descrittore di socket precedentemente creato con la chiamata di sistema socket. 2. backlog: specifica il numero di richieste di connessione che possono essere accodate dal sistema mentre è in attesa che il server esegua la chiamata accept. 4.5.5 Funzione accept() Dopo che un server orientato alla connessione ha eseguito la chiamata di sistema listen, si pone in attesa di una eventuale connessione da parte di un processo client. La chiamata accept prende in esame la richiesta di connessione che si ha in testa alla coda specificata dalla listen e crea un altro socket con le stesse propietà di socketfd. Se non ci sono richieste di connessione in sospeso, questa chiamata blocca il chiamante finche non ne arriva una. Le funzioni sono: int accept( int sockfd, struct sockaddr *pari, int lunghindir); 1. sockfd: Descrittore di socket fd. 2. lunghindr:Contiene la lunghezza della struttura dell'indirizzo del processo connesso (client). Il lunghindir viene prima posto uguale alla dimensione della struttura e succesivamente prende il valore della dimensione della struttura effetivamente occupata dal client connesso. Il programma client, per instaurare la classica trasmissione handsnake a tre vie, a sua volta chiamerà la funzione "write()" per trasmettere i dati e la funzione "read()" per ricevere i dati di risposta a una porta specifica che verranno inviati dal server. A questo punto, il server chiamerà anch'esso le funzioni read() e write(), rispettivamente per ricevere e rispondere. 4.6 Comunicazione di rete non orientata alla connessione Se il programma client non è orientato alla connessione, per configurare le informazioni locali esso chiama la funzione "bind" e la funzione "sendto" per la configurazione delle informazioni remote. Dato che il socket è senza connessione, non viene effettuata la chiamata alla funzione connect. A sua volta, il programma server senza connessione ascolterà passivamente i dati che giungeranno dalla porta di protocollo e chiamerà la funzione "bind" per le informazioni locali e la funzione "recvfrom" per le informazioni remote. Quando giungeranno i dati dal client, il server trasmetterà dati in risposta con la stessa funzione sendto ed il client riceverà tali dati utilizzando la chiamata alla funzione recvfrom (invece di recv o read), esattamente come avviene nel server. In questo tipo di comunicazione, il protocollo utilizzato non permette una connessione diretta tra il programma client ed il programma server, cioè una connessione detta point-to-point tra due punti di arrivo. Come abbiamo già visto, i dati vengono trasmessi mediante l'uso dei datagrammi. 4.7 Riepilogo Ricapitolando, terminata la fase della configurazione, durante la trasmissione dei dati l'API del socket chiamerà cinque diverse funzioni: send, write, writev, sendto e sendmsg. Le prime tre funzioni sono utilizzate solo da socket orientati alla connessione. In particolare, la funzione send contiene quattro parametri e contiene alcuni flag particolari usati per controllare il socket (socket_handle, message_buffer, buffer_lenght e special_flags). La funzione write trasmette i dati utilizzando un semplice buffer e contiene generalmente tre funzioni (socket_handle, message_buffer e buffer_lenght). La funzione writev trasmette i dati utilizzando memoria non contigua come buffer per i dati e contiene tre funzioni (socket_handle, io_vector e vector_lenght). Le ultime due funzioni vengono usate dall'API del socket non connesso. In particolare, la funzione sendto utilizza un semplice buffer per i messaggi e contiene sei parametri (socket_handle, message_buffer, buffer_lenght, special_flags, socket_address_structure e address_structure_lenght). La funzione sendmsg trasmette i dati utilizzando una struttura dei messaggi flessibile come buffer dei dati e contiene tre parametri (socket_handle, message_structure e special_flags). Ecco uno specchietto con le corrispondenze tra le funzioni di trasmissione e le funzioni di ricezione nell'API socket: funzione di trasmissione / funzione di ricezione - send recv - write read - writev readv - sendto recvfrom - sendmsg recvmsg Ed ecco pure uno specchietto delle varie chiamate dei due tipi di socket: - socket con protocollo orientato alla connessione Server=socket-bind-listen-accept--read-write | | Client=socket-connect-write-read - socket con protocollo non orientato alla connessione Server=socket-bind-recvfrom--sendto | | Client=socket-bind-sendto-recvfrom A tutte le funzioni sopra espresse, bisogna aggiungere un'ultima funzione: Select(): è solitamente usata dai programmi server o da programmi client particolarmente sofisticati e permette ad un singolo progesso di verificare lo stato di più socket. Richiede cinque parametri e sono: select(number_sockets, readable_sockets, writeable_sockets, error_sockets, max_time). 4.8 Il winsock Non ci sono grandi differenze di caratteristiche tra il socket Berkeley e il Winsock. Le principali sono: 1. Il socket windows implementa l'API del socket in una libreria con estensione dll, chiamata winsock.dll. 2. Winsock, oltre alle funzioni già definite con il socket Berkeley, richiede sempre la chiamata a due funzioni specifiche: WSAStartup e WSACleanup. WSAStartup() è una funzione chiamata dal programma durante una negoziazione tra il programma stesso e winsock.dll. Il programma specifica le caratteristiche minime richieste al winsock ed il winsock risponde specificando le proprie funzionalità. In pratica questa funzione serve al programma per specificare quale versione dell'API winsock necessita. WSAStartup può essere chiamata diverse volte durante l'attività del programma, ad esempio per fornire le caratteristiche dell'implementazione. A ogni chiamata viene incrementato un contatore delle chiamate. WSACleanup() è una funzione che viene chiamata dal programma per decrementare il contatore delle chiamate alla funzione WSAStartup. 3. In un errore nel socket, l'API Berkeley utilizza la funzione errno() con il valore a -1, mentre il winsock definisce una nuova costante, chiamata Socket_Error, il cui valore è -1; il programma chiamerà quindi la funzione WSAGetLastError, che verificherà la causa che ha provocato l'errore nel winsock. 4. A differenza di quanto avviene con i programmi unix, che necessitano di più file header, nei programmi per Windows l'unico file da includere per il supporto dei socket e' winsock.h sia per la versione a 16 che per quella a 32 bit. L'header winsock.h include automaticamente windows.h e, pertanto, non sarà necessario inserirlo. In fase di compilazione si scegliera' (automaticamente o manualmente) la dll da usare. 5 CONCLUSIONE Ora è ovvio che chi non conosce l'arte della programmazione, più in là non può andare. Memorizzare le varie funzioni chiamate da un programma durante lo stabilimento di una connessione non serve a molto se non si smanetta in C o VB. Lo sforzo di imparare un linguaggio verrà ricompensato dalla capacità di poter capire e commentare, ad esempio, un programma per creare pacchetti TCP, leggendo il sorgente o magari di poterlo modificare per una diversa utilità. Le e-zine tecniche come BFI partono da questo presupposto. Adesso tocca a voi. Per suggerimenti, critiche o segnalazioni di errori: lurkin@freemail.it ========================================================================================== TOP (Teflon Oil Patch) TROJAN - [Quel bastardo di Darat] -------------------------------------------------------- by ×-h4ck3r -------------------------------------------------------- [La Storia]: oggi [ore 3:40 AM ;-)] stavo dando una configuratina al mio PC, quando ad un certo momento (non so perchè!!!) mi viene in mente un vekkio programma ke scaricai dai NetNinja (ShareView). Mi ricordavo ke serviva per vedere le share (condivisioni) nascoste di Windows .... ma dove lo avrò messo? ke casino sto piccì! vabbè ora lo cerco. Dopo un po' di ricerke lo trovo, lo lancio e .... sorpresa immensa per i miei occhi .... tutte le unità dalla A alla Z erano delle 'hidden share', in altre parole condividevo tutti i miei diski e cd-rom senza accorgermene! (avevo avuto una sorta di presentimento :O) Quale dei milioni di programmini del ka§§o ke mi sono installato mi avrà fatto tutto sto casino? E va bene, ora mi è definitivamente passato il sonno; non posso mettermi a letto con questo interrogativo! B-Q Guardando meglio ShareView vedo ke i nomi con cui condividevo i diski erano: TOP-A$ ..... TOP-Z$ Niente male! La settimana scorsa ho scaricato un programmino per unire i file, un 'certo' TOP, ke ho provato e poi abbandonato in favore dello Stealth Installer (grazie Master! Non fare cattive sorprese anke tu, eh? hi hi hi). Verifico ke sia realmente lui a mettermi le share: apro il registro, cancello tutte queste condivisioni (non so se c'è un metodo per farlo senza usare il regedit); con regmon alla mano, faccio qualke prova e mi accorgo ke appena lancio un file unito con il TOP, o semplicemente il file topheader.exe mi ricompaiono tutte le connessioni! Se invece lancio solo il topbinder non succede nulla. e bravo Darat! e io ke ti avevo apprezzato per il tuo simpatico programmino! Ma andiamo ... [... Al Sodo]:) In pratica, quando si lancia un file unito con il TOP (qualsiasi versione, dalla 1 alla 4!) o anche il solo topheader.exe vengono create delle condivisioni nascoste in letture e scrittura su TUTTE le lettere di unità del tuo PC (non solo su C:, come facevano altri programmini simili). Le conseguenze le capisci da solo! ;-P Poikè l'aggiunta di condivisioni crea delle chiavi nel registro ke normalmente non esistono, per eliminarle bisogna andare a cancellarle con il regedit. Non è sufficiente un semplice file .reg! Quelle chiavi vanno cancellate, non modificate. Se conoscete un metodo per farlo, magari da linea di comando, fatemelo sapere. tnx Dicevo, aprite il regedit, andate in: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Network\ \LanMan e cancellate senza timore tutte le kiavi del tipo: TOP-x$ dove x è una lettera dalla A alla Z. Se lì avete altre kiavi vi consiglio di lasciarle stare, a meno ke non siate sicuri ke non volete nessuna condivisione su quel PC! Potrebbero servire alla condivisione ke usa il vostro papà quando va in ufficio! ;-)) Dopo aver fatto ciò, riavviate Windows e tutto tornerà come era prima. Attenzione: le modifike non hanno effetto se prima non riavviate Windows. Volendo, potete verificare di non avere più quelle hidden share usando ShareView ke trovate qui: http://www.netninja.com/files/ShareView.zip 310 Kb [Appendice] Tratto dal readme di Darat del TOP: >Section 4 Dont Blame ME ( But if u like TOP ) Where do i find U >TOP is a progy i maid for myself. But i decided that due to public >demand for a good binder i realsed it and other EGO related >resons ( NOT ME ) any way if u use top im not responsable for killing >your poota or for killing your friends IF U USE IT non si ritiene responsabile .... roba da matti!!! >ITS YOUR PROBLEM. But dont let me put u off. mi sa ke ora i problemi saranni i SUOI ... >Im easy to contact if your not cheaking out my page ( IF U DIDNT GET >TOP FROM THERE TELL ME ) >http://members.xoom.com/DaRaTTy/index.html http://www.darat.cjb.net/ <== sito funzionante, oppure http://members.xoom.com/_XOOM/Tef_oil_Pat/ >OR u can Mail me darattys@hotmail.com >Or Get me ON icq 15443314 >OKYS by for NOW ... bene! ora sapete come rintraciarlo per complimentarvi con lui! bacibaci x PS: le versioni 1 e 2 di TOP hanno problemi a creare le condivisioni con le prome lettere di unità, quelle dei floppy. :-O ... poco male! ~ ~ ^ ~ ^ ~ ^ ~ ~ ~ ~ / ~ ^ ~ ~ ^ \^/ \ ~ ^ \ ^ \ ^ . / \ / \. / ~. \ \_____________/ -=| EnJoY |=- \_______/ -=| SpP |=- \_____/ -=|'99|=- \_x_/ \_/ | EOFF ;) ========================================================================================== Creazione di uno script [seconda parte] Abbiamo visto in precendenza come creare un menu per cambiare il nick e come inserire un comando d' autoidenficazione per il nostro nick in Mirc. In questa seconda parte vedremo come impostare i comandi per crare un "auto-join" ossia una serie di comandi, di menu che ci permeteno di settare dei canali che verranno salvati come variabili e che alla successiva connessione al server si "apriranno" automaticamente e di un menu per la gestione dei canali in cui vedremo come creare il "TakeOver" e una "shit list". Cominciamo dall' aprire il file ai.ini che abbiamo creato in precedenza (o un qualunque altro ini) e proseguiamo il precedente script inserendo queste stringhe: n9=/ajstats { n10=.window -c @Auto-Join n11=/window -l @Auto-Join 190 60 210 140 n12=/aline @Auto-Join _____Auto Join Stats_____ n13=/aline @Auto-Join Channel 1: %chan1 n14=/aline @Auto-Join Channel 2: %chan2 n15=/aline @Auto-Join Channel 3: %chan3 n16=/aline @Auto-Join Channel 4: %chan4 n17=/aline @Auto-Join Channel 5: %chan5 n18=/aline @Auto-Join _____Auto Join Stats_____ n19=} n20=/aj { n21=/echo -a Starting 2Auto Join1 n22=if ((%autojoin == on) && (%chan1 != $null) && (%chan2 != $null) && (%chan3 != $null) && (%chan4 != $null) && (%chan5 != $null)) { n23=/join %chan1 n24=/join %chan2 n25=/join %chan3 n26=/join %chan4 n27=/join %chan5 n28=} n29=else { n30= /echo -a 4Error! 12*** Could Not Join Channel(s) ! n31=} n32=} vediamo che il precedente script crea al comando "/ajstats" una finestra chiamata "@Auto-Join" in cui all' interno verranno visualizzati i canali imposti (se impostati) del tipo "Channel 1: %chan1 (dove %chan1 sarà sostituito dal nome del canale corrispondente. Il successivo comando "/aj" esegue una serie di procedure che permetteranno al nostro script di aprire i canali impostati in precedenza una volta connessi al server. 2 questo rappresenta il colore da assegnare alla stringa che lo segue (normalmente assegnato a del testo da visualizzare): /echo -a 4Error! 12*** Could Not Join Channel(s) ! Se si trava solamente significa che il colore è quello di default. Il comando "$null" indica l' assenza di una chiave assegnata ad una variabile (in questo caso un "%chanX"). A questo punto dobbiamo settare il menu che ci permetterà di far funzionare il tutto, quindi apriamo il nostro file .mrc ed inseriamo alla file (tra l' ultima stringa e la parentesi) i seguenti comandi: - Auto Join .ON:/set %autojoin on | /echo Auto-Join active .OFF:/set %autojoin off | /echo Auto-Join not active .Channel 1:/set %chan1 $$?="inserisci il channel" .Channel 2:/set %chan2 $$?="inserisci il channel" .Channel 3:/set %chan3 $$?="inserisci il channel" .Channel 4:/set %chan4 $$?="inserisci il channel" .Channel 5:/set %chan5 $$?="inserisci il channel" .- .Stats:/ajstats - Questo ci permettera di settare i vari canali che dovremmo in seguito aprire entrando nel server, per far si che questo script funzioni sarà in fine necessario inserire il comando "/aj" come visto in precedenza per il comando di autoidentificazione. A questo punto il nostro script e completo e pronto a funzionare, ricordo che non sempre è necessario settare manualmente le variabili nel file remote.ini, in questo caso non sono essenziali per la visualizzazione dei menu o il funzionamento dello script. Ora vediamo la creazione di un menu per i canali, in cui saranno presenti comandi utili per la gestione degli stessi. Per questo script creeremo per semplicità un nuovo file .mrc (chiamiamolo channel.mrc) ed inseriamo al suo interno questo script: menu channel,menubar,nicklist { - &CHANNEL Action .&TakeOvEr ..&TaKeOvEr Channel: { if ($me isop #) { /md -t } else { echo -a *** Devi essere OP per farlo!!! } } ..&Restituisci Canale:/echo 7*** Canale Restituito!!! | /topic # "¨¨°º©o.,,.o©º°¨¨°º©[- Canale Restituito da $me -]©º°¨¨°º©o.,,.o©º°¨¨" | /mode # -kipnmtslo .- .&Set Modes ..&Manuale:/mode # $$?="Channel Modes (eg: +nt)" ..- ..&Invita[ +i ] ...&Yes:/mode # +i ...&No:/mode # -i ..&Segreto[ +s ] ...&Yes:/mode # +s ...&No:/mode # -s ..&Messagi Esterni[ +n ] ...&Yes:/mode # +n ...&No:/mode # -n ..&Limita Users[ +l ] ...&Yes:/mode # +l $+ $$?="Max Users Allowed:" ...&No:/mode # -l ..&Blocca Topic[ +t ] ...&Yes:/mode # +t ...&No:/mode # -t .&Key[ +k ] ...&Yes:/mode # +k $+ $$?="Key (Password):" ...&No:/mode # -k ..&Moderato[ +m ] ...&Yes:/mode # +m ...&No:/mode # -m .- .&Join channel:/join #$$?="inserisci channel name:" .&Part channel:/part #$$?="inserisci channel name:" .- .Shit List ..Add To Shit List:/.guser 2 $$1 3 | /echo $$1 has been added to your Shit List !!! | /kick $$1 8,1ShitListed | /msg $$1 %logo | /msg $$1 You`re in my Shit List ! | /ignore $$1 1 ..Remove From Shit List:/.ruser 2 $$1 3 | /echo $$1 has been removed from your Shit List | /ignore -r $$1 1 | /echo $$1 has also been removed from your ignore-list ! ..- ..Empty Shit List:/.rlevel -r 2 | /echo You`re Shit List is now Empty !!! } Credo che ormai abbiate capito il meccanismo e che sia superfluo rispiegare le funzioni di questi comandi fatta eccezione per la "shit list" che permette di salvare su un file i nick che ci bannano o kickano ed alla successiva entrata nostra del canale la loro espulsione ( se siamo op ) attraverso un kick :-) Vi ricordo di lincare anche questo file mirc.ini in [rfiles] proseguendo il listato. Ora impostiamo in .ini (o anche continuando in aliases.ini) il seguente script che servirà per il funzionamento del "takeover" allora inseriamo queste nuove righe (cambiando il numero di riga a seconda di dove le mettete in modo da proseguire in ordine crescente di righa): n110=/md { n111=set %Var.Chan $chan n112=set %i 1 n113=set %Var.Index 1 n114=if (s isin $1) { set %Var.Safe $$2 } n115=if (t isin $1) { set %Var.Take y } n116=if (undernet isin $server) { set %Var.Num 6 } n117=else { set %Var.Num 4 } n118=:start n119=set %Var.User $opnick(%i,%Var.Chan) n120=if (%Var.User == $null) { n121= raw -q mode %Var.Chan -oooooo %Var.Nick n122= if (%Var.Take == y) { /mode # +smpti | /topic %Var.Chan <--- 4,1 TaKeOvEr 1,0---> } n123= if (s isin $1) { raw -q mode # +o %Var.Safe } n124= echo -a 12*** Mass Deop On $chan !!! n125= unset %Var.Nick | unset %i | unset %Var.Chan | unset %Var.Index | unset %Var.Num | unset %Var.Safe | unset %Var.Take | halt n126=} n127=if (%Var.User == $me) || (%Var.User == %Var.Safe) { inc %i 1 | goto start } n128=if (%Var.User != $me) { set %Var.Nick %Var.User %Var.Nick | if (%Var.Index == %Var.Num) { raw -q mode %Var.Chan -oooooo %Var.Nick | unset %Var.Nick | set %Var.Index 1 | inc %i 1 | goto start } | inc %Var.Index 1 } n129=inc %i 1 n130=goto start n131=} Con il TakeOver si ha la possibilità di deoppare automaticamente tutti quelli presenti nel canale tranne noi stessi e di bloccare il canale impostando il "/mode # +smpti" ed in più cambiano automaticamente il topic in "<--- 4,1 TaKeOvEr 1,0--->" Ora inseriamo in un nuovo file .ini (script.ini) le seguenti stringhe: [script] n0= n1=on 2:op:#:{ n2= mode $chan -o+b $nick *!*@ $+ $site n3= kick $chan $nick You`re Shit Listed n4=} n5=on 2:join:#:{ n6= mode $chan -o+b $nick *!*@ $+ $site n7= kick $chan $nick You`re Shit Listed n8=} n9=on 2:text:#:{ n10= mode $chan -o+b $nick *!*@ $+ $site n11= kick $chan $nick You`re Shit Listed n12=} Linkiamo il file nel mirc.ini sempre nel [rfiles]. creiamo un file shit.ini e attraverso il client Mirc lo carichiamo nel seguente modo: tools aliases selezioniamo la finestra "Users" e attraverso il menu files: load users ora selezioniamo il file shit.ini e diamo l' ok. In questo modo abbiamo creato tutto il necessario per far funzionare il comando di "shit list" E quì finisce la seconda parte, mi raccomando non divertitevi troppo con il takeover :-) hihihihi. ========================================================================================== Linux: piu' semplice di quanto sembra ------------------------------------- by -=F14m3r=-® - flamer@freemail.it ------------------------------------- INTRODUZIONE E' vero. La prima volta che me l'hanno detto non ci credevo. Quando l'installai per la prima volta ero convinto del contrario. Eppure adesso ne sono convinto: linux e' piu' semplice di quanto sembra. Chi gia' smanettava sui computer quando si parlava solo DOS avra' poca difficolta' ad abituarcisi. Chi invece e' abituato a lavorare sotto windows, usando solo il mouse, all'inizio probabilmente si trovera' un po' spaesato, ma secondo me vale la pena di provare ad installarlo questo sistema operativo... imparare ad utilizzarlo al meglio puo' essere molto interessante. CONSIGLI PER L'INSTALLAZIONE Benche' il kernel (cioe' il nucleo del sistema operativo) di linux sia unico, esistono varie distribuzioni di linux. Non esiste LA distribuzione, ognuna ha caratteristiche differenti. Il mio consiglio e' che proviate ad installarne due o tre prima di scegliere quella che piu' vi piace, ma comunque che installiate una distribuzione semplice come primo tentativo (mandrake ad esempio va benissimo). NB: Linux e windows possono coesistere ad una condizione: che installiate prima windows. Infatti se installate windows su un computer dove gia' c'e' installato linux, il sistema operativo della microsoft cancella il boot record di linux. Risultato: nella peggiore delle ipotesi vi tocca reinstallare linux. COMANDI FONDAMENTALI Benche' gli ambienti grafici siano gia' abbastanza diffusi, linux e' un sistema operativo a linea di comando, e bisogna saper interagire con la shell per utilizzarlo al meglio. Innanzi tutto ricordatevi che linux e' case sensitive, cioe' c'e' differenza tra LS e ls. I comandi principali per navigare nelle directory di linux sono: pwd, ls, cd. pwd - stampa la directory corrente Vi viene stampata la directory corrente. Ad esempio: [alex@flam bin]$ pwd /usr/local/bin [alex@flam bin]$ ls - listato della directory corrente Proprio come il comando dir del DOS vi stampa il contenuto della directory. [alex@flam /]$ ls bin etc lost+found root usr boot home mnt sbin var dev lib proc tmp [alex@flam /]$ Puo' essere comodo a volte scrivere ls -a. Il "-a" sta per "all", cioe' in questo modo vi vengono mostrati anche i file nascosti. Linux considera nascosti tutti i file il cui nome inizia con un punto. cd - cambia la diretory corrente [alex@flam /]$ pwd / [alex@flam /]$ cd /usr/local [alex@flam local]$ pwd /usr/local [alex@flam local]$ cd bin [alex@flam bin]$ pwd /usr/local/bin [alex@flam bin]$ cd .. [alex@flam local]$ pwd /usr/local [alex@flam local]$ Nota: In ogni directory ci sono i file speciali . e ..; il primo rappresenta la directory corrente, mentre il secondo rappresenta la directory precedente. Se scrivete "ls -a" vedrete anche questi due file. Il comando piu' utile in assoluto, pero', a mio parere e' man, che vi permette di esaminare la documentazione di linux. Provate "man ls" oppure "man pwd". DIRECTORY Diamo un'occhiata alle directory piu' importanti che vengono create nella radice. - /bin File binari (eseguibili) di varia utilita'... tra gli altri troverete cat, ls, pwd, grep, gzip, ecc... - /var Qui ci sono tutti i file che si presume debbano crescere in dimensione (file di log, file contenenti le mail in arrivo, ecc...) - /home Sotto questa directory dorebbero andare tutte le directory di partenza dei vari utenti - /root Directory di partenza del superuser - /usr Tutti i file non relativi all'installazione di linux vanno qui. Programmi installati, file scaricati, ecc... - /etc Questa cartella contiene tutti i file di configurazione di linux. - /tmp In questa cartella risiedono tutti i files temporanei - /lib Qui ci sono le librerie condivise dai vari programmi - /dev Questa directory contiene dei files "fittizi", che in realta' rappresentano i dispositivi a cui sotete accedere. Ad esempio /dev/fd0 e' il floppy drive, mentre /dev/cua0 e' la porta che sotto DOS/Win prende l nome di COM1. FILES E PERMESSI Linux e' un sistema multiutente. Questo significa che ogni utente prima di accedere al sistema deve identificarsi tramite un username e una password. Ogni utente ha quindi un nome che lo identifica, ma non solo: gli utenti possono essere divisi in gruppi, che possono contenere diversi utenti. Riassumndo, ogni utente che sta utilizzando il sistema e' identificato da: - User ID, cioe' id utente - Group ID, cioe' id gruppo Tutti i file (e directory) di linux hanno un owner (cioe' l'utente che lo possiede), e un gruppo di appartenenza, che corrispondono a UID e GID di chi ha creato il file. Con il comando "ls -l" possiamo vedere (in terza e quarta colonna) chi sono l'utente e il gruppo proprietari del file. In prima colonna ci viene dato lo schema dei permessi relativi a quei file, che dovrebbe essere qualcosa tipo: -rwxr-x--x che e' piu' semplice di quanto sembri. Infatti, il primo carattere ci indica se questo e' un file (-), una directory (d), o un collegamento (l). Dopodiche' i restanti nove caratteri si dividono in gruppi di tre. La prima serie rappresenta i permessi che ha l'utente possessore di quel file, la seconda rappresenta i permessi che ha su quel file che fa parte del gruppo possessore, mentre la terza rappresenta i permessi che ha su quel file chi non ricade nelle prime due categorie. I permessi che si possono avere sono di tre tipi: lettura (r), scrittura (w) ed esecuzione (x). Nell'esempio precedente il proprietario puo' leggere, modificare ed eseguire il file (rwx), chi appartiene al gruppo puo' leggere ed eseguire il file (r-x), tutti gli altri possono solo eseguirlo (--x) Per cambiare le proprieta'/permessi dei file si usano i comandi chown e chmod, ma per questo vi rimando alle pagine di man. STRUTTURA DELLA LINEA DI COMANDO Vediamo un po' piu' in dettaglio alcune caratteristiche interessanti della shell. Nota: La shell e' il programma con cui "dialogate" col computer. Le shell piu' comuni sono bash e tcsh. In maniera analoga a quanto avveniva nel DOS, ogni comando inizia col nome del programma che si vuole eseguire, seguito dai parametri che si vogliono passare al programma. Ad esempio il comando cp (copia file) necessita di due parametri fondamentali: file di origine e file di destinazione. Per esempio: cp orig.cpp ../dest.cpp copia il file orig.cpp della directory corrente nel file dest.cpp della directory superiore a quella corrente. Tuttavia (e ve ne accorgerete dando un'occhiata alle pagine di man) si possono passare altri parametri al comando cp. Ad esempio: cp -R orig/ dest/ Copia ricorsivamentela directory orig e tutte le sottodirectory che da li' si dipartono nella directory dest. Oppure: cp -f orig.cpp ../dest.cpp copia il file senza chiedere conferma nel caso il file dest.cpp fosse gia' esistente. Un comando un po' piu' interessante e versatile di cp e' cat. Questo comando prende come parametro un file e ne stampa il contenuto sullo standard output. Se non gli vengono passati parametri anziche' un file viene letto lo standard input (quello che scrivete) fino a che non si arriva a un carattere di End Of File (CTRL+D). Provate ad eseguire cat e scrivete qualche riga. E poi provate a dargli in pasto un file come parametro... E' chiaro come funziona cat? Bene! Pero' non e' tutto qui. Le potenzialita' della shell (non del programma!) permettono di usare cat in maniera molto piu' intelligente. Innanzi tutto osserviamo come si puo' far stampare a cat un file senza passarglielo come parametro. Be'... basta sfruttare la redirezione dello standard input della shell, che si fa con il carattere <. Provate a scrivere: cat < nomefile ...Avete capito cosa succede?? cat viene chiamato senza parametri, quindi legge lo standard input per ristamparlo sullo standard output. Solo che in questo caso, lo standard input non e' piu' la tastiera, ma e' un file! Allo stesso modo in cui si puo' redirigere lo standard input, si puo' redirigere anche lo standard output, e lo si fa col carattere >. Scrivere: cat < file_input > file_output equivale a: cp file_input file_output Usando la redirezione con >, se il file di output esiste gia' viene troncato. Per evitarlo si puo' scrivere: cat < file_input >> file_output In questo caso il contenuto di file_input verra' aggiunto alla fine di file_output (che comunque se non esiste verra' creato). Be'... penso che non vi stupirete piu' se vi dico che cat puo' anche essere un rudimentale file editor... :-)) Provate a scrivere: cat > pippo Il programma restera' in attesa di input. Ora tutto quello che scriverete verra' inserito nel file pippo, fino a che non darete il segnale di End Of File (come vi ho gia' detto CTRL+D). Un altra utile funzionalita' della shell e' il carattere | (pipe). Questo carattere ha la funzione di passare l'output di un comando come input ad un altro comando. Ad esempio: ls | cat Stampa il listato della directory corrente. E' pittosto inutile, vero? Inece e' un po' piu' utile scrivere: ls | more More e' un comando che, se l'input supera la lunghezza dello schermo, lo mostra fermandosi dopo una schermata (provatelo: e' piu' semplice vederlo che scriverlo). Facciamo un altro esempio... volete vedere il listato di un file molto lungo? cat < file | more Nota: Provate anche less al posto di more: vi permette di scrollare anche verso l'alto oltre che verso il basso. Ma non e' finita qui... se noi all'interno di un comando inseriamo una stringa racchiusa da apici rovesciati (`), cosa succede? Facciamo un esempio: grep pippo `ls` Nota: grep e' un comando che cerca una stringa all'interno di uno o piu' files... per ulteriori specifiche vi rimando a man. Qui prima viene eseguito il comando ls, dopodiche' viene sostituito nella riga di comando l'output di ls al posto della stringa contenuta nei doppi apici. Il risultato e' che grep cerchera' la stringa "pippo" all'interno di tutti i files della directory. Facendo un esempio un po' piu' concreto: [alex@flam SPPScan-1.0.0]$ ls Makefile coda.cpp pscfg scansock.h README coda.h scansock.cpp sppscan.cpp [alex@flam SPPScan-1.0.0]$ grep main `ls` sppscan.cpp:int main(int argc, char* argv[]) [alex@flam SPPScan-1.0.0]$ Il secondo comando equivale a grep main Makefile coda.cpp pscfg.... eccetera. DUE PAROLLE SULLA FILOSOFIA DI LINUX Concludendo, spero di essere riuscito a farvi comprendere quanto sia versatile linux. La scelta che e' stata fatta nel creare le utility che accompagnano questo sistema operativo e' quella di utilizzare tanti file molto piccoli (il codice di cat ad esempio non supera le 20 righe), che pero', tramite una shell estremamente ben fatta, possono interagire tra loro per fare cose anche molto complicate. Il risultato e' che molte cose in linux si possono fare dalla shell, e installare linux su un computer troppo lento per avviare X non lo rende affatto inutilizzabile, senza per questo togliere nulla a chi invece si puo' permettere un ambiente grafico. -=F14m3r=-® - flamer@freemail.it