Passons rapidement en revue les fichiers des périphériques: sous Linux, les programmes d'application communiquent les opérations rad et d'écriture au noyau via des descripteurs de fichiers . Cela fonctionne très bien pour les fichiers, et il s'est avéré que la même API pouvait être utilisée pour les périphériques de caractères qui produisent et consomment des flux de caractères, et bloquent les périphériques qui lisent et écrivent des blocs de taille fixe à une adresse d'accès aléatoire, simplement en faisant semblant que ces sont également des fichiers.
Mais un moyen était nécessaire pour configurer ces périphériques (définir les débits en bauds, etc.), et pour cela, l' appel ioctl a été inventé. Il transmet simplement une structure de données spécifique au périphérique et au type de contrôle d'E / S utilisé pour le noyau, et récupère les résultats dans la même structure de données, c'est donc une API extensible très générique et peut être utilisée pour beaucoup de choses .
Maintenant, comment les opérations réseau s'intègrent-elles? Une application serveur de réseau typique veut se lier à une adresse réseau, écouter sur un certain port (par exemple 80 pour HTTP ou 22 pour ssh), et si un client se connecte , il veut envoyer et recevoir des données de ce client. Et la double opération pour le client.
Il n'est pas évident de savoir comment intégrer cela aux opérations sur les fichiers (bien que cela puisse être fait, voir Plan 9 ), c'est pourquoi les concepteurs UNIX ont inventé une nouvelle API: les sockets . Vous trouverez plus de détails dans la section 2 pages de manuel socket
, bind
, listen
, connect
, send
et recv
. Notez que bien qu'il soit distinct de l'API d'E / S de fichiers, l' socket
appel renvoie néanmoins également un descripteur de fichier. Il existe de nombreux didacticiels sur la façon d'utiliser les sockets sur le Web, google un peu.
Jusqu'à présent, tout cela est purement UNIX, personne ne parlait des interfaces réseau au moment où les sockets ont été inventées. Et parce que cette API est vraiment ancienne, elle est définie pour une variété de protocoles réseau au-delà du protocole Internet (regardez les AF_*
constantes), bien que seuls quelques-uns soient pris en charge sous Linux.
Mais comme les ordinateurs ont commencé à obtenir plusieurs cartes réseau, une certaine abstraction était nécessaire. Sous Linux, c'est l' interface réseau (NI). Il n'est pas seulement utilisé pour un morceau de matériel, mais aussi pour divers tunnels, points de terminaison d'application utilisateur qui servent de tunnels comme OpenVPN etc. Comme expliqué, l'API socket n'est pas basée sur des fichiers (spéciaux) et indépendante du système de fichiers. De la même manière, les interfaces réseau n'apparaissent pas non plus dans le système de fichiers. Cependant, les NI sont disponibles dans le système de fichiers /proc
et /sys
(ainsi que dans d'autres paramètres de mise en réseau).
Un NI est une simple abstraction du noyau d'un point de terminaison où les paquets réseau entrent et sortent du noyau. Les sockets, en revanche, sont utilisées pour communiquer les paquets avec les applications. Aucun socket ne doit être impliqué dans le traitement d'un paquet. Par exemple, lorsque le transfert est activé, un paquet peut entrer sur un NI et en sortir sur un autre. En ce sens, les sockets et les interfaces réseau sont totalement indépendants.
Mais il devait y avoir un moyen de configurer les NI, tout comme vous aviez besoin d'un moyen de configurer les blocs et les périphériques de caractères. Et puisque les sockets ont déjà renvoyé un descripteur de fichier, il était quelque peu logique d'autoriser simplement un ioctl
sur ce descripteur de fichier. C'est l' interface netdevice que vous avez liée.
Il existe de nombreux autres abus des appels système de la même manière, par exemple pour le filtrage de paquets, la capture de paquets, etc.
Tout cela s'est développé morceau après morceau, et n'est pas particulièrement logique dans de nombreux endroits. S'il avait été conçu en une seule fois, on aurait probablement pu faire une API plus orthogonale.