371
Réseau & embarqué

Présentation de la pile réseau sous gnu linux

Embed Size (px)

Citation preview

Page 1: Présentation de la pile réseau sous gnu linux

Réseau & embarqué

Page 2: Présentation de la pile réseau sous gnu linux

PLAN

Introduction à LinuxLe noyau GNU/LinuxProgrammation systèmeLa pile réseauFiltrage & QoSDéveloppement réseau en userspaceCaptures et simulationLinux embarqué

Page 3: Présentation de la pile réseau sous gnu linux

1. Introduction à Linux

–Qu’est ce que Linux ?–Linux historique–Linux versions–Linux statistiques–Le projet GNU–Les licences

Page 4: Présentation de la pile réseau sous gnu linux

Qu’est-ce que Linux ?

Linux est le noyau du système d’exploitation GNU/Linux

GNU/Linux est le mariage du noyau Linux et des programmes et utilitaires systèmes du projet GNU (toolchain, librairies, shells, etc)

–Logiciel libre (Open Source)

Plusieurs organisations (à but lucratif ou non) distribuent le noyau Linux, les utilitaires GNU, plus d’autres logiciels comme le gestionnaire de bureau Gnome ou KDE, sous la forme d’un CD ou DVD facile à installer

–On parle alors de distributions Linux–Exemples :

•Red-Hat•Slackware•Fedora•Ubuntu•Debian

4

Page 5: Présentation de la pile réseau sous gnu linux

Unix – Historique

Page 6: Présentation de la pile réseau sous gnu linux

Linux – Historique

1991 : Le noyau Linux est écrit à partir de zéro en 6 mois par Linus Torvalds à l'université d'Helsinki

1991 : Linus distribue son noyau sur Internet. 1992 : Linux est distribué sous la licence GPL1993 : Plus de 100 développeurs travaillent sur le noyau1994 : Sortie de Linux 1.01994 : Les sociétés Red Hat et Suse publient les versions 1.0

de leur distribution1996 : Sortie de Linux 2.01999 : Sortie de Linux 2.22001 : IBM investit 1 milliard de dollars dans Linux2002 : Sortie de Linux 2.42004 : Sortie de Linux 2.62011 : Sortie de Linux 3.0

6

Page 7: Présentation de la pile réseau sous gnu linux

Linux – Historique (suite)

Premier post effectué par Linus Torvald sur Usenet :

Path:

gmdzi!unido!fauern!ira.uka.d

e!sol.ctr.columbia.edu!zapho7

Page 8: Présentation de la pile réseau sous gnu linux

Linux – Historique (suite)

Nombre de développeurs travaillant sur le noyau :–1992 : 100–2010 : > 1000

Nombre de lignes de code dans le noyau :–1995 : 250 000–2010 : 14 millions

Top 500 super computers tournant sous Linux :–1998 : 1–2011 : 413

2011 : 80% des serveurs HTTP tournent sous Linux

8

Page 9: Présentation de la pile réseau sous gnu linux

Linux – Historique – Versions

Page 10: Présentation de la pile réseau sous gnu linux

Linux – Statistiques (suite)

10

Page 11: Présentation de la pile réseau sous gnu linux

Linux – Statistiques (suite)

11

Page 12: Présentation de la pile réseau sous gnu linux

Linux – Statistiques (suite)

12

Page 13: Présentation de la pile réseau sous gnu linux

Linux – Statistiques (suite)

13

Page 14: Présentation de la pile réseau sous gnu linux

Linux – Statistiques (suite)

14

Page 15: Présentation de la pile réseau sous gnu linux

Linux – Statistiques (suite)

Page 16: Présentation de la pile réseau sous gnu linux

Linux – Statistiques (suite) – 2.6.35

Page 17: Présentation de la pile réseau sous gnu linux

Linux – Reviewers – 2.6.35

Page 18: Présentation de la pile réseau sous gnu linux

Linux – Marché embarqué

18

Page 19: Présentation de la pile réseau sous gnu linux

Projet GNU

GNU est un projet de système d'exploitation composé exclusivement de logiciels libres

GNU a été initié en 1983 par Richard Stallman à la suitede son désaccord avec les licences de Berkeley

En 1985, Stallman fonde la Free Software Foundation (FSF)Le système d'exploitation GNU reprend les concepts

d'Unix, mais son implémentation est indépendante et originaleLe projet GNU avait prévu le développement d’un noyau (Hurd)L'arrivée du noyau Linux rendit disponibles les logiciels du projet GNU sur

x86 (Torvalds a mis Linux sous licence GPL en 1992 )L'ensemble des distributions Linux portent l'empreinte du projet GNU (ne

serait-ce que dans leurs licences), d'où l'appellation distribution GNU/Linux défendue par R. Stallman

19

Page 20: Présentation de la pile réseau sous gnu linux

Licences – Logiciels libres

Un logiciel libre est un logiciel qui peut être utilisé, copié, étudié, modifié et redistribué sans restriction majeure autre que la mise à disposition du code source

Libertés fondamentales selon la FSF :–Liberté d'exécuter le programme pour tous les usages–Liberté d’étudier le fonctionnement du programme et de l’adapter (accès au code source requis)–La liberté de redistribuer des copies.–Liberté d’améliorer le programme et de publier les améliorations pour en faire profiter toute la communauté (accès au code source requis)

Copyleft :–Opposition à la notion de Copyright–Conservation du status libre pour un logiciel dérivé–Garantie de le code libre le restera dans toutes ses modifications–Impossibilité de distribution d'un logiciel propriétaire incorporant du code sous licence avec Copyleft

20

Page 21: Présentation de la pile réseau sous gnu linux

Licences – General Public License (suite)

La GPL fixe les conditions légales de distribution des logiciels libres du projet GNU

Licence avec Copyleft

La licence GPL requiert que les modifications et les travaux dérivés soient aussi placés sous licence GPL :

–Ne s’applique qu’aux logiciels distribués (donc pas utilisés en interne, en cours de développement, en phase de test, etc.)–Intégrer du code d’un programme GPL dans un autre implique de placer ce programme sous GPL–Tout programme utilisant du code GPL (lié statiquement ou dynamiquement) est considéré comme une extension de ce code et est donc placé sous GPL

GCC a une clause spéciale : il est permis de compiler un programme sans qu’il soit placé sous GPL

http://www.gnu.org/licenses/gpl-faq.html

21

Page 22: Présentation de la pile réseau sous gnu linux

Licences – Lesser General Public License (LGPL)

Licence avec Copyleft

Version limitée, ou amoindrie, de la licence GPL pour permettre à certains logiciels libres de pénétrer certains domaines n’autorisant pas le choix d’une publication entièrement libre

La licence LGPL permet d’intégrer une partie de code non modifiée d’un programme sous LGPL sans contrainte

–Si le code est modifié, alors le programme l’intégrant doit être redistribué sous LGPL.

Il est autorisé de lier, statiquement ou dynamiquement, un programme avec une librairie LGPL, sans contrainte de licence ou de distribution de code source

La LGPL autorise à lier un programme sous cette licence à du code non LGPL, sans pour autant révoquer la licence

22

Page 23: Présentation de la pile réseau sous gnu linux

Licences – Autres licences OSS

MIT ou X11 (Massachusetts Institute of Technology)–Licence sans Copyleft–Autorisation donnée à toute personne recevant un logiciel sous licence MIT/X11 le droit illimité de l'utiliser, le copier, le modifier, le fusionner, le publier, le distribuer, le vendre et de changer sa licence–Seule obligation de mettre le nom des auteurs avec la notice de Copyright

BSD (Berkeley Software Distribution)–Licence sans Copyleft–Conditions aujourd'hui identiques à la licence MIT/X11–Avant 1999, elle contenait une clause publicitaire maintenant disparue.

Il existe une multitude d’autres licences OSS

Toutes les licences OSS ne sont pas compatibles avec la GPL

23

Page 24: Présentation de la pile réseau sous gnu linux

Licences – Noyau Linux

Le noyau Linux est exclusivement sous licence GPL version 2

Les modules propriétaires sont tolérés (mais non recommandés) tant qu'ils ne sont pas considérés comme dérivés de code GPL

Les pilotes propriétaires ne peuvent pas être liés statiquement au noyau

24

Page 25: Présentation de la pile réseau sous gnu linux

Linux – Architecture

Le noyau Linux est monolithique (un binaire statique)–Les pilotes peuvent être compilés comme modules, et chargés ou déchargés tandis que le système tourne

Les pilotes de périphériques tournent en espace noyauLe noyau est multithreadéLe noyau supporte SMPLa plupart des interfaces graphiques sont en espace utilisateurScalabilité : tourne sur des super ordinateurs aussi bien que sur des petits

appareilsConformité aux standards et interopérabilité (POSIX)Support réseau avec une pile très complèteSécurité : discretionary access control, extended FS attributes, etc.Stabilité et fiabilité

25

Page 26: Présentation de la pile réseau sous gnu linux

Linux – Architecture (suite)

Il est développé principalement en langage C (pas de langage objet tel que le C++) avec une légère couche en assembleur

Minimum : processeurs 32 bits, avec ou sans MMU (Memory Management Unit)

Architectures supportées :

–32 bits : alpha, arm, cris, h8300, i386, m68k, m68knommu, mips, parisc, ppc, s390, sh, sparc, v850

–64 bits : ia64, mips64, ppc64, sh64, sparc64, x86_64

–http://en.wikipedia.org/wiki/List_of_Linux_supported_architectures

26

Page 27: Présentation de la pile réseau sous gnu linux

Famille de Linux

Plusieurs systèmes de paquets:–APK (ANDROID) initié par Google–DEB (DEBIAN) initié par Debian–LZM (SLAX)–RPM (RedHat) Package Manager initié par RedHat–PUP ou PET (PUPPY)–…

Conversion possible entre formats (alien)Une distribution possède une base de donnée localeElle est aussi liée à un serveur de paquets (ou repository)

http://en.wikipedia.org/wiki/Linux_package_formats

Page 28: Présentation de la pile réseau sous gnu linux

Dépendance de paquets

Serveur de paquets

Station de travail linux

Noms des packages

déjà installés &

installable + versions

Noms des packages

disponible + versions

Sync des bases

de données

téléchargement

& installation

(avec résolution

des dépendances)Système de fichiers linux

dans lequel s’installeles packages

Packagestéléchargeable

PackagestéléchargeablePackages

téléchargeable

X86X86-64

ARM

Page 29: Présentation de la pile réseau sous gnu linux

Démarrage d’un système linux

Page 30: Présentation de la pile réseau sous gnu linux

Démarrage d’un système linux

Bootloader1

Bootloader2

Initialise le

matériel

et sécurise

la carte(EX :

INTEL CEFDK,

BROADCOM CFE,

etc … )

Prépare le

les paramètres

a donner au

Noyau linux(Ex: uboot,

Redboot,

Grub, lilo, QI, …).

Noyau Linux Root Filesystem

Une fois chargé

en RAM, le

noyau

s’initialise en

commençant

par interpréter

les paramètres.

Si le noyau est

compressé, il se

décompresse

avant.

Paramètres

Le noyau passe

a l’espace

utilisateur en

exécutant par

Le processus

/sbin/init, le père

de tous les autres

process.

Page 31: Présentation de la pile réseau sous gnu linux

Echange noyau / utilisateur

NOYAU GNU/LINUX

/dev/… /proc et /sys Descripteur de fichiers

Il existe plusieurs moyen d’échange avec l’espace utilisateur.

ESPACE UTILISATEUR

PILE RESEAU

SOCKET BSD

Page 32: Présentation de la pile réseau sous gnu linux

2. Le noyau GNU/Linux

–Architecture–Paramétrage d’un noyau–Noyau statique vs modules dynamiques–Détail des paramètres réseau–Génération d’un noyau–Les drivers réseau–Compilation d’un module dynamique–Chargement & déchargement de modules–

Page 33: Présentation de la pile réseau sous gnu linux

Linux tel un oignon

Page 34: Présentation de la pile réseau sous gnu linux

Architecture du noyau

Le noyau est divisé en un ensemble de blocs séparés :

Page 35: Présentation de la pile réseau sous gnu linux

Les deux mondes

Linux est constitué de deux monde, l’un est privilégié où tout est permis

(espace noyau), l’autre moins avec certaines restrictions (espace utilisateur).

Les deux mondes cohabitent autour de la syscall interface (SCI) utilisée utilisée pour

Véhiculer des informations entre les deux. Coté utilisateur, la frontière est délimité par

Une librairie (GNU libc) faisant abstraction avec la SCI. Tout programme y est linké

avec.

Page 36: Présentation de la pile réseau sous gnu linux

Sources du noyau linux

Noyau linux

PILE RESEAU

FILESYSTEM

MEMORY

CORE

DRIVERSRESEAU

. . .

e1000

AppleTalk

. . .

Page 37: Présentation de la pile réseau sous gnu linux

Organisation des sources du noyau

Code de la pile réseau :

Racine des sources du noyau linux (après décompression) :

Codes des drivers réseaux :

Page 38: Présentation de la pile réseau sous gnu linux

Etapes pour la génération d’un noyau

Téléchargement des sources de kernel.orgVérification de la signature de l’archiveExtraction des sourcesConfiguration du noyau

make menuconfigmake xconfigmake gconfig

CompilationMake -j 5

Installationmake install modules_install

La configuration consiste à sélectionner ce qui sera enstatique dans le noyau (chargé en une fois) et ce quisera chargé séparément en modules dynamique.L’étape de configuration est sauvegardé dans unfichier .config ;3 possibilités pour toutes les options du noyau :y : en statique dans le noyaum : en module dynamiqueN : pas inclu Il y a aussi une gestion des dépendances.(ex: la pile réseau permet d’activer un driver réseau)

Page 39: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

make menuconfig Donne un fichier de

paramétrage .config

Page 40: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 41: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 42: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 43: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 44: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 45: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 46: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 47: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 48: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 49: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 50: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 51: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 52: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 53: Présentation de la pile réseau sous gnu linux

Paramétrer un noyau

Page 54: Présentation de la pile réseau sous gnu linux

Interface de configuration graphique

make gconfig

Page 55: Présentation de la pile réseau sous gnu linux

Builder & installer un noyau linux

Compilation du noyau & des modules dynamiques :

make –j 5

Génère une partie statique : vmlinux, vmlinuz ou bzImage

Génère des modules dynamiques *.ko

Installation de la partie statique :

sudo make install

Installation des modules dynamiques :

sudo make modules_install

Page 56: Présentation de la pile réseau sous gnu linux

Découpage modulaire du noyau

kernel

Le noyau peut être diviser en une partie statique (vmlinux)

et des modules dynamique

Page 57: Présentation de la pile réseau sous gnu linux

Chargement d’un module dynamique

Un module dynamique est un kernel object au format ELF

Chargement :–insmod ./mondriver.ko–modprobe mondriver

Déchargement :–rmmod mondriver–modprobe –r mondriver

Autre :–lsmod–modinfo ./mondriver.ko

Page 58: Présentation de la pile réseau sous gnu linux

Programmation système

–Apercu de l'API posix et la system call interface (SCI)–Programmation mutlti-threadé et process–Gestion des priorités des tâches

Page 59: Présentation de la pile réseau sous gnu linux

L’API Posix de la libC

L’API POSIX de la libC regroupe un ensemble de fonctions autour :–Gestion des process (chargement, exécution, création, fin …) ;–Gestion des fichiers (c’éation, suppression, ouverture, fermeture, … ) ;–Gestion des devices (ioctl, … )–Gestions des infos lié au matériel (get/set de la date et de l’heure, … ) ;–De la communication inter-process via des IPC (message queue, sockets, …).

http://syscalls.kernelgrok.com/

Page 60: Présentation de la pile réseau sous gnu linux

Processus – Priorité d’un processus

La fonction nice() permet de changer la priorité d’un processus

#include <unistd.h>int nice(int nice);

–nice : valeur à ajouter à la valeur de nice courante du processus–→ retourne la nouvelle valeur de nice (glibc ≥ 2.2.4) (avec errno)

Si la valeur de nice augmente, la priorité diminue, et vice-versa–Les valeurs possibles vont de -20 à 19

La priorité par défaut est une valeur de nice de 0

Seul l’utilisateur avec UID 0 (root) peut changer nice avec une valeur négative

Un processus hérite de la valeur de nice de son parent après fork() ou exec()

60

Page 61: Présentation de la pile réseau sous gnu linux

Processus – Politiques d’ordonnancement

Le noyau Linux supporte plusieurs politiques d’ordonnancement

FIFO :–Pas de quantum de temps

•Un processus occupe le CPU jusqu'à ce qu'il bloque ou est préempté–Préemption par processus plus prioritaire

•Le processus préempté est de nouveau exécuté dès que le processus plus prioritaire est bloqué

–Queue de processus en attente, par priorité

Round-Robin :–Comme FIFO, mai un processus s'exécute pendant un quantum de temps–Préemption par processus plus prioritaire–Queue de processus en attente, par priorité

61

Page 62: Présentation de la pile réseau sous gnu linux

Processus - Politiques d’ordonnancement (suite)

Other : l’ordonnancement Unix (Posix) traditionnel–Quantum de temps–Priorité de base (statique, valeur de nice) + priorité dynamique

•La priorité est incrémentée en interne lorsqu'un processus est prêt mais se voit refuser le CPU

–Principe d’extinction des priorités

Batch : comme Other, mais permet de défavoriser un processus (Linux >= 2.6.16)

Idle : comme Batch, mais avec une valeur interne de nice > 19 (nice() n'a aucun effet) (Linux >= 2.6.23)

Priorité des processus gérés par les quatre politiques :–1. Processus associé à une FIFO–2. Processus associé à un tourniquet–3. Processus associé à la politique Other, Batch ou Idle

62

Page 63: Présentation de la pile réseau sous gnu linux

Processus – sched_get_priority_*()

Les fonctions sched_get_priority_max() et sched_get_priority_min() permettent de connaitre l’échelle des priorités pour une politique donnée

#include <sched.h>int sched_get_priority_max(int policy);int sched_get_priority_min(int policy);

–policy : SCHED_FIFO, SCHED_RR, SCHED_OTHER, SCHED_BATCH ou SCHED_IDLE–→ retourne la priorité minimale ou maximale pour la politique spécifiée, ou -1si erreur (avec errno)

Couramment, les politiques FIFO et RR ont une échelle de priorité de 1 à 99.

Les politiques OTHER, BATCH et IDLE n’ont qu’un seul niveau de priorité : 0 (priorités relatives gérées par nice() sauf pour IDLE)

63

Page 64: Présentation de la pile réseau sous gnu linux

Processus – sched_setscheduler()

La fonction sched_setscheduler() permet de sélectionner la politique et le niveau de priorité d'un processus

#include <sched.h>int sched_setscheduler(pid_t pid, int policy, struct sched_param *param);

–pid : processus (si 0, processus courant)–policy : SCHED_FIFO, SCHED_RR, SCHED_OTHER, SCHED_BATCH ou SCHED_IDLE–*param :

struct sched_param {int sched_priority; // Priorité de 1 à 99 pour FIFO et RR}

–→ retourne 0 ou -1 si erreur (avec errno)

Seul un processus d'UID effectif 0 (root) peut élever une politique ou une prioritéLa politique et la priorité sont héritées après fork()

64

Page 65: Présentation de la pile réseau sous gnu linux

Processus – sched_getscheduler()

La fonction sched_getscheduler() permet de connaitre la politique d'ordonnancement d'un processus

#include <sched.h>int sched_getscheduler(pid_t pid);

–pid : processus (si 0, processus courant)–→ retourne SCHED_FIFO, SCHED_RR, SCHED_OTHER, SCHED_BATCH ou SCHED_IDLE

65

Page 66: Présentation de la pile réseau sous gnu linux

Processus – sched_setparam()

Les fonctions sched_setparam() et sched_getparam() permettent de changer ou connaitre la priorité d'un processus

#include <sched.h>int sched_setparam(pid_t pid, const struct sched_param *param);int sched_getparam(pid_t pid, struct sched_param *param);

–pid : processus (si 0, processus courant)–*param :

struct sched_param {int sched_priority;}

–→ retourne 0 ou -1 si erreur (avec errno)

Seul un processus d'UID effectif 0 (root) peut élever une priorité

66

Page 67: Présentation de la pile réseau sous gnu linux

Processus – sched_rr_get_interval()

La fonction sched_rr_get_interval() permet de connaitre le quantum de temps Round-Robin alloué à un processus

#include <sched.h>int sched_rr_get_interval(pid_t pid, struct timespec *tp);

–pid : PID du processus (si 0, processus appelant)–*tp : pointeur sur structure timespec :

struct timespec {time_t tv_sec; // Secondeslong tv_nsec; // Nanosecondes

};–→ retourne 0 ou -1 si erreur (avec errno)

La valeur par défaut du quantum est de 0.1 secondesLinux permet de changer le quantum en changeant la valeur de nice (non portable, et le

quantum alloué varie selon la version du noyau)

67

Page 68: Présentation de la pile réseau sous gnu linux

Processus – sched_yield()

La fonction sched_yield() permet à un processus de volontairement se suspendre

#include <sched.h> int sched_yield(void);

–→ retourne 0 ou -1 si erreur (avec errno)

Le processus est placé à la fin de la queue de son niveau de priorité–Si le processus est le seul dans sa queue, il est de nouveau exécuté

68

Page 69: Présentation de la pile réseau sous gnu linux

Processus – sched_setaffinity()

La fonction sched_setaffinity() permet de définir sur quels CPUs un processus est "confiné"

#include <sched.h>int sched_setaffinity(pid_t pid, size_t setsize, cpu_set_t *mask);int sched_getaffinity(pid_t pid, size_t setsize, cpu_set_t *mask);

–pid : PID du processus (si 0, processus appelant)–setsize : nombre de structures *mask–*mask : structure opaque manipulable par des macros (voir man 3 CPU_SET)–→ retournent 0 ou -1 si erreur (avec errno)

Les CPUs sont numérotés de 0 à CPU_SETSIZE (couramment 1024)

Le masque est hérité après fork()

69

Page 70: Présentation de la pile réseau sous gnu linux

Threads – Ordonnancement et priorité

Comme pour les processus, une politique d’ordonnancement et une priorité particulières peuvent être spécifiées pour un thread

Par défaut, un thread hérite de la politique d’ordonnancement et de la priorité de son ancêtre (processus ou autre thread)

–L’héritage peut-être désactivé dans un attribut du thread–Si l’attribut d’héritage n’est pas désactivé, les attributs spécifiant la politique et de la priorité sont sans effet

Le thread doit être privilégié (root) pour pouvoir augmenter la politique et la priorité

70

Page 71: Présentation de la pile réseau sous gnu linux

Threads – pthread_attr_setinheritsched()

La fonction pthread_attr_setinheritsched() permet de spécifier si la politique d’ordonnancement et la priorité sont héritées ou spécifié dans les attributs du thread

int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);

–*attr : attributs du thread–inherited :

•PTHREAD_INHERIT_SCHED : politique et priorité sont hérité du thread créateur•PTHREAD_EXPLICIT_SCHED : honore les attributs de politique et priorité à la création du thread

–→ retourne 0 ou un numéro d’erreur

71

Page 72: Présentation de la pile réseau sous gnu linux

Threads – pthread_attr_setsched*()

Les fonction pthread_attr_setsched*() permettent de spécifier la politique d’ordonnancement et la priorité d’un thread

int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

–*attr : attributs du thread–policy : SCHED_FIFO, SCHED_RR ou SCHED_OTHER –→ retourne 0 ou un numéro d’erreur

int pthread_setschedparam(pthread_attr_t *attr, struct sched_param *param);

–*attr : attributs du thread–*param : structure ayant un membre :

•int sched_priority : priorité pour SCHED_FIFO ou SCHED_RR–→ retourne 0 ou un numéro d’erreur

72

Page 73: Présentation de la pile réseau sous gnu linux

Threads – pthread_attr_setsched*() – Exemple

/* Toutes les conditions d’erreurs ne sont pas vérifiées dans cet exemple */

#include <pthread.h>#include <sched.h>

pthread_attr_t attr;sched_param param;pthread_t thread_id;pthread_attr_init(&attr);

param.sched_priority = 20;pthread_attr_setschedparam(&attr, &param);pthread_attr_setschedpolicy(&attr, SCHED_RR);pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);

pthread_create (&thread_id, &attr, func, NULL);pthread_attr_destroy(&attr);

/* ... */

73

Page 74: Présentation de la pile réseau sous gnu linux

Threads – pthread_setschedparam()

La fonction pthread_setschedparam() permet de changer la politique d’ordonnancement et la priorité d’un thread pendant son exécution

int pthread_setschedparam(pthread_t thread, int policy, struct sched_param *param);

–thread : identificateur du thread–policy : SCHED_FIFO, SCHED_RR ou SCHED_OTHER–*param : structure ayant un membre :

•int sched_priority : priorité pour SCHED_FIFO ou SCHED_RR

–→ retourne 0 ou un numéro d’erreur

74

Page 75: Présentation de la pile réseau sous gnu linux

Threads – Inversion de priorité

75

Page 76: Présentation de la pile réseau sous gnu linux

Threads – pthread_mutexattr_*prioceiling()

L’attribut prioceiling d’un mutex permet de spécifier une priorité minimum appliquée aux threads verrouillant ce mutex

