Manuale per il simulatore di rete ns-3. Capitolo 5

Manuale per il simulatore di rete ns-3. Capitolo 5
capitoli 1,2
capitolo 3
capitolo 4

5 Configurazione
5.1 Utilizzo del modulo di logging
5.1.1 Panoramica del logging
5.1.2 Abilitazione del logging
5.1.3 Aggiunta del logging al tuo codice
5.2 Utilizzo degli argomenti della riga di comando
5.2.1 Sovrascrivere i valori degli attributi predefiniti
5.2.2 Catturare i tuoi comandi personalizzati
5.3 Utilizzo del sistema di tracciamento
5.3.1 Tracciamento ASCII
Parsing dei tracciamenti ASCII
5.3.2 Tracciamento PCAP

Capitolo 5

Configurazione

5.1 Utilizzo del modulo di logging

Abbiamo già esaminato brevemente il modulo di logging di ns-3, controllando lo script first.cc. In questo capitolo daremo un'occhiata più da vicino alle possibili applicazioni della sottosistema di logging.

5.1.1 Panoramica del logging

Molti grandi sistemi supportano qualche forma di registrazione dei messaggi e ns-3 non è un'eccezione. In alcuni casi, nella "console dell'operatore" (che di solito è stderr nei sistemi basati su Unix) vengono registrati solo i messaggi di errore. In altri sistemi, possono essere emessi messaggi di avviso e informazioni più dettagliate. In alcuni casi, gli strumenti di logging vengono utilizzati per emettere messaggi di debug, che possono rapidamente "offuscare" il output.

L'approccio utilizzato in ns-3 presuppone che tutti questi livelli di informatività siano utili, e offriamo un metodo selettivo e multi-livello per la registrazione dei messaggi. Il logging può essere completamente disattivato, abilitato per singoli componenti o a livello globale. Questo è gestito attraverso livelli configurabili di informatività. Il modulo di logging di ns-3 fornisce un modo relativamente semplice per ottenere informazioni utili dalla tua simulazione.

Devi capire che offriamo un meccanismo di uso generale — tracciamento — per estrarre dati dai tuoi modelli, che dovrebbe essere preferito per l'output durante la modellazione (per ulteriori dettagli sul nostro sistema di tracciamento, vedi la sezione 5.3 del manuale). Il logging dovrebbe essere il metodo preferito per ottenere informazioni di debug, avvisi, messaggi di errore o per un rapido output di messaggi dai tuoi script o modelli in qualsiasi momento.

Attualmente, nel sistema sono definiti sette livelli (tipi) di messaggi di log in ordine crescente di informatività.

  • LOG_ERROR — registrazione dei messaggi di errore (macro associato: NS_LOG_ERROR);
  • LOG_WARN — registrazione dei messaggi di avviso (macro associato: NS_LOG_WARN);
  • LOG_DEBUG — registrazione di messaggi di debug relativamente rari (macro associato: NS_LOG_DEBUG);
  • LOG_INFO — registrazione dei messaggi informativi sul progresso del programma (macro associato: NS_LOG_INFO);
  • LOG_FUNCTION — registrazione dei messaggi che descrivono ogni funzione chiamata (due macro associate: NS_LOG_FUNCTION, utilizzata per le funzioni membro, e NS_LOG_FUNCTION_NOARGS, utilizzata per le funzioni statiche);
  • LOG_LOGIC — registrazione dei messaggi che descrivono il flusso logico all'interno di una funzione (macro associato: NS_LOG_LOGIC);
  • LOG_ALL — registrazione di tutto quanto sopra (non c'è macro associato).
    Per ogni tipo (LOG_TYPE) c'è anche un tipo LOG_LEVEL_TYPE, che, se utilizzato, consente di registrare oltre al proprio livello tutti i livelli superiori. (Di conseguenza, LOG_ERROR e LOG_LEVEL_ERROR, così come LOG_ALL e LOG_LEVEL_ALL sono funzionalmente equivalenti.) Ad esempio, attivando LOG_INFO verranno visualizzati solo i messaggi forniti dalla macro NS_LOG_INFO, e attivando LOG_LEVEL_INFO verranno inclusi anche i messaggi forniti dalle macro NS_LOG_DEBUG, NS_LOG_WARN e NS_LOG_ERROR.

Forniamo anche una macro di registrazione incondizionata, che viene sempre visualizzata, indipendentemente dal livello di log o dal componente selezionato.

  • NS_LOG_UNCOND — registrazione incondizionata del messaggio associato (senza livello di log associato).

Ogni livello può essere richiesto separatamente o cumulativamente. La registrazione può essere configurata tramite la variabile di ambiente sh NS_LOG o tramite la registrazione di una chiamata a una funzione di sistema. Come mostrato in precedenza, il sistema di registrazione ha documentazione Doxygen e ora è il momento di rivederla, se non lo hai già fatto.

Ora che hai letto la documentazione in dettaglio, utilizziamo queste conoscenze per ottenere alcune informazioni interessanti dall'esempio di script scratch/myfirst.cc, che hai già compilato.

5.1.2 Abilitazione del logging

Usiamo la variabile di ambiente NS_LOG per eseguire altri log, ma prima, solo per orientarti, esegui l'ultimo script, come hai fatto in precedenza,

$ ./waf --run scratch/myfirst

Dovresti vedere già l'output familiare del primo programma di esempio ns-3

$ Waf: Entrando nella directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Uscendo dalla directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build' 'build'
finito con successo (0.413s)
Inviati 1024 byte a 10.1.1.2
Ricevuti 1024 byte da 10.1.1.1
Ricevuti 1024 byte da 10.1.1.2

Si scopre che i messaggi "inviati" e "ricevuti" che vedi sopra sono in realtà messaggi registrati da UdpEchoClientApplication e UdpEchoServerApplication. Ad esempio, possiamo chiedere all'applicazione client di stampare informazioni aggiuntive, impostando il suo livello di registrazione tramite la variabile di ambiente NS_LOG.

Da questo momento in poi, presumerò che tu stia usando una shell simile a sh, che utilizza la sintassi "VARIABLE = value". Se stai usando una shell simile a csh, dovrai convertire i miei esempi nella sintassi "setenv variable value" richiesta da quelle shell.

Attualmente, l'applicazione UDP echo client risponde alla seguente riga di codice in scratch/myfirst.cc,

LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO);

