next up previous contents
Next: INET-Socket Up: Netzwerkkommunikation Previous: Netzwerkkommunikation   Contents

BSD-Socket

Als Programmierer benutzt man die Socket-Schnittstelle die in der C-Bibliothek zur Verfügung gestellt wird. Diese besteht aus den folgenden Funktionen:

int socket(int domain, int type, int protocol);

int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);

int listen(int s, int backlog);

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

int send(int s, const void *msg, size_t len, int flags);

int sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);

int recv(int s, void *buf, size_t len, int flags);

int recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);

int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);

int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);

Erzeugt man mit socket() einen Socket, so gibt diese Funktion einen Dateideskriptor zurück über den man mit den anderen Funktionen den Socket benutzen kann. Es können auch normale I/O-Systemaufrufe wie write() und read() benutzt werden.

Diese Socket-Funktionen werden allein durch den Systemaufruf sys_socketcall() im Kernel implementiert [net/socket.c]:

asmlinkage long sys_socketcall(int call, unsigned long *args)
Dies ist eine der typischen Multiplexer-Systemaufrufe. call gibt an welcher Funktionsaufruf genau gemeint ist, gefolgt von der dynamischen Liste an Parametern. sys_socketcall() ruft dann die entsprechenden sys_ Funktionen (z.B. sys_socket()) mit den passenden Parametern auf. Diese Funktionen bilden die oberste Schicht der Netzwerkimplementation im Linux-Kernel: die BSD-Socketschicht.

Eine der wichtigsten Strukturen innerhalb des Kernels ist die struct socket [include/linux/net.h]:

struct socket { 
  socket_state state;
Hier wird der aktuelle Zustand des Sockets gespeichert. Z.B.: SS_CONNECTED oder SS_UNCONNECTED [include/linux/net.h].

  unsigned long flags;
Flags die bestimmte Eigenschaften des Sockets beschreiben (z.B. asynchron, nicht blockierend).

  struct proto_ops *ops;
Enthält für Sockets der AF_INET Adressfamilie spezifische Operationen (als Funktionspointer).

  struct inode *inode; 
  struct fasync_struct *fasync_list; 
  struct file *file;
Werden für Sockets der AF_UNIX Adressfamilie benötigt, um einen Socket einer Inode/Datei im Filesystem zuzuordnen.

  struct sock *sk;
Unterstruktur für die AF_INET Adressfamilie.

  wait_queue_head_t wait; 
  short type;
Gibt den Typ des Sockets an. Gültige Werte sind SOCK_STREAM (TCP), SOCK_DGRAM (UDP) und SOCK_RAW (IP) [include/asm/socket.h].

  unsigned char passcred;

};

Eine weitere wichtige Struktur ist die struct sk_buff welche zur Verwaltung einzelner Datenpakete verwendet wird ([include/linux/skbuff.h], Auszugsweise da sehr umfangreich):

struct sk_buff { 
  /* These two members must be first. */ 
  struct sk_buff * next;       /* Next buffer in list */ 
  struct sk_buff * prev;       /* Previous buffer in list */ 
  struct sk_buff_head * list;  /* List we are on */ 
  struct sock *sk;             /* Socket we are owned by */ 
  struct timeval stamp;        /* Time we arrived */ 
  struct net_device *dev;      /* Device we arrived on/are leaving by */ 
 
  /* Transport layer header */ 
  union { 
    struct tcphdr *th; 
    struct udphdr *uh; 
    struct icmphdr *icmph; 
    struct igmphdr *igmph; 
    struct iphdr *ipiph; 
    struct spxhdr *spxh; 
    unsigned char *raw; 
  } h; 
 
  /* Network layer header */ 
  union { 
    struct iphdr *iph; 
    struct ipv6hdr *ipv6h; 
    struct arphdr *arph; 
    struct ipxhdr *ipxh; 
    unsigned char *raw; 
  } nh; 
 
  /* Link layer header */ 
  union { 
    struct ethhdr *ethernet; 
    unsigned char *raw; 
  } mac; 
 
... 
 
  struct dst_entry *dst; 
 
  unsigned int truesize;  /* Buffer size */ 
  unsigned char *head;    /* Head of buffer */ 
  unsigned char *data;    /* Data head pointer */ 
  unsigned char *tail;    /* Tail pointer */ 
  unsigned char *end;     /* End pointer */ 
 
... 
 
};
Diese Struktur verwaltet einen allgemeinen Puffer, der bei der Übertragung von Daten zwischen den einzelnen Schichten verwendet wird. Dazu wird unter anderem das physikalische Netzwerkgerät in einem struct net_device gespeichert über das das Paket übertragen wird. Weiterhin werden jeweils ein Pointer auf die jeweiligen Header-Strukturen des transport, network und link layers innerhalb des Puffers gespeichert. dst_entry ist eine Struktur die das Ziel des Pakets definiert [include/net/dst.h].

Die in [net/socket.c] implementierten Funktionen greifen über den ops Eintrag des struct socket auf die spezifischen Funktionen der INET-Socket Schicht zurück.


next up previous contents
Next: INET-Socket Up: Netzwerkkommunikation Previous: Netzwerkkommunikation   Contents
2002-02-17