int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling);

–*attr : attributs du mutex–prioceiling : priorité minimum (même valeurs que pour SCHED_FIFO)–→ retourne 0 ou numéro d’erreur

En pratique, la priorité spécifiée est au moins égale à la priorité la plus haute utilisée dans les threads

76

Page 77: Présentation de la pile réseau sous gnu linux

Threads – pthread_mutexattr_*protocol()

L’attribut protocol d’un mutex permet de spécifier comment un thread le verrouillant verra sa priorité augmenter ou non

int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol);

–*attr : attributs du mutex –protocol :

•PTHREAD_PRIO_NONE : pas de changement de priorité•PTHREAD_PRIO_INHERIT : thread verrouillant hérite de la plus haute priorité des threads en attente•PTHREAD_PRIO_PROTECT : thread verrouillant s'exécute à la priorité minimum prioceiling du mutex, même sans autre thread bloqué

–→ retourne 0 ou un numéro d’erreur

77

Page 78: Présentation de la pile réseau sous gnu linux

4. La pile réseau

–Architecture de la pile–Les drivers réseau–Les buffer de socket du noyau (SK BUFF)–Circulation des paquets –Configuration via /proc et /sys–Configuration des interfaces–Outils interagissant avec la pile réseau–Estimations du coût des recopies–Latence en UDP et TCP

Page 79: Présentation de la pile réseau sous gnu linux

Historique

Le développement de la couche réseau dans le noyau Linux a été

orchestré par plusieurs programmeurs indépendants.

Le but est d'implémenter un système qui soit au moins aussi

performant que les autres tout en restant dans le domaine du

logiciel libre.

C'est avant tout le protocole TCP/IP qui a été

développé avec des primitives de base par

Ross Biro. Orest Zborowski produisit la

première interface socket BSD pour le noyau

GNU Linux.

Le code fut ensuite repris par Alan Cox de

Red Hat.

Page 80: Présentation de la pile réseau sous gnu linux

Protocoles gérés

Linux gère une multitude de protocoles réseau :

OSI 2 : couche liaison (Driver réseaux) : 1.Ethernet

2.ARP / RARP

3.Tokenring

4.ATM

OSI 3 : couche réseau :

OSI 4 : couche transport :

1.TCP

2.UDP

3.Netbios

1.IP

2.ICMP

3.IGMP

4.ATM

La pile réseau de GNU Linux peut être considéré comme la plus complète et disponible à ce jour.

UNIX Unix domain sockets

INET TCP/IP

AX25 Amateur radio

IPX Novell IPX

APPLETALK Appletalk

X25 X.25

Etc…(define in include/linux/socket.h)

Page 81: Présentation de la pile réseau sous gnu linux

Protocoles gérés

Disponibilité des fonctionnalités dans la pile réseau en

fonction des versions du noyau Linux 2.2, 2.4 et 2.6

Page 82: Présentation de la pile réseau sous gnu linux

Support du réseau dans le Kernel

Modèle Internet de la pile réseau. Architecture de la pile réseau.

La pile réseau couvre le protocole TCP/IP

de la couche liaison (drivers) jusqu'à la

couche transport (sockets BSD).

D'un point de vue de Linux, la pile est localisée

dans le noyau avec une API (les sockets BSD)

pouvant être appelée depuis l'espace utilisateur.

Couche matérielle

Couche de liaison

Couche réseau

Couche transport

Couche applicative

Application utilisateur

Driver réseau

Protocoles réseaux

Interface de diagnostique des devices

Interface de diagnostique des protocoles

Appels système

Carte réseau

ApplicationUser

space

Kernel

space

Page 83: Présentation de la pile réseau sous gnu linux

Les drivers réseaux : introduction

Un driver réseau est la troisième catégorie

de drivers Linux après les drivers de blocs

et de caractères.

Le fonctionnement d'une interface réseau au

sein du système est assez similaire à un driver

de blocs. Un driver de blocs est utilisé par le

noyau pour transmettre ou recevoir des blocs

de données. D'un point de vue similaire, un

driver réseau s'enregistre auprès du noyau de

Façon à pouvoir échanger des paquets de

données avec l'extérieur.

Il y a cependant une différence avec un

driver de blocs qui consiste à ne pas avoir

de point d'entrée dans le répertoire dédié

aux devices /dev. Il n'est donc pas possible

de mettre en application la règle qui veut

que sous Unix / GNU Linux tout soit considéré

comme un fichier.

La différence la plus importante entre ces

deux types de drivers est que le driver de blocs

n'est utilisé que lorsque le driver y fait appel

tandis qu'un drivers réseau reçoit les paquets

réseau de façon asynchrone depuis l'extérieur.

Ainsi, alors qu'un driver de blocs demande

avant d'envoyer quelque chose au noyau,

Page 84: Présentation de la pile réseau sous gnu linux

Les drivers réseaux : découpage modulaire

http://docs.huihoo.com/linux/kernel/a1/index.html

L'architecture réseau permet au noyau

Linux de se connecter à d'autres système

via le réseau.

Il existe un certain nombre important de

matériel ainsi qu'un nombre important de

protocole supportés .

Chaque objet réseau est représenté via une

socket. Les sockets sont associées aux process

dans le même sens que les i-nodes d'un

système de fichiers peuvent être associées.

Une socket peut être partagée par plusieurs

processus.

L'architecture réseau utilise le scheduler de

process du noyau Linux schedule() pour

suspendre ou reprendre un process en état

d'attente de données (géré par un système de

gestion du contrôle et du flow de données).

De plus, la couche VFS apporte un système de

fichiers logique (comme pour le cas de NFS ;

il existe des possibilités en mode user via libfuse)

Page 85: Présentation de la pile réseau sous gnu linux

Interaction entre une carte réseau et le noyau :

Toutes les cartes peuvent interagir avec le noyau de deux façon différentes :

–Polling : Le noyau vérifie le status du device à intervalle régulier de façon à vérifier s'il y a quelque chose à faire ;

–Interruptions : La carte envoie un signal au noyau sous la forme d'une interruption pour lui indiquer qu'il y a quelque chose à faire.–

1.Matériel : elle accepte les paquets entrant en provenance des interfaces réseaux et les positionne directement en file d'entrée.2.2.Software (NET_RX_SOFTIRQ) : elle exécute le handle de paquets de réception. Elle est responsable de la gestion des protocoles. Les paquets entrant sont gérés par cette interruption et placés dans une file d'attente. Les paquets à forwarder sont placés dans la file de sortie de l'interface de sortie.

Les drivers réseaux : liens

Page 86: Présentation de la pile réseau sous gnu linux

Chargement d'un driver

réseau dynamiquement

dans le kernel

Kmod est le chargeur de module

dans le noyau GNU Linux. Le

chargement initialise le nom du

module (argv[0]) à charger. Si au

lieu d'utiliser insmod, modprobe

est utilisé, kmod ira regarder la

configuration /etc/modprobe.conf

Chargement d’un driver réseau

Page 87: Présentation de la pile réseau sous gnu linux

Les drivers réseaux : enregistrement

Machine à états pour l'enregistrement d'un device réseau.

Page 88: Présentation de la pile réseau sous gnu linux

Les drivers réseaux : exemple d'implémentation (old)

#if defined(MODULE) && LINUX_VERSION_CODE > 0x20115MODULE_AUTHOR("Donald Becker <[email protected]>");MODULE_DESCRIPTION("3Com 3c590/3c900 series Vortex/Boomerang driver");MODULE_PARM(debug, "i");...#endif...#ifdef MODULEint init_module(void){...}#elseint tc59x_probe(struct device *dev){...}#endif /* not MODULE */

...static int vortex_scan(struct device *dev, struct pci_id_info pci_tbl[]){...#if defined(CONFIG_PCI) || (defined(MODULE) && !defined(NO_PCI))...#ifdef MODULEif (compaq_ioaddr) {vortex_probe1(0, 0, dev, compaq_ioaddr, compaq_irq,compaq_device_id, cards_found++);dev = 0;}#endifreturn cards_found ? 0 : -ENODEV;}...#ifdef MODULEvoid cleanup_module(void){... ... ...}#endif

Example de code issue du code source du drivers réseau (drivers/net/3c59x.c) destiné au

Noyau 2.2.14. Il y a un nombre important de #ifdef MODULE et de #if defined (MODULE).

Cela est assez représentatif de l'ancienne façon de programmer qui définissait le fonctionnement

d'un module dynamique en fonction de la façon dont il était compilé tel un module statique au sein

De l'image d'un noyau.

Page 89: Présentation de la pile réseau sous gnu linux

Les drivers réseaux : exemple d'implémentation (new)

static char version[] _ _devinitdata = DRV_NAME " ... ";

static struct vortex_chip_info {

...

}

vortex_info_tbl[] _ _devinitdata = {

{"3c590 Vortex 10Mbps",

... ... ...

}

static int _ _init vortex_init (void)

{

...

}

static void _ _exit vortex_cleanup (void)

{

...

}

module_init(vortex_init);

module_exit(vortex_cleanup);

Dans cette nouvelle version, les directives de

pré-processing ne sont plus nécessaires ce

qui enlève tous les #ifdef et #endif.

Cela le rend plus facile à lire pour les

développeurs de drivers via l'utilisation d'un

ensemble de macros (_ _init, _ _exit, et

_ _devinitdata ).

Page 90: Présentation de la pile réseau sous gnu linux

Les drivers réseaux : exemple d'implémentation (macros 1/2)

Liste des sections de mémoire pouvant

être initialisées par des macros dans les

drivers réseau.

La plupart de ces macros sont définies dans

le header include/linux/init.h

Page 91: Présentation de la pile réseau sous gnu linux

Les drivers réseaux : exemple d'implémentation (macros 2/2)

Macro Description

_ _init Routine d'initialisation lors de la séquence de boot.

_ _exit Appelée lorsque le composant kernel est déchargé du noyau.

core_initcall,

postcore_initcall,

arch_initcall,

subsys_initcall,

fs_initcall,

device_initcall,

late_initcall

Ensemble de routine pour modifier l'ordre de priorité dans les routines de virtualisation

exécutées lors de la séquence de BOOT.

_ _initcall Macro obsolète.

_ _exitcall Anciennement appelée par la routine de sortie du drivers lors de son déchargement.

_initdata Initialise une structure à la séquence de BOOT.

_exitdata A utiliser par les structures de données marquées par le tag __exitcall.

Page 92: Présentation de la pile réseau sous gnu linux

Check if a queue is empty : int skb_queue_empty (struct sk_buff_head * list);

Reference buffer : struct sk_buff * skb_get (struct sk_buff * skb);

Free an sk_buff : void kfree_skb (struct sk_buff * skb);

Is the buffer a clone : int skb_cloned (struct sk_buff * skb);

Is the buffer shared : int skb_shared (struct sk_buff * skb);

Make a copy of a shared buffer : struct sk_buff * skb_unshare (struct sk_buff * skb, int pri);

struct sk_buff * skb_peek (struct sk_buff_head * list_);

Get queue length: __u32 skb_queue_len (struct sk_buff_head * list_);

Queue a buffer at the list head : void __skb_queue_head (struct sk_buff_head * list, struct sk_buff * newsk);

void skb_queue_head (struct sk_buff_head * list, struct sk_buff * newsk);

Queue a buffer at the list tail : void __skb_queue_tail (struct sk_buff_head * list, struct sk_buff * newsk);

void skb_queue_tail (struct sk_buff_head * list, struct sk_buff * newsk);

Remove from the head of the queue : struct sk_buff * __skb_dequeue (struct sk_buff_head * list);

struct sk_buff * skb_dequeue (struct sk_buff_head * list);

Primitives réseau du kernel 1/6

Page 93: Présentation de la pile réseau sous gnu linux

Insert a buffer : void skb_insert (struct sk_buff * old, struct sk_buff * newsk);

Append a buffer : void skb_append (struct sk_buff * old, struct sk_buff * newsk);

Remove a buffer from a list : void skb_unlink (struct sk_buff * skb);

Remove from the tail of the queue : struct sk_buff * __skb_dequeue_tail (struct sk_buff_head * list);

Remove from the head of the queue : struct sk_buff * skb_dequeue_tail (struct sk_buff_head * list);

Add data to a buffer : unsigned char * skb_put (struct sk_buff * skb, unsigned int len);

Add data to the start of a buffer : unsigned char * skb_push (struct sk_buff * skb, unsigned int len);

Remove data from the start of a buffer : unsigned char * skb_pull (struct sk_buff * skb, unsigned int len);

Bytes at buffer head : int skb_headroom (const struct sk_buff * skb);

Bytes at buffer end : int skb_tailroom (const struct sk_buff * skb);

Adjust headroom : void skb_reserve (struct sk_buff * skb, unsigned int len);

Primitives réseau du kernel 2/6

Page 94: Présentation de la pile réseau sous gnu linux

Orphan a buffer : void skb_orphan (struct sk_buff * skb);

Empty a list : void skb_queue_purge (struct sk_buff_head * list);

void __skb_queue_purge (struct sk_buff_head * list);

Allocate an skbuff for sending : struct sk_buff * dev_alloc_skb (unsigned int length);

Copy a buffer if need be : struct sk_buff * skb_cow (struct sk_buff * skb, unsigned int headroom);

Private function : void skb_over_panic (struct sk_buff * skb, int sz, void * here);

void skb_under_panic (struct sk_buff * skb, int sz, void * here);

void __kfree_skb (struct sk_buff * skb);

Allocate a network buffer : struct sk_buff * alloc_skb (unsigned int size, int gfp_mask);

Duplicate an sk_buff : struct sk_buff * skb_clone (struct sk_buff * skb, int gfp_mask);

Copy an sk_buff : struct sk_buff * skb_copy (const struct sk_buff * skb, int gfp_mask);

Copy and expand sk_buff : struct sk_buff * skb_copy_expand (const struct sk_buff * skb,

int newheadroom, int newtailroom, int gfp_mask);

Test if a device exists : int dev_get (const char * name);

Primitives réseau du kernel 3/6

Page 95: Présentation de la pile réseau sous gnu linux

Run a filter on a socket : int sk_run_filter (struct sk_buff * skb, struct sock_filter * filter, int flen);

Register ethernet device : struct net_device * init_etherdev (struct net_device * dev, int sizeof_priv );

Add packet handler : void dev_add_pack (struct packet_type * pt);

Remove packet handler : void dev_remove_pack (struct packet_type * pt);

Find a device by its name : struct net_device * __dev_get_by_name (const char * name);

struct net_device * dev_get_by_name (const char * name);

Find a device by its ifindex : struct net_device * __dev_get_by_index (int ifindex);

struct net_device * dev_get_by_index (int ifindex);

Allocate a name for a device : int dev_alloc_name (struct net_device * dev, const char * name);

Allocate a network device and name : struct net_device * dev_alloc (const char * name, int * err);

Device changes state : void netdev_state_change (struct net_device * dev);

Load a network module : void dev_load (const char * name);

Prepare an interface for use : int dev_open (struct net_device * dev);

Primitives réseau du kernel 4/6

Page 96: Présentation de la pile réseau sous gnu linux

Shutdown an interface : int dev_close (struct net_device * dev);

Register a network notifier block : int register_netdevice_notifier (struct notifier_block * nb);

Unregister a network notifier block : int unregister_netdevice_notifier (struct notifier_block * nb);

Transmit a buffer : int dev_queue_xmit (struct sk_buff * skb);

Post buffer to the network code : void netif_rx (struct sk_buff * skb);

void net_call_rx_atomic (void (*fn) (void));

Register a SIOCGIF handler : int register_gifconf (unsigned int family, gifconf_func_t * gifconf);

Set up master/slave pair : int netdev_set_master (struct net_device * slave, struct net_device *master);

Update promiscuity count on a device : void dev_set_promiscuity (struct net_device * dev, int inc);

Update allmulti count on a device : void dev_set_allmulti (struct net_device * dev, int inc);

Network device ioctl : int dev_ioctl (unsigned int cmd, void * arg);

Allocate an ifindex : int dev_new_index ( void);

Primitives réseau du kernel 5/6

Page 97: Présentation de la pile réseau sous gnu linux

Register a network device : int register_netdevice (struct net_device * dev);

Complete unregistration : int netdev_finish_unregister (struct net_device * dev);

Remove device from the kernel : int unregister_netdevice (struct net_device * dev);

Primitives réseau du kernel 6/6

Page 98: Présentation de la pile réseau sous gnu linux

Les buffers sk 1/4

Un paquet issu ou à destination du réseau n’est qu’une suite d’octets, un buffer, à émettre/recevoir.

Il est associé dans le noyau Linux à une structure de contrôle de type sk_buff appelée

sk_buffers (socket buffer). A cette structure est attaché un bloc mémoire contenant le buffer

reçu ou à émettre.

Lorsqu’un paquet doit être émis ou est reçu par la carte réseau, un sk_buff est créé. Cette structure

de contrôle se compose notamment de :

1.structures représentant les couches Ethernet, réseau et transport

2.pointeurs pour la gestion du sk_buffer dans la liste des sk_buffers

3.informations sur les périphériques (devices) d’entrée/sortie

4.informations sur le type de paquet (broadcast, multicast, …)

5.du buffer contenant le paquet à proprement parlé

Des pointeurs *head, *data, *tail, et *end servent à la gestion du bloc mémoire associé au

sk_buffer. head et end pointent respectivement sur le début et la fin du bloc mémoire. data

pointe sur un en-tête du paquet en fonction de l’endroit où le paquet se situe dans la pile de

protocoles.

Par exemple un paquet capturé à l’aide d’un hook netfilter aura son pointeur data positionné sur le

premier

octet de l’en-tête IP. tail pointe sur le premier octet de bourrage du bloc mémoire (le bloc mémoire

pouvant

être plus grand que le paquet à stocker).

Page 99: Présentation de la pile réseau sous gnu linux

Description d'un bloc mémoire associé à un sk_buffer, l'un vide et l'autre initialisé avec un bloc mémoire initialisé avec un paquet :

Les buffers sk 2/4

Il est possible de déplacer ces pointeurs pour, par exemple, positionner le pointeur data sur un en-têtedifférent. Il faut cependant garder à l’esprit qu’en mode noyau aucun contrôle n’est effectué sur les accèsmémoire et qu’un plantage du noyau peut donc se produire du fait d’une manipulation hasardeuse de pointeur.

Les fonctions pour manipuler les sk_buffers sont définies dans le fichier header linux/skbuff.h.

Page 100: Présentation de la pile réseau sous gnu linux

Les buffers sk 3/4

La structure du buffer_sk est géré via une liste doublement chaînée.

Page 101: Présentation de la pile réseau sous gnu linux

struct sk_buff_head {/* These two members must be first. */struct sk_buff * next;struct sk_buff * prev;_ _u32 qlen;spinlock_t lock;

};

Les buffers sk 4/4

Structure

de

données

Init.

Page 102: Présentation de la pile réseau sous gnu linux

Architecture de la pile réseau

La pile TCP/IP est directement implémentée dans le noyau.

Les trames émises et reçues peuvent être amenées à traverser l’ensemble des couches (matérielles et logicielles) :

Emission

Réception

Représentation des trames dans le Kernel Space les paquets sont manipulés par le noyau dans

des structures de type sk_buffer.

Le parcours d’une trame reçue ou à émettre, le traitement dans la pile IP peut être découpé en

phases.

Page 103: Présentation de la pile réseau sous gnu linux

Circulation des paquets 1/2

Le traitement IP comporte 4 grandes phases :

La réception de trame : point d’entrée

dans la couche IP pour les trames reçues sur

les interfaces réseau.

Le routage : choix de la route à suivre par

le paquet (réémission sur une autre interface/

réseau ou destination locale)

Le forwarding : contrôle du TTL et du

MTU avant de passer à la phase de

réémission.

L’émission : les paquets à émettre ou à

réémettre passent par cette étape. Juste

avant de quitter la couche IP l’en-tête

Ethernet est complété.

Page 104: Présentation de la pile réseau sous gnu linux

Circulation des

paquets 2/2

Couche transport

OSI #4

Couche réseau

OSI #3

Couche liaison

OSI #2

Couche physique

OSI #1

Cheminement des paquets

dans les différentes couches

de la stack réseau du kernel

GNU Linux

Une carte réseau utilise 2 listespermettant de gérer les paquetsentrants (rx_ring) et les paquetssortants (tx_ring) de la ou desinterfaces réseaux.

On peut ainsi distinguer la procédure d’émission de laprocédure de réception.

Pour les noyaux 2.2 et inférieurs, le traitement des trames est différent (ex : on ne retrouvepas les files tx et rx).

Page 105: Présentation de la pile réseau sous gnu linux

1: Physical

Layer

2: Data

Link

4: Transport

3: Network

7: Application

6: Presentation

5: Session

Interface Layer (Ethernet, etc.)

Protocol Layer (TCP / IP)

Socket layer

Process

TCP / IP vs. OSI model

Estimation du coût (temps et consommation mémoire) des recopie de paquets dans la pile réseau 1/5

Le but étant de faire une

estimation des recopies

mémoire d'un paquet

réseau de la carte réseau

à la socket BSD

Page 106: Présentation de la pile réseau sous gnu linux

Application

1: sosend (……………... )

Couche des sockets BSD

2: tcp_output ( ……. )

Couche transport (TCP / UDP)

3: ip_output ( ……. )

Couche liaison (Ethernet Device Driver)

Queue de sortie

5: recvfrom(……….)

Queue d'entrée

3: ip_input ( ……... )

4: tcp_input ( ……... )

Couche protocole (IP)

4: ethernet_output ( ……. ) 2: ethernet_input ( …….. )

Carte réseau

Résumé

des

couches

Estimation du coût (temps et consommation mémoire) des recopies de paquets dans la pile réseau 2/5

Page 107: Présentation de la pile réseau sous gnu linux

send (int socket, const char *buf, int length, int flags)Userspace

Kernelspace sendto (int socket, const char *data_buffer, int length, int flags, struct sockaddr *destination, int destination _length)

sendit (struct proc *p, int socket, struct msghdr *mp, int flags, int *return_size)

sosend (struct socket *s, struct mbuf *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags )

uipc_syscalls.c

uipc_socket.c

tcp_userreq (struct socket *s, int request, struct mbuf *m, struct mbuf * nam, struct mbuf * control ) tcp_userreq.c

tcp_output (struct tcpcb *tp) tcp_output.cTCP Layer

Estimation du coût (temps et consommation mémoire) des recopies de paquets dans la pile réseau 3/5

Page 108: Présentation de la pile réseau sous gnu linux

Estimation du coût (temps et consommation mémoire) des recopies de paquets dans la pile réseau 4/5

Réception d'un paquet

Page 109: Présentation de la pile réseau sous gnu linux

Algorigramme de la fonction tcp recvmsg

Estimation du coût (temps et consommation mémoire) des recopies de paquets dans la pileréseau 5/5

Page 110: Présentation de la pile réseau sous gnu linux

Les QDISK

#

# QoS and/or fair queueing

#

CONFIG_NET_SCHED=y

CONFIG_NET_SCH_CBQ=m

CONFIG_NET_SCH_HTB=m

CONFIG_NET_SCH_CSZ=m

CONFIG_NET_SCH_PRIO=m

CONFIG_NET_SCH_RED=m

CONFIG_NET_SCH_SFQ=m

CONFIG_NET_SCH_TEQL=m

CONFIG_NET_SCH_TBF=m

CONFIG_NET_SCH_GRED=m

CONFIG_NET_SCH_DSMARK=m

CONFIG_NET_SCH_INGRESS=m

CONFIG_NET_QOS=y

CONFIG_NET_ESTIMATOR=y

CONFIG_NET_CLS=y

CONFIG_NET_CLS_TCINDEX=m

CONFIG_NET_CLS_ROUTE4=m

CONFIG_NET_CLS_ROUTE=y

CONFIG_NET_CLS_FW=m

CONFIG_NET_CLS_U32=m

CONFIG_NET_CLS_RSVP=m

CONFIG_NET_CLS_RSVP6=m

CONFIG_NET_CLS_POLICE=y

Les dépendances noyau :

Page 111: Présentation de la pile réseau sous gnu linux

Les QDISK - TC

[root@leander]# tc

Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }

where OBJECT := { qdisc | class | filter }

OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] }

http://tldp.org/HOWTO/Traffic-Control-HOWTO/software.html

TC, l’outil de contrôle des classifieur en userspace :

Page 112: Présentation de la pile réseau sous gnu linux

QDISK (pfifo and bfifo)

cat bfifo.tcc

/*

* make a FIFO on eth0 with 10kbyte queue size

*

*/

dev eth0 {

egress {

fifo (limit 10kB );

}

}

[root@leander]# tcc < bfifo.tcc

# ================================ Device eth0

================================

tc qdisc add dev eth0 handle 1:0 root dsmark indices 1 default_index 0

tc qdisc add dev eth0 handle 2:0 parent 1:0 bfifo limit 10240

[root@leander]# cat pfifo.tcc

/*

* make a FIFO on eth0 with 30 packet queue size

*

*/

dev eth0 {

egress {

fifo (limit 30p );

}

}

[root@leander]# tcc < pfifo.tcc

# ================================ Device eth0

================================

tc qdisc add dev eth0 handle 1:0 root dsmark indices 1 default_index 0

