+ All Categories
Home > Documents > Programmazione di rete in C - webalice.it · 2 Dario Maggiorini ([email protected]) -...

Programmazione di rete in C - webalice.it · 2 Dario Maggiorini ([email protected]) -...

Date post: 15-Feb-2019
Category:
Upload: vonguyet
View: 217 times
Download: 0 times
Share this document with a friend
69
1 Dario Maggiorini [email protected] Università degli Studi di Milano Dipartimento di Informatica e Comunicazione Programmazione di rete in C Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003 2 Obiettivi Imparare a programmare con le socket Progettare un protocollo applicativo Implementare un sistema client-server
Transcript

1

Dario [email protected]

Università degli Studi di MilanoDipartimento di Informatica e Comunicazione

Programmazione di rete in C

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/20032

Obiettivi

Imparare a programmare con le socket Progettare un protocollo applicativoImplementare un sistema client-server

2

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/20033

Prerequisiti

Saper usare un editorSaper usare un compilatoreSaper usare un sistema unix (linux/BSD)Rudimenti di programmazione in C

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/20034

Contenuti

Il modello client-serverI protocolli di comunicazioneLe socket

DominioNamingProtocolli

Programmare client e server con TCPProgrammare client e server con UDP

3

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/20035

Testi consigliati

James F. Kurose Computer Networking: A Top-Down Approach Featuring the InternetAddison Wesley

W. Richard StevensUNIX Network ProgrammingPrentice Hall

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/20036

Il modello client-server

Presuppone l’esistenza di due entitàCLIENTrichiede un servizioSERVEReroga un servizio

CLIENT SERVER

Data flow

4

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/20037

Sono sistemi client-server

voi ed uno sportello bancomat una classe ed il docentevoi e la vostra bancalo sportello bancomat al primo punto ed il vostro istituto di credito

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/20038

Server iterativo

CLIENT SERVER

Coda d’attesa

5

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/20039

Server concorrente

Client 1

Client 2

SERVER

Client 4

Client 3

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200310

Server multiprocesso

Client 1 Client 2

SERVER

Client 4Client 3

Server 1 Server 2 Server 4Server 3

6

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200311

Servizi “a più stadi”

Client SERVER SERVER

Client o Server ?

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200312

Protocollo

1. l’insieme delle norme che regolano lo svolgimento di manifestazioni, visite, ricevimenti ufficiali

2. insieme di regole che governano la successione e lo scambio di informazioni fra due dispositivi comunicanti tra loro

dizionario garzanti

7

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200313

Progettazione di un protocollo

Quando si progetta un protocollo si deve stabilire:

Il formato dei messaggiQuali sono le sequenze di messaggi valideQuando inviare e quando ricevere

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200314

Protocolli applicativiDobbiamo definire dei protocolli per far scambiare

informazioni tra applicazioni

I messaggi sono sequenze di byte il cui formato viene stabilito a priori.I programmi dovranno riconoscere e “reagire” a sequenze di messaggi valide

Tutte le considerazioni viste prima sono ancora valide

Le socket ci forniranno solo l’infrastruttura per lo scambio dei messaggi

8

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200315

Socket

È il punto terminale di un sistema di comunicazione

Due processi distinti possono creare una socket ognuno e connetterle tra loro

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200316

Network protocols

Network interface drivers

hardware

Le socket nel S.O.Application

Kernel interface

socket

Network protocols

Network interface drivers

hardware

9

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200317

E a livello di linguaggio ?

Per il S.O. Una socket è un canale di I/O

In C sarà un file descriptor

In un linguaggio a oggetti un file descriptor con una serie di metodi “attorno”

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200318

Indirizzamento

Abbiamo bisogno di identificare in maniera univoca una socket, in modo tale da poterla raggiungere da un altro punto della rete

Problema:

Tecnologie diverse hanno formalismi diversi per i formati degli indirizzi

10

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200319

Università di Milano, D.I.Co.Via Comelico 3920135 MilanoItaly

University of California, C.S. Dept420 Westwood plazaLos Angeles, CA, 90095U.S.A.

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200320

Soluzione: definizione del dominio

“Informiamo” la socket di quale formalismo intendiamo usare

