2013-04-08 17 views
10

Ho letto la documentazione da una delle risposte:cosa fa esattamente ntohs() in pcap?

La funzione ntohs prende un numero a 16 bit per byte di rete TCP/IP (la famiglia AF_INET o l'indirizzo AF_INET6) e restituisce un numero a 16 bit nel byte di accoglienza ordine.

Spiegare con un esempio, come in quello che è l'ordine dei byte di rete e quale è l'ordine dei byte host.

risposta

22

Il numero 1000 è, in binario, 1111101000.

Se questo è un numero binario a 16 bit, che è 0000001111101000.

Se che è diviso in due byte di 8 bit, che è due byte con il valori 00000011 e 11101000.

Questi due byte possono essere in due ordini diversi:

  • per byte "big-endian", il byte contenente gli 8 bit superiori è prima, e th Il byte con gli 8 bit inferiori è il secondo, quindi il primo byte è 00000011 e il secondo byte è 11101000.
  • Nell'ordine dei byte "little-endian", il byte contenente inferiore 8 bit è il primo e il byte contenente le superiori 8 bit è secondo, quindi il primo byte è 11.101.000 e il secondo byte è 00000011.

In una macchina byte addressible, l'hardware può essere "big-endian" o "little-endian ", a seconda del byte memorizzato in un indirizzo inferiore in memoria. La maggior parte dei personal computer è little-endian; i computer più grandi hanno gusti sia big-endian che little-endian, con un numero di computer più grandi (mainframe IBM e computer midrange e server SPARC, ad esempio) big-endian.

La maggior parte delle reti è bit-seriale, quindi i bit vengono trasmessi uno dopo l'altro. I bit di un byte potrebbero essere trasmessi prima con il bit più significativo o meno significativo, ma l'hardware di rete nasconderà quei dettagli dal processore. Tuttavia, trasmetteranno byte nell'ordine in cui sono nella memoria dell'host, quindi, se una macchina little-endian sta trasmettendo dati a una macchina big-endian, il numero che la macchina little-endian trasmette apparirebbe diverso sulla macchina big-endian ricevente; tali differenze sono non nascoste dall'hardware di rete.

Pertanto, al fine di permettere alle macchine big-endian e little-endian per comunicare, ad ogni livello di protocollo, uno:

  • un ordine byte "standard" deve essere scelto, e macchine utilizzando un diverso l'ordine dei byte deve spostare i byte dei numeri a più byte, in modo che non siano nell'ordine dei byte standard della macchina, prima di trasmettere i dati, spostarli, in modo che siano nell'ordine byte standard della macchina, dopo aver ricevuto dati;
  • le due macchine devono negoziare un particolare ordine di byte per la sessione (ad esempio, per il protocollo di windowing di rete X11, il messaggio iniziale dal client al server specifica l'ordine dei byte da utilizzare);
  • i messaggi di protocollo devono specificare l'ordine dei byte utilizzato (come avviene con DCE RPC, ad esempio, è il protocollo utilizzato per "Microsoft RPC");
  • la macchina ricevente ha bisogno di indovinare in qualche modo l'ordine dei byte (non conosco protocolli attualmente utilizzati dove ciò è fatto, ma il vecchio protocollo "talk" di BSD non ha usato nessuna delle tecniche utilizzate sopra, e l'implementazione sul Sun386i doveva usarla per gestire sia le macchine Motorola 68K big-endian sia le macchine Intel x86 little-endian).

Diversi protocolli Internet utilizzano la prima strategia, specificando big-endian come ordine dei byte; è indicato come "ordine dei byte di rete" in vari RFC. (Il protocollo di accesso ai file SMB di Microsoft utilizza anche la prima strategia, ma specifica little-endian.)

Quindi "ordine di byte di rete" è big-endian. "Ordine byte host" è l'ordine dei byte della macchina che stai utilizzando; potrebbe essere big-endian, nel qual caso ntohs() restituisce semplicemente il valore che gli hai fornito, oppure potrebbe essere little-endian, nel qual caso ntohs() scambia i due byte del valore che gli hai fornito e restituisce quel valore. Ad esempio, su una macchina big-endian, ntohs(1000) restituirebbe 1000 e, su una macchina little-endian, lo ntohs(1000) scambierà i byte di ordine alto e di ordine basso, dando 1110100000000011 in binario o 59395 in formato decimale.