tc qdisc add dev eth0 handle 2:0 parent 1:0 pfifo limit 30

Page 113: Présentation de la pile réseau sous gnu linux

QDISK (pfifo_fast)

Page 114: Présentation de la pile réseau sous gnu linux

QDISC (SFQ)

cat sfq.tcc

/*

* make an SFQ on eth0 with a 10 second perturbation

*

*/

dev eth0 {

egress {

sfq( perturb 10s );

}

}

[root@leander]# tcc < sfq.tcc

# ================================ Device eth0

================================

tc qdisc add dev eth0 handle 1:0 root dsmark indices 1 default_index 0

tc qdisc add dev eth0 handle 2:0 parent 1:0 sfq perturb 10

Page 115: Présentation de la pile réseau sous gnu linux

QDISK (ESFQ, Extended Stochastic Fair Queuing)

Usage: ... esfq [ perturb SECS ] [ quantum BYTES ] [ depth FLOWS ]

[ divisor HASHBITS ] [ limit PKTS ] [ hash HASHTYPE]

Where:

HASHTYPE := { classic | src | dst }

Page 116: Présentation de la pile réseau sous gnu linux

QDISK (TBF, Token Bucket Filter)

Page 117: Présentation de la pile réseau sous gnu linux

Latence 1/2

L'étude de la latence des couches de la pile réseau TCP/IP sur l'envoi d'un paquet de 1024 octets

en UDP et en TCP toutes les secondes montre les résultats suivant :

Globalement le temps de recopie pour 1024 octets est de 1 µs, l'appel à la primitive système de la socket BSD est

D'environ 2 µs et le temps de checksum en UDP est aussi de 2 µs.

L'utilisation du DMA pour le transfert des données entre le device et la mémoire est un réel atout d'un point de vue des

Performances.

Le temps d'émission par le driver réseau d'un paquet réseau est en dessous des 2 µs mais il monte à environ 4 µs en

réception du fait de la complexité inhérente du driver dans son mode réception. De plus, ce dernier mode possède une

recopie mémoire non négligeable.

UDP:

Le temps d'émission pour 1024 octets en UDP quand le checksum est requis est de 18.9 µs alors qu'en réception cela

Demande 35 µs. La capacité maximum d'envoie en UDP est donc de 433 Mbits/s alors qu'en réception le taux est de

234 Mbits/s.

TCP:

Avec le protocole TCP, l'envoie d'un paquet de 1024 octets met 22.5 µs et 36 µs en réception. La vitesse maximum en

Émission est de 364Mbits/s alors qu'en réception elle est de 228Mbits/s.

Lorsque le destinataire/expéditaire est local (localhost) la capacité maximale est d'environ 150 Mbit/s.

Le temps global nécessaire dans le noyau GNU Linux pour les recopies mémoires, les checksums et les appels systèmes

sont de 22% pour la partie émission en TCP et 16.7% pour la partie réception avec le même protocole. Idem pour UDP.

Page 118: Présentation de la pile réseau sous gnu linux

Latence 2/2

Résumé du benchmark précédent :

Emission

Réception

Page 119: Présentation de la pile réseau sous gnu linux

Routage 1/5 : routage statique vs dynamique

Routage statique vs routage dynamique Le paramétrage statique d'une interface se fait de différente façon selon les familles de linux. Sous GNU Debian/Ubuntu il y a le fichier /etc/network/interfaces qui contient le paramétrage des interfaces réseau alors que sous Redhat/Fedora/suze c'est le fichier /etc/sysconfig/network-scripts/ifcfg-eth0

Statique (paramétrage manuel) :$ ifconfig eth0 192.168.1.1 netmask 255.255.255.0 broadcast

192.168.1.255 upPar convention l'adresse réseau est celle la plus basse : 192.168.1.0. L'adresse de broadcast celle la plus haute : 192.168.1.255. Pour finir, la gateway est : 192.168.1.1. Au dela de cette convention, les adresses peuvent être choisis séparément.Pour un paquet réseau destiné à être émis sur le réseau, le routage statique consiste à utiliser l'adresse réseau (Ex: 192.168.1.X) pour savoir sur quelle interface envoyer le paquet. Lorsqu'aucune interface ne possède d'adresse en adéquation avec celle des interfaces, la table de routage envoie sur celle désigné pour être associée à la route par défault (plus précisément à la passerelle). Pour spécifier une route manuellement il suffit d'utiliser la commande suivante :

$ route add default gw 192.168.1.1 eth0

Il ne s'agit pas ici de routage interne ou externe utilisé sur les WAN comme RIP ou OSPF mais d'un routage local sur un LAN.

Définition d'une adresse virtuelle ou alias :$ ifconfig eth0:0 192.168.10.12 netmask 255.255.255.0 broadcast

192.168.10.255 $ route add -host 192.168.10.12 dev eth0$ route add -host 192.168.10.14 dev eth0

Page 120: Présentation de la pile réseau sous gnu linux

Routage 2/5

http://www.subnetmask.info/ http://www.subnet-calculator.com/

Déclaration en statique d'une interfaceDebian/Ubuntu (/etc/network/interfaces) : auto loiface lo inet loopbackauto eth0iface eth0 inet staticaddress 208.88.34.106netmask 255.255.255.248broadcast 208.88.34.111network 208.88.34.104gateway 208.88.34.110

RedHad/Fedora/Suse/Mandriva (/etc/sysconfig/network) :DEVICE=eth0BOOTPROTO=staticBROADCAST=XXX.XXX.XXX.255IPADDR=XXX.XXX.XXX.XXX NETMASK=255.255.255.0 NETWORK=XXX.XXX.XXX.0 ONBOOT=yes

Déclaration dynamique (DHCP) d'une interface

Debian/Ubuntu (/etc/network/interfaces) :auto lo

iface lo inet loopback

auto eth0

iface eth0 inet dhcp

RedHad/Fedora/Suse/Mandriva

(/etc/sysconfig/network) :DEVICE=eth0

ONBOOT=yes

BOOTPROTO=dhcp

lo: Loopback interface (network within your system

without slowing down for the real ethernet based

network)

ethx: Ethernet interface card

wlanx : wireless card

Dynamique : c'est un moyen supplémentaire (par rapport au routage statique) pour résoudre un

nom de machine.

Page 121: Présentation de la pile réseau sous gnu linux

Fichier /etc/resolv.conf : fichier de résolution des noms d'hôtes (hostname)Search nom-de_domaine.com : nom du nom de domaine (souvent celui du fournisseur d'accès à

l'Internet).nameserver IPADDRESS : adresse IP du serveur DNS primaire, secondaire

Cela configure la résolution avec le DNS (Domain Name Server) et les adresses IP. Si la configuration cliente utilise le protocole DHCP avec une interface réseau il sera possible de récupérer une configuration réseau complète : $ dhclient eth0

Fichier /etc/hosts : fichier de résolution adresse IP / Nom d'hôteIPADDRESS HOSTNAME : associe une adresse IP à un nom d'hôte.Ex : 127.0.0.1 localhost Ce système est utilisé pour les systèmes n'utilisant ni DNS, ni NIS ou bien lorsqu'il est nécessaire de forcer l'association d'une adresse IP à un nom d'hôte.

Fichier: /etc/nsswitch.conf : fichier de configuration vers le système base de données de noms via le protocole DNS, NIS, NIS+

Le système résoud premièrement les noms d'hôte par le fichier d'association /etc/hosts, ensuite essaye une résolution DNS (/etc/resolv.conf) et enfin recherche le serveur NIS/NIS+. Anciennement, il y avait une recherche dans les fichiers suivants /etc/nsswitch.conf, /etc/svc.conf, /etc/netsvc.conf …. suivant la distribution.

Définition du hostname d'une machine :$ hostname : permet de connaître le nom du host courant.

Pour le modifier : /etc/hostname (sous Debian/Ubuntu)Ou sous toutes les distrib : sysctl -w kernel.hostname="superserver"

Routage 3/5 : résolution de noms

Page 122: Présentation de la pile réseau sous gnu linux

Routage 4/5 : chemin de recherche

Pour bien comprendre la fonction de recherche deroute décrite plus tard, il faut commencer par comprendre comment les routes sont définies dans le noyau

Vérification de l'activation du routage :

sudo sysctl -a | grep forward

Activation du routage :

echo "1" > /proc/sys/net/ipv4/ip_forward

Inhibition du routage :

echo "0" > /proc/sys/net/ipv4/ip_forward

L'activation du routage (prise en compte

dynamique, c'est-à-dire sans avoir à rebooter

permet à la pile réseau de se comporter

comme un "routeur" de paquets IP

Page 123: Présentation de la pile réseau sous gnu linux