Essa attiva il livello di registrazione LOG_LEVEL_INFO. Quando passiamo il flag del livello di registrazione, in realtà stiamo attivando quel livello e tutti i livelli inferiori. In questo caso, abbiamo attivato NS_LOG_INFO, NS_LOG_DEBUG, NS_LOG_WARN e NS_LOG_ERROR. Possiamo aumentare il livello di registrazione e ottenere più informazioni, senza modificare lo script e ricompilare, impostando la variabile di ambiente NS_LOG nel seguente modo:

$ export NS_LOG=UdpEchoClientApplication=level_all

Così impostiamo il seguente valore della variabile NS_LOG per la shell sh,

UdpEchoClientApplication=level_all

Il lato sinistro dell'assegnazione è il nome del componente registrabile che vogliamo configurare, mentre il lato destro è il flag che vogliamo applicare. In questo caso, stiamo per includere nell'applicazione tutti i livelli di debug. Se esegui lo script con questo NS_LOG impostato, il sistema di registrazione ns‑3 noterà le modifiche e dovresti vedere il seguente output:

Waf: Entrando nella directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Uscendo dalla directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' finito con successo (0.404s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
Inviati 1024 byte a 10.1.1.2
Ricevuti 1024 byte da 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
Ricevuti 1024 byte da 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Le informazioni di debug aggiuntive fornite dall'applicazione sono ora conformi al livello NS_LOG_FUNCTION. Mostra ogni caso di chiamata delle funzioni durante l'esecuzione dello script. In generale, è preferibile utilizzare (almeno) nelle funzioni-metodiNS_LOG_FUNCTION (this). Usa NS_LOG_FUNCTION_NOARGS ()
solo nelle funzioni statiche. Tuttavia, si prega di notare che nel sistema ns-3 non ci sono requisiti per mantenere alcuna funzionalità di registrazione. La decisione su quante informazioni vengono registrate rimane a discrezione dello sviluppatore del modello. Nel caso di applicazioni echo, è disponibile una grande quantità di dati in uscita per la registrazione.

Ora puoi visualizzare il registro delle chiamate delle funzioni effettuate dall'applicazione. Se guardi attentamente, noterai i due punti tra la riga UdpEchoClientApplication e il nome del metodo, nel punto in cui ci si aspetterebbe di vedere l'operatore di ambito C++ (::). Questo è fatto intenzionalmente.

Infatti, non è il nome della classe, ma il nome del componente di registrazione. Quando c'è una corrispondenza tra il file sorgente e la classe, di solito è il nome della classe, ma devi capire che in realtà non è il nome della classe, e lì c'è un solo due punti invece di due punti doppi. È un modo per aiutarti, in modo relativamente sottile, a separare concettualmente il nome del componente di registrazione dal nome della classe.

Tuttavia, in alcuni casi può essere difficile determinare quale metodo genera effettivamente il messaggio di registro. Se guardi il testo sopra, ti verrà in mente la domanda da dove proviene la stringa “Ricevuti 1024 byte da 10.1.1.2». Puoi risolvere questo problema impostando il livello prefix_func nell variabile d'ambiente NS_LOG. Prova a fare quanto segue,

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func'

Si prega di notare che le virgolette sono necessarie poiché la barra verticale, che utilizziamo per indicare l'operazione OR, è anche un delimitatore di pipe Unix. Ora, se esegui lo script, vedrai che il sistema di registrazione garantisce che ogni messaggio da questo registro abbia un prefisso con il nome del componente.

Waf: Entrando nella directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Uscendo dalla directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' completato con successo (0.417s)
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Inviato 1024 byte a 10.1.1.2
Ricevuti 1024 byte da 10.1.1.1
UdpEchoClientApplication:HandleRead(0x6241e0, 0x624a20)
UdpEchoClientApplication:HandleRead(): Ricevuti 1024 byte da 10.1.1.2
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()

Ora puoi vedere che tutti i messaggi provenienti dall'applicazione UDP echo client sono identificati come tali. Il messaggio "Ricevuti 1024 byte da 10.1.1.2" è ora chiaramente definito come proveniente dall'applicazione echo client. Il messaggio rimanente dovrebbe provenire dall'applicazione UDP echo server. Possiamo attivare questo componente inserendo un elenco di componenti separati da due punti nella variabile d'ambiente NS_LOG.

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func:
               UdpEchoServerApplication=level_all|prefix_func'

Attenzione: nell'esempio di testo sopra, dovrai rimuovere il carattere di nuova riga dopo i due punti (:), utilizzato per la formattazione del documento. Ora, se esegui lo script, vedrai tutti i messaggi di log dalle applicazioni echo client e server. Potresti notare che questo può essere molto utile durante il debug.

Waf: Entrando nella directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
Waf: Uscendo dalla directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build'
'build' completato con successo (0.406s)
UdpEchoServerApplication:UdpEchoServer()
UdpEchoClientApplication:UdpEchoClient()
UdpEchoClientApplication:SetDataSize(1024)
UdpEchoServerApplication:StartApplication()
UdpEchoClientApplication:StartApplication()
UdpEchoClientApplication:ScheduleTransmit()
UdpEchoClientApplication:Send()
UdpEchoClientApplication:Send(): Inviato 1024 byte a 10.1.1.2
UdpEchoServerApplication:HandleRead(): Ricevuti 1024 byte da 10.1.1.1
UdpEchoServerApplication:HandleRead(): Echoing packet
UdpEchoClientApplication:HandleRead(0x624920, 0x625160)
UdpEchoClientApplication:HandleRead(): Ricevuti 1024 byte da 10.1.1.2
UdpEchoServerApplication:StopApplication()
UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

