نصائح وأكواد لاجتياز الاختبار العملي لشبكات الكمبيوتر ("Reti di calcolatori") بسهولة في بادوا. يمكنك العثور على كل ما هو موجود في هذا الملف التمهيدي من خلال man
و RFCs المختلفة. لقد فعلت ذلك فقط كمرجع سريع.
يحتوي إطار Ethernet (طبقة ارتباط البيانات) على مخطط بيانات IP (طبقة الشبكة) الذي يمكن أن يحتوي على واحد مما يلي { tcp_segment (طبقة النقل)، icmp_packet } (لغرض هذا الاختبار). والطريقة السهلة لتحقيق ذلك هي:
eth = ( struct eth_frame * ) buffer ;
ip = ( struct ip_datagram * ) eth -> payload ;
tcp = ( struct tcp_segment * ) ip -> payload ;
// or
icmp = ( struct icmp_packet * ) ip -> payload ;
(يعتمد على البنية، ولكن يمكنك افتراض أن ما يلي ينطبق على هذا الاختبار)
unsigned char
: 1 بايتunsigned short
: 2 بايتunsiged int
: 4 بايتللنقل على الشبكة يتم استخدام Big endian. معظم وحدات المعالجة المركزية الخاصة بشركة Intel صغيرة الحجم. للتحويل، استخدم هاتين الوظيفتين اللتين تفهمان تلقائيًا ما إذا كانت هناك حاجة إلى تحويل:
htonl(x)
أو htons(x)
لتحويل x من H ost إلى N شبكة endianess، l إذا كان عليك تحويل متغير 4 بايت، فهو 2 بايت واحد.ntohl(x)
أو ntohs(x)
للعكس. (قد تلاحظ أن تطبيق htonx وntohx هو نفسه) // Frame Ethernet
struct eth_frame {
unsigned char dst [ 6 ]; // mac address
unsigned char src [ 6 ]; // mac address
unsigned short type ; // 0x0800 = ip, 0x0806 = arp
char payload [ 1500 ]; //ARP or IP
};
بفضل type
يمكننا فهم مكان إعادة توجيهه إلى المستوى التالي (مثالان هما ip أو arp)
طول الرأس: تحقق من النصف الثاني من سمة ver_ihl
. مثال: إذا كان '5'، فإن طول الرأس هو 4 * 5 = 20 بايت.
// ما يجب إضافة صورة
// Datagramma IP
struct ip_datagram {
unsigned char ver_ihl ; // first 4 bits: version, second 4 bits: (lenght header)/8
unsigned char tos ; //type of service
unsigned short totlen ; // len header + payload
unsigned short id ; // useful in case of fragmentation
unsigned short flags_offs ; //offset/8 related to the original ip package
unsigned char ttl ;
unsigned char protocol ; // TCP = 6, ICMP = 1
unsigned short checksum ; // only header checksum (not of payload). Must be at 0 before the calculation.
unsigned int src ; // ip address
unsigned int dst ; // ip address
unsigned char payload [ 1500 ];
};
طول الرأس (كما هو محدد هنا): 20
struct tcp_segment {
unsigned short s_port ;
unsigned short d_port ;
unsigned int seq ; // offset in bytes from the start of the tcp segment in the stream (from initial sequance n)
unsigned int ack ; // useful only if ACK flag is 1. Next seq that sender expect
unsigned char d_offs_res ; // first 4 bits: (header len/8)
unsigned char flags ; // check rfc
unsigned short win ; // usually initially a 0 (?)
unsigned short checksum ; // use tcp_pseudo to calculate it. Must be at 0 before the calculation.
unsigned short urgp ;
unsigned char payload [ 1000 ];
};
لحساب المجموع الاختباري لقطعة TCP، من المفيد تحديد بنية إضافية (تحقق من RFC النسبي). حجمه، بدون جزء tcp_segment
struct tcp_pseudo {
unsigned int ip_src , ip_dst ;
unsigned char zeroes ;
unsigned char proto ; // ip datagram protocol field (tcp = 6, ip = 1)
unsigned short entire_len ; // tcp length (header + data)
unsigned char tcp_segment [ 20 /*to set appropriatly */ ]; // entire tcp packet pointer
};
لحساب حجم مقطع TCP بأكمله (أو ICMP)، أو بشكل عام حمولة IP:
unsigned short ip_total_len = ntohs ( ip -> totlen );
unsigned short ip_header_dim = ( ip -> ver_ihl & 0x0F ) * 4 ;
int ip_payload_len = ip_total_len - ip_header_dim ;
يمكننا استخدام هذه الوظيفة لكل من مخطط بيانات IP وقطاع TCP، ولكن يجب أن نهتم بمعلمة len
.
unsigned short checksum ( unsigned char * buffer , int len ){
int i ;
unsigned short * p ;
unsigned int tot = 0 ;
p = ( unsigned short * ) buffer ;
for ( i = 0 ; i < len / 2 ; i ++ ){
tot = tot + htons ( p [ i ]);
if ( tot & 0x10000 ) tot = ( tot & 0xFFFF ) + 1 ;
}
return ( unsigned short ) 0xFFFF - tot ;
}
الحالتين هما:
ip->checksum=htons(checksum((unsigned char*) ip, 20));
` int TCP_TOTAL_LEN = 20 ;
struct tcp_pseudo pseudo ; // size of this: 12
memcpy ( pseudo . tcp_segment , tcp , TCP_TOTAL_LEN );
pseudo . zeroes = 0 ;
pseudo . ip_src = ip -> src ;
pseudo . ip_dst = ip -> dst ;
pseudo . proto = 6 ;
pseudo . entire_len = htons ( TCP_TOTAL_LEN ); // may vary
tcp -> checksum = htons ( checksum (( unsigned char * ) & pseudo , TCP_TOTAL_LEN + 12 ));
#include <arpa/inet.h>
void print_ip ( unsigned int ip ){
struct in_addr ip_addr ;
ip_addr . s_addr = ip ;
printf ( "%sn" , inet_ntoa ( ip_addr ));
}
أنصح VIM. ويرجى وضع مسافة بادئة للتعليمات البرمجية الخاصة بك.
:wq
للحفظ والانسحاب.esc
مرتين إذا كنت لا تفهم ما يحدث/query
للبحث عن "استعلام" و n
و N
للبحث عن النتيجة السابقة/التالية " auto reformat when you pres F7
map <F7> mzgg=G`z
" F8 to save and compile creating np executable
map <F8> :w <CR> :!gcc % -o np -g <CR>
" F9 to execute
map <F9> :!./np <CR>
" make your code look nicer
set tabstop=3
set shiftwidth=3
set softtabstop=0 expandtab
set incsearch
set cindent
" Ctrl+shift+up/down to swap the line up or doen
nnoremap <C-S-Up> <Up>"add"ap<Up>
nnoremap <C-S-Down> "add"ap
" ctrl+h to hilight the last search
nnoremap <C-h> :set hlsearch!<CR>
set number
set cursorline
set mouse=a
set foldmethod=indent
set foldlevelstart=99
let mapleader="<space>"
nnoremap <leader>b :make <CR> :cw <CR>
أولاً، قم بإنشاء makefile
في الدليل مع الملفات المراد تجميعها، مثل هذا:
np : ws18.c
gcc -o np ws18.c
انتبه إلى وضع علامة تبويب قبل "gcc"، وليس مسافات (إذا قمت بتمكين Exploretab في vim، فاستخدم ctrl=v tab
). هنا np
هو ما تريد إنشاءه (الملف القابل للتنفيذ)، و ws18.c
هو الملف المراد تجميعه. يوجد في السطر أدناه أمر للاتصال في كل مرة تكتب فيها :make
in vim. بعد ذلك، باستخدام .vimrc
المتوفر أعلاه، اضغط على space
(حررها) و b
( b uild). سيتم تنفيذ الأمر، وسترى في الجزء السفلي من التعليمات البرمجية الخاصة بك قائمة الأخطاء. يمكنك القفز بسرعة في السطر الصحيح عن طريق الضغط على زر الإدخال في كل إدخال. للتنقل بين الجزء العلوي والسفلي، اضغط على CTRL+W
W
لإغلاق العرض السفلي (الإصلاح السريع) :q
أو :cw
.
يمكنك العثور على بيان الاختبار الكامل في الموقع في بداية هذا الملف التمهيدي. الكود الكامل موجود في المجلدات.
تنفيذ المصافحة الثلاثية لبروتوكول TCP (ACK+SYN).
نصائح : يمكنك التحقق باستخدام wireshark مما إذا كان المجموع الاختباري لـ TCP صحيحًا أم لا.
تنفيذ الرد بالارتداد فقط لطلبات ICMP ذات حجم معين
نصائح : يمكنك حساب حجم رسالة icmp بهذه الطريقة:
unsigned short dimension = ntohs ( ip -> totlen );
unsigned short header_dim = ( ip -> ver_ihl & 0x0F ) * 4 ;
int icmp_dimension = dimension - header_dim ;
قم بتنفيذ خادم HTTP الذي:
نصائح : يتم تجاهل رأس Retry-After
من قبل معظم متصفحات الويب، لذلك لن تتم إعادة التوجيه بعد 10 ثوانٍ، بل على الفور. يوجد في الحل مصفوفة تحافظ على حالة الاتصال لكل IP.
تنفيذ ICMP "الوجهة غير قابلة للوصول" التي تشير إلى أن المنفذ غير متوفر
نصائح : يجب عليك إرسال الحزمة ردًا على اتصال TCP. icmp->type = 3
, icmp->code=3
. وتذكر أن تنسخ في الحمولة محتوى الحمولة الأصلية لـ icmp.
اعتراض أول اتصال تم استلامه، وطباعة التسلسل والإقرار بأرقامه. ثم قم بإعادة بناء التدفقين في مخزنين مؤقتين مختلفين، وطباعة محتواهما.
نصائح : لاعتراض نهاية الاتصال، فقط تحقق مما إذا كانت الحزمة تحتوي على بت FIN عند 1 (بعد تصفية جميع الحزم، مع الحفاظ فقط على تلك التي تنتمي إلى الاتصال الأول). استخدم حقل تسلسل tcp لنسخ شبكة الاتصال عند الإزاحة اليمنى في المخزنين المؤقتين. لا تكرر الكود.
قم بتعديل الوكيل للسماح بالطلب فقط من مجموعة عناوين IP، والسماح فقط بنقل الملفات التي تحتوي على نص أو HTML.
نصائح : من الأفضل أن تتلقى أولاً الاستجابة من الخادم في مخزن مؤقت، ثم انسخ هذا المحتوى إلى مخزن مؤقت آخر لاستخراج الرؤوس كما هو الحال دائمًا. وذلك لأن إجراء استخراج الرأس يعدل المخزن المؤقت. إذا كانت حالة نوع المحتوى ممتلئة، فما عليك سوى إعادة توجيه شبكة الاتصال الخاصة بالمخزن المؤقت الأولي.
أرسل استجابة HTTP بنص مقسم.
تلميحات : قم بإضافة Content-Type: text/plainrnTransfer-Encoding: chunkedrn
إلى رؤوس HTTP. بعد ذلك، لإنشاء كل قطعة لإرسالها، يمكنك استخدام شيء مثل:
int build_chunk ( char * s , int len ){
sprintf ( chunk_buffer , "%xrn" , len ); // size in hex
// debug printf("%d in hex: %s",len,chunk_buffer);
int from = strlen ( chunk_buffer );
int i = 0 ;
for (; i < len ; i ++ )
chunk_buffer [ from + i ] = s [ i ];
chunk_buffer [ from + ( i ++ )] = 'r' ;
chunk_buffer [ from + ( i ++ )] = 'n' ;
chunk_buffer [ i + from ] = 0 ;
return i + from ;
}
قم بتنفيذ رأس Last-Modified
لـ HTTP/1.0
نصائح : بعض وظائف تحويل الوقت المفيدة في قسم متنوعات. وكان من الممكن أيضًا أن يتم ذلك دون الحاجة إلى هذه التحويلات. تنسيق تاريخ HTTP هو %a, %d %b %Y %H:%M:%S %Z
1: طول المحتوى (تم تنفيذه بالفعل) 2: التتبع (؟؟)
قم بتعديل صدى icmp لتقسيم الطلب إلى مخططتي بيانات IP، واحدة بحجم حمولة 16 بايت والأخرى بحجم الحمولة المطلوبة.
خلال الدورة يتم تعيين بعض الواجبات المنزلية (ليست إلزامية). حتى لو لم تكن اختبارات، فهي تتمتع بنفس المستوى من الصعوبة تقريبًا.
قم بتنفيذ برنامج تتبع المسار، لتتبع كل عقدة تزورها الحزم قبل الوصول إلى الوجهة. تلميح: عندما يصبح وقت البقاء 0، تتجاهل العقدة الحزمة وترسل "رسالة تجاوز الوقت" إلى عنوان IP المصدر للحزمة (راجع RFC793).
استخدم رأس HTTP WWW-Authenticate
لطلب بيانات اعتماد الوصول إلى العميل.
تنفيذ عميل يقبل المحتوى المقسم.
تنسيق تاريخ HTTP هو %a, %d %b %Y %H:%M:%S %Z
char date_buf [ 1000 ];
char * getNowHttpDate (){
time_t now = time ( 0 );
struct tm tm = * gmtime ( & now );
strftime ( date_buf , sizeof date_buf , "%a, %d %b %Y %H:%M:%S %Z" , & tm );
printf ( "Time is: [%s]n" , date_buf );
return date_buf ;
}
// parse time and convert it to millisecond from epoch
time_t httpTimeToEpoch ( char * time ){
struct tm tm ;
char buf [ 255 ];
memset ( & tm , 0 , sizeof ( struct tm ));
strptime ( time , "%a, %d %b %Y %H:%M:%S %Z" , & tm );
return mktime ( & tm );
}
// returns 1 if d1 < d2
unsigned char compareHttpDates ( char * d1 , char * d2 ){
return httpTimeToEpoch ( d1 ) < httpTimeToEpoch ( d2 );
}
unsigned char expired ( char * uri , char * last_modified ){
char * complete_name = uriToCachedFile ( uri );
FILE * fp = fopen ( complete_name , "r" );
if ( fp == NULL ) return 1 ;
//read the first line
char * line = 0 ; size_t len = 0 ;
getline ( & line , & len , fp );
if ( compareHttpDates ( last_modified , line )) return 0 ;
return 1 ;
//todo read First line and compare
}
rewind(FILE*)
اضبط المؤشر في البداية
FILE * fin ;
if (( fin = fopen ( uri + 1 , "rt" )) == NULL ) { // the t is useless
printf ( "File %s non aperton" , uri + 1 );
sprintf ( response , "HTTP/1.1 404 File not foundrnrn<html>File non trovato</html>" );
t = write ( s2 , response , strlen ( response ));
if ( t == -1 ) {
perror ( "write fallita" );
return -1 ;
}
} else {
content_length = 0 ;
while (( c = fgetc ( fin )) != EOF ) content_length ++ ; // get file lenght
sprintf ( response , "HTTP/1.1 200 OKrnConnection: keep-alivernContent-Length: %drnrn" , content_length );
printf ( "Response: %sn" , response );
//send header
t = write ( s2 , response , strlen ( response ));
//rewind the file
rewind ( fin );
//re-read the file, char per char
while (( c = fgetc ( fin )) != EOF ) {
//printf("%c", c);
//sending the file, char per char
if ( write ( s2 , ( unsigned char * ) & c , 1 ) != 1 ) {
perror ( "Write fallita" );
}
}
fclose ( fin );
}
char car ;
while ( read ( s3 , & car , 1 )) {
write ( s2 , & car , 1 );
// printf("%c",car);
}
unsigned char targetip [ 4 ] = { 147 , 162 , 2 , 100 };
unsigned int netmask = 0x00FFFFFF ;
if (( * (( unsigned int * ) targetip ) & netmask ) == ( * (( unsigned int * ) myip ) & netmask ))
nexthop = targetip ;
else
nexthop = gateway ;
من اسم المضيف (مثل www.google.it) إلى عنوان IP
/**
struct hostent {
char *h_name; // official name of host
char **h_aliases; // alias list
int h_addrtype; // host address type
int h_length; // length of address
char **h_addr_list; // list of addresses
}
#define h_addr h_addr_list[0] // for backward compatibility
*/
struct hostent * he ;
he = gethostbyname ( hostname );
printf ( "Indirizzo di %s : %d.%d.%d.%dn" , hostname ,
( unsigned char )( he -> h_addr [ 0 ]), ( unsigned char )( he -> h_addr [ 1 ]),
( unsigned char )( he -> h_addr [ 2 ]), ( unsigned char )( he -> h_addr [ 3 ]));
للاستماع:
int s = socket ( AF_INET , // domain: ipv4
/*
SOCK_STREAM Provides sequenced, reliable, two-way, connection-based byte streams. An out-of-band data
transmission mechanism may be supported.
SOCK_DGRAM Supports datagrams (connectionless, unreliable messages of a fixed maximum length).
SOCK_RAW Provides raw network protocol access.
*/
SOCK_STREAM , // type: stream
0 ); // protocol (0=ip), check /etc/protocols
if ( s == -1 ) {
perror ( "Socket Fallita" );
return 1 ;
}
// https://stackoverflow.com/questions/3229860/what-is-the-meaning-of-so-reuseaddr-setsockopt-option-linux
// SO_REUSEADDR allows your server to bind to an address which is in a TIME_WAIT state.
int yes = 1 ;
if ( setsockopt ( s , SOL_SOCKET , SO_REUSEADDR , & yes , sizeof ( int )) == -1 ) {
perror ( "setsockopt" );
return 1 ;
}
struct sockaddr_in indirizzo ;
indirizzo . sin_family = AF_INET ;
indirizzo . sin_port = htons ( 8987 );
indirizzo . sin_addr . s_addr = 0 ;
t = bind ( s , ( struct sockaddr * ) & indirizzo , sizeof ( struct sockaddr_in ));
if ( t == -1 ) {
perror ( "Bind fallita" );
return 1 ;
}
t = listen ( s ,
// backlog defines the maximum length for the queue of pending connections.
10 );
if ( t == -1 ) {
perror ( "Listen Fallita" );
return 1 ;
}
int lunghezza = sizeof ( struct sockaddr_in );
// the remote address will be placed in indirizzo_remoto
s2 = accept ( s , ( struct sockaddr * ) & indirizzo_remoto , & lunghezza );
if ( s2 == -1 ) {
perror ( "Accept Fallita" );
return 1 ;
}
// now we can read in this way:
char buffer [ 10000 ];
int i ;
for ( i = 0 ; ( t = read ( s2 , buffer + i , 1 )) > 0 ; i ++ ); // ps. it's not a good way
// if the previous read returned -1
if ( t == -1 ) {
perror ( "Read Fallita" );
return 1 ;
}
في النهاية، تذكر إغلاق جميع المقابس close(s)
(حيث يوجد في المقبس الذي تريد إغلاقه)
int s = socket (
//AF_PACKET Low level packet interface packet(7)
AF_PACKET ,
//SOCK_RAW Provides raw network protocol access.
SOCK_RAW ,
// When protocol is set to htons(ETH_P_ALL), then all protocols are received.
htons ( ETH_P_ALL ));
unsigned char buffer [ 1500 ];
bzero ( & sll , sizeof ( struct sockaddr_ll ));
struct sockaddr_ll sll ;
sll . sll_ifindex = if_nametoindex ( "eth0" );
len = sizeof ( sll );
int t = sendto ( s , //socket
buffer , //things to send
14 + 20 + 28 , // len datagram
0 , //flags
( struct sockaddr * ) & sll , // destination addr
len // dest addr len
);
// to receive
t = recvfrom ( s , buffer , 1500 , 0 , ( struct sockaddr * ) & sll , & len );
if ( t == -1 ) {
perror ( "recvfrom fallita" );
return 1 ;
}
void stampa_eth ( struct eth_frame * e ){
printf ( "nn ***** PACCHETTO Ethernet *****n" );
printf ( "Mac destinazione: %x:%x:%x:%x:%x:%xn" , e -> dst [ 0 ], e -> dst [ 1 ], e -> dst [ 2 ], e -> dst [ 3 ], e -> dst [ 4 ], e -> dst [ 5 ] );
printf ( "Mac sorgente: %x:%x:%x:%x:%x:%xn" , e -> src [ 0 ], e -> src [ 1 ], e -> src [ 2 ], e -> src [ 3 ], e -> src [ 4 ], e -> src [ 5 ] );
printf ( "EtherType: 0x%xn" , htons ( e -> type ) );
}
void stampa_ip ( struct ip_datagram * i ){
unsigned int ihl = ( i -> ver_ihl & 0x0F ) * 4 ; // Lunghezza header IP
unsigned int totlen = htons ( i -> totlen ); // Lunghezza totale pacchetto
unsigned int opt_len = ihl - 20 ; // Lunghezza campo opzioni
printf ( "nn ***** PACCHETTO IP *****n" );
printf ( "Version: %dn" , i -> ver_ihl & 0xF0 );
printf ( "IHL (bytes 60max): %dn" , ihl );
printf ( "TOS: %dn" , i -> tos );
printf ( "Lunghezza totale: %dn" , totlen );
printf ( "ID: %xn" , htons ( i -> id ) );
unsigned char flags = ( unsigned char )( htons ( i -> flag_offs ) >> 13 );
printf ( "Flags: %d | %d | %d n" , flags & 4 , flags & 2 , flags & 1 );
printf ( "Fragment Offset: %dn" , htons ( i -> flag_offs ) & 0x1FFF );
printf ( "TTL: %dn" , i -> ttl );
printf ( "Protocol: %dn" , i -> proto );
printf ( "Checksum: %xn" , htons ( i -> checksum ) );
unsigned char * saddr = ( unsigned char * ) & i -> saddr ;
unsigned char * daddr = ( unsigned char * ) & i -> daddr ;
printf ( "IP Source: %d.%d.%d.%dn" , saddr [ 0 ], saddr [ 1 ], saddr [ 2 ], saddr [ 3 ] );
printf ( "IP Destination: %d.%d.%d.%dn" , daddr [ 0 ], daddr [ 1 ], daddr [ 2 ], daddr [ 3 ] );
if ( ihl > 20 ){
// Stampa opzioni
printf ( "Options: " );
for ( int j = 0 ; j < opt_len ; j ++ ){
printf ( "%.3d(%.2x) " , i -> payload [ j ], i -> payload [ j ]);
}
printf ( "n" );
}
}
void stampa_arp ( struct arp_packet * a ){
printf ( "nn ***** PACCHETTO ARP *****n" );
printf ( "Hardware type: %dn" , htons ( a -> htype ) );
printf ( "Protocol type: %xn" , htons ( a -> ptype ) );
printf ( "Hardware Addr len: %dn" , a -> hlen );
printf ( "Protocol Addr len: %dn" , a -> plen );
printf ( "Operation: %dn" , htons ( a -> op ) );
printf ( "HW Addr sorgente: %x:%x:%x:%x:%x:%xn" , a -> hsrc [ 0 ], a -> hsrc [ 1 ], a -> hsrc [ 2 ], a -> hsrc [ 3 ], a -> hsrc [ 4 ], a -> hsrc [ 5 ] );
printf ( "IP Source: %d.%d.%d.%dn" , a -> psrc [ 0 ], a -> psrc [ 1 ], a -> psrc [ 2 ], a -> psrc [ 3 ] );
printf ( "HW Addr Destinazione: %x:%x:%x:%x:%x:%xn" , a -> hdst [ 0 ], a -> hdst [ 1 ], a -> hdst [ 2 ], a -> hdst [ 3 ], a -> hdst [ 4 ], a -> hdst [ 5 ] );
printf ( "IP Dest: %d.%d.%d.%dn" , a -> pdst [ 0 ], a -> pdst [ 1 ], a -> pdst [ 2 ], a -> pdst [ 3 ] );
}
void stampa_icmp ( struct icmp_packet * i ){
printf ( "nn ***** PACCHETTO ICMP *****n" );
printf ( "Type: %dn" , i -> type );
printf ( "Code: %dn" , i -> code );
printf ( "Code: 0x%xn" , htons ( i -> checksum ) );
printf ( "ID: %dn" , htons ( i -> id ) );
printf ( "Sequence: %dn" , htons ( i -> seq ) );
}
void stampa_tcp ( struct tcp_segment * t ){
printf ( "nn ***** PACCHETTO TCP *****n" );
printf ( "Source Port: %dn" , htons ( t -> s_port ) );
printf ( "Source Port: %dn" , htons ( t -> d_port ) );
printf ( "Sequence N: %dn" , ntohl ( t -> seq ) );
printf ( "ACK: %dn" , ntohl ( t -> ack ) );
printf ( "Data offset (bytes): %dn" , ( t -> d_offs_res >> 4 ) * 4 );
printf ( "Flags: " );
printf ( "CWR=%d | " , ( t -> flags & 0x80 ) >> 7 );
printf ( "ECE=%d | " , ( t -> flags & 0x40 ) >> 6 );
printf ( "URG=%d | " , ( t -> flags & 0x20 ) >> 5 );
printf ( "ACK=%d | " , ( t -> flags & 0x10 ) >> 4 );
printf ( "PSH=%d | " , ( t -> flags & 0x08 ) >> 3 );
printf ( "RST=%d | " , ( t -> flags & 0x04 ) >> 2 );
printf ( "SYN=%d | " , ( t -> flags & 0x02 ) >> 1 );
printf ( "FIN=%dn" , ( t -> flags & 0x01 ) );
printf ( "Windows size: %dn" , htons ( t -> win ) );
printf ( "Checksum: 0x%xn" , htons ( t -> checksum ) );
printf ( "Urgent pointer: %dn" , htons ( t -> urgp ) );
}
ليس مفيدًا حقًا، ولكن..
// es. tcp.c
printf ( "%.4d. // delta_sec (unsigned int)
% .6d // delta_usec
% .5d -> % .5d // ports (unsigned short)
% .2 x // tcp flags (unsigned char) in hex: es: "12"
% .10u // seq (unsigned int)
% .10u // ack
% .5u //tcp win
% 4.2f n ", delta_sec , delta_usec , htons ( tcp -> s_port ), htons ( tcp -> d_port ), tcp -> flags , htonl ( tcp -> seq ) - seqzero , htonl ( tcp -> ack ) - ackzero , htons ( tcp -> win ), ( htonl ( tcp -> ack ) - ackzero ) / ( double )( delta_sec * 1000000 + delta_usec ));
/etc/services
: لمعرفة جميع منافذ TCP المتوفرة على مستوى التطبيق./etc/protocols
nslookup <URL>
: يبحث عن عنوان IP لعنوان URL المحدد ( مثال : www.google.com)netstat -rn
جدول التوجيهtraceroute
بتوجيه حزمة IP في المسار الذي تنتقل فيه عن طريق طباعة عنوان IP لكل بوابة تقرر إسقاط الحزمة التي تم تزويرها بعدد TTL منخفض (مدة البقاء، تتناقص في كل قفزة).