Routage 5/5Le rôle de la couche IP est de décider comment orienter les paquets vers leur destination finale. Pour rendre cela possible,chaque interface sur le réseau est associée à un contexte réseau obtenu soit statiquement, soit dynamiquement. Uneadresse IP est constituée de quatre nombres séparés par des points, comme `167.216.245.249'. Chaque nombre étantcompris entre zéro et 255.

Consultation de la table de routage :

$ ip route ls

192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.3

192.168.1.0/24 dev eth2 proto kernel scope link src 192.168.1.4

10.194.61.0/24 dev eth1 proto kernel scope link src 10.194.61.86

default via 10.194.61.1 dev eth1

default via 192.168.1.1 dev eth2

default via 192.168.1.1 dev eth0

http://mirabellug.org/wikini/upload/Documentations_routage.pdf

$ /sbin/route –n

Table de routage IP du noyau

Destination Passerelle Genmask Indic Metric Ref Use Iface

192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth2

10.194.61.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1

0.0.0.0 10.194.61.1 0.0.0.0 UG 0 0 0 eth1

0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth2

0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0

Page 124: Présentation de la pile réseau sous gnu linux

Administration réseau

ifconfig : permet de configurer les interfaces réseau résidentes dans le noyau

Ex: sudo ifconfig eth0:1 192.168.5.96 netmask 255.255.255.0 /sbin/ifconfig eth0 down

ifconfig eth0 inet6 add 2001:6ff:10:1::1000/64

route : permet la gestion de la table de routage

Ex : route add default gw 192.168.0.1 netmask 0.0.0.0 route -A inet6 add default gw 2001:6ff:10:1::ffff

ip (ou iproute2) : permet un gestion précise du réseau

Ex : ip addr add 192.168.0.2/24 dev eth0 brodcast 192.168.0.255 ip addr lsip link set dev eth0 up ip -6 addr add 2001:6ff:10:1::1000/64 dev eth0 ip -6 route add default via 2001:6ff:10:1::ffff

iwconfig : permet la gestion des interfaces sans fil.

ipsysctl : permet la gestion du procfs /proc/sys/net

TCP tuning guide : http://www-didc.lbl.gov/TCP-tuning/TCP-tuning.html

Page 125: Présentation de la pile réseau sous gnu linux

Administration réseau

nameif : assigne un nom à une interface réseaunetstat : donne des statistiques sur la pile réseaulsof : donne les ressources enregistrés par le noyau (inclus les

sockets BSD)arp : permet de connaître son voisinage dans le LAN ;ping : permet l’envoie de requêtes ICMP ping/pong ;traceroute : outil permettant de connaître le routage emprunter

jusqu’à un serveur ;

Page 126: Présentation de la pile réseau sous gnu linux

/PROC

$ ls /proc/sys/net/ipv4

conf/ ip_autoconfig tcp_abc tcp_low_latency

Etc …

$ ls /proc/sys/net/ipv4/route

error_burst gc_elasticity gc_min_interval_ms x_delay min_delay

redirect_load

Etc …

http://linuxgazette.net/issue77/lechnyr.html

$ echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects

Listing des paramètres disponible dans le RAMFS du KERNEL :

Affichage et modifications des paramètres :

$ cat /proc/sys/net/ipv4/ip_forward

1

PROCFS est un RAMFS géré par le

noyau. C'est un lien entre le monde user

et le monde kernel.

http://mirrors.deepspace6.net/Linux+IPv6-HOWTO-fr/proc-net.html

Page 127: Présentation de la pile réseau sous gnu linux

Le protocole IPv4 permet d'utiliser un peu plus de quatre milliards d'adresses différentes pour connecter les ordinateurs et les autres appareils reliés au réseau. Du temps des débuts d'Internet, quand les ordinateurs étaient rares, cela paraissait plus que suffisant. Il était pratiquement inimaginable qu'il y aurait un jour suffisamment de machines sur un unique réseau pour que l'on commence à manquer d'adresses disponibles.Une grande partie des quatre milliards d'adresses IP théoriquement disponibles ne sont pas utilisables, soit parce qu'elles sont destinées à des usages particuliers (par exemple, le multicast), soit parce qu'elles appartiennent déjà à des sous-réseaux importants. En effet, d'immenses plages de 16,8 millions d'adresses, les réseaux dits de classe A, ont été attribuées aux premières grandes organisations connectées à Internet, qui les ont conservées jusqu'à aujourd'hui sans parvenir à les épuiser. Les Nord-Américains, et dans une moindre mesure les Européens, se sont partagé les plus grandes plages d'adresses, relativement peu nombreuses, tandis que les régions connectées plus tardivement, comme l'Amérique du Sud et surtout l'Asie, sont restées sur la touche.En conséquence, il y a aujourd'hui, principalement en Asie, une pénurie d'adresses que l'on doit compenser par des mécanismes comme la Traduction d'adresse et de port réseau (NAPT) et l'attribution dynamique d'adresses, et en assouplissant le découpage en classes des adresses (CIDR).Au vu de l'importance et de la croissance d'Internet, cette situation pose de plus en plus de problèmes. Il est de plus prévisible que la demande d'adresses Internet va augmenter dans les années à venir, même dans les régions du monde épargnées jusqu'ici, suite à des innovations comme les téléphones mobiles (et bientôt, sans doute, les automobiles et divers appareils) connectés à Internet.C'est principalement en raison de cette pénurie, mais également pour résoudre quelques-uns des problèmes révélés par l'utilisation à vaste échelle d'IPv4, qu'a commencé en 1995 la transition vers IPv6. Parmi les nouveautés essentielles, on peut citer :

–l'augmentation de 232 (soit environ 10^10) à 2128 (soit environ 10^38) du nombre d'adresses disponibles ; –des mécanismes de configuration et de renumérotation automatique ; –IPsec, QoS et le multicast implémentés nativement ; –la simplification des en-têtes de paquets, qui facilite notamment le routage.

IPv6 1/3 : rappels

Page 128: Présentation de la pile réseau sous gnu linux

Une adresse IPv6 est longue de 16 octets, soit 128 bits, contre 4 octets (32 bits) pour IPv4. On dispose ainsi d'environ 3,4 × 1038 adresses, soit 340 282 366 920 938 463 463 374 607 431 768 211 456, soit encore, pour reprendre l'image usuelle, plus de 667 132 000 milliards (6,67 x 10^17) d'adresses par millimètre carré de surface terrestre.

On abandonne la notation décimale pointée employée pour les adresses IPv4 (par exemple 172.31.128.1) au profit d'une écriture hexadécimale, où les 8 groupes de 16 bits sont séparés par un signe deux-points :1fff:0000:0a88:85a3:0000:0000:ac1f:8001

La notation canonique complète ci-dessus comprend exactement 39 caractères.Les 64 premiers bits de l'adresse IPv6 (préfixe) servent généralement à l'adresse de sous-réseau, tandis que les 64 bits suivants identifient l'hôte à l'intérieur du sous-réseau : ce découpage joue un rôle un peu similaire aux masques de sous-réseau d'IPv4.

Différentes sortes d'adresses IPv6 jouent des rôles particuliers. Ces propriétés sont indiquées par le début de l'adresse, appelé préfixe.

L'Internet IPv6 est défini comme étant le sous-réseau 2000::/3 (les adresses commençant par un 2 ou un 3). Seules ces adresses peuvent être routées. Toutes les autres adresses ne peuvent être utilisées que localement sur un même réseau physique (de niveau 2), ou par un accord privé de routage mutuel. Parmi les adresses de 2000::/3, on distingue :

–Les adresses 6to4 (2002::/16) permettant d'acheminer le trafic IPv6 via un ou plusieurs réseaux IPv4. –Les adresses du 6bone (3ffe::/16) pour l'expérimentation des interconnexions de réseaux IPv6. (Le 6bone n'est plus opérationnel depuis le 6/6/2006)

IPv6 2/3 : rappels

Page 129: Présentation de la pile réseau sous gnu linux

IPv6 : 3/3

Test du support d'IPv6 : test -f /proc/net/if_inet6 && echo "Support IPv6 available."

Test si IPv6 est activé : lsmod |grep -w 'ipv6' && echo "IPv6 enabled"

Résumé : http://www.bieringer.de/linux/IPv6/status/IPv6+Linux-status-distributions.htmlGuide : http://deepspace6.net/sections/docs.htmlIPv6 théorie et pratique : http://livre.point6.net/index.php/Accueil

La souche IPv6 a été intégrée officiellement au noyau depuis les versions 2.2, mais

ces noyaux étaient incomplets et non conformes aux RFC. Les noyaux 2.4 sont plus

corrects, mais eux aussi présentent quelques lacunes. Les noyaux 2.6 sont donc

préférables ; ils intègrent un partie des développements du projet japonais USAGI, en

particulier la sécurité (IPsec). Il faut aussi un noyau compilé avec l'option IPv6 (dans le

noyau ou en module). Ce type de noyau est en général disponible dans toutes les

distributions (au moins comme paquetage optionnel).

Les applications, quand à elles, doivent utiliser une librairie C supportant IPv6. La GNU

Libc 2 intègre correctement le support IPv6 à partir de la version 2.2 de la Glibc. Aussi,

il est important d'utiliser une distribution Linux qui réponde à ces critères.

Aujourd'hui la pile réseau est complètement opérationnelle avec IPv6.

Page 130: Présentation de la pile réseau sous gnu linux

5. Filtrage & QOS

–Architecture de netfilter–Implémentation d’un hook (drivers)–Utilisation d’iptable /ip6table–Utilisation d’un bridge (ebtable)–Utilisation de tc d’iproute2

Page 131: Présentation de la pile réseau sous gnu linux

L'équipe de Netfilter et son leader actuel

Patrick McHardy :

Team Leader du projet

Netfilter .

The core Team du projet Netfilter.

Page 132: Présentation de la pile réseau sous gnu linux

Netfilter 1/2

L'intégration de netfilter, le firewall de Linux, se fait au travers de hook [1], de la façon suivante.

Les différents passages de fonctions s'effectuent via l'appel de NF_HOOK, une constante préprocesseur,avec les paramètres suivants :

protocole du HOOK, exemple : PF_INET pour IPv4 ;

chaîne, exemple : NF_IP_PRE_ROUTING, NF_IP_LOCAL_IN, etc ;

pointeur vers une structure struct sk_buff, qui contient en fait des données relative au paquet ;

interface d'entrée ;

interface de sortie (peut être NULL) ;

la fonction à appeler si le paquet n'est pas supprimé.

Ainsi, si CONFIG_NETFILTER, n'est pas définie, la constante NF_HOOK est définie à :

#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)

se résumant à un simple appel de la fonction okfn, avec le paramètre skb.

[1] on peut traduire hook par crochet ou accroche, ou bien encore intercepteur

http://www.netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-3.html

Page 133: Présentation de la pile réseau sous gnu linux

Netfilter

Page 134: Présentation de la pile réseau sous gnu linux

Netfilter 2/2

Un hook peut se définir comme un

point d’accès dans une chaîne de

traitement (par exemple : saisie au

clavier, parcours de la pile TCP/IP…).

Netfilter est un ensemble de hooks

à l’intérieur du noyau Linux permettant

aux modules noyau d’enregistrer des

fonctions de callback dans la pile IP.

Les trames ainsi capturées peuvent

être analysées, jetées ou modifiées.

Le firewall « natif » de linux iptables

n’est qu’un module « sur-couche » de

netfilter permettant de définir un

système de règles de filtrage et

masquerading (translation d’adresse)

de trames IP à partir des hooks.

Page 135: Présentation de la pile réseau sous gnu linux

Netfilter, étude de cas

Ecriture d'un driver gérant un hook netfilter :

// Fonction standard de chargement d'un driver sous GNU linux :

int init_module()

{

nfho_tunnel_in.hook = hook_func_tunnel_in;

nfho_tunnel_in.hooknum = NF_IP_PRE_ROUTING;

nfho_tunnel_in.pf = PF_INET;

nfho_tunnel_in.priority = NF_IP_PRI_FIRST;

nf_register_hook(&nfho_tunnel_in);

printk("\n\tNF_HOOK: Module instale\n\n");

return 0;

}

// Fonction standard de déchargement d'un driver

// sous GNU Linux :

void cleanup_module()

{

printk("\n\t NF_HOOK: I'll be back ....\n\n");

nf_unregister_hook(&nfho_tunnel_in);

}

Page 136: Présentation de la pile réseau sous gnu linux

Netfilter, etude de cas

#define __KERNEL__

#define MODULE

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/netfilter.h>

#include <linux/netfilter_ipv4.h>

static struct nf_hook_ops netfilter_ops_in; /* NF_IP_PRE_ROUTING */

static struct nf_hook_ops netfilter_ops_out; / * NF_IP_POST_ROUTING */

/* Function prototype in <linux/netfilter> */

unsigned int main_hook(unsigned int hooknum,

struct sk_buff **skb,

const struct net_device *in,

const struct net_device *out,

int (*okfn)(struct sk_buff*))

{

return NF_DROP; /* Drop ALL Packets */

}

Page 137: Présentation de la pile réseau sous gnu linux

Netfilter, etude de cas

int init_module()

{

// Premier hook

netfilter_ops_in.hook = main_hook;

netfilter_ops_in.pf = PF_INET;

netfilter_ops_in.hooknum = NF_IP_PRE_ROUTING;

netfilter_ops_in.priority = NF_IP_PRI_FIRST;

// Second hook

netfilter_ops_out.hook = main_hook;

netfilter_ops_out.pf = PF_INET;

netfilter_ops_out.hooknum = NF_IP_POST_ROUTING;

netfilter_ops_out.priority = NF_IP_PRI_FIRST;

nf_register_hook(&netfilter_ops_in); /* register NF_IP_PRE_ROUTING hook */

nf_register_hook(&netfilter_ops_out); /* register NF_IP_POST_ROUTING hook */

return 0;

}

void cleanup()

{

nf_unregister_hook(&netfilter_ops_in); /* unregister NF_IP_PRE_ROUTING hook */

nf_unregister_hook(&netfilter_ops_out); /* unregister NF_IP_POST_ROUTING hook */

}

Page 138: Présentation de la pile réseau sous gnu linux

Netfilter, etude de cas#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/netfilter.h>

#include <linux/netfilter_ipv4.h>

#include <linux/skbuff.h>

#include <linux/udp.h>

#include <linux/ip.h>

static struct nf_hook_ops nfho; //net filter hook option struct

struct sk_buff *sock_buff;

struct udphdr *udp_header; //udp header struct (not used)

struct iphdr *ip_header; //ip header struct

unsigned int hook_func(unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int

(*okfn)(struct sk_buff *))

{

sock_buff = *skb;

ip_header = (struct iphdr *)skb_network_header(sock_buff); //grab network header using accessor

if(!sock_buff) { return NF_ACCEPT;}

// Vérifie s’il s’agit d’un paquet UDP :

if (ip_header->protocol==17)

{

udp_header = (struct udphdr *)skb_transport_header(sock_buff); //grab transport header

printk(KERN_INFO "got udp packet \n"); //log we’ve got udp packet to /var/log/messages

return NF_DROP;

}

return NF_ACCEPT;

}

Page 139: Présentation de la pile réseau sous gnu linux

Netfilter, etude de cas

int init_module()

{

nfho.hook = hook_func;

nfho.hooknum = NF_IP_PRE_ROUTING;

nfho.pf = PF_INET;

nfho.priority = NF_IP_PRI_FIRST;

nf_register_hook(&nfho);

return 0;

}

void cleanup_module()

{

nf_unregister_hook(&nfho);

}

Page 140: Présentation de la pile réseau sous gnu linux

unsigned int hook_func_tunnel_in (unsigned int hooknum, struct sk_buff **skb,const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) {

struct sk_buff* sb= *skb;struct iphdr* ip;struct net_device *dev= NULL;struct Qdisc *q;int len;len = sb->len;ip = sb->nh.iph;

if((strcmp("eth0", in->name)==0) && (ip->daddr == ip1) ){

affic_skb(sb,0);sb->data -= 14;sb->len = len+ 14;memcpy(sb->data, hd_mac2, 14);dev = dev_get_by_name("eth1");spin_lock_bh (&(dev->queue_lock));q = dev->qdisc;q->enqueue(sb,q);qdisc_run(dev);spin_unlock_bh(&(dev->queue_lock));affic_skb(sb,1);

return( NF_STOLEN );}

Netfilter, étude de cas

(SUITE)

if((strcmp("eth1", in->name)==0) &&(ip->daddr

== ip0))

{

affic_skb(sb,0);

sb->data -= 14;

sb->len = len+14 ;

memcpy(sb->data,hd_mac1,

14);

dev =

dev_get_by_name("eth0");

spin_lock_bh (&(dev-

>queue_lock));

q = dev->qdisc;

q->enqueue(sb,q);

qdisc_run(dev);

spin_unlock_bh(&(dev-

>queue_lock));

return NF_STOLEN;

}

return( NF_ACCEPT );

}

Exemple d'implémentation de la fonction de hook utilisée dans le driver réseau.

http://www.linuxjournal.com/article/7184

Page 141: Présentation de la pile réseau sous gnu linux

Projet Open STB / Orange Labs - R&D – Présentation pile réseau sous GNU Linux

Spécificité du protocole ARP

A l ‘émission, seuls les paquets de type ETH_P_ALL

peuvent être capturés.

Il est important de noter que, comme pour le chemin

suivi par les trames dans le noyau, les fonctions

utilisées dans le packet handling peuvent changer

selon la version du noyau utilisé.

Pour récupérer les trames ARP, il suffit d’enregistrer

une structure packet_type dans une des listes

ptype (ptype_base ou ptype_all) avec la fonction de

callback dev_add_pack() (définie dans

linux/netdevice.h).

Comme pour les netfilter hooks, il faut supprimer ce

hook (packet handling) lorsque le module est retiré

du noyau. Ceci se fait grâce à la fonction

dev_remove_pack() (linux/netdevice.h).

En enregistrant une fonction pour ETH_P_ALL notre

packet type se retrouvera dans la liste ptype_all.

On va ainsi récupérer toutes les trames arrivant

(ou à destination) du driver de la carte réseau.

Lorsque l’on récupère un sk_buffer avec ce type de hook, c’est en fait une copie du sk_buffer capturé sur

laquelle on va travailler. La copie doit être détruite en fin de fonction avec la fonction kfree_skb().

Position des hooks de type « packet handling » dans la chaîne

de traitement des trames reçues ou à émettre.

Page 142: Présentation de la pile réseau sous gnu linux

Netfilter

Permet de filtrer et de manipuler les paquets réseau qui passent dans le système

Fonctions de pare-feu :–Contrôle des machines qui peuvent se connecter–Sur quels ports–Depuis l’extérieur vers l’intérieur, ou vice-versa

Fonctions de traduction d’adresses :–Partage d’une connexion Internet (masquerading)–Masquer des machines du réseau local–Rediriger des connexions

Fonctions d’historisation du trafic réseauCommande qui permet de configurer Netfilter : iptables

142

Page 143: Présentation de la pile réseau sous gnu linux

Netfilter

Intercepte les paquets réseau à différents endroits du système

–Réception–Avant de les transmettre aux processus–Avant des les envoyer à la carte réseau–Etc.

Les paquets interceptés passent à travers des tables qui contiennent des chaînes qui vont déterminer ce que le système doit faire avec le paquet

En modifiant ces chaines on va pouvoir bloquer certains paquets et en laisser passer d'autres

143

Page 144: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

Une chaîne est un ensemble de règles qui indiquent ce qu'il faut faire des paquets qui la traversent

Lorsqu'un paquet arrive dans une chaîne–Netfilter regarde la 1ère règle de la chaîne–Regarde si les critères de la règle correspondent au paquet–Si le paquet correspond, la cible est exécutée (jeter le paquet, le laisser passer, etc.)–Sinon, Netfilter prend la règle suivante–Ainsi de suite jusqu'à la dernière règle

Si aucune règle n'a interrompu le parcours de la chaîne, la politique par défaut est appliquée

144

Page 145: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

145

Page 146: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

Il est possible d'avoir de multiples tablesChaque table peut contenir de multiples chainesChaque chaine peut contenir de multiples règles Table Chaine Règle

146

Page 147: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

La table FILTER est la table par défautCette table a trois chaines par défaut :

–INPUT

•Filtre les paquets à destination du système

–OUTPUT

•Filtre les paquets émis par les processus du système

–FORWARD

•Filtre les paquets que le système doit transmettre

147

Page 148: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

La table NAT a par défaut les chaines :

–PREROUTING

•Modifie les paquets avant routage

–POSTROUTING

•Modifie les paquets après routage

–OUTPUT

•Pour les paquets localement générés

148

Page 149: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

La table MANGLE permet d'altérer les paquets (ex. TOS)

–PREROUTING

–OUTPUT

–FORWARD

–INPUT

–POSTROUTING

La table RAW sert pour les exemptions (pas de filtrage)

–PREROUTING

–OUTPUT

149

Page 150: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

manglePREROUTING

réseau

natPREROUTING

routagemangleINPUTfilter

INPUT

processus

routage

mangleOUTPUT

natOUTPUT

filterOUTPUT

routage

manglePOSTROUTING

natPOSTROUTING

réseau

mangleFORWARD

filterFORWARD

Page 151: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

151

Arrivée d'un paquet dans la machine :Table Chaîne

1 Arrivée du paquet sur l'interface réseau

2 raw PREROUTING Permet de modifier le paquet

3 mangle PREROUTING Permet de modifier le paquet

4 nat PREROUTING Permet de faire du DNAT

5 Décision de routage

6 mangle INPUT Permet de modifier le paquet avant envoi à processus

7 filter INPUT Filtrage du paquet à destination de la machine locale

8 Un processus reçoit le paquet

Page 152: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

152

Envoi d'un paquet depuis la machine :Table Chaîne

1 Processus envoie le paquet

2 Décision de routage

3 raw OUTPUT Permet le traçage/marquage des connexions

4 Traçage des connexions, changements d'état

5 mangle OUTPUT Permet de modifier le paquet

6 nat OUTPUT Permet de faire du NAT

7 Décision de routage

8 filter OUTPUT Filtrage du paquet à destination du réseau

9 mangle POSTROUTING Permet de modifier le paquet

10 nat POSTROUTING Permet de faire du SNAT

Page 153: Présentation de la pile réseau sous gnu linux

Netfilter – Tables et chaînes

153

Paquet redirigé :Table Chaîne

1 Processus envoie le paquet

2 raw PREROUTING Permet de modifier le paquet

3 mangle PREROUTING Permet de modifier le paquet

4 nat PREROUTING Permet de faire du DNAT

5 Décision de routage

6 mangle FORWARD Permet de modifier le paquet avant routage final

7 filter FORWARD Filtrage du paquet redirigé

8 mangle POSTROUTING Permet de modifier le paquet

9 nat POSTROUTING Permet de faire du SNAT

Page 154: Présentation de la pile réseau sous gnu linux

Netfilter – Règles

Une règle est une combinaison de critères et une cible

Lorsque tous les critères correspondent au paquet, le paquet est envoyé vers la cible.

Les critères disponibles et les actions possibles dépendent de la chaîne manipulée

Il est possible de spécifier un saut vers une chaîne différente de la même table

–Chaîne spécifique utilisateur

154

Page 155: Présentation de la pile réseau sous gnu linux

Netfilter – Cibles

Cibles de la table mangle :–TOS

•Permet de définir ou modifier le champ Type Of Service–TTL

•Permet de modifier le champ Time To Live–MARK

•Permet d'associer une valeur de marquage au paquet–Permet d'appliquer un routage différent–Gestion de bande passante / priorité

–SECMARK et CONNSECMARK•Marquage dans une contexte de sécurité (ex. SELinux)

155

Page 156: Présentation de la pile réseau sous gnu linux

Netfilter – Cibles

Cibles de la table nat :–DNAT

•Change l'adresse de destination–SNAT

•Change l'adresse source–MASQUERADE

•Comme SNAT mais avec adresse IP dynamique–REDIRECT

•Redirige les paquets vers la machine (ex. proxy transparent)

156

Page 157: Présentation de la pile réseau sous gnu linux

Netfilter – Cibles

Cibles de la table raw :–NOTRACK

•Pas de traçage

157

Page 158: Présentation de la pile réseau sous gnu linux

Netfilter – Cibles

Cibles de la table filter :–ACCEPT

•Laisse passer le paquet–DROP

•Jette le paquet, n'en prévient pas l'émetteur–DROP

•Jette le paquet, en prévient pas l'émetteur–QUEUE

•Passe le paquet vers l'espace utilisateur–RETURN

•N'exécute pas les prochaines règles de la chaine

158

Page 159: Présentation de la pile réseau sous gnu linux

Netfilter – conntrack

Netfilter est un pare-feu à états–Traçage des connexions–Réalisé avec une structure appelée conntrack–Prend en charge les protocoles TCP, UDP et ICMP–Défragmentation intégrée des paquets

Les paquets générés localement sont tracés dans la chaîne OUTPUT

Le traçage de connexion est pris en charge dans la chaîne PREROUTING

La liste des connexions tracées est lisible dans /proc/net/ip_conntrack

159

Page 160: Présentation de la pile réseau sous gnu linux

Netfilter – conntrack

Etats pour les flux de paquets :–NEW

•Premier paquet de la connexion–ESTABLISHED

•Résulte de l'observation de trafic dans les deux sens–RELATED

•Connexion liée a une connexion ESTABLISHED•Nécessite d'analyser les contenus des paquets (ALGs)

–INVALID

•Paquet non identifié ou sans état–UNTRACKED

•Paquet marqué dans la table raw avec la cible NOTRACK

160

Page 161: Présentation de la pile réseau sous gnu linux

Netfilter – conntrack

Etats internes pour tracer les connexions TCP :–NONE

–ESTABLISHED 5 jours–SYN_SENT2 minutes–SYN_RECV60 secondes–FIN_WAIT2 minutes–TIME_WAIT 2 minutes–CLOSE 10 secondes–CLOSE_WAIT 12 heures–LAST_ACK30 secondes–LISTEN 2 minutes

Délais ajustables : /proc/sys/net/ipv4/netfilter/ip_ct_tcp_*

161

Page 162: Présentation de la pile réseau sous gnu linux

Netfilter – conntrack

Connexion TCP

162

Client

SYN

Pare-feu

SYN_SENT

Serveur

SYN/ACK

SYN_RECV

ACK

ESTABLISHED

Page 163: Présentation de la pile réseau sous gnu linux

Netfilter – conntrack

Client

FIN/ACK

Pare-feu

FIN_WAIT

Serveur

ACK

CLOSE_WAIT

(closed)

FIN/ACK

FIN_WAIT

ACK

CLOSED

(closed)

Page 164: Présentation de la pile réseau sous gnu linux

Netfilter – Configuration noyau

164

Il existe un large éventail d'options, configurables dans le noyau

Ces options peuvent être compilées statiquement ou en tant que modules

Page 165: Présentation de la pile réseau sous gnu linux

Netfilter – Configuration noyau

165

Page 166: Présentation de la pile réseau sous gnu linux

Netfilter – Configuration noyau

166

Page 167: Présentation de la pile réseau sous gnu linux

Netfilter – Configuration noyau

167

Page 168: Présentation de la pile réseau sous gnu linux

Netfilter – Configuration noyau

168

Page 169: Présentation de la pile réseau sous gnu linux

Netfilter – Configuration noyau

169

Page 170: Présentation de la pile réseau sous gnu linux

Netfilter – Configuration noyau

170

Page 171: Présentation de la pile réseau sous gnu linux

iptables

La forme générale de la commande est :iptables [-t <table>] <commande> <options>

Chaque paramètre peut souvent être spécifié sous une forme longue (ex. --append) ou une forme courte (ex. -A)

Les paramètres indiqués entre crochets sont facultatifs (ex. [-t <table>])

Ce qui se trouve entre inférieur et supérieur doit être remplacé par une valeur (ex. <table>)

171

Page 172: Présentation de la pile réseau sous gnu linux

iptables – Commandes principales

--list|-L [<chaîne>]

–Affiche les règles contenues dans les ou la chaîne–Si -v est placé avant, le nombre de paquets ayant traversé chaque règle sera affiché–Ajouter -n pour éviter la résolution de noms

--append|-A <chaîne> <critères> -j <cible>

–Ajoute une règle à la fin de la chaîne–Si tous les critères correspondent au paquet, il est envoyé à la cible

--insert|-I <chaîne> <critères> -j <cible>

–Comme --append mais ajoute la règle au début de la chaîne

172

Page 173: Présentation de la pile réseau sous gnu linux

iptables – Commandes principales

--delete|-D <chaîne> <critères> -j <cible>

–Supprime la règle correspondante de la chaîne

--flush|-F [<chaîne>]

–Efface toutes les règles de la chaîne–Si aucune chaîne n'est indiquée, toutes les chaînes de la table seront vidées

--policy|-P <chaîne> <cible>

–Détermine la cible lorsque qu'aucune règle n'a interrompu le parcours et que le paquet arrive en fin de chaîne–Cibles autorisées : DROP et ACCEPT

173

Page 174: Présentation de la pile réseau sous gnu linux

iptables – Commandes principales

--protocol|-p [!] <protocole>

–Protocoles possibles : tcp, udp, icmp, all ou une valeur numérique (/etc/protocol)–Si un ! se trouve avant le protocole, un paquet

correspondra seulement s'il n'est pas du protocole spécifié--source|-s [!] <adresse>[/<masque>]

--destination|-d [!] <adresse>[/<masque>]

–Si un masque est précisé, seules les parties actives du masque sont comparées–Le masque par défaut est /32–Un ! ne fera correspondre le paquet que s'il n'a pas cette adresse source

174

Page 175: Présentation de la pile réseau sous gnu linux

iptables – Commandes principales

-dport [!] <port>

-sport [!] <port>

– Il est obligatoire de préciser le protocole (-p tcp ou -p udp)

-i <interface>

–L'interface réseau d'où provient le paquet–N'est utilisable que dans la chaîne INPUT

-o <interface>

–L'interface réseau de laquelle va partir le paquet–N'est utilisable que dans les chaînes OUTPUT et FORWARD

175

Page 176: Présentation de la pile réseau sous gnu linux

iptables – Cibles

-j ACCEPT

–Autorise le paquet à passer et interrompt son parcours de la chaîne

-j DROP

–Jette le paquet sans prévenir l'émetteur, le parcours de la chaîne est interrompu

-j REJECT

–Comme DROP mais prévient l'émetteur que le paquet est rejeté

176

Page 177: Présentation de la pile réseau sous gnu linux

iptables – Cibles

LOG

–Enregistre dans le journal du noyau–La règle suivante sera évaluée–Options :

--log-level <niveau>

--log-prefix <préfixe>

--log-tcp-sequence

--log-tcp-options

--log-ip-options

--log-uid

177

Page 178: Présentation de la pile réseau sous gnu linux

iptables – Cibles

DNAT --to-destination [ip[-ip]][:port[-port]]

SNAT --to-source [ip[-ip]][:port[-port]]

–Spécifie une nouvelle adresse IP source ou destination, ou un ensemble d'adresses–En option : un ensemble de ports (si -p tcp ou -p udp)

MASQUERADE

–Utilisée si l'adresse IP est dynamique (DHCP)–Options :

--to-ports <port[-port]>

–si -p tcp ou -p udp), surcharge le mécanisme automatique SNAT

--random

178

Page 179: Présentation de la pile réseau sous gnu linux

iptables – Cibles

-j REDIRECT --to-ports <port[-port]>

–Redirige un paquet vers un ou des ports spécifiques de la machine–Exemple :

# iptables -t nat -A PREROUTING -p tcp

--dport 80 -j REDIRECT --to-ports 8080

179

Page 180: Présentation de la pile réseau sous gnu linux

iptables – Cibles

AUDIT [--type <accept|drop|reject>]

–Utilisée pour compter les paquets acceptés, jetés ou rejetés–Voir man 8 auditd–Exemple :

# iptables -A INPUT -j AUDIT --type drop

# iptables –A INPUT –j DROP

CLASSIFY --set-class <major:minor>

–Permet de mettre le paquet dans une classe CBQ–Voir man 8 tc

180

Page 181: Présentation de la pile réseau sous gnu linux

iptables – Chaînes

--new-chain|-N <chaîne>

–Créé une nouvelle chaîne dans la table spécifiée

--delete-chain|-X <chaîne>

–Efface une chaîne dans la table spécifiée

--rename-chain|-E <chaîne>

–Renomme une chaîne dans la table spécifiée

181

Page 182: Présentation de la pile réseau sous gnu linux

iptables – TCP

-p tcp [!] --tcp-flags <mask> <comp>

–Match lorsque les flags TCP sont spécifiés dans le paquet

•<mask> est la liste des flags à examiner•<comp> est la liste des flags qui doivent être spécifiés

–Les flags sont :•SYN, ACK, FIN, RST, URG, PSH, ALL, NONE

Exemple :-p tcp --tcp-flags SYN,ACK,FIN,RST SYN

–Match les paquets avec SYN mais sans les ACK, FINet RST

182

Page 183: Présentation de la pile réseau sous gnu linux

iptables – TCP

-p tcp [!] --syn

–Equivalent à --tcp-flags SYN,RST,ACK,FIN SYN

-p tcp [!] --tcp-option <number>

–Match si les options sont spécifiées dans le paquet–Liste des options :

•www.iana.org/assignments/tcp-parameters/tcp-parameters.xml

-p tcp [!] –mss <value>[:value]

–Maximum segment size–Utilisable seulement sur les paquets SYN ou SYN/ACK

183

Page 184: Présentation de la pile réseau sous gnu linux

iptables – ICMP

-p icmp [!] --icmp-type <type[/code]|typename>

–Permet de spécifier les type ICMP, par valeur numérique ou par nom–Liste des noms :

# iptables -p icmp –help

Exemple pour ping :-A INPUT -p icmp --icmp-type 0 -j ACCEPT

-A INPUT -p icmp --icmp-type 8 -j ACCEPT

-A OUTPUT -p icmp --icmp-type 0 -j ACCEPT

184

Page 185: Présentation de la pile réseau sous gnu linux

iptables – Correspondances

Une correspondance spécifique doit être chargée par l'option -m ou –match

-m |--match addrtype [!]

<--src-type|--dst-type>

<type>

–Type d'adresse des paquets :•LOCAL , UNICAST, BROADCAST, ANYCAST, MULTICAST, UNREACHABLE

-m |--match iprange [!]

<--src-range|--dst-range> <from>[-

to]

–Plage d'adresses IP

185

Page 186: Présentation de la pile réseau sous gnu linux

iptables – Correspondances

-m|--match limit ...

–Limite un taux :--limit <rate>[/second|/minute|/hour|/day]

--limit-burst number

-m|--match mac [!] --mac-source <adresse>

–Match les paquets avec adresse MAC spécifiée

-m|--match multiport [!] ...

–Permet de spécifier plusieurs port pour une même règle :

[!] --sports <port>[,port|,port:port] ...

[!] --dports <port>[,port|,port:port] ...

186

Page 187: Présentation de la pile réseau sous gnu linux

iptables – Correspondances

-m|--match owner ...

–Permet de sélectionner des paquets à partir de l'identité du processus qui les a crées :

[!] --uid-owner <username>|<uid[-uid]>

[!] --gid-owner <groupname>|<gid[-gid]>

[!] --socket-exists

-m |--match pkttype [!] --pkt-type

<unicast|broadcast|multicast>

–Match le type de paquet

187

Page 188: Présentation de la pile réseau sous gnu linux

iptables – Correspondances

-m |--match state [!] --state <state>[,state]...

–Correspondance au traçage des paquets dans netfilter (conntrack)–Indique dans quel état doit être la connexion pour que les paquets correspondent–Etats possibles :

•INVALID, NEW, ESTABLISHED, RELATED, UNTRACKED

Il existe beaucoup d'autres correspondances, moins usuelles

–Voir man 8 iptables

188

Page 189: Présentation de la pile réseau sous gnu linux

iptables – /proc

Paramètres du noyau affectant Netfilter :

/proc/sys/net/ipv4/ip_dynaddr

•Support d'adresses dynamiques

/proc/sys/net/ipv4/ip_forward

•Autorisation des redirections/forwarding

/proc/sys/net/ipv4/conf/default/rp_filter

/proc/sys/net/ipv4/conf/all/rp_filter

•Valide qu'un paquet arrive par la bonne interface

/proc/sys/net/ipv4/tcp_syncookies

•Active la protection contre les tempêtes SYN

189

Page 190: Présentation de la pile réseau sous gnu linux

iptables – /proc

/proc/sys/net/ipv4/

icmp_ignore_bogus_error_responses

•Ignore les message ICMP falsifiés

/proc/sys/net/ipv4/conf/all/accept_redirects

/proc/sys/net/ipv4/conf/all/send_redirects

•Mettre à 0 pour désactiver les ICMP-Redirect

/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

•Ignore les pings broadcastés

/proc/sys/net/ipv4/conf/all/log_martians

•Log les paquets venant d'adresses impossibles

190

Page 191: Présentation de la pile réseau sous gnu linux

iptables – Exemple

# Tout réinitialiseriptables –Fiptables –X

# Politiques par défautiptables -P INPUT DROPiptables -P FORWARD DROPiptables -P OUTPUT DROP

# Tout accepter sur l'interface loopbackiptables -A INPUT ! -i lo -s 127.0.0.1/8 -j DROPiptables -A INPUT ! -i lo -d 127.0.0.1/8 -j DROPiptables -A INPUT -i lo -j ACCEPTiptables -A OUTPUT ! -o lo -s 127.0.0.1/8 -j DROPiptables -A OUTPUT ! -o lo -d 127.0.0.1/8 -j DROPiptables -A OUTPUT –o lo -j ACCEPT

191

Page 192: Présentation de la pile réseau sous gnu linux

iptables – Exemple

# Chaîne pour jeter des paquets et en notifier le journaliptables -N LOGNDROP

iptables -A LOGNDROP -p tcp -m limit --limit 1/s-j LOG --log-prefix "[TCP drop] " --log-level=info

iptables -A LOGNDROP -p udp -m limit --limit 1/s-j LOG --log-prefix "[UDP drop] " --log-level=info

iptables -A LOGNDROP -p icmp -m limit --limit 1/s-j LOG --log-prefix "[ICMP drop] " --log-level=info

iptables -A LOGNDROP -f -m limit --limit 1/s-j LOG --log-prefix "[FRAG drop] " --log-level=info

iptables -A LOGNDROP -j DROP

192

Page 193: Présentation de la pile réseau sous gnu linux

iptables – Exemple

# Chaîne pour vérifier les flags TCPiptables -N TCPFLAGS

iptables -A TCPFLAGS -p tcp--tcp-flags ALL FIN,URG,PSH -j LOGNDROP

iptables -A TCPFLAGS -p tcp--tcp-flags ALL NONE -j LOGNDROP

iptables -A TCPFLAGS -p tcp--tcp-flags ALL ALL -j LOGNDROP

iptables -A TCPFLAGS -p tcp--tcp-flags ALL SYN,RST,ACK,FIN,URG -j LOGNDROP

iptables -A TCPFLAGS -p tcp--tcp-flags SYN,FIN SYN,FIN -j LOGNDROP

iptables -A TCPFLAGS -p tcp--tcp-flags SYN,RST SYN,RST -j LOGNDROP

193

Page 194: Présentation de la pile réseau sous gnu linux

iptables – Exemple

iptables -A TCPFLAGS -p tcp--tcp-flags FIN,RST FIN,RST -j LOGNDROP

iptables -A TCPFLAGS -p tcp--tcp-flags ACK,FIN FIN -j LOGNDROP

iptables -A TCPFLAGS -p tcp--tcp-flags ACK,PSH PSH -j LOGNDROP

iptables -A TCPFLAGS -p tcp--tcp-flags ACK,URG URG -j LOGNDROP

iptables -A TCPFLAGS –j DROP

194

Page 195: Présentation de la pile réseau sous gnu linux

iptables – Exemple

# Chaîne inputiptables -A INPUT -p all

-m state --state ESTABLISHED,RELATED -j ACCEPT

iptables -A INPUT -p tcp -j TCPFLAGS

# SSHiptables -A INPUT -p tcp --dport 22

--syn -m state --state NEW -j ACCEPT

# ICMPiptables -A INPUT -p icmp --icmp-type 0 -j ACCEPTiptables -A INPUT -p icmp --icmp-type 8

-m limit --limit 1/s -j ACCEPT

iptables -A INPUT -p all -j DROP

195

Page 196: Présentation de la pile réseau sous gnu linux

iptables – Exemple

# Chaîne output

iptables -A BADPACKETS -p all -m state --state INVALID -j DROP

iptables -A BADPACKETS -f -j DROP

iptables -A ICMPOUT -p icmp --icmp-type 0 -j ACCEPT

iptables -A ICMPOUT -p icmp -j DROP

iptables -A ICMPOUT -p all -j ACCEPT

196

Page 197: Présentation de la pile réseau sous gnu linux

iptables – Exemple NAT

# NAT

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

iptables -A INPUT -i ppp0-m state --state NEW,INVALID -j DROP

iptables -A FORWARD -i ppp0-m state --state NEW,INVALID -j DROP

iptables -A FORWARD -o ppp0 -j ACCEPT

echo 1 > /proc/sys/net/ipv4/ip_forward

197

Page 198: Présentation de la pile réseau sous gnu linux

iptables – Exemple FTP

# FTP actif

iptables -A OUTPUT -o eth0 -p tcp-m multiport --sport 20,21-m state --state ! INVALID -j ACCEPT

iptables -A INPUT -i eth0 -p tcp-m multiport --dport 20,21-m state --state RELATED,ESTABLISHED -j ACCEPT

# FTP passif (requiert ip_conntrack et ip_conntrack_ftp)iptables -A OUTPUT -o eth0 -p tcp

--sport 1024:-m state --state ! INVALID -j ACCEPT

iptables -A INPUT -i eth0 -p tcp--dport 1024:-m state --state RELATED,ESTABLISHED -j ACCEPT

198

Page 199: Présentation de la pile réseau sous gnu linux

iptables – Exemple Port Forwarding

# PF vers eth2, machine 192.168.1.50 port 80

iptables -P FORWARD DROP

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80-j DNAT --to 192.168.1.50:80

iptables –A FORWARD -i eth0 -o eth2 -p tcp-m state --state NEW --dport 80 -j ACCEPT

iptables -A POSTROUTING -t nat -o eth2 -j MASQUERADE

199

Page 200: Présentation de la pile réseau sous gnu linux

Bridge

Permet de bridger une interface réseau physique vers deux interface réseau

virtuelles

Permet le filtrage Ethernet

ebtable s’utilise similairement à iptable.

N2cessite le support « bridge » dans le noyau

+ les outils bridge-utils

Page 201: Présentation de la pile réseau sous gnu linux

Netfilter & iptable/ebtable

Page 202: Présentation de la pile réseau sous gnu linux

EBTABLE

bloquant comme un routeur Ipv4 :

ebtables -P FORWARD DROP

ebtables -A FORWARD -p Ipv4 -j ACCEPT

ebtables -A FORWARD -p ARP -j ACCEPT

...idem pour tables INPUT et OUTPUT

– Anti-spoofing :

ebtables -A FORWARD -p Ipv4 –ip-src 172.16.2.5 \

-s ! 00:11:22:33:44:55 -j DROP

– NATing :

ebtables -t nat -A PREROUTING -d 00:11:22:33:44:55 -i eth0 \

-j dnat –to-destination 00:66:77:88:99:AA

Page 203: Présentation de la pile réseau sous gnu linux

NETEM

Networking -->

Networking Options -->

QoS and/or fair queuing -->

Network emulator

Le noyau linux nécessite que la config noyau suivante :

http://www.linuxfoundation.org/collaborate/workgroups/networking/netem

Page 204: Présentation de la pile réseau sous gnu linux

TC / NETwork EMulator

NETEM est un ordonnanceur de paquet réseau. Il peut servir à simuler le comportement d’une connexion.

Commande Netm pour générer les pertes sur les paquets émis par l'interface Eth0 :

- Premier lancement avec 1% de paquet perdu : sudo tc qdisc add dev eth0 root netem loss 1%

- Modification des pertes à 0,3% : sudo tc qdisc change dev eth0 root netem loss 0.3%

Arrêt des pertes de paquets : sudo tc qdisc change dev eth0 root netem loss 0%

Commande Netm pour générer les pertes sur les paquets émis par l'interface Eth1 :

- Premier lancement avec 1% de paquet perdu : sudo tc qdisc add dev eth1 root netem loss 1%

- Modification des pertes à 0,3% : sudo tc qdisc change dev eth1 root netem loss 0.3%

- Arrêt des pertes de paquets : sudo tc qdisc change dev eth1 root netem loss 0%

Commande NetEm pour rajouter du délai sur les paquets émis par l'interface Eth0 :

- Premier lancement avec 100ms de latence : sudo tc qdisc add dev eth0 root netem delay 100ms

- Modification de la latence à 10ms : sudo tc qdisc change dev eth0 root netem delay 10ms

- Suppression de la latence supplémentaire : sudo tc qdisc change dev eth0 root netem delay 0ms

Pour aller plus loin avec NetEm :

- http://www.linuxfoundation.org/en/Net:Netem

- http://devresources.linux-foundation.org/shemminger/netem/example.html

Page 205: Présentation de la pile réseau sous gnu linux

NETEM

Pour appliquer un simple delai de 100ms :

# tc qdisc add dev eth0 root netem delay 100ms

Si on veut un jitter 10ms autour de 100ms, on peut changer la régle :

# tc qdisc change dev eth0 root netem delay 100ms 10ms

Si on veut une corrélation on peut rajouter un pourcenage à la de la commande :

# tc qdisc change dev eth0 root netem delay 100ms 10ms 25%

On peut appliquer une distribution (loi normale, distribution de pareto) sur le delai :

# tc qdisc change dev eth0 root netem delay 100ms 10ms distribution normal

Quand on utilise les paramètres pas défaut, si on applique un jitter trop important on

a un réordonnancement de packet.

Pour eviter ceci on utilse la fifo d'entrée pure et non pas la fifo de la discipline de

queue. Pour ceci on change les commandes :

# tc qdisc add dev eth0 root handle 1: netem delay 10ms 100ms

# tc qdisc add dev eth0 parent 1:1 pfifo limit 1000

Page 206: Présentation de la pile réseau sous gnu linux

6. Développement réseau en userspace

–API des sockets BSD–Architecture client/serveur–Paramétrage des sockets–Netlink–MPTCP

Page 207: Présentation de la pile réseau sous gnu linux

Les sockets BSD

L'utilisation des primitives réseau

ne se fait pas directement mais

via une API disponible

en userspace

http://www-adele.imag.fr/users/Didier.Donsez/cours/socketunix.pdf

Page 208: Présentation de la pile réseau sous gnu linux

Les sockets BSD

Vue synthétique des couches montrant la

localisation de l'API des sockets BSD

http://docs.huihoo.com/linux/kernel/a2/index.html

Page 209: Présentation de la pile réseau sous gnu linux

Sockets – Introduction

Les sockets sont une interface système utilisée pour la communication entre processus, notamment à travers un réseau

Cette API permet à un processus de spécifier un port et un protocole et d’y accéder pour émettre ou recevoir des données

Couvre les protocoles AppleTalk, AX.25, IPX, NetRom, TCP/IP, IPC local, Netlink…

Certaines fonctionnalités ne sont accessibles ne sont accessibles qu’aux processus avec un UID effectif de 0 (root) :

–Les ports privilégiés (en dessous de 1024)–Les API permettant d'accéder à certains protocoles bas-niveau (ex. ICMP)

209

Page 210: Présentation de la pile réseau sous gnu linux

Sockets – Fichiers et commandes

Le fichier /etc/host.conf indique quels services (et leur ordre d’utilisation) seront utilisés pour la résolution de noms (DNS)

Le fichier /etc/resolv.conf défini les domaines et adresses IP de serveurs DNS

Le fichier /etc/hosts contient une table statique d’adresses IP et de noms symboliques

Le fichier /etc/services contient une liste des ports et services TCP et UDP communs

Le fichier /etc/protocols contient une table de protocoles et leur numéros tels que définis par l’IANA

Commandes utiles : ifconfig, ip, netstat, arp, rarp, route

210

Page 211: Présentation de la pile réseau sous gnu linux

Sockets – /proc/net

L’interface /proc/net permet d’obtenir des statistiques réseau/proc/net/dev

–Contient des informations sur les interfaces réseau (nombre de paquets, erreurs, collisions, etc)

/proc/net/tcp, /proc/net/udp, /proc/net/unix, /proc/net/raw

–Contiennent des informations pour chaque socket ouverte (adresses locale et distante, état, taille des queues, timers, UID, etc)

/proc/net/arp, /proc/net/rarp, /proc/net/route–Contiennent les tables ARP et de routage

/proc/net/snmp–Contient des statistiques protocoles (MIB-2 RFC)

La plupart des adresses IP sont représentées en 4 octets hexadécimaux little-endian (ex : 0100007F:0017 -> 127.0.0.1:23)

211

Page 212: Présentation de la pile réseau sous gnu linux

Sockets – /proc/sys/net

L’interface /proc/sys/net permet d’ajuster certains paramètres réseau

–/proc/sys/net/core/(r|w)mem_(default|max)–/proc/sys/net/ipv4/tcp_timestamps–/proc/sys/net/ipv4/tcp_window_scaling–/proc/sys/net/ipv4/tcp_sack–/proc/sys/net/ipv4/tcp_rmem–/proc/sys/net/ipv4/tcp_wmem–/proc/sys/net/ipv4/tcp_fin_timeout–/proc/sys/net/ipv4/tcp_keepalive_intvl–/proc/sys/net/ipv4/tcp_keepalive_probes–/proc/sys/net/ipv4/tcp_tw_recycle–/proc/sys/net/ipv4/tcp_tw_reuse

Voir Documentation/networking/ip-sysctl.txt dans les sources du noyau

212

Page 213: Présentation de la pile réseau sous gnu linux

Sockets – Domaines

Domaine Unix–Une socket peut être utilisé pour la communication entre processus d’une même machine

Domaine Internet Protocol•Une socket peut être utilisé pour la communication entre processus de machines différentes•La socket est alors définie par

–Le protocole–L’adresse IP de la machine A–Le port associé sur la machine A–L’adresse IP de la machine B–Le port associé sur la machine B

Autres domaines : Netlink, AppleTalk, Packet, etc

213

Page 214: Présentation de la pile réseau sous gnu linux

Sockets – Types

Type datagramme–Sockets en mode non connecté–Dans le domaine Internet, le protocole est UDP–Datagrammes de taille bornée

Type flux (ou stream)–Socket en mode connecté–Dans le domaine Internet, le protocole est TCP

Type raw–Fournit un accès bas-niveau direct avec la couche IP ou ICMP–L’UID effectif du processus doit être 0 (root)

214

Page 215: Présentation de la pile réseau sous gnu linux

Sockets – hton*() et ntoh*()

Les protocoles fondés sur IP figent l’ordre des octets dans le réseau en big-endian (network byte-order)

Sur une machine little-endian, il faut convertir l’ordre des données envoyées et reçues

Il est de bonne pratique de systématiquement convertir les données quelque soit l’endianness de la machine (portabilité)

Des fonctions de conversion sont déclarées dans <netinet/in.h>

unsigned long int htonl(unsigned long int val);unsigned short int htons(unsigned short int val);unsigned long int ntohl(unsigned long int val);unsigned short int ntohs(unsigned short int val);

215

Page 216: Présentation de la pile réseau sous gnu linux

Sockets – Structure sockaddr

La structure sockaddr sert à définir une adresse réseauLa plupart des fonctions sur les sockets l’utilisent

struct sockaddr {unsigned short int sa_family;char sa_data[14];};

–sa_familly : AF_UNIX, AF_INET, AF_INET6, AF_IPX, …–sa_data : données propres au protocole

Cette structure est générique (coquille vide)

Chaque protocole utilise en fait sa propre structure (sockaddr_un, sockaddr_ipx, sockaddr_in6, etc.) qui est castée :

–(struct sockaddr *) &sockaddr_un

216

Page 217: Présentation de la pile réseau sous gnu linux

Sockets – Structure sockaddr_in

Les structures adresses du domaine Internet IPv4 sont

sockaddr_in {sa_family_t sin_family; // toujours AF_INETin_port_t sin_port; // portstruct in_addr sin_addr; // adresse IPv4};

struct in_addr {uint32_t s_addr; // adresse IPv4};

L’adresse et le port doivent être sous la forme réseau (big-endian)L’adresse INADDR_ANY (0.0.0.0) associe une socket avec toutes les interfacesLa valeur 0 dans sin_port laisse le système choisir le port source

217

Page 218: Présentation de la pile réseau sous gnu linux

Sockets – Structure sockaddr_in6

Les structures adresse du domaine Internet IPv6 sont :

sockaddr_in6 {sa_family_t sin6_family; // toujours AF_INET6in_port_t sin6_port; // portuint32_t sin6_flowinfo; // information de fluxstruct in6_addr sin6_addr; // adresse IPv6uint32_t sin6_scope_id; // scope ID};

struct in6_addr {unsigned char s6_addr[16]; // adresse IPv6};

L’adresse et le port doivent être sous la forme réseau (big-endian)

L’adresse in6addr_any associe une socket avec toutes les interfaces

218

Page 219: Présentation de la pile réseau sous gnu linux

Sockets – inet_*()

Les adresses IPv4 sont habituellement écrites sous la forme du chaine de caractères x.x.x.x (dotted quad)

Des fonctions permettent de passer de cette forme à la forme réseau (big-endian) et vice-versa

Il faut inclure les headers <sys/socket.h>, <netinet/in.h> et <arpa/inet.h>int inet_aton(const char *cp, struct in_addr *inp);char *inet_ntoa(struct in_addr in);in_addr_t inet_addr(const char *cp);int inet_pton(int af, const char *src, void *dst);

NOTE : En cas d’erreur (adresse IP malformée), la fonction inet_addr()retourne INADDR_NONE, qui a pour valeur -1, qui est une valeur d’adresse IP légale (255.255.255.255)

219

Page 220: Présentation de la pile réseau sous gnu linux

Sockets – inet_pton()

La fonction inet_pton() sert à convertir une adresse IPv4 ou IPv6 sous forme de chaine de caractères en une structure adresse#include <arpa/inet.h>int inet_pton(int af, const char *src, void *dst);

–af : AF_INET ou AF_INET6–*src : adresse IP :

•IPv4 : "xxx.xxx.xxx.xxx"•IPv6 : "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx"

–*dst : structure adresse :•IPv4 : struct in_addr•IPv6 : struct in6_addr

–→ retourne 1 si conversion réussie, 0 si *src ne représente pas une adresse valide, -1 si af ne contient pas une famille valide

220

Page 221: Présentation de la pile réseau sous gnu linux

Sockets – inet_ntop()

La fonction inet_ntop() sert à convertir une adresse IPv4 ou IPv6 d’une structure adresse en une chaine de caractères#include <arpa/inet.h>char *inet_ntop(int af, const void *restrict src,

char *restrict dst, socklen_t size);

–af : AF_INET ou AF_INET6–*src : structure adresse :

•IPv4 : struct in_addr•IPv6 : struct in6_addr

–*dst : buffer qui contiendra l’adresse IP–size : taille du buffer dst (INET_ADDRSTRLEN ou INET6_ADDRSTRLEN)–→ retourne un pointeur sur le buffer si conversion réussie, NULL sinon (avec errno)

221

Page 222: Présentation de la pile réseau sous gnu linux

Sockets – gethostbyname()

La fonction gethostbyname() permet de faire une résolution de nom DNS vers une adresse IPv4 ou IPv6#include <netdb.h>struct hostent *gethostbyname(const char *name);

–*name : nom de domaine ou adresse IP–→ retourne un pointeur sur hostent ou NULL si erreur (avec h_errno)

struct hostent {char *h_name; // nom DNS officielchar **h_aliases; // liste d’aliasint h_addrtype; // AF_INET ou AF_INET6int h_length; // longueur d’une adresse en octetschar **h_addr_list; // liste chainée d'adresses IP};

Note : cette fonction n’est pas réentrante

222

Page 223: Présentation de la pile réseau sous gnu linux

Sockets – gethostbyaddr()

La fonction gethostbyaddr() permet de faire une résolution inverse d’une adresse IP vers un nom de domaine#include <netdb.h>struct hostent *gethostbyaddr(const void *addr, int len, int type);

–*addr : pointeur sur une structure adresse (sin_addr pour AF_INET)–len : longueur de la structure addr (4 pour IPv4, 16 pour IPv6)–type : AF_INET ou AF_INET6–→ retourne un pointeur sur hostent ou NULL si erreur (avec h_errno)

Note : cette fonction n’est pas réentrante

223

Page 224: Présentation de la pile réseau sous gnu linux

Sockets – getaddrinfo()

La fonction getaddrinfo() est l’équivalent réentrant (donc thread-safe) de gethostbyname() et fonctionne pour IPv4 et IPv6#include <netdb.h>int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);

–*node : nom de domaine (ex. "www.exemple.com") ou adresse IP–*service : nom du service (ex. "http") ou port–*hints : structure pré-remplie (voir ci-après) ou NULL–*res : liste chainée (voir ci-après)–→ retourne 0 ou un code d’erreur

La liste chainée *res doit être libérée avec :–freeaddrinfo(struct addrinfo *res);

Voir getnameinfo() pour la fonction inverse

224

Page 225: Présentation de la pile réseau sous gnu linux

Sockets – Structure addrinfo

addrinfo est une structure utilisée par la fonction getaddrinfo()

struct addrinfo {int ai_flags; // AI_PASSIVE, AI_CANONNAME, etcint ai_family; // AF_INET, AF_INET6, AF_UNSPECint ai_socktype; // SOCK_STREAM, SOCK_DGRAMint ai_protocol; // 0size_t ai_addrlen; // taille de ai_addrstruct sockaddr *ai_addr; // sockaddr_in or _in6char *ai_canonname; // canonical hostnamestruct addrinfo *ai_next; // linked list, next node};

AF_UNSPEC permet de s’affranchir de la version IP

225

Page 226: Présentation de la pile réseau sous gnu linux

Sockets – getaddrinfo() – Exemple

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

int status;struct addrinfo *servinfo;

if ((status = getaddrinfo("site.com", NULL, NULL, &servinfo)) != 0) {fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));retourn -1;

}

/* le domaine site.com est résolu, servinfo pointe sur une liste chainée d’une ou plusieurs struct addrinfos */

/* ... */

freeaddrinfo(servinfo);

226

Page 227: Présentation de la pile réseau sous gnu linux

Sockets – socket()

La fonction socket() permet de créer une socket nécessaire pour la communications entre processus (locaux ou distants)

#include <sys/socket.h>int socket(int domain, int type, int protocol);

–domain : domaine de la socket (AF_UNIX, AF_INET, AF_INET6, …)–type : type de socket

•SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_PACKET–protocol : numéro du protocole utilisé, ou 0 pour le protocole par défaut–→ retourne un descripteur ou -1 si erreur (avec errno)

Le descripteur est utilisable par les fonctions telles que read() et write()

La fonction close() permet de fermer le descripteur d’une socket

227

Page 228: Présentation de la pile réseau sous gnu linux

Sockets – Streams

Socket du type SOCK_STREAM

Protocole TCP dans le domaine AF_INET–Transport fiable, vérification qu’un message envoyé est bien reçu–Contrôle de flux–Contrôle de congestion–Checksum

L’établissement de la connexion entre machines se fait en plusieurs étapes

La dissymétrie entre le serveur et le client est clairement marquée–Le serveur doit être en attente de connexion–Lorsque le serveur reçoit une connexion, une socket "de service" est créée–Le client prend l’initiative d’une connexion

228

Page 229: Présentation de la pile réseau sous gnu linux

Sockets – Streams : Client / Serveur

229

Page 230: Présentation de la pile réseau sous gnu linux

Sockets – Streams – bind()

La fonction bind() permet d’attacher une sockets à une adresseDoit être utilisée avant de pouvoir accepter des connexions

#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,

socklen_t addr_len);

–sockfd : descripteur de socket–*addr : pointeur sur une structure d’adresse–addr_len : taille en octets de la structure addr–→ retourne 0 ou -1 si erreur (avec errno)

Peut être utilisée avec d'autres protocoles que TCP

La structure addr employée dépend de la famille d’adresse utilisée (ex : sockaddr_in pour une adresse IPv4)

230

Page 231: Présentation de la pile réseau sous gnu linux

Sockets – Streams – listen()

La fonction listen() permet de créer une file d’attente pour les demandes de connexion

#include <sys/socket.h>int listen(int sockfd, int backlog);

–sockfd : descripteur de la socket–backlog : longueur de la file d’attente–→ retourne 0 ou -1 si erreur (avec errno)

La file est limitée à la valeur de /proc/sys/net/core/somaxconn(128 par défaut)

Lorsque la file d’attente est pleine, les connections suivantes sont refusées

231

Page 232: Présentation de la pile réseau sous gnu linux

Sockets – Streams – listen()

La fonction accept() permet a un serveur d’accepter une connexion en attente dans la file crée par listen()

#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t addr_len);

–sockfd : descripteur–*addr : adresse du client se connectant–addr_len : taille en octets de la structure addr–→ retourne un descripteur sur une nouvelle socket ou -1 si erreur (avec errno)

Le descripteur original continue d’être utilisé pour les connexions suivantes

S’il n’y a pas de connexion pendante, par défaut la fonction bloque

232

Page 233: Présentation de la pile réseau sous gnu linux

Sockets – Streams – connect()

En mode SOCK_STREAM, la fonction connect() permet a un client de se connecter à un serveur

#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr,

socklen_t addr_len);

–sockfd : descripteur–*addr : adresse du serveur–addr_len : taille en octets de la structure addr–→ retourne 0 ou -1 si erreur (avec errno)

La fonction connect() bloque jusqu’à ce que le serveur accepte la connexion (ou timeout dépendant du protocole) (sauf si la socket est en mode non bloquant)

En mode SOCK_STREAM, il n'est pas possible de réutiliser connect() sur la même socket pour se connecter à un autre serveur

233

Page 234: Présentation de la pile réseau sous gnu linux

Sockets – Streams – Exemple client

/* Toutes les conditions d’erreurs ne sont pas vérifiées dans cet exemple */

void tcp_client(void){int sockfd;struct sockaddr_in address;char ch = 'A';

sockfd = socket(AF_INET, SOCK_STREAM, 0);

address.sin_family = AF_INET;address.sin_addr.s_addr = inet_addr("127.0.0.1");address.sin_port = htons(9734);connect(sockfd, (struct sockaddr *)&address, sizeof(address));write(sockfd, &ch, 1);read(sockfd, &ch, 1);printf("char from server = %c\n", ch);close(sockfd);}

234

Page 235: Présentation de la pile réseau sous gnu linux

Sockets – Streams – Exemple serveur

/* Toutes les conditions d’erreurs ne sont pas vérifiées dans cet exemple */

void tcp_server(void){

int server_sockfd, client_sockfd, client_len;struct sockaddr_in server_address;struct sockaddr_in client_address;char ch;

server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

server_address.sin_family = AF_INET;server_address.sin_addr.s_addr = htonl(INADDR_ANY);server_address.sin_port = htons(9734);bind(server_sockfd, (struct sockaddr *)&server_address,

sizeof(server_address));listen(server_sockfd, 5);client_len = sizeof(client_address);

235

Page 236: Présentation de la pile réseau sous gnu linux

Sockets – Streams – Exemple serveur (suite)

while(1)

{client_sockfd = accept(server_sockfd, (struct sockaddr *)

&client_address, &client_len);read(client_sockfd, &ch, 1);ch++;write(client_sockfd, &ch, 1);close(client_sockfd);

}

236

Page 237: Présentation de la pile réseau sous gnu linux

Sockets – Streams – close()

La fonction close() est utilisée pour fermer un descripteur de socket–Effectif seulement lorsque tous les processus partageant la socket ont appelé close()

En TCP, par défaut, close() retourne immédiatement–Normalement, génère l'envoi d'un segment FIN–Il se peut que certaines données n'aient pas encore été transmises ou reçues

•Si des données sont encore dans le buffer de réception, envoi d'un RST–Timeout TCP

Durant les timeouts TCP, la socket continue d'exister dans le système–Par défaut, un nouveau bind() sur le même port échouera

Lorsqu'un hôte distant termine son coté de la connexion, read() retourne 0

237

Page 238: Présentation de la pile réseau sous gnu linux

Sockets – Streams – shutdown()

La fonction shutdown() permet de fermer une socket en mode connecté, en réception et/ou émission

#include <sys/socket.h> int shutdown(int sockfd, int how);

–sockfd : descripteur–how :

•SHUT_RD : ferme en réception–Des données déjà dans le buffer de réception sont ignorées

•SHUT_WR : ferme en émission–Des données déjà dans le buffer d'émission sont envoyées

•SHUT_RDWR : ferme en réception et en émission–→ retourne 0 ou -1 si erreur (avec errno)

shutdown() initie la fin d'une connexion (FIN) quelque soit le nombre de références sur la socket

238

Page 239: Présentation de la pile réseau sous gnu linux

Sockets – Streams – shutdown() – Exemple

sock = socket(AF_INET, SOCK_STREAM, 0);

/* ... */

write(sock, buffer, 1000000);

shutdown(sock, SHUT_WR);

while(1) {res = read(sock, buffer, 4000);if (res < 0) {

perror("reading");return -1;

}if (!res)

break;}close(sock);

239

Page 240: Présentation de la pile réseau sous gnu linux

Sockets – Sockets type datagramme

Socket du type SOCK_DGRAM

Protocole UDP dans le domaine AF_INET–Aucune vérification qu’un message envoyé est bien reçu–Les messages peuvent être reçu dans un ordre différent de l’ordre d’envoi–Aucun contrôle de flux–Aucun contrôle de congestion–Checksum à la fin du message

Deux modes de fonctionnement :–Socket non connectée :

•Chaque message est envoyé ou reçu potentiellement à ou depuis un hôte différent

–Socket connectée :•La socket est connecté avec à une adresse et un port, l’envoi ou la réception de messages se fait avec le même hôte

240

Page 241: Présentation de la pile réseau sous gnu linux

Sockets – Datagrammes – sendto() et recvfrom()

Les fonctions sendto() et recvfrom() permettent d’envoyer ou recevoir un message par une socket, non nécessairement en mode connectée

Les adresses de destination et provenance sont donc spécifiées

#include <sys/socket.h>ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen);ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,

struct sockaddr *src_addr, socklen_t *addrlen);

–sockfd : descripteur de socket–*buf : buffer–len : taille en octets de buf–flags : options (voir page sur send() et recv())–*addr : adresse du destinataire ou de l’émetteur–addr_len : taille en octets de addr–→ retournent le nombre d’octets lus ou écrits ou -1 si erreur (avec errno)

241

Page 242: Présentation de la pile réseau sous gnu linux

Sockets – Datagrammes – connect()

La fonction connect() peut être utilisé sur une socket SOCK_DGRAM

Cela n’implique pas une connexion protocolaire comme avec SOCK_STREAM

Tous les paquets envoyés le seront vers l’adresse spécifiée

Seuls les paquets venant de l’adresse spécifiée seront reçus

Il est donc ensuite possible d’utiliser read() et write() au lieu de recvfrom() et sendto()

Il est possible d’utiliser plusieurs fois connect() sur la même socket pour changer d’association

Une association peut être rompue en utilisant AF_UNSPEC

242

Page 243: Présentation de la pile réseau sous gnu linux

Sockets – Datagrammes – send() et recv()

Les fonctions send() et recv() permettent d’envoyer et recevoir des données à travers une socket en mode connecté

#include <sys/socket.h>int send(int sockfd, const void *msg, int len, int flags);int recv(int sockfd, void *msg, int len, int flags);

–sockfd : descripteur–*msg : buffer de données à envoyer ou reçues–len : taille du buffer–flags : 0 ou OU binaire entre :

•MSG_DONTROUTE : pas de routage à travers un gateway•MSG_DONTWAIT : opération non bloquante•MSG_OOB : message out-of-band (flag TCP URG)

–→ retourne le nombre d’octets envoyés ou lus ou -1 si erreur (avec errno)

243

Page 244: Présentation de la pile réseau sous gnu linux

Sockets – Principales options des sockets

SOL_SOCKET Description

SO_REUSADDR Permet de réutiliser une socket immédiatement

SO_KEEPALIVE Envoie des messages keep-alive (streams)

SO_LINGER Délai entre messages non envoyés et retour de close()

SO_BROADCAST Permet l’envoie ou reçoit des datagrammes broadcast

SO_SNDBUF Taille du buffer d’émission

SO_RCVBUF Taille du buffer de réception

SO_TYPE Permet de lire le type de socket

SO_DONTROUTE N’envoie pas de données à travers un gateway

TCP_NODELAY Désactive l’algorithme de Nagle

244

Page 245: Présentation de la pile réseau sous gnu linux

Sockets – setsockopt()

Les fonctions setsockopt() et getsockopt() permettent de spécifier ou relire les options d’une socket

#include <sys/socket.h>int setsockopt(int sockfd, int level, int optname, void *optval, socklen_t optlen);int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

–sockfd : descripteur–level : niveau de protocole (SOL_SOCKET, SOL_TCP, IPPROTO_TCP, …)–optname : nom de l’option–*optval : valeur de l’option–optlen : longueur de la valeur en octets–→ retourne 0 ou -1 si erreur (avec errno)

245

Page 246: Présentation de la pile réseau sous gnu linux

Sockets – SO_REUSADDR

Par défaut, refaire un bind() sur un même port lorsqu'une socket TCP est dans l'état TIME_WAIT échoue

–bind() retourne EADDRINUSE

L'option SO_REUSADDR permet de pouvoir réutiliser une socket TCP–Permet de relancer un serveur immédiatement

Exemple :

int sd = socket(AF_INET, SOCK_DGRAM, 0);if (sd < 0) return -1;

int yes = 1;setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof yes);

bind(sd,(struct sockaddr *)(&addr),sizeof(struct sockaddr));

/* ... */

246

Page 247: Présentation de la pile réseau sous gnu linux

Sockets – SO_LINGER

L'option SO_LINGER configure le comportement de close() si le buffer d'émission n'est pas vide

Avec SO_LINGER et son timeout activé, close() est bloquant jusqu'à ce que les données aient été envoyées, ou jusqu'à ce que le timeout expire

Avec SO_LINGERmais avec un timeout nul, close() retourne immédiatement et un RST est envoyé à l'hôte distant

L'argument passé à setsocktopt() est une structure :

struct linger {int l_onoff; // linger activé ou nonint l_linger; // délai en secondes

};

247

Page 248: Présentation de la pile réseau sous gnu linux

Sockets – Multicast

La fonction setsockopt() permet de joindre ou quitter un groupe multicast

setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,struct ip_mreq *mreq, sizeof

(ip_mreq));setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP,

struct ip_mreq *mreq, sizeof (ip_mreq));

struct ip_mreq {struct in_addr imr_multiaddr; // Adresse IP multicaststruct in_addr imr_interface; // Adresse IP locale

};

En multicast, il est nécessaire d’autoriser l’utilisation répétée d’une adresse IP :

char one = 1;setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(char));

248

Page 249: Présentation de la pile réseau sous gnu linux

Sockets – Multiplexage

Le multiplexage permet à un serveur de traiter plusieurs connexions clientes simultanément

Plusieurs implémentations possibles :–Utiliser un processus par client (fork() après accept())–Utiliser une réserve de processus (plusieurs fork() avant accept())–Utiliser un thread par client (pthread_create() après accept())–Utiliser une réserve de thread (pthread_create() avant accept())–Utiliser une réserve de sockets (select() ou poll())

249

Page 250: Présentation de la pile réseau sous gnu linux

Sockets – Multiplexage – Exemple forking

/* Toutes les conditions d’erreurs ne sont pas vérifiées dans cet exemple */

/* socket(), bind() et listen() ont été appelées à ce point */

while(1){

new_sock = accept(server_sock, NULL, NULL);if ((pid = fork()) == 0){

/* processus fils */close(server_sock);nread = read(new_sock, buffer, 25, 0);/* ... */close(new_sock);exit(EXIT_SUCCESS);

} else {/* processus parent */close(new_sock);

}}

250

Page 251: Présentation de la pile réseau sous gnu linux

Sockets – Multiplexage – Exemple pre-forking

/* Toutes les conditions d’erreurs ne sont pas vérifiées dans cet exemple */

/* socket(), bind() et listen() ont été appelées à ce point */

for (x = o; x < MAX_CHILDREN; ++x){if ((pid = fork()) == 0){/* process fils */while(1){new_sock = accept(server_sock, NULL, NULL);nread = read(new_sock, buffer, 25, 0);/* ... */close(new_sock);}}}

251

Page 252: Présentation de la pile réseau sous gnu linux

Sockets – Multiplexage – Exemple threaded

/* Toutes les conditions d’erreurs ne sont pas vérifiées dans cet exemple */

/* socket(), bind() et listen() ont été appelées à ce point */

while(1){

new_sock = accept(server_sock, NULL, NULL);pthread_create(&thread_id, NULL, &thread_proc, (void *) new_sock);pthread_detach(thread_id);

}

void thread_proc(void *arg){

int sock = (int) arg;int nread = read(sock, buffer, 25, 0);/* ... */close(sock);

}

252

Page 253: Présentation de la pile réseau sous gnu linux

Sockets – select()

La fonction select() permet de surveiller (attente d’un événement) plusieurs descripteurs (donc sockets) à la fois

La fonction distingue trois ensembles de descripteurs à surveiller en lecture, écriture et exceptions

En retour, la fonction ne garde dans chaque ensemble que les descripteurs ayant eu un événement

Les ensembles de descripteurs sont placés dans une variable de type fd_set

Des macros permettent de manipuler les variables de type fd_set :–FD_SET(int fd, fd_set *set); // Ajoute fd à l'ensemble–FD_CLR(int fd, fd_set *set); // Enlève fd de l'ensemble–FD_ISSET(int fd, fd_set *set);// Vrai si fd est dans l'ensemble–FD_ZERO(fd_set *set); // Efface l'ensemble

Un ensemble ne peut contenir plus de FD_SETSIZE descripteurs

253

Page 254: Présentation de la pile réseau sous gnu linux

Sockets – select() (suite)

#include <sys/select.h>int select(int n, fd_set *readfds, fd_set *writefds,

fd_set *exceptfds, struct timeval timeout);

–n : valeur du descripteur le plus élevé des trois ensembles + 1–*readfds, *writefds, *exceptfds : ensembles de descripteurs à surveiller–timeout : délai d’attente ou NULL pour infini–→ retourne le nombre de descripteurs modifiés, 0 si timeout ou -1 si erreur (avec errno)

La fonction select() peut être utilisée avec tout type de descripteur

L’établissement d’une nouvelle connexion sur une socket est signalé dans l’ensemble de lecture

Un descripteur sur fichier régulier est toujours prêt en lecture si pas à la fin du fichier, et est toujours prêt en écriture

254

Page 255: Présentation de la pile réseau sous gnu linux

Sockets – select() – Exemple 1

#include <stdio.h>#include <sys/select.h>

int main(void){fd_set readfds;struct timeval tv;tv.tv_sec = 2;tv.tv_usec = 500000;FD_ZERO(&readfds);FD_SET(STDIN_FILENO, &readfds);

if (select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv) > 0) {if (FD_ISSET(STDIN_FILENO, &readfds))printf("Une touche a été appuyée\n");}else printf("Timeout.\n");

return 0;}

255

Page 256: Présentation de la pile réseau sous gnu linux

Sockets – select() – Exemple 2

/* socket(), bind() et listen() ont été appelées à ce point */

fd_set readset;FD_ZERO(&readfds);FD_SET(sockfd, &readfds);result = select(sockfd + 1, &readfds, NULL, NULL, NULL);if (result > 0) {if (FD_ISSET(sockfd, &readfds)) {result = read(sockfd, buffer, buffer_len);if (result == 0) {close(socket_fd); // hôte distant à fermé la connexion} else {/* ... */}}}else if (result < 0) {printf("Erreur sur select(): %s\", strerror(errno));}

256

Page 257: Présentation de la pile réseau sous gnu linux

Sockets – select() – Exemple 3

fd_set read_set, test_set;FD_ZERO(&read_set);FD_SET(sockfd, &read_set)max_sockfd = sockfd;while(1) {test_set = read_set;if (1 <= select(max_sockfd + 1, &test_set, NULL, NULL, NULL)) {for (var x = 0; x < max_sockfd; x++) {if (FD_ISSET(x, &test_set)) {if (x == sockfd) {int new_sock = accept(sockfd, NULL, NULL);FD_SET(new_sock, &read_set);max_sockdf = max(max_sockdf, new_sock)} else {nread = read(x, buffer, 25, 0)/* ... */close(x);FD_CLR(x, $read_set);}}}}}

257

Page 258: Présentation de la pile réseau sous gnu linux

Sockets – poll()

La fonction poll() s’apparente à select()

#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);

–*fds : tableau de structure (voir ci-après):struct pollfd {int fd; // descripteur de fichiershort events;// événements à surveillershort revents; // événements retournés};

–nfds : nombre de structures dans fds–timeout : délai d’attente ou NULL pour infini–→ retourne le nombre de structures avec événements, 0 si timeout ou -1 si erreur (avec errno)

258

Page 259: Présentation de la pile réseau sous gnu linux

Sockets – poll() (suite)

Les événements sont définis avec un OU binaire :

–POLLIN : données reçues en attente–POLLPRI : données urgentes reçues (par exemple TCP OOB)–POLLOUT : écrire ne bloquerait pas–POLLHUP : déconnection de la connexion–POLLERR : condition d’erreur–POLLNVAL : descripteur invalide

En définissant _GNU_SOURCE :–POLLRDHUP : l’hôte distant a fermé sa socket (SOCK_STREAM)

259

Page 260: Présentation de la pile réseau sous gnu linux

Sockets – poll() – Exemple

struct pollfd fds[2];int ret, i;

fds[0].fd = open("/dev/dev0", O_WRONLY);fds[1].fd = open("/dev/dev1", O_WRONLY);/* ... Vérification de la validité des descripteurs ... */

fds[0].events = POLLOUT | POLLERR;fds[1].events = POLLOUT | POLLERR;

if ((ret = poll(fds, 2, timeout_msecs)) > 0) {for (i = 0; i < 2; ++i) {if (fds[i].revents & POLLERR) {/* ... gestion de l'erreur ... */}if (fds[i].revents & POLLOUT) {/* ... écriture sur le device ... */}}}

260

Page 261: Présentation de la pile réseau sous gnu linux

Sockets – Mode non bloquant

Les sockets peuvent être configurées en mode non bloquant

Les fonctions (accept(), connect(), read(), write(), etc) qui normalement bloquent retournent immédiatement

–Si l’opération n’est pas possible, elles retournent -1 et errno est égal à EAGAIN (or EWOULDBLOCK)

La fonction fcntl() est utilisée pour configurer un descripteur en mode non bloquant :

#include <fcntl.h>

int sockfd = socket(AF_INET, SOCK_DGRAM, 0);/* ... */int flags = fcntl(sockfd, F_GETFL, 0);fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

261

Page 262: Présentation de la pile réseau sous gnu linux

Sockets – Domaine Unix

Les sockets du domaine Unix sont similaires dans le principe à un tube nommé

S'utilisent en SOCK_STREAM ou SOCK_DGRAM

L’adresse utilisée pour bind() ou connect() est un nom de fichier–Les sockets créées dans le système de fichiers ne peuvent être utilisées qu’avec l’API des sockets–Le fichier socket ne doit pas exister avant la création d’une nouvelle socket (le supprimer avec unlink())

La structure adresse du domaine Unix est :

struct sockaddr_un {sa_family_t sun_family; // Domaine : AF_UNIX ou AF_LOCALchar sun_path[104]; // Nom de fichier};

262

Page 263: Présentation de la pile réseau sous gnu linux

Sockets – Domaine Unix – Exemple serveur

/* Toutes les conditions d’erreurs ne sont pas vérifiées dans cet exemple */

#define SOCKET_FILE "/tmp/mysocket"

void server(void){

int server_sockfd, client_sockfd, client_len;struct sockaddr_un server_address;struct sockaddr_un client_address;char ch;

unlink(SOCKET_FILE);

server_sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

server_address.sun_family = AF_UNIX;strcpy(server_address.sun_path, SOCKET_FILE);bind(server_sockfd, (struct sockaddr *)&server_address,

sizeof(server_address));

263

Page 264: Présentation de la pile réseau sous gnu linux

Sockets – Domaine Unix – Exemple serveur (suite)

listen(server_sockfd, 5);

client_len = sizeof(client_address);

while(1){

client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);

read(client_sockfd, &ch, 1);ch++;write(client_sockfd, &ch, 1);close(client_sockfd);

}}

264

Page 265: Présentation de la pile réseau sous gnu linux

Sockets – Domaine Unix – Exemple client

/* Toutes les conditions d’erreurs ne sont pas vérifiées dans cet exemple */

#define SOCKET_FILE "/tmp/mysocket"

void client(void) {int sockfd;struct sockaddr_un address;char ch = 'A';

sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

address.sun_family = AF_UNIX;strcpy(address.sun_path, SOCKET_FILE);connect(sockfd, (struct sockaddr *)&address, sizeof(address));write(sockfd, &ch, 1);read(sockfd, &ch, 1);printf("char from server = %c\n", ch);

close(sockfd);}

265

Page 266: Présentation de la pile réseau sous gnu linux

Sockets – socketpair()

La fonction socketpair() permet de créer une paire de sockets Unix connectées entre-elles, full-duplex

L’utilisation est similaire à pipe()

#include <sys/socket.h>int socketpair(int dom, int type, int protocol, int sv[2]);

–dom : domaine, toujours AF_UNIX ou AF_LOCAL–type : SOCK_STREAM ou SOCK_DGRAM–protocol : 0–sv : tableau de 2 descripteur–→ retourne 0 ou -1 si erreur (avec errno)

266

Page 267: Présentation de la pile réseau sous gnu linux

Sockets – socketpair() – Exemple

/* Toutes les conditions d’erreurs ne sont pas vérifiées dans cet exemple */

int sockets[2];socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);

child = fork();if (child) {

/* processus parent. */close(sockets[0]);read(sockets[1], buf, 1024, 0); // danger de débordementprintf("-->%s\n", buf);write(sockets[1], DATA2, sizeof(DATA2));close(sockets[1]);

} else {/* processus fils */close(sockets[1]);write(sockets[0], DATA1, sizeof(DATA1));read(sockets[0], buf, 1024, 0); // danger de débordementprintf("-->%s\n", buf);close(sockets[0]);

}

267

Page 268: Présentation de la pile réseau sous gnu linux

ioctl

Netlink

Kernel-Space Netlink

RTNelink

268

Page 269: Présentation de la pile réseau sous gnu linux

ioctl

ioctl est un moyen de communication qui est, entre autres, utilisé pour paramétrer les options des sockets

L'interface ioctl est considérée obsolète, mais beaucoup de code l'utilise toujours (ex. ifconfig)

ioctl opère sur un descripteur de fichier, donc aussi une socket :

int ioctl(int descriptor, int ioctl_op, ...);

La liste des opérations est disponible avec man ioctl_list

269

Page 270: Présentation de la pile réseau sous gnu linux

ioctl – Structure ifreq

L'accès aux informations et à la configuration des interfaces réseau se fait avec un structure ifreq(net/if.h)

struct ifreq {

char ifr_name[IFNAMSIZ];

union {

struct sockaddr ifr_addr;

struct sockaddr ifr_dstaddr;

struct sockaddr ifr_broadaddr;

struct sockaddr ifr_netmask;

struct sockaddr ifr_hwaddr;

short ifr_flags;

int ifr_ifindex;

int ifr_metric;

int ifr_mtu;

struct ifmap ifr_map;

char ifr_slave[IFNAMSIZ];

char ifr_newname[IFNAMSIZ];

char *ifr_data;

};

};

270

Page 271: Présentation de la pile réseau sous gnu linux

ioctl – Structure ifreq – Opérations

SIOCGIFNAME

–En utilisant ifr_ifindex, renvoie le nom de l'interface dans ifr_name

SIOCGIFINDEX

–Retrouve le numéro d'interface et le place dans ifr_ifindex

SIOCGIFMETRIC, SIOCSIFMETRIC–Lire ou écrire le MTU du périphérique avec ifr_mtu

SIOCGIFHWADDR, SIOCSIFHWADDR–Lire ou écrire l'adresse matérielle du périphérique en utilisant ifr_hwaddr

271

Page 272: Présentation de la pile réseau sous gnu linux

ioctl – Structure ifreq – Attributs

SIOCADDMULTI, SIOCDELMULTI

–Ajouter ou supprimer une adresse des filtres multicast du niveau 2 du périphérique en utilisant ifr_hwaddr

SIOCGIFTXQLEN, SIOCSIFTXQLEN–Lire ou écrire la taille de la file d'émission du périphérique avec ifr_qlen

SIOCSIFNAME

–Changer le nom de l'interface indiquée dans ifr_name pour ifr_newname

SIOCGIFFLAGS, SIOCSIFFLAGS–Lire ou écrire les attributs actifs du périphérique

272

Page 273: Présentation de la pile réseau sous gnu linux

ioctl – Structure ifreq – Opérations

ifr_flags contient un masque de bits :–IFF_UP : Interface fonctionne–IFF_RUNNING : Ressources allouées–IFF_BROADCAST : Adresse de broadcast valide–IFF_LOOPBACK : Interface de type loopback–IFF_POINTOPOINT : Interface de type point-à-point–IFF_NOARP : Pas de protocole Arp–IFF_PROMISC : Interface en mode promiscuous–IFF_ALLMULTI : Accepte tous les paquets multicast–IFF_MULTICAST : Support multicast

273

Page 274: Présentation de la pile réseau sous gnu linux

ioctl – Structure ifreq – Exemple

/* Récupère l'adresse MAC de l'interface eth0 */

#include <sys/ioctl.h>#include <net/if.h>

void get_eth0_mac(unsigned char* mac_addr){

struct ifreq ifr;int sockfd;

sock_fd = socket(AF_INET, SOCK_DGRAM, 0);

memset(&ifr, 0, sizeof(struct ifreq));memcpy(ifr.ifr_name, "eth0", IFNAMSIZ);

ioctl(sock_fd, SIOCGIFHWADDR, &ifr);memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);

close(sock_fd);}

274

Page 275: Présentation de la pile réseau sous gnu linux

ioctl – Structure ifconf

L'opération SIOCGIFCONF renvoie la liste des adresses IPv4

L'accès à la liste se fait à travers une structure ifconf qui contient un pointeur sur une table de structures ifreq :

struct ifconf {

int ifc_len;

union {

char* ifc_buf;

struct ifreq* ifc_req;

};

};

Pour chaque ifreq :–ifr_name contient le nom de l'interface–ifr_addr contient l'adresse MAC

275

Page 276: Présentation de la pile réseau sous gnu linux

ioctl – Structure ifconf

/* Récupère la liste des interfaces */

Void print_ifaces(void){

struct ifconf config;struct ifreq ifreq[128];int sock_fd, nb, ii;

sock_fd = socket(AF_INET, SOCK_STREAM, 0);

memset(&config, 0, sizeof(struct ifconf));config.ifc_buf = (char*) ifreq;config.ifc_len = 128 * sizeof(struct ifreq);

ioctl(devices, SIOCGIFCONF, (char *) &config);

nb = config.ifc_len / (sizeof(struct ifreq));for (ii = 0; ii < nb; ii++) {

printf("Interface : %s\n", ifreq[ii].ifr_name);}close(sock_fd);

}

276

Page 277: Présentation de la pile réseau sous gnu linux

Netlink

Netlink est un mécanisme de transfert d'informations entre le noyau et les processus de l'espace utilisateur, ou entre les processus d'une même machine

Netlink est conçu et utilisé pour transférer des informations relatives à la pile réseau

Netlink est le successeur de l'interface ioctl

Interface basée sur les sockets standards pour les processus utilisateur

API interne pour les modules du noyau

277

Page 278: Présentation de la pile réseau sous gnu linux

Netlink – nlmsghdr

Une socket Netlink fonctionne un peu comme une socket raw

Contrairement aux protocoles comme TCP, où les entêtes sont auto-générées, l'entête des messages Netlink doit être préparée par le programme

L'entête du message Netlink est définie dans cette structure :

struct nlmsghdr

{

__u32 nlmsg_len; /* Longueur y compris en-tête */

__u16 nlmsg_type; /* Contenu message */

__u16 nlmsg_flags; /* Attributs supplémentaires */

__u32 nlmsg_seq; /* Numéro de séquence */

__u32 nlmsg_pid; /* PID du créateur socket */

};

278

Page 279: Présentation de la pile réseau sous gnu linux

Pour créer un socket Netlink :int socket(PF_NETLINK, int type, int protocol);

type :–SOCK_RAW et SOCK_DGRAM sont des valeurs possibles pour le type de la socket

protocol :–sélectionne le module du noyau ou le groupe Netlink avec qui communiquer

Netlink – socket()

279

Page 280: Présentation de la pile réseau sous gnu linux

Netlink – Protocoles

NETLINK_ROUTE

–Reçoit les modifications de routage et peut être utilisé pour mettre à jour les tables de routage IPv4

NETLINK_ROUTE6

–Reçoit et envoie les mise à jour de la table de routage IPv6

NETLINK_FIREWALL

–Reçoit les paquets envoyés par le code du firewall

NETLINK_IP6_FW

–Pour recevoir les paquets rejetés par le firewall IPv6

280

Page 281: Présentation de la pile réseau sous gnu linux

Netlink – Protocoles

NETLINK_ARPD

–Pour gérer la table Arp dans l'espace utilisateur

NETLINK_NFLOG

–Interface entre Netfilter et iptables

NETLINK_AUDIT

–Fournit une interface sur le sous-système

NETLINK_USERSOCK

–Réservé pour les protocoles dans l'espace utilisateur

281

Page 282: Présentation de la pile réseau sous gnu linux

Netlink – bind()

Comme pour une socket IP, bind() associe une adresse locale avec

une socket

La structure d'adresse Netlink est :

struct sockaddr_nl

{

sa_family_t nl_family; /* AF_NETLINK */

unsigned short nl_pad; /* zero */

__u32 nl_pid; /* process pid */

__u32 nl_groups; /* mcast groups mask */

}

282

Page 283: Présentation de la pile réseau sous gnu linux

Netlink – bind()

Le champ nl_pid sert d'adresse locale–L'application doit donc choisir un entier unique :

Si pour un même processus, une seule socket pour un protocole Netlink particulier est utilisée :

–nl_pid = getpid();

Si pour un même processus, plusieurs sockets pour un protocole Netlink particulier sont utilisées :

–nl_pid = pthread_self() << 16 |

getpid();

283

Page 284: Présentation de la pile réseau sous gnu linux

Netlink – bind()

Il est possible de définir jusqu'à 32 groupes multicast pour chaque famille Netlink

–1<<i avec 0 <= i <=31

Utilisé lorsqu'un groupe de processus et le noyau s'entendent sur une fonctionnalité commune

Pour recevoir des messages multicast :–nl_groups = bitmask des groupes visés

Si pas de groupes multicast :–nl_groups = 0;

284

Page 285: Présentation de la pile réseau sous gnu linux

Netlink – sendmsg()

Pour envoyer un message Netlink au noyau ou à un autre processus, une structure sockaddr_nl doit être utilisée comme adresse de destination, et fournie à une structure msghdr

Message est à destination du noyau :–nl_pid = nl_groups = 0;

Message unicast à destination d'un autre processus :–nl_pid = nl_pid du processus visé–nl_groups = 0;

Message multicast :–nl_groups = bitmask des groupes visés

285

Page 286: Présentation de la pile réseau sous gnu linux

Netlink – sendmsg()

L'entête des messages Netlink doit être fournie par le programme :

struct nlmsghdr

{

__u32 nlmsg_len; /* Length of message */

__u16 nlmsg_type; /* Message type*/

__u16 nlmsg_flags; /* Additional flags */

__u32 nlmsg_seq; /* Sequence number */

__u32 nlmsg_pid; /* Sending process PID */

};

286

Page 287: Présentation de la pile réseau sous gnu linux

Netlink – sendmsg()

–nlmsg_len : longueur totale du message incluant le header

–nlmsg_type : permet d'indiquer un message à ignorer, un message d'erreur, ou un message multi-parties

–nlmsg_flags : attributs supplémentaires pour messages de requête, messages multi-parties, demandes d'acquittements, etc.

–nlmsg_seq et nlmsg_pid : pas de signification particulière, libre à l'application de les utiliser

287

Page 288: Présentation de la pile réseau sous gnu linux

Netlink – sendmsg()

Pour les messages multi-parties :–Tous les entêtes ont l'attribut NLM_F_MULTI actif, sauf le dernier en-tête qui a le type NLMSG_DONE

Le flux d'octets du message ne doit être accédé qu'à travers les macros standards NLMSG_*

–Similaires aux macros CMSG_*

Finalement le message en lui-même est attaché à la structure msghdr et envoyé avec sendmsg()

288

Page 289: Présentation de la pile réseau sous gnu linux

Netlink – sendmsg() – Exemple

/* Toutes les conditions d'erreur ne sont pas vérifiées */

#include <sys/socket.h>#include <linux/netlink.h>

struct sockaddr_nl src_addr, dest_addr;struct nlmsghdr *nlh = NULL;struct iovec iov;int sock_fd;

sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USERSOCK);

memset(&src_addr, 0, sizeof(src_addr));src_addr.nl_family = AF_NETLINK;src_addr.nl_pid = getpid();src_addr.nl_groups = 0;bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));

289

Page 290: Présentation de la pile réseau sous gnu linux

Netlink – sendmsg() – Exemple

memset(&dest_addr, 0, sizeof(dest_addr));dest_addr.nl_family = AF_NETLINK;dest_addr.nl_pid = 0;dest_addr.nl_groups = 0;

nlh = (struct nlmsghdr*) malloc(NLMSG_SPACE(1024));nlh->nlmsg_len = NLMSG_SPACE(1024);nlh->nlmsg_pid = getpid();nlh->nlmsg_flags = 0;strcpy(NLMSG_DATA(nlh), "Hello world");

iov.iov_base = (void *)nlh;iov.iov_len = nlh->nlmsg_len;msg.msg_name = (void *)&dest_addr;msg.msg_namelen = sizeof(dest_addr);msg.msg_iov = &iov;msg.msg_iovlen = 1;

sendmsg(fd, &msg, 0);

290

Page 291: Présentation de la pile réseau sous gnu linux

Netlink – recvmsg()

Une application désirant recevoir un message Netlink doit allouer un buffer suffisamment large

La réception se fait à travers une structure msghdr pointant sur une structure sockaddr_nl

Après réception, le membre nlh pointe sur l'entête du message

La macro NLMSG_DATA retourne un pointeur sur les données

291

Page 292: Présentation de la pile réseau sous gnu linux

Netlink – recvmsg() – Exemple

struct sockaddr_nl nladdr;struct msghdr msg;struct iovec iov;char data[1024];

iov.iov_base = (void*) nlh;iov.iov_len = MAX_NL_MSG_LEN;

msg.msg_name = (void*) &nladdr;msg.msg_namelen = sizeof(nladdr);msg.msg_iov = &iov;msg.msg_iovlen = 1;recvmsg(fd, &msg, 0);

strncpy(data, NLMSG_DATA(nlh), 1023);data[1023] = '\0';

292

Page 293: Présentation de la pile réseau sous gnu linux

Kernel-Space Netlink

293

Page 294: Présentation de la pile réseau sous gnu linux

Netlink – Noyau

L'API Netlink du noyau peut être utilisée par des modules pour communiquer avec des programmes d'espace utilisateur

L'API Netlink du noyau est dans net/netlink/af_netlink.c

Il est possible d'ajouter son propre protocole Netlink dans include/linux/netlink.h

#define NETLINK_ROUTE 0

/* … */

#define NETLINK_GENERIC 16

#define NETLINK_EUROGICIEL 17

294

Page 295: Présentation de la pile réseau sous gnu linux

Netlink – netlink_kernel_create

Pour créer une socket Netlink dans le noyau :

struct sock*

netlink_kernel_create(int unit,

void (*input)(struct

sock *sk, int len));

–unit : protocol Netlink–input : pointeur sur fonction appelée quand un message arrive

295

Page 296: Présentation de la pile réseau sous gnu linux

Netlink – netlink_kernel_create

Exemple de callback :

void input (struct sock *sk, int len)

{

struct sk_buff *skb;

struct nlmsghdr *nlh = NULL;

u8 *payload = NULL;

while ((skb = skb_dequeue(&sk->receive_queue))

!= NULL) {

nlh = (struct nlmsghdr *)skb->data;

payload = NLMSG_DATA(nlh);

}

}

296

Page 297: Présentation de la pile réseau sous gnu linux

Netlink – netlink_kernel_create

La fonction callback est exécutée suite à l'appel à sendmsg() en espace utilisateur

–sendmsg() est bloquante jusqu'au retour de la fonction callback

Si la fonction callback devait prendre beaucoup de temps, il faudrait déferrer son travail

Par exemple :–Un thread noyau qui lit sur la socket retournée :

skb = skb_recv_datagram(nl_sk);

–La fonction callback débloque ce thread à réception :wake_up_interruptible(sk->sleep);

297

Page 298: Présentation de la pile réseau sous gnu linux

Netlink – netlink_unicast

Pour envoyer une message unicast :

int netlink_unicast(struct sock *ssk,

struct sk_buff *skb, u32 pid, int

nonblock);

–ssk : socket retournée par netlink_kernel_create()–skb : adresses source et destination :

NETLINK_CB(skb).groups = 0;

NETLINK_CB(skb).pid = 0;

NETLINK_CB(skb).dst_groups = 0;

NETLINK_CB(skb).dst_pid = dst_pid;

–pid : PID du processus visé–nonblock : API bloquante ou non

298

Page 299: Présentation de la pile réseau sous gnu linux

Netlink – netlink_broadcast

Pour envoyer une message multicast :

int netlink_broadcast(struct sock *ssk, struct

sk_buff *skb, u32 pid, u32 group, int allocation);

–A la différence de la version unicast, on précisera les groupes :NETLINK_CB(skb).groups = dst_group;

NETLINK_CB(skb).dst_groups = dst_groups;

NETLINK_CB(skb).dst_pid = 0;

group = dst_groups;

–allocation : GFP_ATOMIC ou GFP_KERNEL

299

Page 300: Présentation de la pile réseau sous gnu linux

Netlink – netlink_broadcast

Pour envoyer une message multicast :

int netlink_broadcast(struct sock *ssk, struct

sk_buff *skb, u32 pid, u32 group, int allocation);

–A la différence de la version unicast, on précisera les groupes :NETLINK_CB(skb).dst_groups = dst_groups;

NETLINK_CB(skb).dst_pid = 0;

group = dst_groups

–allocation : GFP_ATOMIC ou GFP_KERNEL

300

Page 301: Présentation de la pile réseau sous gnu linux

Netlink – Noyau

struct sock *nl_sk = NULL;

void nl_data_ready (struct sock *sk, int len){wake_up_interruptible(sk->sleep);

}

void netlink_test(){struct sk_buff *skb = NULL;struct nlmsghdr *nlh = NULL;int err;u32 pid;

nl_sk = netlink_kernel_create(NETLINK_TEST, nl_data_ready);

skb = skb_recv_datagram(nl_sk, 0, 0, &err);

301

Page 302: Présentation de la pile réseau sous gnu linux

Netlink – Noyau

nlh = (struct nlmsghdr *)skb->data;printk("message reçcu : %s\n", NLMSG_DATA(nlh));

pid = nlh->nlmsg_pid;NETLINK_CB(skb).groups = 0;NETLINK_CB(skb).pid = 0;NETLINK_CB(skb).dst_pid = pid;NETLINK_CB(skb).dst_groups = 0;netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);

sock_release(nl_sk->socket);}

302

Page 303: Présentation de la pile réseau sous gnu linux

RTNetlink

303

Page 304: Présentation de la pile réseau sous gnu linux

RTNetlink

RTNetlink permet de lire et modifier :–Les tables de routage–Les adresses IP–Les paramètres de liaison–La configuration du voisinage–Les files, les classes de trafic et les classes de paquets

Basé sur les sockets Netlink

304

Page 305: Présentation de la pile réseau sous gnu linux

RTNetlink – Attributs

Certains messages Netlink ont des attributs supplémentaires après l'en-tête initial :

struct rtattr {

unsigned short rta_len; /* Longueur option */

unsigned short rta_type; /* Type d'option */

/* Les données suivent... */

};

Ces attributs ne doivent être manipulés qu'en utilisant les macros RTA_*

305

Page 306: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Link

RTNetlink est constitué de trois types de messages :

RTM_NEWLINK, RTM_DELLINK, RTM_GETLINK–Crée, supprime, ou renvoie des informations d'une interface réseau–Une structure ifinfomsg suivie d'une série de rtattr

struct ifinfomsg {

unsigned char ifi_family; /* AF_UNSPEC */

unsigned short ifi_type; /* Type périphérique */

int ifi_index; /* Index interface */

unsigned int ifi_flags; /* Attributs périph. */

unsigned int ifi_change; /* Masque modificat. */

};

306

Page 307: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Link

–ifi_flags : contient les attributs du périphérique (comme pour la structure ifreq)–ifi_change : réservé et doit toujours valoir 0xFFFFFFFF

–rta_type :•IFLA_ADDRESS : adresse MAC•IFLA_BROADCAST : adresse broadcast MAC•IFLA_IFNAME : nom du périphérique•IFLA_MTU : MTU du périphérique•IFLA_LINK : type de liaison•IFLA_QDISC : Mécanismes files•IFLA_STATS : struct net_device_stats

307

Page 308: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Addr

RTM_NEWADDR, RTM_DELADDR, RTM_GETADDR

–Ajoute, supprime ou renvoie des informations sur une adresse IP associée à une interface–Une structure ifaddrmsg, suivie éventuellement par une structure rtaddr

struct ifaddrmsg {

unsigned char ifa_family; /* Type adresse */

unsigned char ifa_prefixlen;/* Longueur masque */

unsigned char ifa_flags; /* Attributs adresse */

unsigned char ifa_scope; /* Portée adresse */

int ifa_index; /* Index interface */

};

308

Page 309: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Addr

–ifa_family : AF_INET ou AF_INET6–ifa_prefixlen : longueur du masque d'adresse–ifa_scope : portée de l'adresse–ifa_index : index de l'interface associée à l'adresse–ifa_flags : IFA_F_PERMANENT, IFA_F_SECONDARY

–rta_type :•IFA_ADDRESS : Adresse de l'interface•IFA_LABEL : Nom de l'interface•IFA_BROADCAST : Adresse broadcast•IFA_ANYCAST : Adresse anycast

309

Page 310: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Route

RTM_NEWROUTE, RTM_DELROUTE, RTM_GETROUTE –Crée, supprime ou renvoie des informations à propos d'une route–Une structure rtmsg suivie d'une séquence éventuelle de structures rtattr

struct rtmsg {

unsigned char rtm_family; /* Famille d'adresse */

unsigned char rtm_dst_len; /* Longueur source */

unsigned char rtm_src_len; /* Longueur dest. */

unsigned char rtm_tos; /* Filtre TOS */

unsigned char rtm_table; /* ID table routage */

unsigned char rtm_protocol;/* Cf page suivante */

unsigned char rtm_scope; /* Cf page suivante */

unsigned char rtm_type; /* Cf page suivante */

unsigned int rtm_flags;

};

310

Page 311: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Route

–Pour RTM_GETROUTE : mettre rtm_dst_len et rtm_src_len à 0 signifie obtenir toutes les entrées pour la table de routage indiquée–Pour les autres champs, sauf rtm_table et rtm_protocol, 0 est le symbole générique signifiant "toutes valeurs"–rtm_type :

•RTN_UNICAST, RTN_LOCAL, RTN_ANYCAST, RTN_MULTICAST, RTN_BLACKHOLE, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_THROW, RTN_NAT

–rtm_protocol :•RTPROT_KERNEL, RTPROT_BOOT, RTPROT_STATIC

–rtm_scope :•RT_SCOPE_UNIVERSE, RT_SCOPE_SITE, RT_SCOPE_LINK, RT_SCOPE_HOST, RT_SCOPE_NOWHERE

Page 312: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Route

–rtm_flags :•RTM_F_NOTIFY, RTM_F_CLONED

–rtm_table :•RT_TABLE_UNSPEC, RT_TABLE_DEFAULT, RT_TABLE_MAIN, RT_TABLE_LOCAL

–rta_type :•RTA_DST, RTA_SRC : adresses destination et source•RTA_IIF, RTA_OIF : interfaces d'entrée et de sortie•RTA_GATEWAY : adresse de passerelle•RTA_PRIORITY : priorité de la route•RTA_METRICS : métrique de la route

312

Page 313: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Neighbor

RTM_NEWNEIGH, RTM_DELNEIGH, RTM_GETNEIGH

–Ajoute, supprime ou renvoie des informations sur les voisinage d'un élément de table (ex : entrée ARP)–Contient une structure ndmsg

struct ndmsg {

unsigned char ndm_family;

int ndm_ifindex; /* Index interface */

__u16 ndm_state; /* États */

__u8 ndm_flags; /* Attributs */

__u8 ndm_type;

};

313

Page 314: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Neighbor

struct nda_cacheinfo

{

__u32 ndm_confirmed;

__u32 ndm_used;

__u32 ndm_updated;

__u32 ndm_refcnt;

};

–ndm_state : champ de bits :•NUD_INCOMPLETE : entrée non résolue•NUD_REACHABLE : entrée confirmée correcte•NUD_STALE : entrée expirée•NUD_DELAY : entrée en attente de time•NUD_PROBE : entrée en cours de vérification

314

Page 315: Présentation de la pile réseau sous gnu linux

RTNetlink – Messages – Neighbor

–ndm_state : (suite)•NUD_FAILED : entrée invalide•NUD_NOARP : périphérique sans cache de destination•NUD_PERMANENT : entrée permanente

–ndm_flags :•NTF_PROXY : entrée proxy Arp•NTF_ROUTER : routeur IPv6

–rta_type :•NDA_DST : adresse niveau réseau•NDA_LLADDR : adresse niveau liaison

315

Page 316: Présentation de la pile réseau sous gnu linux

RTNetlink – Exemple

/* Récupère la liste des interfaces réseau */

#include <linux/netlink.h>#include <linux/rtnetlink.h>

typedef struct nl_req_s nl_req_t;struct nl_req_s {

struct nlmsghdr hdr;struct rtgenmsg gen;

};

int main(int argc, char **argv){

int fd;struct sockaddr_nl local;struct sockaddr_nl kernel;struct msghdr rtnl_msg;struct iovec io;nl_req_t req;char reply[8192];pid_t pid = getpid();int end = 0;

fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

316

Page 317: Présentation de la pile réseau sous gnu linux

RTNetlink – Exemple

memset(&local, 0, sizeof(local));local.nl_family = AF_NETLINK;local.nl_pid = pid;local.nl_groups = 0;bind(fd, (struct sockaddr *) &local, sizeof(local));

memset(&rtnl_msg, 0, sizeof(rtnl_msg));memset(&kernel, 0, sizeof(kernel));memset(&req, 0, sizeof(req));

kernel.nl_family = AF_NETLINK;

req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));req.hdr.nlmsg_type = RTM_GETLINK;req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;req.hdr.nlmsg_seq = 1;req.hdr.nlmsg_pid = pid;req.gen.rtgen_family = AF_PACKET;

io.iov_base = &req;io.iov_len = req.hdr.nlmsg_len;rtnl_msg.msg_iov = &io;rtnl_msg.msg_iovlen = 1;rtnl_msg.msg_name = &kernel;rtnl_msg.msg_namelen = sizeof(kernel);

317

Page 318: Présentation de la pile réseau sous gnu linux

RTNetlink – Exemple

while (!end) {

int len;struct nlmsghdr *msg_ptr;struct msghdr rtnl_reply;struct iovec io_reply;

memset(&io_reply, 0, sizeof(io_reply));memset(&rtnl_reply, 0, sizeof(rtnl_reply));

io.iov_base = reply;io.iov_len = IFLIST_REPLY_BUFFER;

rtnl_reply.msg_iov = &io;rtnl_reply.msg_iovlen = 1;rtnl_reply.msg_name = &kernel;rtnl_reply.msg_namelen = sizeof(kernel);

len = recvmsg(fd, &rtnl_reply, 0);

318

Page 319: Présentation de la pile réseau sous gnu linux

RTNetlink – Exemple

if (len) {

for (msg_ptr = (struct nlmsghdr *) reply; NLMSG_OK(msg_ptr, len); msg_ptr = NLMSG_NEXT(msg_ptr, len))

{switch(msg_ptr->nlmsg_type){case 3: /* NLMSG_DONE */

end++;break;

case 16: /* RTM_NEWLINK */rtnl_print_link(msg_ptr);break;

default:}

}}

}

close(fd);}

319

Page 320: Présentation de la pile réseau sous gnu linux

RTNetlink – Exemple

void rtnl_print_link(struct nlmsghdr *h){

struct ifinfomsg *iface;struct rtattr *attribute;int len;

iface = NLMSG_DATA(h);len = h->nlmsg_len - NLMSG_LENGTH(sizeof(*iface));

for (attribute = IFLA_RTA(iface); RTA_OK(attribute, len); attribute = RTA_NEXT(attribute, len)) {

switch(attribute->rta_type) {case IFLA_IFNAME:

printf("Interface %d : %s\n", iface->ifi_index, (char *) RTA_DATA(attribute));break;

default:break;

}}

}

320

Page 321: Présentation de la pile réseau sous gnu linux

Environ 10000 lines of code in the Linux Kernel ;Travaux initiés par Sébastien Barré ;Désormais 3 threads actifs sont suivis coté développement

noyau par :Christoph PaaschFabien DuchêneGregory Detal

Disponible gratuitement : http://mptcp.info.ucl.ac.be

MPTCP (MultiPath TCP)

Page 322: Présentation de la pile réseau sous gnu linux

Entête MPTCP

Source Port Destination Port

Sequence Number

Acknowledgment Number

Receive WindowHeader

LengthReserved Code bits

Checksum

Options

Urgent Pointer

Data

Bit 0 Bit 15 Bit 16 Bit 31

20

Bytes

0 - 40

Bytes

Subflow

Subflow

Subflow Subflow

Data sequence number Data ACK

Page 323: Présentation de la pile réseau sous gnu linux

Création d’une session MPTCP

Page 324: Présentation de la pile réseau sous gnu linux

Création d’une socket TCP

Page 325: Présentation de la pile réseau sous gnu linux

Création d’une socket MPTCP

Page 326: Présentation de la pile réseau sous gnu linux

Création d’une méta-socket par le noyau

Page 327: Présentation de la pile réseau sous gnu linux

Création de nouveau subflow

Page 328: Présentation de la pile réseau sous gnu linux

Association des différents MPTCP subflow par le noyau

Page 329: Présentation de la pile réseau sous gnu linux

7. Captures & simulations

–Captures réseau (tcpdump, wireshark, …)–Outils de monitoring (iptraf, iperf, …)–Utilisation de la librairie libpcap–Présentation de NS2/3

Page 330: Présentation de la pile réseau sous gnu linux

Outils

Il existes pléthore d’outils :–Tcpprobe– iperf–netperf–netPIPE–gensink–Ttcp–curl-loader–Nttcp–n-u-t-t-c-p–ISIC–tcpdump / wireshark–…

http://www.ubuntugeek.com/bandwidth-monitoring-tools-for-linux.html

Page 331: Présentation de la pile réseau sous gnu linux

TCPDUMP

tcpdump est un analyseur de paquets en ligne de commande. Il permet d'obtenir le détail du

trafic visible depuis une interface réseau. L'outil distribué par les distributions GNU/Linux,

FreeBSD, NetBSD, OpenBSD et Mac OS X dépend de la bibliothèque logicielle libpcap. Leur

portage sous Windows est connu sous les appellations WinPCAP/WinDUMP.

tcpdump et libpcap sont développés en 1987 au laboratoire national Lawrence Berkeley aux

États-Unis par Van Jacobson, Steven McCanne et Craig Leres, le créateur d'arpwatch. Vers la

fin des années 1990, tcpdump est distribué dans de nombreux systèmes ce qui ne favorisait

guère l'application de correctifs. Michael Richardson (mcr) et Bill Fenner créent un site officiel

en 1999 pour répondre à ce manque de coordination et deviennent alors les mainteneurs du

projet.

La bibliothèque logicielle libpcap est à l'origine développée pour l'outil tcpdump mais peut être

utilisée par tous les analyseurs de paquets. Elle fournit en effet une interface de programmation

pour de tels programmes leur permettant de capturer et d'analyser n'importe quel paquet

(réseau) à partir d'un périphérique réseau (en). La librairie est également distribuée

séparément pour compiler ou programmer soi-même de tels outils.

Page 332: Présentation de la pile réseau sous gnu linux

TCPDump

tcpdump [ -AdDefIKlLnNOpqRStuUvxX ] [ -B buffer_size ] [ -c count ]

[ -C file_size ] [ -G rotate_seconds ] [ -F file ]

[ -i interface ] [ -m module ] [ -M secret ]

[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]

[ -W filecount ]

[ -E spi@ipaddr algo:secret,... ]

[ -y datalinktype ] [ -z postrotate-command ] [ -Z user ]

[ expression ]

Page 333: Présentation de la pile réseau sous gnu linux

TCPDUMP

Cette commande va capturer les paquets et sauvegarder le tout dans le fichier

capture.dump:

# tcpdump -v -r capture.dump

Si vous souhaitez maintenant afficher le contenu de ce fichier avec l'option -r, il faut

taper la commande:

reading from file capture.dump, link-type EN10MB (Ethernet)

13:28:09.495897 IP (tos 0x0, ttl 64, id 47730, offset 0, flags [DF], proto: TCP (6),

length: 52) 192.168.29.246.49084 > ftp.fu-berl

in.de.60772: ., cksum 0x13d0 (correct), ack 1339443207 win 2003

13:28:09.503376 IP (tos 0x0, ttl 64, id 47731, offset 0, flags [DF], proto: TCP (6),

length: 52) 192.168.29.246.49084 > ftp.fu-berl

in.de.60772: ., cksum 0x0e1d (correct), ack 1449 win 2003

13:28:09.506374 IP (tos 0x0, ttl 64, id 47732, offset 0, flags [DF], proto: TCP (6),

length: 52) 192.168.29.246.49084 > ftp.fu-berl

in.de.60772: ., cksum 0x0872 (correct), ack 2897 win 2003

Page 334: Présentation de la pile réseau sous gnu linux

TCPDUMP

Quelques exemples (consulter le man tcpdump pour une liste exhaustive):

# tcpdump host www.google.fr

Affiche seulement les paquets qui ont pour adresse source ou destination www.google.fr:

# tcpdump dst www.google.fr

Affiche seulement les paquets qui ont pour adresse destination www.google.fr

# tcpdump port http

Affiche seulement les paquets HTTP (web):

# tcpdump proto gre

Affiche seulement les paquets GRE (utilisés lors de tunnel ipsec). Il est bien sur possible de

mixer plusieurs filtres:

# tcpdump dst 192.168.29.10 and port domain

Affiche tous les paquets DNS (domain) à destination de l'adresse 192.168.29.10

Page 335: Présentation de la pile réseau sous gnu linux

TCPDUMP

# tcpdump –v

...

11:34:23.480144 IP (tos 0x0, ttl 64, id 10784, offset 0, flags [DF], proto: UDP (17), length: 67) 192.168.29.246.32794 >

192.168.29.1.domain: 8576+ A? ftp.redhat.ikoula.com. (39)

...

On peut alors voir les informations supplémentaires suivantes:

(tos 0x0, ttl 64, id 10784, offset 0, flags [DF], proto: UDP (17), length: 67)

Associés au champs IP, elle fournie des informations sur le protocole (flags, protocole UDP, taille du paquet...).

8576+ A? ftp.redhat.ikoula.com. (39)

Donne un apercu du champ data (dans notre exemple, on peut voir que c'est une requête DNS qui demande l'adresse

IP du serveur ftp.redhat.ikoula.com)

Si vous voulez encore plus d'informations, vous pouvez utiliser les options -vv et même –vvv. Si vous souhaité avoir

un dump du contenu du de chaque paquet, vous pouvez utiliser l'option -A, par exemple:

# tcpdump -v –A

11:46:00.607145 IP (tos 0x0, ttl 64, id 33771, offset 0, flags [DF], proto: TCP (6), length: 765) 192.168.29.157.49659 >

mu-in-f104.google.com.http: P 1543672215:1543672940(725) ack 1290089933 win 65535

E.....@.@.}......U.h...P...L.5.P...9...GET / HTTP/1.1

Host: www.google.fr

User-

Page 336: Présentation de la pile réseau sous gnu linux

WIRESHARK

Wireshark est un analyseur de paquets libre utilisé dans le dépannage et l'analyse de

réseaux informatiques, le développement de protocoles, l'éducation et la rétro-ingénierie. Son

appellation d'origine (Ethereal) est modifiée en mai 2006 pour des questions relatives au droit

des marques.

Wireshark utilise la bibliothèques logicielles GTK+ pour l'implémentation de son interface

utilisateur et pcap pour la capture des paquets; il fonctionne sur de nombreux environnements

compatibles UNIX comme GNU/Linux, FreeBSD, NetBSD, OpenBSD ou Mac OSX, mais

également sur Microsoft Windows.

Wireshark reconnaît 759 protocoles.

À la fin des années 1990, Gerald Combs est diplômé de l'Université du Missouri-Kansas City

et travaille au sein d'un petit fournisseur d'accès à Internet. L'analyseur de protocole utilisé en

interne est un logiciel propriétaire commercialisé près de 1500 $2 et ne fonctionne pas sur la

plateforme de production de la société (GNU/Linux et Solaris). Gerald Combs débute alors les

développements d'Ethereal et réalise sa première version en 19983.

En mai 2006, Combs intègre la société CACE Technologies. Il clone alors le dépôt SVN du

projet Ethereal sur son propre dépôt de code source Wireshark en toute légalité puisqu'il

détient les droits d'auteur sur la majeure partie du code source d'Ethereal, le reste étant

également distribué selon les termes de la licence publique générale GNU. Il n'est toutefois pas

propriétaire de la marque Ethereal et change donc le nom de son projet en Wireshark.

Page 337: Présentation de la pile réseau sous gnu linux

WIRESHARK

http://www.thegeekstuff.com/2010/08/tcpdump-command-examples/

Page 338: Présentation de la pile réseau sous gnu linux

WIRESHARK

Mesure de la bande passante :

Page 339: Présentation de la pile réseau sous gnu linux

WIRESHARK

Statistics > Summary

Page 340: Présentation de la pile réseau sous gnu linux

IPERF

iperf -s

------------------------------------------------------------

Server listening on TCP port 5001

TCP window size: 60.0 KByte (default)

------------------------------------------------------------

[ 4] local <IP Addr node2> port 5001 connected with <IP Addr node1> port 2357

[ ID] Interval Transfer Bandwidth

[ 4] 0.0-10.1 sec 6.5 MBytes 5.2 Mbits/sec

Iperf est un logiciel informatique permettant la mesure de différentes variables

d'une connexion réseau IP. Iperf est développé par le National Laboratory for

Applied Network Research (NLANR, États-Unis d'Amérique). Basé sur une

architecture client/serveur et disponible sur différents systèmes d'exploitation (Unix,

Windows, MacOS X,...).

Iperf doit être lancé sur deux machines se trouvant de part et d'autre du réseau à

tester. La première machine lance Iperf en "mode serveur" (avec l'option -s), la

seconde en "mode client" (option -c). Par défaut le test réseau se fait en utilisant le

protocole TCP (mais il est également possible d'utiliser le mode UDP avec l'option -

u).

Page 341: Présentation de la pile réseau sous gnu linux

IPERF

Page 342: Présentation de la pile réseau sous gnu linux

IPTRAF

Page 343: Présentation de la pile réseau sous gnu linux

Ip traffic monitor : vous allez pouvoir voir toutes les connections entrantes et

sortantes, les ports et protocoles, ainsi que les IP des connexions….un peu

brouillon, mais cela permet de voir precisement pour une IP le volume de data qui

transite

General interface statistics : c’est le menu du volume brut qui transite

Detailled interface statistics : vous devez indiquer quelle interface vous désirez

voir, et vous aurez des statistiques détaillées de son utilisation (entrée et sortie,

TCP et UDP, IP et non IP, icmp, broadcast….), c’est très intéressant.

Statistical breakdowns : information par paquet ou par protocole transitant par

une interface, assez intéressant à étudier.

Lan station monitor : les adresses macs et le volume de donnée transitant par

elles….inutile donc indispensable

Page 344: Présentation de la pile réseau sous gnu linux

Mesure TCP

Lorsque l’on expérimente autour de bande passante variable il peut être

nécessaire de changer la taille maximum de la fenêtre TCP disponible. La couche

TCP est paramétrable (Documentation/networking/ip-sysctl.txt). Lorsqu’un le

minimum est atteint, tcp_rmem[2] est incrémenté pour le reçeveur et

tcp_wmem[2] pour l’émetteur et ce deux fois.

Il peut être aussi nécessaire de de désactiver les métrique lié aux routes :

sysctl -w net.ipv4.tcp_no_metrics_save=1

Normalement Linux doit se souvenir du dernier démarrage lent (ssthresh). Cela

modifiera le résultat du prochain test et causera une erreur

Page 345: Présentation de la pile réseau sous gnu linux

Mesure TCP

A basic test would be:

Start iperf server on the receiver : iperf -s

Insert tcp_probe module (as root) on sending machine and filter for iperf port. You can change the mode to allow non-root user

access: modprobe tcp_probe port=5001

chmod 444 /proc/net/tcpprobe

Capture tcp probe output (on sender) and place in background

cat /proc/net/tcpprobe >/tmp/tcpprobe.out & TCPCAP=$!

Run iperf test on sender for 15 minutes : iperf -i 10 -t 300 -c receiver

Kill capture process

kill $TCPCAP

The tcp probe capture file will contain one line for each packet sent.

0.073678 10.8.0.54:38644 192.168.1.42:5001 24 0xb6b19bb 0xb6b19bb 2 2147483647 5792

^ ^ ^ ^ ^ ^ ^ ^ ^

| | | | | | | | +- [9] Send window

| | | | | | | +------------ [8] Slow start threshold

| | | | | | +-------------- [7] Congestion window

| | | | | +------------------------ [6] Unacknowledged sequence #

| | | | +---------------------------------- [5] Next send sequence #

| | | +------------------------------------- [4] Bytes in packet

| | +------------------------------------------------------- [3] Receiver address:port

| +----------------------------------------------------------------------- [2] Sender address:port

+-------------------------------------------------------------------------------- [1] Time seconds

* The value of slow start threshold here is (-1) which means it hasn't been determined yet

Page 346: Présentation de la pile réseau sous gnu linux

Mesure TCP

This text file can be easily filtered and modified with standard tools such as awk and perl. A common usage is to make a plot

of congestion window and slow start threshold over time using gnuplot.

$ gnuplot -persist <<"EOF"

set data style linespoints

show timestamp

set xlabel "time (seconds)"

set ylabel "Segments (cwnd, ssthresh)"

plot "/tmp/tcpprobe.out" using 1:7 title "snd_cwnd", \

"/tmp/tcpprobe.out" using 1:($8>=2147483647 ? 0 : $8) title "snd_ssthresh"

EOF

The result should look something like this:

Page 347: Présentation de la pile réseau sous gnu linux

pcap

pcap (« packet capture ») est une interface de programmation permettant de capturer un

trafic réseau. Elle est implémentée sous les systèmes GNU/Linux, FreeBSD, NetBSD,

OpenBSD et Mac OS X au sein de la librairie libpcap. WinPcap est le portage sous Windows

de libpcap.

Les outils de supervision réseau peuvent utiliser pcap et/ou WinPcap afin de capturer les

paquets transitant sur le réseau. Les versions récentes permettent également de transmettre

des paquets sur la couche de liaison.

libpcap et WinPcap permettent aussi de sauvegarder les paquets capturés dans un fichier, et

la lecture de fichiers provenant de captures précédentes. Des applications peuvent être

développées utilisant libpcap ou WinPcap pour pouvoir capturer du trafic réseau, le lire,

l’enregistrer et l’analyser.

libpcap et Winpcap fournissent l’outil de filtrage et de capture de paquets qu'utilisent de

nombreux logiciels libres ou commerciaux d’analyse de trafic, allant des analyseurs de

protocoles, moniteurs réseaux aux systèmes de détection d’intrusion, générateurs de trafic et

testeurs de réseau.

libpcap a été initialement écrit par les développeurs de tcpdump au laboratoire national

Lawrence Berkeley. Le code de capture bas niveau, de lecture et d'écriture de fichiers de

tcpdump a été extrait et transformé en bibliothèque. libpcap est toujours développé sur le site

tcpdump.org.

Page 348: Présentation de la pile réseau sous gnu linux

PCAP

#include <pcap.h>

#include <stdio.h>

int main(int argc, char *argv[])

{

pcap_t *handle; /* Session handle */

char *dev; /* The device to sniff on */

char errbuf[PCAP_ERRBUF_SIZE]; /* Error string */

struct bpf_program fp; /* The compiled filter */

char filter_exp[] = "port 23"; /* The filter expression */

bpf_u_int32 mask; /* Our netmask */

bpf_u_int32 net; /* Our IP */

struct pcap_pkthdr header; /* The header that pcap gives us */

const u_char *packet; /* The actual packet */

/* Define the device */

dev = pcap_lookupdev(errbuf);

if (dev == NULL) {

fprintf(stderr, "Couldn't find default device: %s\n", errbuf);

return(2);

}

/* Find the properties for the device */

if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {

fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);

net = 0;

mask = 0;

}

Page 349: Présentation de la pile réseau sous gnu linux

PCAP

/* Open the session in promiscuous mode */

handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);

if (handle == NULL) {

fprintf(stderr, "Couldn't open device %s: %s\n", somedev, errbuf);

return(2);

}

/* Compile and apply the filter */

if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {

fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));

return(2);

}

if (pcap_setfilter(handle, &fp) == -1) {

fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));

return(2);

}

/* Grab a packet */

packet = pcap_next(handle, &header);

/* Print its length */

printf("Jacked a packet with length of [%d]\n", header.len);

/* And close the session */

pcap_close(handle);

return(0);

}

Page 350: Présentation de la pile réseau sous gnu linux

PCAP

#include <stdio.h>

#include <stdlib.h>

#include <pcap.h> /* GIMME a libpcap plz! */

#include <errno.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

int main(int argc, char **argv)

{

char *dev; /* name of the device to use */

char *net; /* dot notation of the network address */

char *mask;/* dot notation of the network mask */

int ret; /* return code */

char errbuf[PCAP_ERRBUF_SIZE];

bpf_u_int32 netp; /* ip */

bpf_u_int32 maskp;/* subnet mask */

struct in_addr addr;

/* ask pcap to find a valid device for use to sniff on */

dev = pcap_lookupdev(errbuf);

/* error checking */

if(dev == NULL)

{

printf("%s\n",errbuf);

exit(1);

}

/* print out device name */

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

Page 351: Présentation de la pile réseau sous gnu linux

PCAP/* ask pcap for the network address and mask of the device */

ret = pcap_lookupnet(dev,&netp,&maskp,errbuf);

if(ret == -1)

{

printf("%s\n",errbuf);

exit(1);

}

/* get the network address in a human readable form */

addr.s_addr = netp;

net = inet_ntoa(addr);

if(net == NULL)/* thanks Scott :-P */

{

perror("inet_ntoa");

exit(1);

}

printf("NET: %s\n",net);

/* do the same as above for the device's mask */

addr.s_addr = maskp;

mask = inet_ntoa(addr);

if(mask == NULL)

{

perror("inet_ntoa");

exit(1);

}

printf("MASK: %s\n",mask);

Page 352: Présentation de la pile réseau sous gnu linux

8. Embarqué

–Système de fichiers d’un desktop–Description et utilisation d’une chaîne de cross-compilation–Description des binutils–Exemple de compilation d’un package basé sur autotools–Adaptation d’un Makefile pour la cross-compilation

Page 353: Présentation de la pile réseau sous gnu linux

Architecture d’un linux

Un ROOTFS contient habituellement :

•Des binutils : ar, ldd, strip, …

•Une chaine de compilation native: gcc, system, libraries (libc, libm, libpthread, …),

headers, …

•Un debugger : gdb

Seulement une architecture est disponible à un instant t (x86, x86-64, …).

http://www.pathname.com/fhs/

Page 354: Présentation de la pile réseau sous gnu linux

Cross-compilation

SDK (stagingdir) :

Rootfs intermédiaire / il y en a

un par architecture

Toolchain :

• gcc

• headers

• host tools

• …

Rootfs local

Gestion de version

Installation

intermédiaire

Utilisé pour la compilation

(headers), et l’édition de liens

(librairies) Real rootfs for

the

Embedded target Target

embarqué

FirmwaresFlashage

Boot

TFTP /

NFS

Installation finale

(dans le rootfs)

Page 355: Présentation de la pile réseau sous gnu linux

Les binutils

Les GNU Binutils Sont une collection d’outils utiles pour le développement :

* ld - the GNU linker.* as - the GNU assembler.* addr2line - Converts addresses into filenames and line numbers.* ar - A utility for creating, modifying and extracting from archives.* gprof - Displays profiling information.* nm - Lists symbols from object files.* objcopy - Copys and translates object files.* objdump - Displays information from object files.* ranlib - Generates an index to the contents of an archive.* readelf - Displays information from any ELF format object file.* size - Lists the section sizes of an object or archive file.* strings - Lists printable strings from files.* strip - Discards symbols.

Pour de lacross-compilation l’usage d’un prefixe est requis devant le nom des binaires (sh4-linux-ar, sh4-linux-nm, sh4-linux-strip, .... )

Page 356: Présentation de la pile réseau sous gnu linux

Librairie statique

Creating a static library is an easy task thank to the ar tool from the binutils :

$ ar –rv mystaticlibrary.a file1.o file2.o file3.o

or

$ ar –rv mystaticlibrary.a *.o

The previous command merge the three objects (test1.o, test2.o et test3.o) in one archive.

A static library is:

•a tank for ELF objects

•similar to an archive such as zip or tar

•have a .a extension

A static library is not linked but is an archive make by the ar binutil. Thus, This is possible

extract it the buildin objects.

Extracting the content of a static library use the same tool: $ ar x

mystaticlibrary.a

Some tools such as Midnight commanger (mc) can browse into.

For more information: man ar

Page 357: Présentation de la pile réseau sous gnu linux

Libraries statiques

Il est aussi possible de lister le contenu des fichiers objets inclus dans la librairie :

$ ar –t mystaticlibrary

cominter.o

com_util.o

filointer.o

miscell.o

paral.o

pilot.o

simul_api.o

spyinter.o

userint.o

La commande suivante permet de lister la liste des symboles par objets :

$ nm mystaticlibrary.a

ad_server.o:

00000099 T affichage_etat_client

00000004 C bDebugAd

00000004 C bDebugSu

U bTrace

00000390 T close_socket

cominter.o:

00000004 d bComInit

00000000 d bNoInitWarn

00000010 b bTrComInter

U : undefined (implémentation externe)

T : implémenté à l’intérieur « Pour un objet

cela liste les fonctions et pour une librairie

les fonctions par objet . »

Page 358: Présentation de la pile réseau sous gnu linux

Librairie dynamique

La création d’une librairie dynamique necessite de rassenbler les objets en un

objet ELF.$ gcc -Wall -fPIC -c test1.c –o test1.o

$ gcc -Wall -fPIC -c test2.c -0 test2.o

$ gcc -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0 test1.o

test2.o

$ ranlib libtest.so.1.0

Liste des paramètres à passer à l’éditeur de liens :

Pour plus d’information : man ld

Compiler options Definitions

-Wall include all warnings. See man page for warnings specified.

-fPIC Compiler directive to output position independent code, a characteristic required by shared libraries. Also see -fpic.

-shared Produce a shared object which can then be linked with other objects to form an executable.

-W1 Pass options to linker. In this example the options to be passed on to the linker are: ”-soname libctest.so.1”. The name passed with the ”-o” option is passed to gcc.

-o Output of operation. In this case the name of the shared object to be output will be libctest.so.1.0

Page 359: Présentation de la pile réseau sous gnu linux

Cross-compilation via des autotools

La compilation d’un package autotools se fait de la façon suivante :./configure --prefix=/usr makesudo make install Le compilateur natif gcc sera utilisé.

La cross-compilation est assez similaire au paramètre --host prêt:./configure --prefix=/usr --host=arm-linuxmakesudo make install Le cross-compilateur arm-linux-gcc sera utilisé.

Page 360: Présentation de la pile réseau sous gnu linux

Cross-compilation à base d’un Makefile

La compilation d’un package autotools se fait de la façon suivante :all: mybinarymybinary: objet1.o objet2.o

gcc $< -o [email protected]:objet1.c

gcc -c $< -o [email protected]:objet2.o

gcc -c $< -o $@

La cross-compilation est assez similaire au paramètre --host prêt:all: mybinarymybinary: objet1.o objet2.o

arm-linux-gcc $< -o [email protected]:objet1.c

arm-linux-gcc -c $< -o [email protected]:objet2.o

arm-linux-gcc -c $< -o $@

XPREFIX=arm-linux-

CC=$(XPREFIX)gcc

all: mybinary

mybinary: objet1.o objet2.o

$(CC) $< -o $@

objet1.o:objet1.c

$(CC) -c $< -o $@

objet2.o:objet2.o

$(CC) -c $< -o $@

Page 361: Présentation de la pile réseau sous gnu linux

REFERENCES

Page 362: Présentation de la pile réseau sous gnu linux

Livres / Linux

Page 363: Présentation de la pile réseau sous gnu linux

Livres / Réseau

Page 364: Présentation de la pile réseau sous gnu linux

Livres / Réseau

Page 365: Présentation de la pile réseau sous gnu linux

Livres / Réseau

Page 366: Présentation de la pile réseau sous gnu linux

Livres / Réseau

Page 367: Présentation de la pile réseau sous gnu linux

Livres / Noyau & drivers

Page 368: Présentation de la pile réseau sous gnu linux

Livres / Embarqué

Page 369: Présentation de la pile réseau sous gnu linux

LiensGNU Linux DDK : http://www.kroah.com/log/2006/05/24/#ddkLinux Device Drivers, Third Edition - Network Drivers : http://lwn.net/images/pdf/LDD3/ch17.pdfIpsysctl tutorial : http://ipsysctl-tutorial.frozentux.net/ipsysctl-tutorial.htmlLinux IP Networking : http://www.cs.unh.edu/cnrg/gherrin/linux-net.htmlUNIX IP Stack Tuning Guide : http://www.cymru.com/Documents/ip-stack-tuning.htmlPerformance Analysis of the TCP/IP Stack of Linux Kernel :http://user.informatik.uni-goettingen.de/~kperf/gaug-ifi-tb-2005-03.pdfLinux IP Masquerade mini HOWTO : http://www.ibiblio.org/pub/Linux/docs/HOWTO/translations/fr/pdf/IP-Masquerade-HOWTO.pdfPont + pare-feu + DSL Mini-HOWTO :http://www.ibiblio.org/pub/Linux/docs/HOWTO/translations/fr/pdf/Bridge+Firewall+DSL.pdfMini How-To sur la configuration de l’aliasing IP sous Linux : http://www.ibiblio.org/pub/Linux/docs/HOWTO/translations/fr/pdf/IP-Alias.pdfLinux Network Administrators Guide : http://tldp.org/LDP/nag2/nag2.pdfThe Linux Networking Overview HOWTO : http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/pdf/Networking-Overview-HOWTO.pdfTCP/IP Stack Hardening : http://www.cromwell-intl.com/security/security-stack-hardening.htmlVoyage au centre de la pile TCP/IP de Linux : http://asyd.net/docs/kernel/tcpip-stack.html

A Measurement Study of the Linux TCP/IP Stack Performance and

Scalability on SMP systems : http://www.cse.iitb.ac.in/~varsha/allpapers/mypapers/comswarepaper.pdf

Berkeley sockets : http://en.wikipedia.org/wiki/Berkeley_sockets

Linux TCP/IP Stack : http://www.cs.odu.edu/~csi/tcpipstack.ppt

IP & Ethernet Interfaces : http://www.beyondlogic.org/etherip/ip.htm

Implementation of TCP/IP in Linux : http://netweb.usc.edu/~rsinha/docs/tcp-ip.ppt

Conception du sous-système réseau de linux : http://lacl.univ-paris12.fr/cegielski/reseau.html

Page 370: Présentation de la pile réseau sous gnu linux

Liens

Serial Line IP Implementation for Linux Kernel TCP/IP Stack : http://www.cse.iitb.ac.in/~bestin/pdfs/slip.pdf

HOWTO du routage avancé et du contrôle de trafic sous Linux :

http://www.ibiblio.org/pub/Linux/docs/HOWTO/translations/fr/pdf/lartc.pdf

Linux NAT HOWTO : http://www.linux-france.org/prj/inetdoc/guides/NAT-HOWTO/

Linux Packet Filtering HOWTO : http://www.linux-france.org/prj/inetdoc/guides/packet-filtering-HOWTO/

Linux inetdoc : http://www.linux-france.org/prj/

Linux IPv6 HOWTO : http://cvs.tldp.org/go.to/LDP/LDP/users/Peter-Bieringer/Linux+IPv6-HOWTO.fr.pdf

Nisnet (network emulator) : http://www-x.antd.nist.gov/nistnet/

TCPStackPerformance : http://www.gelato.unsw.edu.au/IA64wiki/TCPStackPerformance

Anatomy of the Linux networking stack :

http://www.ibm.com/developerworks/linux/library/l-linux-networking-stack/

Guide pratique du multicast sur les réseaux TCP/IP :

http://www.ibiblio.org/pub/Linux/docs/HOWTO/translations/fr/pdf/Multicast-HOWTO.pdf

Historique de la stack IP :

http://www.linuxfranch-county.org/docs/guideLLLinux/implementation_reseau_5-2.pdf

Fonctions réseau du noyau Linux : http://www.linux-france.org/prj/inetdoc/telechargement/interco.noyau.pdf

Understanding Linux Network Internals :

http://book.chinaunix.net/special/ebook/oreilly/Understanding_Linux_Network_Internals/

Algorithmic Complexity Attacks and the Linux Networking Code :

http://www.enyo.de/fw/security/notes/linux-dst-cache-dos.html

Linux Network Stack Walkthrough :

http://gicl.cs.drexel.edu/people/sevy/network/Linux_network_stack_walkthrough.html

Data Link Layer : http://lion.cs.uiuc.edu/courses/cs498hou_spring05/lectures/lecture8.pdf

skb - Linux network buffers : http://ftp.gnumonks.org/pub/doc/skb-doc.html

Page 371: Présentation de la pile réseau sous gnu linux

Paris240-244

Avenue Pierre-Brossolette

92240 MalakoffTel: +33 1 49 65 63 00

Nantes2, rue du Tyrol

104 rue Leinster – Bât.CLe Parc du Vieux Moulin

44240 La Chapelle sur Erdre

Tel: +33 2 72 64 40 17

Toulouse417 L’Occitane

BP 4750631675 Labège Cedex

Tel: +33 5 61 00 79 79

Sophia-AntipolisBâtiment Frégate

2400 route des Crêtes06560 Sophia-

AntipolisTel: +33 4 92 91 36 36

BristolEurogiciel at Voith Unit 23 Ape

Court, WoodlandsAlmondsbury Bristol BS32KJ

UNITED KINGDOMTel: +441 454 275 610

RennesCentre Affaires Alizés

La Rigourdière35510 Cesson SévignéTel: +33 2 28 23 21 00

BordeauxDomaine Millenium6 avenue Henri Le

Chatelier33700 Mérignac

Tel: +33 5 57 92 38 38

MarseilleImm. Optimum, Bât C165 avenue du Marin

Blanc13400 Aubagne

Tel: +33 4 42 72 19 19

MunichNymphenburger Str.4

80335 MünchenGERMANY

Tel: +49 89 208 0270

TunisPôle Technologique Gazala

BP432088 Ariana

TUNISIETel: +216 71 857 778

Principales références

Implantations

www.eurogiciel.fr – [email protected]

ACTIA - Aerolia - Afpa - Airbus - Air France-KLM - Air Liquide - Alstom - Amadeus - Ansaldo - ArcelorMittal - Areva - Banque Populaire - BouyguesTelecom - Caisse d’Epargne - CEA - Cegedim Activ - Cegelec - CLS - CNES - Continental - Cultura - Dassault Aviation - DCNS - DGA - EADS - EDF - ELTA -Envivio - Euler Hermes – Eurocopter - France Télévisions - GDF Suez - Latécoère - Hermès – Honeywell - INTEL - Intercontrole - IRSN - Labinal - LaPoste - Lafarge - Lectra - Leroy-Somer - Liebherr - MMA - Ministère de l’Agriculture – Ministère de l’Ecologie, du Développement durable, desTransports et du Logement - Ministère de l’Education Nationale - Monaco Telecom - Nagravision - Nexter Orange - Panasonic - Pierre Fabre - PSA –RATP - Recaéro - RIETER - Rockwell Collins - Rolls Royce - Safran - Saft - Sanofi - Siemens - Technicolor - SmarDTV - SNCF - Société Générale - Thales -Tisséo - TOTAL - Viaccess - ZODIAC

Ch

arte

Gra

ph

iqu

e EU

RO

GIC

IEL

Ingé

nie

rie

VF-

v2_0