home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Current Shareware 1994 January
/
SHAR194.ISO
/
hamradio
/
netspy.zip
/
RETI.DOC
< prev
next >
Wrap
Text File
|
1989-07-25
|
37KB
|
730 lines
I N D I C E
1. INTRODUZIONE...........................................2
2. IL PROTOCOLLO AX25.....................................2
3. L'INTERFACCIA RADIO - TNC - COMPUTER...................9
4. LE ROUTINE DI GESTIONE DELLA PORTA SERIALE............11
5. IL PROGRAMMA NETSPY.C.................................12
5.1 La Strategia del programma.........................12
5.2 Come usare il programma............................16
5.3 Le principali strutture dati del programma.........20
5.4 Le principali costanti " " .........23
5.5 Le principali routines " " .........24
8. LISTATI...............................................29
1. INTRODUZIONE.
Con questa relazione si vuole descrivere come e' stato
progettato e implementato il programma NETSPY .C. Esso e' in
grado, tramite un ricevitore radio e un TNC, di intercettare
le comunicazioni in "packet" su un dato canale radio, e di
analizzare i relativi pacchetti.
Inizieremo con una breve descrizione del protocollo AX25,
usato per le comunicazioni in packet radio, per poi
descrivere come le conoscenze acquisite nello studio di
questo protocollo ci hanno permesso di affrontare il problema
propostoci.
2. IL PROTOCOLLO AX25.
La comunicazione in packet radio fra due stazioni avviene
attraverso lo scambio di piccoli blocchi, o pacchetti, di
dati. Ogni pacchetto (frame) e' costituito dall'insieme di
altre piccole sequenze, dette campi. La prima grossolana
classificazione possibile e' dividere i frames in tre gruppi
principali: frame U, S, I, rispettivamente pacchetti di
informazione non numerati, pacchetti di supervisione del
protocollo, pacchetti di informazione numerati. I campi che
formano questi tipi di pacchetti sono i seguenti:
Pacchetto I (o UI)
FLAG ADDRESS CONTROL PID INFO FCS FLAG
(n.bytes) 1 14/70 1 1 n 2 1
Pacchetto S (o U)
FLAG ADDRESS CONTROL FCS FLAG
(n.bytes) 1 14/70 1 2 1
Prendiamo ora in esame il contenuto dei vari campi.
FLAG. Il campo flag (7E Hex, 01111110) delimita l'inizio e la
fine di un pacchetto. Se questo byte deve comparire
all'interno di altri campi, vi e' inserito con la tecnica del
"byte stuffing".
ADDRESS. Il campo address serve per conoscere mittente e
destinatario di ogni frame. I primi 7 byte sono relativi al
mittente, i bytes 8-14 al destinatario, gli altri (eventuali)
alla catena dei digipeater che rendono possibile il
collegamento. Per individuare il termine del campo address,
tutte i byte relativi alle lettere dei nominativi vengono
shiftati di una posizione a sinistra, lasciando al bit meno
significativo il compito di indicare se il campo indirizzo e'
terminato oppure no. Un bit a 1 in questa posizione dara' il
termine del campo. Per ogni nominativo sono presenti 7 byte:
6 di nominativo vero e proprio, 1 per l'identificativo
secondario di stazione (localmente verra' aggiunto il
carattere "-").
CONTROL. Il campo control serve per identificare che
tipo di frame (I, U, S) e' stato inviato. I due bits meno
significativi del campo controllo specificano la natura del
pacchetto:
x 0 : Pacchetto di tipo I (x indica indifferenza)
0 1 : Pacchetto di tipo S
1 1 : Pacchetto di tipo U.
Tutte le decodifiche successive (compresa quella relativa ai
bits rimanenti del campo control) hanno modalita' diverse a
seconda di questa prima distinzione.
FRAME I.
Cominciamo dalla decodifica dei bits rimanenti del campo
control (bit 1-7, intendendo 0 bit meno significativo e primo
ad essere trasmesso).
I bits 1, 2 e 3 identificano il numero progressivo (modulo 8)
della sequenza di pacchetti I trasmessi. Il bit 4 e' il
sottocampo di poll/final: quando questo campo e' a 1 si vuole
una risposta immediata dalla stazione dall'altra parte del
link, che rispondera' anch'essa con un sottocampo di P/F a 0.
Questo serve per accertarsi, qualora ve ne fosse bisogno,
della 'presenza' dell' altra stazione.
I bit 5, 6 e 7 identificano il numero progressivo (modulo 8)
della sequenza di pacchetti I ricevuti.
FRAME I.- Campo PID -
Il Byte successivo al campo controllo e' il Protocol
Identifier Field, che dice se esiste un protocollo a livello
3 e quale esso sia. Il valore 240d codifica il fatto che
nessun protocollo a livello 3 e' implementato; il valore 207d
codifica il protocollo NETROM; il valore 204d codifica il
protocollo IP.
FRAME I.- Campo Info e successivi -
Dopo il Byte di PID, inizia la serie di bytes di contenuto
informativo veri e propri, cioe' la sequenza di byte ASCII
che costituiscono il messaggio. Essi sono terminati da un
byte di FCS (Frame Check Sequence), su cui il TNC dovra' fare
il test di correttezza del pacchetto, e da un byte di flag
(01111110) che termina il pacchetto stesso.
FRAME S
Con questo nome si identificano i pacchetti di supervisione
del protocollo, quelli cioe' a cui e' assegnato il compito di
controllare l'esatto flusso dei dati sul link. I bytes 2 e 3
del campo control descrivono la natura del pacchetto S: in
particolare:
bit 3 2 tipo
0 0 RR (Receive Ready)
0 1 RNR (Receive Not Ready)
1 0 REJ (Frame Reject)
Il bit 4 e' il gia' spiegato sottocampo di poll/final, mentre
i bits 5, 6, 7 danno il numero progressivo, sempre modulo
8, della sequenza di pacchetti ricevuti.
FRAME S.- Tipo RR -
Il tipo RR serve principalmente per tre scopi:
-) Per indicare che chi trasmette RR e' pronto a ricevere
pacchetti di tipo I;
-) Per indicare che sono stati ricevuti correttamente i
pacchetti I inviati;
-) Per ridare il via a una condizione precedentemente
bloccata.
FRAME S.- Tipo RNR -
Questo tipo di pacchetti viene usato per indicare a chi
trasmette pacchetti di tipo I che il ricevitore e'
temporaneamente occupato e non puo' ricevere altri pacchetti.
FRAME S.- Tipo REJ -
Questo pacchetto viene usato per richiedere la ritrasmissione
della sequenza di pacchetti I che non e' stata esattamente
ricevuta ( per esempio per cattive condizioni di ricezione).
FRAME U.
Questo tipo di pacchetto (Unnumbered, non numerato), puo'
essere sia di comando che di risposta. I bits 2, 3, 5, 6, 7
del campo control danno informazione sul tipo di pacchetto in
questo modo:
bits 7 6 5 3 2 tipo
0 0 1 1 1 SABM
0 1 0 0 0 DISC
0 0 0 1 1 DM
0 1 1 0 0 UA
1 0 0 0 1 FRMR
0 0 0 0 0 UI
Il bit 4 e' il solito sottocampo di poll/final.
FRAME U - tipo SABM -
Il tipo SABM (Set Asynchronous Balance Mode) serve per porre
due stazioni in collegamento. Il link viene attivato quando
una stazione che riceve SABM risponde con un UA.
FRAME U - tipo DISC -
Il Tipo DISC (Disconnect) serve per terminare un
collegamento. IL link si disattiva immediatamente.
FRAME U - tipo DM -
Il tipo DM (Disconnect Mode) viene inviato da ogni stazione
che, essendo disconnessa, riceve un messaggio diverso da
SABM, oppure per indicare che al momento non c'e'
possibilita' di connessione (BUSY).
FRAME U - tipo UA -
Il tipo UA (Unnumbered Acknowledgment) viene inviato per
confermare la ricezione di un pacchetto U.
FRAME U - tipo FRMR -
Il tipo FRMR (Frame Reject) viene inviato per indicare che in
un pacchetto ricevuto e' stato evidenziato un errore non
recuperabile con la ritrasmissione del pacchetto stesso (per
esempio, un pacchetto con numero progressivo fuori sequenza o
con campi invalidi). Un pacchetto FRMR contiene, in un campo
aggiuntivo, la descrizione codificata dell'errore rilevato.
FRAME U - tipo UI -
Il pacchetto UI (Unnumbered Information) e' un pacchetto di
informazione e come tale contiene successivamente tutti i
campi gia' visti per il pacchetto I. Questo tipo di
pacchetto, pero', non riceve conferma di ricezione e percio'
puo' essere perduto.
Tutti i pacchetti di qualunque tipo sono poi terminati dai
gia' descritti campi FCS e FLAG.
3. L'INTERFACCIA RADIO - TNC - COMPUTER.
Per ricevere i pacchetti che viaggiano su un determinato
canale si e' fatto uso di un ricevitore FM sulle bande 2
metri e 70 cm (144 e 433 Mhz), di un TNC PK 87 e di un
personal AT su cui e' stato sviluppato il software.
Il primo problema e' stato come configurare il TNC in modo da
rendere l'algoritmo il piu' generale possibile. Lo si e'
configurato in KISS mode (per il PK 87 la sequenza che
setta il TNC in KISS e' contenuta nello script file KISS.XTK
eseguibile da CROSSTALK).
Tale modo, operando a basso livello, fa soltanto un controllo
di correttezza del pacchetto e poi lo invia byte per byte al
computer ospite, dopo averlo filtrato dei byte di FLAG e FCS
e corredato di un byte di inizio e fine pacchetto (192d). In
realta' si e' notato che all'inizio del pacchetto vi e'
sempre la sequenza 192d 000d, e non soltanto 192d. Questo in
contraddizione con le istruzioni, riportate sul manuale, del
modo KISS, che prevedevano il solo 192d. I byte cosi' giunti
saranno poi decodificati dal programma secondo la descrizione
del protocollo che e' stata data.
Il secondo problema e' stato come gestire da programma
l'arrivo dei dati alla porta seriale su cui il TNC e'
collegato. In sostanza, da programma vengono per prima cosa
configurati i registri che gestiscono l'informazione relativa
alla porta seriale (velocita'in Baud, lunghezza di parola,
byte di parita', byte di stop); inoltre, il programma
provvede a sostituire la normale routine di gestione della
RS232 del BIOS (interrupt 0Ch) con un nuovo interrupt handler
che consente di lavorare con i byte che arrivano alla porta
seriale in modo asincrono rispetto al flusso del programma.
Di queste routine daremo una spiegazione nel prossimo
paragrafo.
4. LE ROUTINE DI GESTIONE DELLA PORTA SERIALE.
Queste routine si trovano nel file GestSer.C. Di esse daremo
una sommaria spiegazione.
Con la InitSer1(speed) si accede direttamente nei registri
del WD8250, chip programmabile che gestisce la porta seriale,
e lo si inizializza coni parametri di ricezione: velocita',
che puo' venire cambiata da programma con il passaggio della
variabile speed (default = 1200 Baud), bit di dati (8),
parita' (nessuna), bit di stop (1).
Tramite la Com1_Handler() si riscrive il vettore di interrupt
0Ch che si attiva quando e' pronto un dato dalla seriale:
tale dato viene scritto in un buffer circolare Com1buf che
viene gestito con due puntatori: uno all'ultimo dato letto
dal nostro programma, uno all'ultimo dato arrivato tramite
seriale. Per evitare ragionevolmente il rischio di overrun
dei dati, la dimensione del buffer e' stata fissata in 10000
caratteri.
La GetSer1() permette di leggere questo buffer rimanendo
fuori del vettore di interrupt; cioe', in pratica, il buffer
Com1buf si riempe asincronicamente rispetto al programma e
viene letto invece tramite la GetSer1() quando il programma
stesso lo richiede. Quest'ultima funzione riceve un puntatore
a carattere e basa il suo funzionamento sui due suddetti
puntatori che si chiamano Last_Read1 e Last_Char1; se essa li
ritrova uguali, ritorna -1 a significare che non c'e' nessun
dato nuovo; altrimenti ritorna 0 e il carattere nuovo.
Come ultima routine utilizzata c'e' la PutSer1() che permette
di mandare dati in uscita sulla seriale (per esempio per
forzare il TNC ad uscire da Kiss mode).
5. IL PROGRAMMA NETSPY.C .
Con le premesse fatte, si possono ora descrivere le
caratteristiche e il funzionamento del programma. Esso si
propone di:
-) Intercettare i pacchetti che viaggiano su un canale radio;
-) Costruire una tabella dei link attivi segnalando il numero
di pacchetti informativi scambiati, il numero di
collisioni rilevate, il tipo di protocollo a livello 3
eventualmente presente, l'ora di inizio e di fine del
colloquio. Tale tabella si aggiorna in tempo reale; tutto
cio' che esce dalla tabella viene salvato su file; tutta
la tabella viene poi salvata, a richiesta, al termine
dell'elaborazione.
-) Dare, a richiesta, ulteriori informazioni sui link
costituiti, come, ad esempio, gli eventuali digipeater
tramite i quali avviene la connessione.
-) Permettere di "catturare" a livello di byte i pacchetti
passanti sui vari link, permettendone poi una
consultazione in un ambiente dove essi sono gia' stati
divisi nei campi che li costituiscono.
5.1 LA STRATEGIA DEL PROGRAMMA.
In questo paragrafo verra' spiegato come il programma
raggiunge gli scopi prefissati. All'inizio viene visualizzata
una pagina di spiegazione d'uso che serve all'utente che si
accosti al programma per la prima volta. Poi inizia il
programma vero e proprio, con la visualizzazione dello
schermo principale che consta di tre finestre: nella
principale, la piu' grande, troveranno posto i link
(collegamenti tra due stazioni) con i loro parametri
significativi; in una seconda, in basso a sinistra, saranno
visualizzati, in forma breve, gli ultimi 5 pacchetti
transitati sul canale; in una terza, in basso a destra, sara'
visualizzato un menu di opzioni tra le quali la possibilita'
di effettuare la cattura e poi la visualizzazione byte a byte
dei pacchetti transitati sui vari link. Inoltre vengono anche
visualizzate l'ora e la data attuali.
Normalmente il programma attende i dati dalla seriale.
Durante questa attesa vengono chiamate alcune routine che
svolgono compiti di contorno. Una di esse analizza i link
presenti in tabella: se qualcuno di essi non ha traffico
(scambio di pacchett) da piu' di TIME_OUT minuti, il link
viene considerato disconnesso e si aggiorna l'ora di fine
collegamento.
TIME_OUT e' una costante del programma, posta uguale a 15: e'
consigliabile che tale valore non sia troppo elevato, per
evitare di lasciare in tabella troppi link apparentemente
'attivi'; in ogni caso TIME_OUT non potra' mai essere
maggiore di 59.
Altre routine si occupano di scrivere l'ora, di visualizzare
i vari menu, di interpretare i comandi dell'utente.
E' in seguito presente una descrizione dettagliata di queste
routine. All' arrivo del primo dato il programma inizia ad
elaborare il pacchetto. Una cosa da tenere presente, e' la
seguente: all'arrivo del primo dato si potrebbe supporre che
il secondo dato sia subito dopo immediatamente disponibile, e
tralasciare un test sull'effettivo arrivo di un dato nuovo.
In realta', essendo il codice compilato generalmente molto
piu' veloce dell'arrivo, sebbene continuativo, dei dati dalla
seriale, tale test va fatto PRIMA di leggerne qualunque di
essi, non solo il primo.
Avendo quindi rilevato l'arrivo di un pacchetto nuovo, lo si
mette in una variabile e, quando lo si ha completo, si
procede all'estrazione di tutti i suoi parametri
fondamentali; inoltre, se l'utente ha selezionato l'opzione
relativa, lo si inserisce nell'apposito buffer.
A questo punto si fa una distinzione: si considerano solo i
pacchetti di tipo I, U(UI,DISC,DM), S(RR,RNR,REJ).
Considerare questo sottoinsieme e' sufficiente per gli scopi
seguenti e semplifica l'algoritmo. Se viene intercettato un
pacchetto I o pacchetti RR, RNR, REJ con bit di poll = 0 (che
sono relativi a un precedente invio di pacchetti I), si ha la
presenza di a un link attivo. Se questo link e' presente in
tabella, si aggiornano semplicemente tutti i dati relativi:
si controllano ripetizioni di pacchetti per rilevare
collisioni, si aggiorna l'ora dell'ultimo pacchetto ricevuto
e cosi' via. Se il link non e' in tabella, lo si aggiunge; se
la tabella e' piena si elimina il link 'piu' vecchio'
salvandolo su file. Inoltre si aggiornano le scritte sullo
schermo e si scrive in basso a sinistra il pacchetto
intercettato.
Se si e' ricevuto un pacchetto DISC o DM il link si e'
disconnesso, e percio' si aggiorna l'ora di fine collegamento
che viene scritta sullo schermo.
Se si riceve un pacchetto UI si controlla tramite il campo
PID se e' implementato un protocollo a livello 3: se si', si
aggiunge anche questo link in tabella, considerandolo
significativo. Gli altri pacchetti UI non IP o NETROM vengono
ignorati a questo livello perche' di scarso interesse (a
quest'ultima categoria appartengono, per esempio, i pacchetti
di identificazione che i vari nodi trasmettono ogni tanto sul
canale).
Questo e' cio' che il programma fa per 'default', cioe' senza
interventi dell'utente. Quest'ultimo ha pero' sempre a
disposizione un menu che gli permette di fare altre analisi
contemporaneamente all'arrivo e all'elaborazione dei
pacchetti. L'utente puo' chiedere notizie aggiuntive su un
link, puo' decidere se e come abbandonare il programma, puo'
svolgere attivita' in una shell del sistema operativo, puo'
decidere di iniziare o terminare di catturare, per poi
vederli byte a byte, tutti i pacchetti che transitano sul
canale.
Questa opzione funziona nel seguente modo: esiste una
variabile 'capture' che puo' essere posta ON oppure OFF. Nel
primo caso tutti i pacchetti intercettati, anche quelli che
non influenzano la tabella principale, sono catturati in una
struttura dati. Questa cattura termina o quando l'utente pone
a OFF la variabile, oppure quando sono stati catturati un
numero max di pacchetti (numero che e'fissato con una
costante del programma, NUMPAK_MAX uguale a 250), oppure
ancora se non esiste piu' memoria disponibile per
l'allocazione dei nuovi pacchetti.
A questo punto l'utente puo' entrare in un nuovo ambiente
dove puo' vedere con semplici comandi tutti i pacchetti byte
per byte, gia' divisi nei loro campi. Intanto, il buffer
della seriale continuera' a riempirsi di dati in arrivo, che
pero' non saranno elaborati istantaneamente, ma solo ogni un
certo numero di secondi (nel programma tale numero e'
definito dalla costante TEMPO_AGGIORNAMENTO, uguale a 30) in
modo da non perdere continuita' nell'elaborazione dei dati in
arrivo senza pero' rallentare in modo vistoso la sessione
corrente.
Vengono ora descritte le operazioni che svolge il programma
nel caso che l'utente desideri avere una rappresentazione
grafica dell'attivita' del canale. Una volta inizializzato il
sistema con la funzione StartPlacet() descritta
dettagliatamente in seguito, il programma legge la tabella in
cui sono memorizzati i pacchetti che sono arrivati e con
queste informazioni costruisce la schermata grafica
corrispondente. A questo punto, il programma prosegue come al
solito continuando ad aggiornare la tabella dei link man mano
che arrivano i nuovi pacchetti; questa tabella costituisce
sempre il riferimento per l'aggiornamento della situazione
grafica e viene quindi riletta ad ogni nuovo ciclo.
5.2 COME USARE IL PROGRAMMA.
Il programma viene lanciato da DOS con il comando 'netspy' al
quale possono essere aggiunte, sulla stessa riga, le seguenti
opzioni:
-h : evita la visualizzazione, all' inizio del programma,
delle due pagine di istruzioni.
-p xx: permette di specificare il path xx per il file
LOG.PKT che altrimenti viene scritto nella directory
corrente.
-s yyyy: pone a yyyy la velocita' di trasferimento TNC-
Computer che per default e' 1200 Baud.
Da prove effettuate si e' visto che, specialmente con PC XT,
e' consigliabile non salire oltre 4800 baud per non rischiare
di perdere qualche dato e far abortire il programma che tenta
di decodificare pacchetti con campi invalidi o mancanti.
Lanciato senza l'opzione -h, il programma presenta due
schermate di informazione: la prima schermata attende la
pressione del tasto 'PgDn' prima di presentare la seconda. Al
termina di quest'ultima premendo F1 si inizia il programma
vero e proprio, premendo F10 si ritorna al sistema operativo.
A programma iniziato, ogni volta che un pacchetto transita
sul canale, lo si vedra' apparire sullo schermo, e, se il
pacchetto indica la presenza di un link attivo secondo le
modalita' previste e prima spiegate, il link stesso apparira'
nella finestra principale.
Se i pacchetti sono rilevati correttamente dal TNC il
programma seguira' l'evolversi dei vari link sul canale
aggiornando le informazioni sullo schermo. In questa fase
l'utente ha a disposizione i seguenti comandi:
n - Battendo n dove n e' il numero di un link presente in
tabella, l'utente avra' a disposizione per il link scelto le
seguenti informazioni:
-) Numero di pacchetti I inviati da un lato all'altro
del link e viceversa (in tabella principale viene
riportato il numero complessivo);
-) Digipeater eventualmente presenti sul link (in
questo caso viene visualizzata la frase
'connessione via: <digipeaters> ', altrimenti
'connessione diretta'.
C (Capture ON - OFF) - Battendo 'c' l'utente puo' attivare o
disattivare la cattura byte per byte di tutti i pacchetti che
transitano. La condizione di default e' OFF, lo stato della
variabile viene comunque sempre visualizzato. Tale variabile.
se posta ON, puo' tornare in modo OFF manualmente, quando
l'utente lo decide, oppure automaticamente nei seguenti due
casi: quando si e' superato il numero di pacchetti massimi
catturabili NUMPAKMAX (per ora posta a 250 ), o ancora, in
sistemi con basse disponibilita' di memoria, quando la
memoria disponibile per la cattura di altri pacchetti e'
insufficiente.
A (Analisi pacchetti) - Battendo 'a' l'utente entra in un
ambiente dove e' possibile visualizzare i pacchetti catturati
precedentemente.
A questo livello, sullo schermo viene visualizzato un
pacchetto per volta secondo queste modalita': in alto vi sono
il numero d'ordine del pacchetto catturato, il numero di
pacchetti che sono nel buffer e una minima decodifica del
pacchetto stesso i cui bytes vengono rappresentati in codice
esadecimale.
Sono poi rappresentati divisi nei campi descritti nel
paragrafo relativo al protocollo ax25, tutti i byte contenuti
nel pacchetto. Se esiste un campo informativo, e' data anche
una conversione dei bytes in codice ASCII; se in tale campo
sono presenti caratteri non stampabili essi vengono
sostituiti dal carattere di codice ASCII 2d (una 'faccetta'
in reverse video) se si tratta di un carattere il cui codice
e' < 26d, da quello di codice ASCII 254d (un quadratino
bianco) se si tratta di uno di codice > 127d. L' utente ora
potra' spostarsi nel buffer di cattura tramite i comandi:
Up per vedere il dato precedente;
Dn per vedere il dato seguente;
Home per andare all'inizio del buffer;
End per andare in fondo al buffer;
F3 per abbandonare la sessione pulendo il buffer
F5 per abbandonare la sessione mantenendo i dati nel
buffer.
Come gia' detto in precedenza, i dati in arrivo vengono
elaborati ogni TEMPO_AGGIORNAMENTO secondi: poiche' il numero
di secondi e' piuttosto basso, e quindi solo pochi pacchetti
possono essere in attesa di elaborazione, quest'ultima e'
praticamente istantanea, tanto che l'utente che sta
effettuando l'analisi pacchetti quasi non viene disturbato,
se non rilevando che, in caso di 'capture' posta a ON, il
numero di pacchetti nel buffer di cattura e' aumentato. La
sessione puo' essere abbandonata o mantenendo i dati nel
buffer di cattura, oppure svuotandolo lasciando piu' spazio
per una successiva cattura.
D (DOS Shell) - Premendo 'd' l'utente ha a disposizione una
shell del sistema operativo. In essa e' possibile effettuare
in generale tutto cio' che normalmente si fa da DOS, a patto
di tenere presente queste due avvertenze: non trattenersi
molto in tale sessione specie se vi e' molto traffico sul
canale radio (i pacchetti in arrivo si accumulano nel buffer
di seriale e possono andare in overrun) ed evitare nel modo
piu' assoluto di eseguire programmi che agiscano sulla stessa
porta seriale (COM1:). In questo caso NETSPY non
funzionerebbe piu' e sarebbe necessario un reset di tutto il
sistema.
V (Vista Grafica) - Questa e' l'opzione che consente di
passare dal formato tabellare al formato grafico.
Quest'ultimo riespecchia fedelmente il formato tabellare;
l'angolo superiore sinistro e' assegnato in permanenza alla
visualizzazione del nominativo di tutti i pacchetti in
transito, costituendo cosi' l'equivalente grafico della
'scroll window' del modo 'testo' in cui sono visualizzati gli
ultimi 5 pacchetti ricevuti.
E' opportuno far notare che cio' che si vede sullo schermo
sono i collegamenti che hanno mittente e destinatario nel
pacchetto e cioe' quelli a LIVELLO FISICO AX25, compresi
NETROM e IP.
Nel formato grafico sono disponibili due comandi per
l'utente:
(R)idisegna le stazioni sullo schermo vengono
riposizionate; questo per permettere all'utente di
cambiare una configurazione poco apprezzabile da un
punto di vista estetico.
ESC torna al menu precedente, dopo aver 'chiuso' il
sistema grafico.
E (Esce senza salvare)- Con questo comando l'utente ritorna a
DOS senza salvare sul file LOG.PKT il contenuto della tabella
principale. In detto file rimarranno solo gli eventuali link
'vecchi' eliminati dalla tabella per dare posto ai nuovi
arrivati. All'uscita del programma e' possibile togliere il
TNC da KISS mode per farlo tornare in modo normale, mediante
la PutSer1(), con la sequenza 0Ch, FFh, 0Ch valida per il PK
87 della AEA.
S (Esce Salvando su file) - Battendo 's' l'utente esce
(previa conferma) dal programma salvando su file il contenuto
della tabella principale.
5.3 LE PRINCIPALI STRUTTURE DATI.
In questa sezione vengono descritte le principali strutture
dati usate per implementare il programma.
Avendo gia' parlato del buffer di seriale Com1buf vediamo ora
le rimanenti strutture significative.
La piu' importante e' sicuramente Info[]: essa contiene tutte
le informazioni relative ad un link: i nominativi degli
operatori (.link[]), il tipo di protocollo presente a livello
piu' alto (.protocollo[]), il numero di pacchetti I scambiati
(.num_p), il numero di collisioni rilevate (.num_coll), il
numero di pacchetti inviati da una parte all'altra del link e
viceversa (.a_to_btot, .b_to_atot), il numero progressivo
dell'ultimo pacchetto I intercettato (.a_to_bprog,
.b_to_aprog), la data e l'ora del primo e dell'ultimo
pacchetto intercettato (.data_primo, .data_ultimo,
.ora_primo, .ora_ultimo) lo stato del link, cioe' se esiste
ancora la connessione o se e' gia' cessata (.stato), e una
struttura a lista del tipo elemento - puntatore all'elemento
successivo dove vengono salvati i nominativi degli eventuali
digipeaters (.digi_struct).
Un'altra importante struttura dati e' quella nella quale sono
memorizzati byte per byte i pacchetti che devono essere
intercettati. Essa e' costituita da un array buffer[] di
strutture composte dai seguenti campi: .*pacchetto, che
contiene i byte relativi al pacchetto catturato, e .pac_len
che indica la sua lunghezza.
Per quanto riguarda la parte grafica, le strutture dati
significative sono l'array punto[] di strutture cosi'
composte: (.stato) in cui e' memorizzato lo stato del punto
sullo schermo, (.nome) che contiene il nome dell'eventuale
stazione presente in quel punto e (.link[]) che e' un array
di nomi delle eventuali stazioni collegate.
Questo array e' usato dalle varie funzioni per sapere se un
punto sullo schermo e' libero, se e' una stazione o una
linea. Inoltre, nel caso il punto sia una stazione si tiene
traccia dei suoi eventuali collegamenti con altre stazioni.
L'altra struttura dati di rilievo e' la strittura chiave che
consente di creare una lista di corrispondenze nomi di
stazione - posizione da esse occupata sullo schermo.
In questa lista si inseriscono le nuove stazioni, si trovano
quelle gia' inserite, e vengono rimosse quelle che non
servono piu'; in sostanza, questa struttura svolge le
funzioni di un piccolo data-base.
5.4 LE PRINCIPALI COSTANTI DEL PROGRAMMA.
Si riporta un elenco delle costanti significative presenti
nel programma, dove sono implementate tramite #define.
Volutamente vengono tralasciate le costanti relative alle
routine di inizializzazione ed uso della porta seriale.
BUFSIZE: 10000 - Dimensione in byte del buffer di seriale.
FEND: 192 - Byte del kiss mode che da' l'inizio e la fine di
un pacchetto.
FESC, TFEND, TFESC - Parametri che permettono di eseguire il
byte stuffing di un pacchetto.
NET_ROM: 207, IP: 204 - Valori del Byte PID che
identificano i rispettiviprotocolli a livello 3.
MAX_LINK: 10 - Numero massimo di link nella tabella
principale.
TIME_OUT: 15 - Numero di minuti dopo i quali un link
'silenzioso' viene considerato disconnesso. TIME_OUT deve
essere compresa nell'intervallo (0, 59).
NUMPAKMAX: 250 - Numero massimo di pacchetti catturabili
byte per byte.
TEMPO_AGGIORNAMENTO: 30 - Numero di secondi dopo i quali
viene svuotato il buffer di seriale durante l'uso della
sessione di Analisi dei pacchetti.
5.5 LE PRINCIPALI ROUTINE DEL PROGRAMMA.
void Introduzione (void) - All'inizio del programma
visualizza le due pagine di informazioni.
void Lista_Digipeater() - Questa routine crea la lista dei
digipeater eventualmente presenti nel campo indirizzo,
salvandoli nella struttura Digi_struct.
void Byte_Stuffing(), Decodifica_Ind(),
Decodifica_Controllo(), Decodifica_Tipo() - Queste routines
decodificano i parametri significativi di ogni pacchetto
intercettato.
void Gestisci_File (void) - All'inizio del programma
controlla se esiste gia' un file "log.pkt" - Se si' lo apre
per l'eventuale aggiunta dei dati, altrimenti lo crea
scrivendo per prima cosa delle informazioni su come detto
file e' strutturato.
void Aggiorna_Connessioni (void) - Questa routine considera
disconnesso un link che non dialoga da piu' di TIME_OUT
minuti, ponendo cosi' lo stato a 0 (disconnesso). Utile per
quei link di cui non si riceve il pacchetto DISC o per quegli
altri in cui il dialogo avviene al di fuori del normale AX25
(per esempio link in NETROM o IP).
void Scrivi_Orologio (byte x,y) - Questa routine aggiorna data
e ora correnti che vengono visualizzate nella schermata
principale alle posizioni indicate da x e y.
void Visualizza_Menu (void), void Mostra_Info (void),
void Host_Off (void), void Esci() - Visualizzano il menu dei
comandi disponibili nella finestra video in basso a destra,
e/o gestiscono le eventuali scelte dell'utente.
void Usa_FullScreen (void) - void Usa_Window1 (void) - void
(Usa_Window2) - Gestiscono il sistema di riferimento attuale
per il cursore.
Int Esiste_Link (unsigned char *i, crea_posto_vuoto) - Questa
routine analizza il link presente nella variabile globale
LINK_1 e stabilisce se in tabella esiste gia' oppure no. In
caso positivo ritorna 1, altrimenti ritorna 0. In
quest'ultimo caso, inoltre, se crea_posto_vuoto e' a 1, la
routine restituisce tramite *i l'indice di tabella dove e'
possibile memorizzare il nuovo link (eventualmente
eliminando, salvandolo su file tramite apposita routine, il
link disconnesso piu' vecchio; se nessun link in tabella e'
in stato di disconnessione, la ricerca del piu' vecchio viene
fatta su tutti i link) .
void Salva_Info(unsigned char nr) - Salva su file il link di
indice nr della tabella.
void Crea_Nuovo_Link (unsigned char in, fr) - Crea il nuovo
link LINK1 alla posizione in, ponendo i parametri del link in
accordo con il frame ricevuto fr.
void Cattura_Pacchetto(), Resetta_Capture() - Gestiscono la
cattura byte a byte dei pacchetti riferendosi alla variabile
capture che viene eventualmente resettata quando si
verificano certe condizioni.
void Analisi_Pacchetti() - Permette l'analisi dei pacchetti
catturati, secondo le modalita' di cui sopra.
void Salva_Tabella (void) - All'uscita del programma, se
richiesto, salva su file la tabella corrente.
Dos_Shell (void) - Apre una shell del DOS gestendo il
salvataggio della situazione video e tutti gli imprevisti che
possono capitare a tale livello.
Controlla_Tbaud (int*speed) - Controlla che il valore di
velocita' inserito sulla linea di comando sia ragionevole,
(300, 600, 1200, 2400, 4800 , 9600) altrimenti lo assume
1200.
void StartPlacet(void) - Predispone la partenza del sistema
grafico e la creazione dinamica delle strutture dati in
funzione del tipo di scheda video disponibile.
void EndPlacet(void) - Rilascia la memoria allocata dalla
funzione precedente e predispone il ritorno del sistema al
modo 'testo'.
word PiazzaStazione(char *nome) - Disegna una stazione sullo
schermo in modo casuale e ritorna un numero associato alla
sua posizione.
void PiazzaStazioni(char *nome1, char *nome2, byte pr
word *s1, word *s2) - Disegna due
stazioni sullo schermo in modo casuale, ritorna in s1 e s2 le
posizioni delle medesime e provvede a collegarle con una
linea di diverso tipo a seconda del valore del protocolllo
contenuto in pr.
boolean LinkaStazioni(word s1, char *nome, byte pr, word *s2)
Collega la stazione associata a nome alla stazione s1, gia'
presente sullo schermo con una linea di diverso tipo a
sseconda del valore del protocollo contenuto in pr.
Ritorna in s2 la posizione della stazione collegata; se la
funzione non riesce a collegare la nuova stazione e quella
vecchia, la funzione ritorna FALSE.
boolean LinkAttivi(word s) - Questa funzione ritorna TRUE o
FALSE a seconda che la stazione s sia o meno collegata con
altre stazioni.
boolean StazioniCollegate(word s1, word s2) - Questa funzione
ritorna TRUE se la stazione s1 e la s2 sono collegate,
FALSE altrimenti.
void RimuoviStazione(word s) - Cancella la stazione s dallo
schermo a aggiorna l'array punto[].
void RimuoviLInk(word s1, word s2) - Cancella il collegamento
fra la stazione s1 e la s2 e aggiorna l'array punto[].
void BlinkStazione(word s) - Fa lampeggiare la stazione s.
void AddStazione(char *nome, word s) - Aggiunge nel data-base
la nuova relazione nome_stazione - posizione, aggiornando la
lista chiave.
void DelDtazione(char *nome) - Rimuove dal data-base la
posizione della stazione associata a nome: se la stazione non
e' presente nel data-base, la funzione ritorna NOT_FOUND.
void ClearKeyt(void) - Reinizializza il data-base rilasciando
tutta la memoria di cui era costituita la lista chiave.