A volte è utile avere la capacità di vedere il tempo di simulazione in cui è stato creato il messaggio di log. Puoi farlo aggiungendo un bit di O prefix_time:

$ export 'NS_LOG=UdpEchoClientApplication=level_all|prefix_func|prefix_time: UdpEchoServerApplication=level_all|prefix_func|prefix_time'

Ancora una volta, dovrai rimuovere il carattere di nuova riga sopra. Se ora esegui lo script, dovresti vedere il seguente output:

Waf: Entrando nella directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Uscendo dalla directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
'build' completato con successo (0.418s)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:Send()
2s UdpEchoClientApplication:Send(): Inviati 1024 byte a 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Ricevuti 1024 byte da 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Rispondendo al pacchetto
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Ricevuti 1024 byte da 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Si prega di notare che il costruttore per UdpEchoServer è stato chiamato durante la simulazione di 0 secondi. Questo accade in realtà prima dell'inizio della simulazione, ma questo tempo viene visualizzato come zero secondi. Lo stesso vale per il messaggio del costruttore di UdpEchoClient.

Waf: Entrando nella directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Uscendo dalla directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
'build' completato con successo (0.418s)
0s UdpEchoServerApplication:UdpEchoServer()
0s UdpEchoClientApplication:UdpEchoClient()
0s UdpEchoClientApplication:SetDataSize(1024)
1s UdpEchoServerApplication:StartApplication()
2s UdpEchoClientApplication:StartApplication()
2s UdpEchoClientApplication:ScheduleTransmit()
2s UdpEchoClientApplication:Send()
2s UdpEchoClientApplication:Send(): Inviati 1024 byte a 10.1.1.2
2.00369s UdpEchoServerApplication:HandleRead(): Ricevuti 1024 byte da 10.1.1.1
2.00369s UdpEchoServerApplication:HandleRead(): Rispondendo al pacchetto
2.00737s UdpEchoClientApplication:HandleRead(0x624290, 0x624ad0)
2.00737s UdpEchoClientApplication:HandleRead(): Ricevuti 1024 byte da 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
10s UdpEchoClientApplication:StopApplication()
UdpEchoClientApplication:DoDispose()
UdpEchoServerApplication:DoDispose()
UdpEchoClientApplication:~UdpEchoClient()
UdpEchoServerApplication:~UdpEchoServer()

Ricordiamo che lo script scratch/first.cc ha avviato l'applicazione echo server un secondo prima dell'inizio della simulazione. Ora puoi vedere che il metodo StartApplication del server viene effettivamente chiamato al primo secondo. Puoi anche notare che l'echo client viene avviato al secondo secondo della simulazione, come richiesto nello script.

Ora puoi seguire l'andamento della simulazione attraverso la chiamata a ScheduleTransmit nel client, che chiama Send richiamando HandleRead nell'applicazione echo server. Si noti che il tempo scaduto per l'invio del pacchetto attraverso il collegamento punto-punto è di 3,69 millisecondi. È evidente che l'echo server registra il messaggio che ha risposto al pacchetto e, dopo un ritardo nel canale, puoi vedere che l'echo client riceve il pacchetto di echo nel suo metodo HandleRead.

In questa simulazione, molte cose accadono in modo invisibile per te. Ma puoi seguire facilmente l'intero processo abilitando tutti i componenti di registrazione nel sistema. Prova a impostare la variabile NS_LOG con il seguente valore,

$ export 'NS_LOG=*=level_all|prefix_func|prefix_time'

L'asterisco sopra è un carattere jolly per il componente di registrazione. Questo attiverà tutte le registrazioni in tutti i componenti utilizzati nella simulazione. Non riprodurrò qui l'output (al momento della scrittura genera 1265 righe di output per un pacchetto echo), ma puoi reindirizzare queste informazioni in un file e visualizzarlo nel tuo editor preferito,

$ .\/waf --run scratch\/myfirst > log.out 2>&1

Personalmente, utilizzo questa versione estremamente verbosa del logging quando ho un problema e non ho idea di dove le cose siano andate male. Posso seguire facilmente l'esecuzione del codice senza impostare punti di interruzione e eseguire il debug passo dopo passo. Posso semplicemente modificare l'output nel mio editor preferito e cercare ciò che mi aspetto, vedendo cosa avviene che non mi aspettavo. Quando ho un'idea generale di cosa non stia funzionando, passo al debugger per esaminare in dettaglio il problema. Questo tipo di output può essere particolarmente utile quando il tuo script fa qualcosa di completamente inaspettato. Se utilizzi solo il debugger, potresti perdere completamente una svolta inaspettata. Il logging rende tali svolte evidenti.

5.1.3 Aggiunta del logging al tuo codice

Puoi aggiungere nuove voci alle tue simulazioni effettuando chiamate al componente log da diversi macro. Facciamo questo nello script myfirst.cc, che abbiamo nella directory "pulita". Ricordiamo che abbiamo definito in questo script il componente di logging:

NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");

Sei a conoscenza del fatto che puoi abilitare il logging di tutti i messaggi di questo componente impostando la variabile d'ambiente NS_LOG a diversi livelli. Continuiamo e aggiungiamo alcune voci allo script. Il macro utilizzato per aggiungere messaggi di livello informativo al log è NS_LOG_INFO. Aggiungiamo un messaggio (proprio prima di iniziare a creare i nodi) che ti avverte che lo script è nella fase di creazione della topologia ("Creating Topology"). Questo si fa nel seguente frammento di codice,
Apri scratch/myfirst.cc nel tuo editor preferito e aggiungi la riga,
NS_LOG_INFO ("Creating Topology");
proprio prima delle righe,

NodeContainer nodes;
nodes.Create (2);

Ora compila lo script utilizzando waf, e ripristina la variabile NS_LOG per disattivare il flusso di logging che abbiamo attivato in precedenza:

$ .\/waf
$ export NS_LOG=
Ora, se esegui lo script,
$ .\/waf --run scratch\/myfirst

non vedrai il nuovo messaggio, poiché il componente di logging associato (FirstScriptExample) non è stato abilitato. Per vedere il tuo messaggio, devi attivare il componente di logging FirstScriptExample con un livello non inferiore a NS_LOG_INFO. Se vuoi semplicemente vedere questo specifico livello di logging, puoi abilitarlo così,

$ export NS_LOG=FirstScriptExample=info

Se esegui ora lo script, vedrai un nuovo messaggio «Creating Topology».

Waf: Entrando nella directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Uscendo dalla directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
'build' completato con successo (0.404s)
Creating Topology
Inviati 1024 byte a 10.1.1.2
Ricevuti 1024 byte da 10.1.1.1
Ricevuti 1024 byte da 10.1.1.2

5.2 Utilizzo degli argomenti della riga di comando

5.2.1 Sovrascrivere i valori degli attributi predefiniti

Un altro modo per modificare il comportamento degli script ns-3 senza modificarli e ricompilarli è utilizzare gli argomenti della riga di comando. Forniamo un meccanismo per analizzare gli argomenti della riga di comando e impostare automaticamente variabili locali e globali in base ai risultati.

Il primo passo nell'utilizzo del sistema degli argomenti della riga di comando è dichiarare l'analizzatore della riga di comando. È abbastanza semplice farlo (nella tua funzione principale), come nel seguente codice,

int
main (int argc, char *argv[])
{
...
CommandLine cmd;
cmd.Parse (argc, argv);
...
}

Questo semplice frammento di due righe è in realtà molto utile di per sé. Apre la porta a variabili globali ns-3 e al sistema di attributi. Aggiungiamo due righe di codice all'inizio della funzione principale dello script. scratch/myfirst.cc. Procedendo, compiliamo lo script e lo eseguiamo, richiedendo assistenza nel seguente modo,

$ ./waf --run "scratch/myfirst --PrintHelp"

Questo comando chiederà Waf di eseguire lo script scratch/myfirst e di passargli l'argomento della riga di comando --PrintHelp. Le virgolette sono necessarie per indicare a quale programma è destinato l'argomento. L'analizzatore della riga di comando rileverà l'argomento --PrintHelp e restituirà una risposta,

Waf: Entrando nella directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
Waf: Uscendo dalla directory `/home/craigdo/repos/ns-3-allinone/ns-3-dev/build`
'build' completato con successo (0.413s)
TcpL4Protocol:TcpStateMachine()
CommandLine:HandleArgument(): Gestisci arg nome=PrintHelp valore=
--PrintHelp: Stampa questo messaggio di aiuto.
--PrintGroups: Stampa l'elenco dei gruppi.
--PrintTypeIds: Stampa tutti i TypeIds.
--PrintGroup=[group]: Stampa tutti i TypeIds del gruppo.
--PrintAttributes=[typeid]: Stampa tutti gli attributi di typeid.
--PrintGlobals: Stampa l'elenco delle variabili globali.

Ora consideriamo l'opzione --PrintAttributes. Abbiamo già menzionato il sistema di attributi ns-3, mentre esploravamo lo script first.cc. Abbiamo visto le seguenti righe di codice,

PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));

e abbiamo detto che DataRate è in realtà un attributo PointToPointNetDevice. Applichiamo l'analizzatore degli argomenti della riga di comando per visualizzare gli attributi PointToPointNetDevice. L'elenco di aiuto indica che dobbiamo fornire TypeId. Questo è il nome della classe a cui appartengono gli attributi di interesse. Nel nostro caso sarà ns3::PointToPointNetDevice. Continuiamo, inserite

$ .\/waf --run "scratch\/myfirst --PrintAttributes=ns3::PointToPointNetDevice"

Il sistema stamperà tutti gli attributi di questo tipo di dispositivo di rete. Vedrete che tra gli attributi nell'elenco ci sono

--ns3::PointToPointNetDevice::DataRate=[32768bps]:
Il tasso di dati predefinito per i collegamenti punto a punto.

Questo è il valore predefinito che sarà utilizzato dal sistema quando si crea un oggetto PointToPointNetDevice. Sovrascriveremo questo valore predefinito utilizzando il parametro Attribute in PointToPointHelper sopra. Utilizziamo i valori predefiniti per i dispositivi e i canali punto a punto. Per fare ciò, rimuoviamo le chiamate SetDeviceAttribute e SetChannelAttribute da myfirst.cc, che abbiamo nella directory pulita.

Il vostro script dovrebbe ora semplicemente dichiarare PointToPointHelper e non eseguire alcuna operazione di configurazione, come mostrato nell'esempio qui sotto,

...
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
...

Continuate e create un nuovo script con Waf (.\/waf) e torniamo indietro e attiviamo alcuni log dall'applicazione server UDP echo e attiviamo il prefisso del tempo.

$ export 'NS_LOG=UdpEchoServerApplication=level_all|prefix_time'

Se eseguite lo script, dovreste vedere il seguente output:

Waf: Entrando nella directory `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'\nWaf: Uscendo dalla directory `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'\n'build' completato con successo (0.405s)\n0s UdpEchoServerApplication:UdpEchoServer()\n1s UdpEchoServerApplication:StartApplication()\nInviati 1024 byte a 10.1.1.2\n2.25732s Ricevuti 1024 byte da 10.1.1.1\n2.25732s Ricevuta del pacchetto\nRicevuti 1024 byte da 10.1.1.2\n10s UdpEchoServerApplication:StopApplication()\nUdpEchoServerApplication:DoDispose()\nUdpEchoServerApplication:~UdpEchoServer()

Ricordiamo che l'ultima volta che abbiamo guardato il tempo di simulazione, il momento in cui il pacchetto è stato ricevuto dal server echo era alle 2,00369 secondi.