Equivale a dire al postino la cultura di riferimento in cui è stato scritto l’indirizzo

Il dominio di una socket stabilisce vincoli al suo utilizzo, in quanto la correla al sistema di indirizzamento sottostante

11

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200321

Possibili domini

ATMAppletalkDECNetInternetInternet6

IPXIRDANETBIOSUNIXSNA

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200322

Altro problema: “a chi ?”

Gli indirizzi a livello di rete non bastano:identificano un host, non una entità al suo interno

Dobbiamo usare indirizzi di livello trasporto

12

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200323

Indirizzi transport

Un indirizzo a livello di trasporto unisce all’indirizzo di livello rete un identificativo per indirizzare un’entità all’interno dell’host

Nel caso di TCP/IP vengono ottenuti concatenando l’indirizzo IP con un numero di 16 bit che prende il nome di porta

Alcuni servizi tipici di Internet vengono forniti usando porte standardizzate

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200324

Porte standard

22ssh

23telnet

21ftp

80WWW

25mail

PortaServizio

13

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200325

Naming / Binding

È l’operazione in cui associamo un indirizzo transport ad una socket già creata

In questo modo l’indirizzo diventa noto al sistema operativo ed altre socket sono in grado di stabilire una connessione

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200326

Semantica di comunicazione

È possibile impostare il protocollo a livello rete che verràutilizzato per il trasferimento dei dati

Nel caso delle socket abbiamo due opzioni:

byte-streamI dati vengono trasferiti come una sequenza ordinata ed affidabile di

byte

datagramI dati vengono inviati come messaggi indipendenti ed inaffidabili

14

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200327

Implementazione di un client

Dobbiamo andare a costruire un programma in C che richiede un servizio

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200328

creazione socket

connessione

scambio dati

chiusura canale

15

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200329

socket()

connect()

read()/write()

close()

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200330

socket()

#include <sys/socket.h>

int s;

s = socket (domain, type, protocol)

AF_UNIXAF_INETAF_NS

SOCK_DGRAMSOCK_STREAMSOCK_RAWSOCK_SEQPACKET

“/etc/protocols”

16

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200331

socket()

int s;s = socket(AF_INET, SOCK_STREAM, 0);if ( s < 0 ) {

perror("socket() ");exit(1);

}

?

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200332

## Internet protocols## $FreeBSD: src/etc/protocols,v 1.13.2.1 2000/09/24 11:26:39 asmodai Exp $# from: @(#)protocols 5.1 (Berkeley) 4/17/89## See also http://www.isi.edu/in-notes/iana/assignments/protocol-numbers#ip 0 IP # internet protocol, pseudo protocol numbericmp 1 ICMP # internet control message protocoligmp 2 IGMP # internet group management protocolggp 3 GGP # gateway-gateway protocolipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')st2 5 ST2 # ST2 datagram mode (RFC 1819)tcp 6 TCP # transmission control protocolcbt 7 CBT # CBT, Tony Ballardie <[email protected]>egp 8 EGP # exterior gateway protocolnvp 11 NVP-II # Network Voice Protocolpup 12 PUP # PARC universal packet protocolargus 13 ARGUS # ARGUSemcon 14 EMCON # EMCONxnet 15 XNET # Cross Net Debuggerchaos 16 CHAOS # Chaosudp 17 UDP # user datagram protocol...

17

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200333

getprotobyname()

#include <sys/socket.h>

struct protoent *p;p = getprotobyname (“name”)

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200334

int s, protocol_number;struct protoent *protocol_entry;

protocol_entry = getprotobyname("tcp");If ( protocol_entry == NULL ) {

perror("getprotobyname() ");exit(1);

}

protocol_number = protocol_entry -> p_proto;

s = socket(AF_INET, SOCK_STREAM, protocol_number);if ( s < 0 ) {

perror("socket() ");exit(2);

}

18

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200335

connect()

#include <sys/socket.h>

int error;

error = connect(socket, addr, len);

socket()

struct sockaddr_instruct sockaddr_un sizeof(addr)

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200336

struct sockaddr_un

sun_familyDominio

sun_pathLocazione della socket nel file system

19

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200337

struct sockaddr_in

sin_familyDominiosin_portPorta (16 bit indirizzo transport)sin_addrIndirizzo IP

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200338

hton / ntoh

Host -> network Short (16 bit) htons(int)Long (32 bit) htonl(int)

Network - > hostShort (16 bit) ntohs(int)Long (32 bit) ntohl(int)

20

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200339

gethostbyname()

#include <sys/socket.h>

struct hostent *server;

server = gethostbyname(“name”);

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200340

struct hostent

gethostbyname()

struct in_addr

h_addr

bcopy()

struct sockaddr_in

assegnamento

htons(porta)

21

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200341

struct hostent *server_host;struct in_addr server_host_addr;struct sockaddr_in server_addr;

server_host = gethostbyname(“www.dsi.unimi.it");if ( server_host == NULL ) {

perror("gethostbyname() ");exit(1);

}

bcopy(server_host->h_addr, &server_host_addr, server_host->h_length);

server_addr.sin_family = AF_INET;server_addr.sin_port = htons(80);bcopy(&server_host_addr, &server_addr.sin_addr,

sizeof(server_host_addr));

if(connect(s, &server_addr, sizeof(server_addr)==-1) {perror("connect() ");exit(1);

}

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200342

inet_addr()

#include <sys/socket.h>

unsigned long addr;addr = inet_addr(“xxx.xxx.xxx.xxx”);

server_addr.sin_addr.s_addr = addr

22

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200343

getservbyname()

Get SERVICE by name

struct servent *service;service = getservbyname(“service”, proto)

/etc/services

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200344

struct servent *service_entry;int service_port;

service_entry = getservbyname("chargen", "tcp");if(service_entry == NULL) {

perror("getservbyname() ");exit(2);

}service_port = service_entry -> s_port;

23

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200345

## Network services, Internet style### $FreeBSD: src/etc/services,v 1.62.2.3 2000/10/05 07:37:37# sheldonh Exp $# From: @(#)services 5.8 (Berkeley) 5/9/91## WELL KNOWN PORT NUMBERS#rtmp 1/ddp #Routing Table Maintenance Protocoltcpmux 1/tcp #TCP Port Service Multiplexertcpmux 1/udp #TCP Port Service Multiplexernbp 2/ddp #Name Binding Protocolecho 4/ddp #AppleTalk Echo Protocolecho 7/tcpecho 7/udpdiscard 9/tcp sink nulldiscard 9/udp sink null

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200346

systat 11/tcp users #Active Userssystat 11/udp users #Active Usersdaytime 13/tcpdaytime 13/udpqotd 17/tcp quote #Quote of the Dayqotd 17/udp quote #Quote of the Daychargen 19/tcp ttytst #Character Generatorchargen 19/udp ttytst #Character Generatorftp-data 20/tcp #File Transfer [Default Data]ftp-data 20/udp #File Transfer [Default Data]ftp 21/tcp #File Transfer [Control]ftp 21/udp #File Transfer [Control]ssh 22/tcp #Secure Shell Loginssh 22/udp #Secure Shell Logintelnet 23/tcptelnet 23/udp...

24

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200347

read / write

int num_bytes;num_bytes = read(socket, buffer, size);

int num_bytes;num_bytes = write(socket, buffer, size);

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200348

close()

int error;error = close(socket);

25

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200349

Implementazione di un server

Dobbiamo scrivere un programma in C che offre un servizio

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200350

Server iterativo

Offro servizio ad un client alla volta

Il sistema operativo tiene gli altri client “in coda”

È la variante più semplice

26

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200351

creazione socket

naming

scambio dati

chiusura canale

messa in attesa

accettazione client

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200352

socket()

bind()

read()/write()

close()

listen()

accept()

27

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200353

socket()

bind()

listen()

close()

read()/write()

accept()

Server

socket()

connect()

close()

Client

read()/write()

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200354

bind()

Associa ad una socket l’indirizzo transport sul quale dovrà attendere i clientViene anche chiamato “naming” della socketAnche in questo caso dobbiamo “riempire”una struttura che contiene un indirizzo transport

28

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200355

bind()

int error;error = bind(socket, localaddr, addrlen);

socket()

sizeof(localaddr)struct sockaddr_instruct sockaddr_un

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200356

Local address

L’indirizzo IP e la porta prendono significati diversi rispetto al client

L’indirizzo IPÈ lindirizzo LOCALE tramite il quale sarà possibile accettare connessioni (ha senso solo nel caso ci siano più schede di rete)

local_addr.sin_addr.s_addr = INADDR_ANY;

La portaÈ la porta sulla quale il server sarà in attesa.Questa è un informazione che interessa al client

29

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200357

Le porte disponibili

Non tutte le porte sono ugualiDa 1 a 1024 sono riservate al sistema

Solo il superuser può fare una bind a quella portaSono quasi tutte standardizzate

Da 1025 a 65535 sono allocabili dagli utentiChiunque può fare bindSe specifichiamo “porta 0” alla bind li sistema alloca il server sulla prima libera maggiore di 1024Alcune sono standardizzate

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200358

int s;struct sockaddr_in local_addr;

s = socket(AF_INET, SOCK_STREAM, 0);if ( s < 0 ) {

perror("socket() ");exit(1);

}

local_addr.sin_family = AF_INET;local_addr.sin_port = htons(0);local_addr.sin_addr.s_addr = INADDR_ANY;

If (bind(s, &local_addr, sizeof(local_addr)) == -1) {perror("bind() ");exit(1);

}

30

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200359

E adesso ?

Ho lasciato scegliere al sistema la porta, e adesso ... come faccio a sapere qual’è ?

int error;error = getsockname(socket, sockaddr, addrlen);

indirizzo da riempire

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200360

struct sockaddr_in query_addr;int query_addrlen;

...

if (bind(s, &local_addr, sizeof(local_addr)) == -1) {perror("bind() ");exit(1);

}

query_addrlen = sizeof(query_addr);if (getsockname(s, &query_addr, &query_addrlen) == -1){

perror("getsockname() ");exit(2);

}

printf(“binded on port %d\n”, ntohs(query_addr.sin_port));

31

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200361

listen()

Abilita la socket a ricevere connessioni dai clientStabilisce la lunghezza massima della coda d’attesaQuando un client si presenta e tutta la coda è giàpiena, allora a questo viene rifiutato il servizioPer motivi non molto chiari la lunghezza massima della coda è 5Dopo che una socket viene abilitata all’attesa, non potrà più essere usata per trasferire dati, ma solo per attendere richieste di connessione

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200362

listen()

int error;error = listen(socket, queuelen);

if (listen(s, 5) == -1) {perror("listen() ");exit(1);

}

32

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200363

accept()

Serve ad “accettare” richieste di connessione da parte di un client

Il processo rimane bloccato fino a che un client non esegue una connectall’indirizzo transport su cui siamo in attesa

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200364

accept()

int data_socket;data_socket = accept(socket, peeraddr, addrlen);

socket()

sizeof(peeraddr)Verrà riempito conl’indirizzo dellasocket del client

33

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200365

struct sockaddr_in accept_addr;int accept_addrlen;char client_host[255];int client_port;

...

accept_addrlen = sizeof(struct sockaddr_in);

data_sock = accept(s, &accept_addr, &accept_addrlen);if (data_sock < 0) {

perror("accept() ");exit(1);

}

strcpy(client_host, inet_ntoa(accept_addr.sin_addr));client_port = ntohs(accept_addr.sin_port);

printf(“client on host %s, port %d\n", client_host, client_port);

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200366

Implementazione di un server concorrente o multiprocesso

Dobbiamo scrivere un programma in C che offre un servizio, ma non vogliamo tenere gente “in coda”

34

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200367

Server multiprocesso

Offro servizio a più client contemporaneamente

È una variante di poco più complicata del server iterativo

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200368

creazione socket

naming

scambio dati

chiusura canale

messa in attesa

accettazione client

35

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200369

creazione socket

naming

creazione processo

messa in attesa

accettazione client

scambio dati

chiusura canale

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200370

socket()

bind()

fork()

listen()

accept()

read()/write()

close()

36

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200371

fork()

int pid;pid = fork();

if (pid == 0)printf(“figlio\n”);

elseprintf(“padre\n”);

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200372

fork()int data_socket;int pid;

while(1) {data_socket = accept(s, &accept_addr,

&accept_addrlen);pid = fork();if (pid == 0)

give_service(data_socket);close(data_socket); /* codice del padre */

}

...

void give_service(int socket) {close(s);...close(socket);exit(0);

}

37

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200373

La morte del processo figlio

Il sistema operativo notifica l’avvenuta morte al padreUn segnale viene messo in coda al PCB del processo padre ed il figlio viene tolto dalla process table solo quando il processo è stato gestitoQuindi, il server deve prendersi cura di gestire il segnale, altrimenti avremmo una proliferazioni di processi “zombie”

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200374

socket()

bind()

fork()

listen()

accept()

read()/write()

close()

exit()signal()

38

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200375

signal()/exit()

int reaper();

void main(int argc, char ** argv) {...signal(SIGCHLD, reaper);...while (1) { ... }

}

int reaper() {int status;while ( wait3 (&status, WNOHANG, NULL) >= 0);(void) signal(SIGCHLD, reaper);

}

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200376

Server concorrente

Offro servizio a più client contemporaneamente

È la variante più complessa da gestire

39

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200377

creazione socket

naming

scambio dati

messa in attesa

attesa multipla

chiusura connessione

accettazione client

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200378

socket()

bind()

read()/write()

listen()

select()

close()

accept()

40

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200379

Maschere di bit

Servono ad elencare dei gruppi di file descriptor

Questo non vuol dire che ci limitiamo alle socketPotremmo voler scrivere un server che gestisce delle socket e contemporaneamente un operatore da tastiera

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200380

select()

Ci permette di stare in attesa su più canali contemporaneamente

La select termina quando è possibile fare una operazione su uno qualunque dei canali, secondo certi criteri di selezione

41

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200381

seletc()

select( maxfd, read_mask, write_mask, error_mask, timeout)

fd_set

struct timeval

FOPEN_MAX

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200382

Maschere di bit

ATTENZIONE

Dopo essere stata usata come parametro per la select, una maschera di bit non è più utilizzabile.

Dentro ci saranno le informazioni su quali canali sono disponibile per effettuare operazioni

42

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200383

Manipolazione delle maschere

FD_ZERO(maschera)Azzeramento della maschera

FD_SET(fd, maschera)Impostazione di un canale

FD_CLR(fd, maschera)De-impostazione di un canale

FD_ISSET(fd, maschera)Controlle se è possibile fare operazioni sul canale

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200384

fd_set fds;fd_set temp_fds;int nfds;...FD_ZERO(&fds);FD_SET(s, &fds);...while(1) {

bcopy((char *)&fds,(char *)&temp_fds, sizeof(fds));if (select(nfds, temp_fds, NULL, NULL, NULL) < 0) {

perror(“select()”);exit(1);

}...

}

43

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200385

int fd;

while(1) {bcopy((char *)&fds,(char *)&temp_fds, sizeof(fds));select(nfds, temp_fds, NULL, NULL, NULL);if(FD_ISSET(s, &temp_fds)) {

data_sock = accept(s, ...);FD_SET(data_sock,&fds);

}else {

for(fd = 0; fd <= nfds; fd += 1) {if(FD_ISSET(fd, &temp_fds)) {

do_read_write(fd);}

}}

}

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200386

int fd;

while(1) {...else {

for(fd = 0; fd <= nfds; fd += 1) {if(FD_ISSET(fd, &temp_fds)) {

do_echo(fd);FD_CLR(fd, &fds);close(fd);

}}

}}

44

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200387

Socket UDP

La differnza tra TCP e UDP è che il secondo non implementa strutture per il controllo di flusso

Ogni singolo blocco di dati viene spedito come un pacchetto indipendente, se viene perso il sistema non si preoccupa di ritrasmetterlo

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200388

creazione socket

connessione

scambio dati

chiusura canale

45

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200389

socket()

connect()

send()/recv()

close()

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200390

socket()

#include <sys/socket.h>

int s;

s = socket (domain, type, protocol)

AF_UNIXAF_INETAF_NS

SOCK_DGRAMSOCK_STREAMSOCK_STREAMSOCK_STREAMSOCK_RAWSOCK_SEQPACKET

“/etc/protocols”

46

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200391

socket()

int s;s = socket(AF_INET, SOCK_DGRAM, 0);If ( s < 0 ) {

perror("socket() ");exit(1);

}

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200392

connect()

#include <sys/socket.h>

int error;

error = connect(socket, addr, len);

socket()

struct sockaddr_instruct sockaddr_un sizeof(addr)

47

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200393

send()

#include <sys/types.h>#include <sys/socket.h>

int size;size = send(socket, buffer, len, flags)

socket()

0MSG_EOF

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200394

recv()

#include <sys/types.h>#include <sys/socket.h>

int size;size = recv(socket, buffer, len, flags)

0MSG_PEEKMSG_WAITALL

48

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200395

creazione socket

naming

scambio dati

chiusura canale

messa in attesa

accettazione client

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200396

socket()

bind()

send()/recv()

close()

49

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200397

bind()

int error;error = bind(socket, localaddr, addrlen);

socket()

sizeof(localaddr)struct sockaddr_instruct sockaddr_un

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200398

socket()

bind()

send()/recv()

close()

?????

50

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/200399

Connectionless !

Non avendo fatto la connect la socket locale NON possiede informazioni sul peer remoto !

Questa cosa può essere risolta a livello applicazione, dall’altra parte anche il client deve fare una binde darci la possibilità di mandare indietro i dati (comunicandoci la porta)

NOTA: lo schema appena visto NON va bene!

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003100

Client/Server completamente connectionless

Perchè fare la connect (o accept) se puoi non abbiamo controllo di flusso ?

È possibile usare la socket in maniera connectionless se facciamo uso di altre primitive (specializzate) per inviare/ricevere messaggi a/da indirizzi arbitrari

51

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003101

socket()

bind()

sendto()/recvfrom()

close()

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003102

sendto()

#include <sys/types.h>#include <sys/socket.h>

int size;size = sendto(socket, buffer, len, flags,

to_addr, addrlen);

struct sockaddr_instruct sockaddr_un sizeof(to_addr)

52

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003103

recvfrom()

#include <sys/types.h>#include <sys/socket.h>

int size;size = recvfrom(socket, buffer, len, flags,

from_addr, addrlen);

struct sockaddr_instruct sockaddr_un sizeof(from_addr)

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003104

Client/Server completamente connectionless

Anche da parte del client possiamo fare a meno della connect

Però questo ci costringe ad usare una bind, altrimenti il sistema non allocherà una porta alla socket locale ed il server non riusciràcomunque a rispondere

53

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003105

creazione socket

connessione

scambio dati

chiusura canale

naming

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003106

socket()

bind()

sendto()/recvfrom()

close()

54

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003107

Client o Server ?

Lo schema ottenuto risulta identico allo schema che abbiamo visto parlando del server

Siamo di fronte ad una struttura completamente simmetrica

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003108

Raw socket

Il sistema compie molte operazioni sui livelli bassi della rete, ma che non sono immediatamente visibili all’utente tramite l’interfaccia delle socket

L’intercettazione di un pacchetto IPAnche se non era indirizzato a noi (sniffing)

La generazione di un pacchetto (IP) partendo da un array di byte

Possiamo creare un header arbitrario (spoofing)

55

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003109

Cose certe ...

Java ? No grazie !La programmazione dipende fortemente dal sistema operativo

Gli header con cui interpretiamo/costruiamo i pacchetti sono molto specifici per ogni implementazione (BSD/Linux/SUN/HP)

Dobbiamo essere superuser per poter utilizzare queste funzionalità

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003110

PCAP

PCAP (Packet CAPture) è una libreria scritta da Van Jacobson, Craig Leres e Steven McCanne all’università diBerkeleyAttualmente è subito disponibile dopo l’installazione in molte distribibuzioni di UNIX (BSD e Linux-mandrake), in altre occorre installare software aggiuntivo (Linux-redhat e UNIX commerciali)Non è inclusa di default, per farne uso occorre specificare “-lpcal” alla compilazione

cc file.o –o file -lpcap

56

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003111

Ricezione di pacchetti

Identificare l’interfaccia da utilizzareInizializzare (aprire) l’interfacciaApplicare dei filtri sui pacchetti da intercettare (opzionale)Intercettare pacchettiChiudere l’interfaccia

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003112

Identificazione interfaccia

Abbiamo bisogno di una stringa che identifica la periferica per il sistema operativo (e.g. ”eth0”)

Abbiamo due possibilità:L’utente ce la fornisce (con un parametro)La richiediamo al sistema

I nomi delle interfacce variano da sistema a sistemaLinux: ethXBSD: xlX, deX, edX ...

57

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003113

pcap_lookupdev()

#include <pcap.h>

char error_desc[PCAP_ERRBUF_SIZE];char *dev;

dev = pcap_lookupdev(error_desc)

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003114

#include <stdio.h>#include <pcap.h>

int main() {char *dev, errbuf[PCAP_ERRBUF_SIZE];dev = pcap_lookupdev(errbuf);if (dev == null)

printf(“Error: %s\n”, errbuf);else

printf("Device: %s\n", dev);}

58

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003115

Apertura dell’interfaccia

Usiamo la funzione pcap_open_live() per ottenere un handle dell’interfaccia da cui leggere i pacchetti

L’interfaccia può essere aperta in due modalitàStandard: vedo solo i pacchetti indirizzati alla

mia macchinaPromisqua: vedo tutti i pacchetti sulla mia sottorete

(TUTTI!)

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003116

pcap_open_live()

#include <pcap.h>

pcap_t *handle;char *dev;int snaplen, promisc, timeout;char error_desc[PCAP_ERRBUF_SIZE];

handle = pcap_open_live(dev, snaplen, promisc, timeout, errror_desc)

pcap_lookupdev()

True/False

milliseconds

packet snapsize

59

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003117

#include <pcap.h>

...

char *dev;char errbuf[PCAP_ERRBUF_SIZE];pcap_t *handle;char packet[PACKET_SIZE];

...

dev = pcap_lookupdev(errbuf);printf("Device: %s\n", dev);

handle = pcap_open_live(dev, PACKET_SIZE, 1, 0, errbuf);

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003118

Filtri

Se la rete è molto congestionata potremmo non voler vedere tutto il traffico ma solo una parte (e.g. quello verso il server web)Risulta utile poter scrivere dei filtri in modo che l’interfaccia selezioni “a monte” quello che il programma vedrà

La creazione di un filtro avviene in due passaggi:La “compilazione”, che permette di passare da una rappresentazione tramite stringa ad una binariaL’associazione della rappresentazione binaria all’interfaccia

60

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003119

pcap_compile()

#include <pcap.h>

pcap_t *handle;struct bpf_program *binarychar * source;int optimize;unsigned int netmask;int error;

error = pcap_compile(handle, binary, source, optimize, netmask)

pcap_open_live()

True/False

inputtcpdump(1) expression

output

???

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003120

pcap_setfilter()

#include <pcap.h>

pcap_t *handle;struct bpf_program *binary;int error;

error = pcap_setfilter(handle, binary)

pcap_open_live()

pcap_compile()

61

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003121

L’informazione mancante

A volte è necessario passare parametri relativi alla configurazione della scheda di rete alle funzioni di PCAPPotremmo richiederli all’utente o andare a interpretare i file di configurazioneIn realtà PCAP ci mette a disposizione una funzione per chiedere alla scheda stessa come è configurata (pcap_lookupnet())

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003122

pcap_lookupnet()

#include <pcap.h>

char *dev;unsigned int net, mask;char errbuf[PCAP_ERRBUF_SIZE];int error;

error = pcap_lookupnet(dev, &net, &mask, errbuf);

pcap_open_live()non serve

netmask

Identificativo della reteIP & NETMASK

62

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003123

#include <pcap.h>

...char *dev = “eth0”;unsigned int net, mask;char errbuf[PCAP_ERRBUF_SIZE];pcap_t *handle;char packet[PACKET_SIZE];struct bpf_program binary;char * source = “port 80”;...pcap_lookupnet(dev, &net, &mask, errbuf);handle = pcap_open_live(dev, PACKET_SIZE, 1, 0, errbuf);pcap_compile(handle, &binary, source, 0, mask);pcap_setfilter(handle, &binary);...

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003124

Ricezione dei pacchetti

Abbiamo due possibilità:

Prelevare un pacchetto alla volta

Predisporre una routine che verrà chiamata ogni volta che arriva un pacchetto fino al raggiungimento di un numero prefissato

63

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003125

pcap_next()

#include <pcap.h>

pcap_t *handler;struct pcap_pkthdr *header;char packet[PACKET_SIZE];

packet = pcap_next(handler, header)

payload

informazioni

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003126

struct pcap_pkthdr {struct timeval ts;

/* time stamp */bpf_u_int32 caplen;

/* length of portion present */bpf_u_int32 len;

/* length this packet (off wire) */};

64

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003127

pcap_loop()

#include <pcap.h>

pcap_t *handler;int counter;pcap_handler handler; char * user;int error;

error = pcap_loop(handler, counter, callback, *user)

numeropacchetti

routinedi gestione

dati utente

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003128

La routine di gestione

#include <pcap.h>

char * args;struct pcap_pkthdr *header;char packet[PACKET_SIZE];

void got_packet(args, header, packet);

ultimo parametro di pcap_loop()

header

payload

65

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003129

Interpretazione di un pacchetto

Quello che otteniamo tramite le routine di PCAP è un array di byte

È compito nostro interpretare il contenuto

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003130

DATA

TCPheader

IPheader

Ethernetheader

DATA

DATA

DATATCPheader

TCPheader

IPheader

Ethernet frame

16 bit src TCP port #16 bit dst TCP port #

Protocol TCP32 bit src IP addr32 bit dst IP addr

Frame type IP48 bit src ETH addr48 bit dst ETH addr

66

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003131

0 1 2 30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Ethernet destination address (first 32 bits) |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Ethernet dest (last 16 bits) |Ethernet source (first 16 bits)|+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Ethernet source address (last 32 bits) |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Type code | |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| data || |

...| || end of data |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Ethernet Checksum |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

IP, ARP, RARP ...

Ethernet header

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003132

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Time to Live | Protocol | Header Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | data || |

TCP, UDP, MPLS ...

IP header

67

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003133

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Source Port | Destination Port |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Sequence Number |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Acknowledgment Number |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Data | |U|A|P|R|S|F| || Offset| Reserved |R|C|S|S|Y|I| Window || | |G|K|H|T|N|N| |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Checksum | Urgent Pointer |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Options | Padding |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| data || |

TCP header

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003134

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Source Port | Destination Port |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Length | Checksum |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Data || |

UDP header

68

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003135

Interpretazione di un pacchetto

L’unica cosa di cui siamo sicuri è che l’inizio dell’array corrisponde ad un header ethernet

Il sistema operativo mette a disposizione delle strutture che interpretano gli header usando i loro campi

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003136

char * packet;struct ether_header * eptr; /* net/ethernet.h */struct iphdr * iph; /* netinet/ip.h */struct tcphdr * tcph; /* netinet/tcp.h */struct udphdr * udph; /* netinet/udp.h */

...

eptr = (struct ether_header *) packet;

if (ntohs (eptr -> ether_type) == ETHERTYPE_IP) {printf("IP packet\n“);iph = (struct iphdr *) (packet +

sizeof(struct ether_header));if (ntohs (iph -> ip_p) == IPTYPE_TCP) {

tcph = (struct tcphdr *) ((char *) iph + sizeof(struct iphdr));

69

Dario Maggiorini ([email protected]) - Programmazione di rete in C – Ultima Revisione: 20/11/2003137

printf(“TCP destination port is %x\n”, ntohs(tcph -> th_dport);

}else if (ntohs (iph -> ip_p == IPTYPE_UDP) {

udph = (struct udphdr *) ((char *) iph + sizeof(struct iphdr));

printf(“UDP destination port is %x\n”, ntohs(udph -> uh_dport);

}else {

printf(“IP type not TCP nor UDP“);}

}else if (ntohs (eptr -> ether_type) == ETHERTYPE_ARP) {

printf("ARP packet\n“); else {

printf("Ethernet type %x not IP nor ARP“,ntohs(eptr->ether_type));

}


Recommended