2.00369s UdpEchoServerApplication:HandleRead(): Ricevuti 1024 byte da 10.1.1.1

Ora riceve il pacchetto a 2.25732 secondi. Questo perché abbiamo semplicemente ripristinato la velocità di trasmissione del PointToPointNetDevice da cinque megabit al secondo al valore predefinito di 32768 bit al secondo. Se avessimo inserito un nuovo DataRate tramite la riga di comando, potremmo accelerare nuovamente la nostra simulazione. Lo faremo nel seguente modo, secondo la formula implicata nell'elemento di aiuto:

$ .\/waf --run "scratch\/myfirst --ns3::PointToPointNetDevice::DataRate=5Mbps"

Di conseguenza, il valore dell'attributo DataRate per impostazione predefinita tornerà a cinque megabit al secondo. Sei sorpreso dal risultato? Si scopre che, per ripristinare il comportamento originale dello script, dobbiamo anche impostare il ritardo del canale corrispondente alla velocità della luce. Possiamo chiedere al sistema della riga di comando di stampare gli attributi del canale, proprio come abbiamo fatto per il dispositivo di rete:

$ .\/waf --run "scratch\/myfirst --PrintAttributes=ns3::PointToPointChannel"

Scopriremo che l'attributo di ritardo del canale è impostato come segue:

--ns3::PointToPointChannel::Delay=[0ns]:
Ritardo di trasmissione attraverso il canale

Poi possiamo impostare entrambi questi valori predefiniti tramite il sistema della riga di comando,

$ .\/waf --run "scratch\/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms"

in questo caso stiamo ripristinando il tempo che avevamo quando avevamo esplicitamente impostato DataRate e Delay nello script:

Waf: In ingresso nella directory `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
Waf: In uscita dalla directory `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
'build' completato con successo (0.417s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Inviati 1024 byte a 10.1.1.2
2.00369s Ricevuti 1024 byte da 10.1.1.1
2.00369s Ripetizione pacchetto
Ricevuti 1024 byte da 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Nota che il pacchetto è stato nuovamente ricevuto dal server dopo 2.00369 secondi. Potremmo in effetti impostare in questo modo qualsiasi degli attributi utilizzati nello script. In particolare, potremmo impostare valori diversi da uno per gli attributi MaxPackets UdpEchoClient.

Come lo utilizzeresti? Prova. Ricorda che devi commentare il punto in cui stiamo sovrascrivendo il valore dell'attributo predefinito e impostarlo esplicitamente MaxPackets nello script. Poi devi ricompilare lo script. Puoi anche ottenere aiuto sul sintassi per impostare un nuovo valore predefinito dell'attributo tramite riga di comando. Capendo questo, sarai in grado di gestire il numero di pacchetti visualizzati nella riga di comando. Poiché siamo persone diligenti, la nostra riga di comando dovrebbe apparire più o meno così:

$ .\/waf --run "scratch\/myfirst
--ns3::PointToPointNetDevice::DataRate=5Mbps
--ns3::PointToPointChannel::Delay=2ms
--ns3::UdpEchoClient::MaxPackets=2"

La naturale domanda che sorge a questo punto è come conoscere l'esistenza di tutti questi attributi. Ancora una volta, il sistema della riga di comando ha una funzione di aiuto in merito. Se richiediamo aiuto dalla riga di comando, dovremmo vedere:

$ .\/waf --run "scratch\/myfirst --PrintHelp"
myfirst [Program Arguments] [General Arguments]
General Arguments:
--PrintGlobals: Stampa l'elenco delle variabili globali.
--PrintGroups: Stampa l'elenco dei gruppi.
--PrintGroup=[group]: Stampa tutti gli TypeIds del gruppo.
--PrintTypeIds: Stampa tutti gli TypeIds.
--PrintAttributes=[typeid]: Stampa tutti gli attributi di typeid.
--PrintHelp: Stampa questo messaggio di aiuto.

Se scegli l'argomento "PrintGroups", dovresti vedere l'elenco di tutti i gruppi registrati. TypeId. I nomi dei gruppi corrispondono ai nomi dei moduli nella directory sorgente (anche se con la lettera maiuscola). Stampare tutte le informazioni contemporaneamente sarebbe troppo ingombrante, quindi è disponibile un filtro aggiuntivo per stampare informazioni per gruppi. Così, concentrandoci di nuovo sul modulo "point-to-point":

.\/waf --run "scratch\/myfirst --PrintGroup=PointToPoint"
TypeIds nel gruppo PointToPoint:
ns3::PointToPointChannel
ns3::PointToPointNetDevice
ns3::PointToPointRemoteChannel
ns3::PppHeader

Qui puoi trovare i nomi TypeId disponibili per la ricerca degli attributi, ad esempio, in
--PrintAttributes = ns3 :: PointToPointChannel, come mostrato sopra.

Un altro modo per conoscere gli attributi è tramite Doxygen ns-3. Lì c'è una pagina che elenca tutti gli attributi registrati nel simulatore.

5.2.2 Catturare i tuoi comandi personalizzati

Puoi anche aggiungere i tuoi hook tramite il sistema della riga di comando. Questo è piuttosto semplice usando il metodo del parser della riga di comando. AddValue.
Utilizziamo questa possibilità per specificare il numero di pacchetti che devono essere visualizzati, in un modo completamente diverso. Aggiungiamo una variabile locale chiamata nPackets nella funzione main. La impostiamo a uno, per corrispondere al nostro comportamento predefinito precedente. Per consentire al parser della riga di comando di modificare questo valore, dobbiamo catturare questo valore nel parser. Lo facciamo aggiungendo la chiamata AddValue. Vai e modifica lo script scratch/myfirst.cc in modo da iniziare con il seguente codice,

int
main (int argc, char *argv[])
{
uint32_t nPackets = 1;
CommandLine cmd;
cmd.AddValue("nPackets", "Numero di pacchetti da echo", nPackets);
cmd.Parse (argc, argv);
...

Scorri verso il basso fino al punto nello script in cui impostiamo l'attributo MaxPackets e modificalo affinché sia impostato sulla variabile nPackets invece che sulla costante 1, come mostrato di seguito.

echoClient.SetAttribute ("MaxPackets", UintegerValue (nPackets));

Ora, se esegui lo script e fornisci l'argomento --PrintHelp, dovresti vedere il nuovo argomento utente elencato nella schermata di aiuto. Inserisci,

$ .\/waf --run "scratch\/myfirst --PrintHelp"
Waf: Entrando nella directory `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
Waf: Uscendo dalla directory `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
'build' completato con successo (0.403s)
--PrintHelp: Stampa questo messaggio di aiuto.
--PrintGroups: Stampa l'elenco dei gruppi.
--PrintTypeIds: Stampa tutti gli TypeIds.
--PrintGroup=[group]: Stampa tutti gli TypeIds del gruppo.
--PrintAttributes=[typeid]: Stampa tutti gli attributi di typeid.
--PrintGlobals: Stampa l'elenco delle variabili globali.
Argomenti utente:
--nPackets: Numero di pacchetti da inviare

Se desideri cambiare il numero di pacchetti trasmessi, puoi farlo impostando l'argomento - -nPackets nella riga di comando,

$ .\/waf --run "scratch\/myfirst --nPackets=2"

Ora dovresti vedere

Waf: Entrando nella directory `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
Waf: Uscendo dalla directory `\/home\/craigdo\/repos\/ns-3-allinone\/ns-3-dev\/build'
'build' completato con successo (0.404s)
0s UdpEchoServerApplication:UdpEchoServer()
1s UdpEchoServerApplication:StartApplication()
Inviati 1024 byte a 10.1.1.2
2.25732s Ricevuti 1024 byte da 10.1.1.1
2.25732s Echoing packet
Ricevuti 1024 byte da 10.1.1.2
Inviati 1024 byte a 10.1.1.2
3.25732s Ricevuti 1024 byte da 10.1.1.1
3.25732s Echoing packet
Ricevuti 1024 byte da 10.1.1.2
10s UdpEchoServerApplication:StopApplication()
UdpEchoServerApplication:DoDispose()
UdpEchoServerApplication:~UdpEchoServer()

Hai ora inviato due pacchetti. Abbastanza semplice, vero?
Puoi vedere che, come utente di ns‑3, puoi utilizzare il sistema di argomenti della riga di comando per gestire i valori globali e gli attributi. Se sei l'autore del modello, puoi aggiungere nuovi attributi ai tuoi oggetti e questi saranno automaticamente disponibili per la configurazione da parte dei tuoi utenti tramite il sistema della riga di comando. Se sei l'autore dello script, puoi aggiungere nuove variabili ai tuoi script e collegarle senza problemi al sistema della riga di comando.

5.3 Utilizzo del sistema di tracciamento

Il tutto del modellaggio consiste nel creare output per ulteriori studi, e il sistema di tracciamento ns‑3 è il meccanismo principale per farlo. Poiché ns‑3 è un programma in C++, possono essere utilizzati gli strumenti standard di generazione dell'output di un programma in C++:

#include <iostream>
...
int main ()
{
...
std::cout << "The value of x is " << x << std::endl;
...
}

Puoi anche utilizzare il modulo di registrazione per aggiungere un po' di struttura alla tua soluzione. Sono noti molti problemi derivanti da questo approccio, e per risolvere tali problemi abbiamo fornito un sistema comune di tracciamento degli eventi.

Obiettivi principali del sistema di tracciamento ns‑3:

  • Per le attività di base, il sistema di tracciamento dovrebbe consentire all'utente di generare un tracciamento standard per fonti popolari e selezionare gli oggetti che generano il tracciamento;

  • Gli utenti intermedi devono avere la possibilità di estendere il sistema di tracciamento per modificare il formato di uscita generato o per inserire nuove fonti di tracciamento, senza modificare il nucleo del simulatore;

  • Gli utenti esperti possono modificare il nucleo del simulatore per aggiungere nuove fonti e ricevitori di tracciamento. Il sistema di tracciamento ns-3 è costruito sui principi di fonti e ricevitori di tracciamento indipendenti, nonché su un meccanismo unificato per connettere le fonti ai consumatori.

Il sistema di tracciamento ns-3 è costruito sui principi di fonti e ricevitori di tracciamento indipendenti, nonché su un meccanismo unificato per collegare le fonti ai ricevitori. Le fonti di tracciamento sono oggetti che possono segnalare eventi che si verificano nella simulazione e fornire accesso a dati di base di interesse. Ad esempio, una fonte di tracciamento può indicare quando un dispositivo di rete ha ricevuto un pacchetto e fornire accesso al contenuto del pacchetto per i ricevitori di tracciamento interessati.

Le fonti di tracciamento sono di per sé inutili se non sono "collegate" ad altre parti del codice che fanno realmente qualcosa di utile con le informazioni fornite dal ricevitore. I tracciatori sono consumatori di eventi e dati forniti dalle fonti di tracciamento. Ad esempio, si può creare un ricevitore di tracciamento che stamperà le parti interessanti del pacchetto ricevuto (quando collegato alla fonte di tracciamento dell'esempio precedente).

Una giusta ragione per tale chiara separazione è permettere agli utenti di collegare nuovi tipi di ricevitori a fonti di tracciamento esistenti senza dover modificare e ricompilare il nucleo del simulatore. Pertanto, nell'esempio sopra, l'utente può definire un nuovo tracciatore nel proprio script e collegarlo a una fonte di tracciamento esistente definita nel nucleo della simulazione, modificando solo lo script dell'utente.

In questa guida esamineremo alcune fonti e ricevitori predefiniti e mostreremo come configurarli con il minimo sforzo da parte dell'utente. Vedi la Guida ns-3 o le sezioni delle istruzioni per ulteriori informazioni sulla configurazione avanzata del tracciamento, inclusa l'estensione dello spazio dei nomi del tracciamento e la creazione di nuove fonti di tracciamento.

5.3.1 Tracciamento ASCII

ns-3 fornisce funzionalità di supporto che offrono un sistema di tracciamento a basso livello per aiutarti con i dettagli durante la configurazione di tracciati di pacchetti semplici. Se abiliti questa funzione, vedrai i risultati in file ASCII. Per coloro che sono familiari con l'output di ns-2, questo tipo di tracciamento è simile a out.tr, generato da molti script.

Passiamo ai fatti e aggiungiamo alcuni risultati di tracciamento ASCII al nostro script scratch/myfirst.cc. Proprio prima della chiamata a Simulator :: Run (), aggiungi le seguenti righe di codice:
AsciiTraceHelper ascii;

pointToPoint.EnableAsciiAll(ascii.CreateFileStream("myfirst.tr"));

Come in molte altre idiomi di ns-3, questo codice utilizza un oggetto helper per creare tracciati ASCII. La seconda riga contiene due chiamate a metodi annidati. Il metodo 'interno' CreateFileStream () utilizza l'idoma dell'oggetto anonimo per creare un oggetto flusso di file nello stack (senza un nome oggetto) e lo passa al metodo chiamato. In futuro approfondiremo questo argomento, ma tutto ciò che devi sapere in questo momento è che stai creando un oggetto che rappresenta un file con il nome myfirst.tr e passarlo a ns-3. Affidiamo a ns-3 la gestione dell'oggetto creato per tutta la sua vita, durante la quale vengono risolti i problemi causati da una limitazione poco nota (intenzionale) legata ai costruttori di copia degli oggetti flusso in C++.

La chiamata esterna EnableAsciiAll() informa l'assistente che desideri abilitare il tracciamento ASCII nella tua simulazione per tutte le connessioni dei dispositivi punto-punto e che desideri che i ricevitori di tracciamento (specificati) registrino informazioni sul movimento dei pacchetti in formato ASCII.

Per coloro che sono familiari con ns-2, gli eventi tracciati corrispondono ai noti punti di tracciamento che registrano gli eventi '+', '-', 'd' e 'r'.
Ora puoi compilare lo script ed eseguirlo dalla riga di comando:

$ ./waf --run scratch/myfirst

Come molte altre volte, vedrete alcuni messaggi da Waf e poi “‘build’ finished successfully” (costruzione completata con successo) con un certo numero di messaggi dal programma in esecuzione.

Durante l'esecuzione, il programma creerà un file con il nome myfirst.tr. A causa delle modalità operative Waf, per impostazione predefinita il file viene creato non nella directory locale, ma nella directory di livello superiore del repository. Se desiderate cambiare il percorso dove vengono salvate le tracce, potete utilizzare il parametro per Waf --cwd. Non lo abbiamo fatto, per visualizzare il file ASCII di tracciamento myfirst.tr nel vostro editor preferito, dobbiamo andare nella directory di livello superiore del nostro repository.

Parsing dei tracciamenti ASCII

Ci sono molte informazioni in forma piuttosto densa, ma la prima cosa da notare è che il file è composto da righe separate. Questo sarà evidente se allargherete la finestra di visualizzazione.

Ogni riga del file corrisponde a un evento di tracciamento. In questo caso, stiamo tracciando eventi nell'enqueue presente in ogni dispositivo di rete point-to-point della simulazione. L'enqueue è la coda attraverso cui deve passare ogni pacchetto per il canale point-to-point. Si noti che ogni riga nel file di tracciamento inizia con un simbolo singolo (e ha uno spazio dopo di esso). Questo simbolo avrà il seguente significato:

+: si è verificata un'operazione di enqueuing nel dispositivo;
-: si è verificata un'operazione di dequeue nel dispositivo;
d: il pacchetto è stato scartato, di solito perché la coda è piena;
r: il pacchetto è stato ricevuto dal dispositivo di rete.

Esaminiamo più nel dettaglio la prima riga del file di tracciamento. La dividerò in parti (con rientri per chiarezza) e con il numero di riga a sinistra:

0 +
1 2
2 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
3 ns3::PppHeader (
4   Point-to-Point Protocol: IP (0x0021))
6   ns3::Ipv4Header (
7     tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]
8     length: 1052 10.1.1.1 > 10.1.1.2)
9     ns3::UdpHeader (
10      length: 1032 49153 > 9)
11      Payload (size=1024)

La prima sezione di questo evento di tracciamento esteso (riga 0) è l'operazione. Abbiamo qui il simbolo +, che corrisponde a un'operazione di enqueuing per la trasmissione. La seconda sezione (riga 1) è il tempo di simulazione, espresso in secondi. Potete ricordare che abbiamo chiesto UdpEchoClientApplication iniziare l'invio dei pacchetti tra due secondi. Qui vediamo la conferma che ciò sta realmente accadendo.

Nella sezione successiva dell'esempio di tracciamento (a partire dalla riga 2) viene mostrato quale origina abbia generato quest'evento (viene specificato lo spazio dei nomi del tracciamento). Puoi pensare allo spazio dei nomi del tracciamento in modo simile allo spazio dei nomi del file system. La radice dello spazio dei nomi è NodeList. Questo corrisponde a un contenitore gestito principalmente dal codice ns-3. Contiene tutti i nodi creati nello script. Proprio come un file system può avere directory nella radice, anche NodeList noi possiamo avere più nodi. Pertanto, la stringa /NodeList/0 fa riferimento al nodo zero in NodeList, che normalmente intendiamo come "nodo 0". Ogni nodo ha un elenco di dispositivi che sono stati installati. Questo elenco si trova successivamente nello spazio dei nomi. Puoi vedere che questo evento di tracciamento proviene da DeviceList/0, che è il dispositivo zero installato nel nodo.

La sottostringa successiva, $ ns3::PointToPointNetDevice, indica quale dispositivo si trova nella posizione zero: l'elenco dei dispositivi del nodo zero. Ricordiamo che l'operazione +, che si trova nella riga 0, significava che è stato aggiunto un elemento nella coda di trasmissione del dispositivo. Questo è riflesso negli ultimi segmenti "del percorso del tracciamento": TxQueue/Enqueue.

Le altre sezioni nel tracciamento dovrebbero essere abbastanza intuitive. Le righe 3-4 mostrano che il pacchetto è incapsulato nel protocollo punto-punto. Le righe 5-7 mostrano che il pacchetto ha un'intestazione di versione IP4 e originate dall'indirizzo IP 10.1.1.1 ed è destinato a 10.1.1.2. Le righe 8-9 mostrano che questo pacchetto ha un'intestazione UDP e, infine, la riga 10 mostra che il payload - esattamente 1024 byte.

La riga successiva nel file di tracciamento mostra che lo stesso pacchetto è stato estratto dalla coda di trasmissione sullo stesso nodo.

La terza riga nel file di tracciamento mostra che il pacchetto è stato ricevuto dal dispositivo di rete sul nodo con il server echo. Ho riprodotto questo evento qui sotto.

0 r
1 2.25732
2 /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/MacRx
3   ns3::Ipv4Header (
4     tos 0x0 ttl 64 id 0 protocol 17 offset 0 flags [none]
5     lunghezza: 1052 10.1.1.1 > 10.1.1.2)
6     ns3::UdpHeader (
7       lunghezza: 1032 49153 > 9)
8       Payload (size=1024)

Si prega di notare che l'operazione di traceroute è ora r, e il tempo di simulazione è stato aumentato a 2,25732 secondi. Se hai seguito attentamente le istruzioni del manuale, ciò significa che hai lasciato il DataRate dei dispositivi di rete e la latenza del canale ai loro valori predefiniti. Questo tempo dovrebbe esserti familiare, poiché l'hai già visto nella sezione precedente.

Lo spazio dei nomi della sorgente traccia (riga 2) è stato modificato per riflettere che questo evento proviene dal nodo 1 (/NodeList/1) и пакет принят источником трассировки (/MacRx). Dovrebbe esserti abbastanza facile seguire il movimento del pacchetto attraverso la topologia, visualizzando le tracce rimaste nel file.

5.3.2 Tracciamento PCAP

I dispositivi assistenti di ns‑3 possono essere utilizzati anche per creare file di traccia in formato .pcap. L'acronimo pcap (di solito scritto in minuscolo) indica il cattura pacchetti ed è sostanzialmente un'API che include la definizione del formato del file .pcap. Il programma più popolare in grado di leggere e visualizzare questo formato é Wireshark (precedentemente noto come Ethereal). Tuttavia, esistono molti analizzatori di traffico che utilizzano questo formato di pacchetto. Consigliamo agli utenti di utilizzare una varietà di strumenti disponibili per analizzare le tracce pcap. In questa guida ci concentreremo sulla visualizzazione delle tracce pcap utilizzando tcpdump.

Abilitare la traccia pcap viene eseguito con una riga di codice.

pointToPoint.EnablePcapAll ("myfirst");

Inserisci questa riga di codice dopo il codice di traccia ASCII che abbiamo appena aggiunto in scratch/myfirst.cc. Si prega di notare che abbiamo passato solo la stringa «myfirst», e non «myfirst.pcap» o qualcosa di simile. Questo perché il parametro è un prefisso e non un nome di file completo. Durante la simulazione, l'assistente creerà effettivamente un file di traccia per ogni dispositivo punto-punto. I nomi dei file saranno costruiti utilizzando il prefisso, il numero del nodo, il numero del dispositivo e il suffisso «.pcap».

Per il nostro esempio di scenario, alla fine vedremo file con nomi «myfirst-0-0.pcap" e "myfirst-1-0.pcap», che sono tracce pcap per il nodo 0-dispositivo 0 e il nodo 1-dispositivo 0 rispettivamente. Dopo aver aggiunto la riga di codice per abilitare la traccia pcap, puoi eseguire lo script nel modo consueto:

$ ./waf --run scratch/myfirst

Se guardi nella directory di livello superiore della tua distribuzione, dovresti vedere tre file: il file di traccia ASCII myfirst.tr, che abbiamo appena esaminato, i file myfirst-0-0.pcap e myfirst-1-0.pcap — nuovi file pcap che abbiamo appena generato.

Leggere l'output con tcpdump

Attualmente, il modo più semplice per visualizzare i file pcap è utilizzare tcpdump.

$ tcpdump -nn -tt -r myfirst-0-0.pcap
reading from file myfirst-0-0.pcap, link-type PPP (PPP)
2.000000 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.514648 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024
tcpdump -nn -tt -r myfirst-1-0.pcap
reading from file myfirst-1-0.pcap, link-type PPP (PPP)
2.257324 IP 10.1.1.1.49153 > 10.1.1.2.9: UDP, length 1024
2.257324 IP 10.1.1.2.9 > 10.1.1.1.49153: UDP, length 1024

Nel dump myfirst-0-0.pcap (dispositivo client) puoi vedere che il pacchetto di echo viene inviato dopo 2 secondi di simulazione. Se guardi il secondo dump (myfirst-1-0.pcap), vedrai che il pacchetto viene ricevuto al momento 2,257324 secondi. Vedrai nel secondo dump che il pacchetto viene restituito al momento 2.257324 secondi e, infine, che il pacchetto è stato ricevuto dal client nel primo dump al momento 2.514648 secondi.

Leggere l'output con Wireshark

Se non sei familiare con Wireshark, c'è un sito web da cui puoi scaricare programmi e documentazione: http://www.wireshark.org/. Wireshark — è un'interfaccia grafica che puoi utilizzare per visualizzare questi file di tracciamento. Se hai Wireshark, puoi aprire uno qualsiasi dei file di tracciamento e visualizzare il contenuto come se avessi catturato pacchetti utilizzando un analizzatore di pacchetti.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster