root/net/inet/protocol.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. inet_get_protocol
  2. inet_add_protocol
  3. inet_del_protocol

   1 /*
   2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
   3  *              operating system.  INET is implemented using the  BSD Socket
   4  *              interface as the means of communication with the user level.
   5  *
   6  *              INET protocol dispatch tables.
   7  *
   8  * Version:     @(#)protocol.c  1.28    20/12/93
   9  *
  10  * Authors:     Ross Biro, <bir7@leland.Stanford.Edu>
  11  *              Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  12  *
  13  * Fixes:
  14  *              Alan Cox        : Ahah! udp icmp errors don't work because
  15  *                                udp_err is never called!
  16  *              Alan Cox        : Added new fields for init and ready for
  17  *                                proper fragmentation (_NO_ 4K limits!).
  18  *              Alan Cox        : Final clean up.
  19  *
  20  *              This program is free software; you can redistribute it and/or
  21  *              modify it under the terms of the GNU General Public License
  22  *              as published by the Free Software Foundation; either version
  23  *              2 of the License, or (at your option) any later version.
  24  */
  25 #include <asm/segment.h>
  26 #include <asm/system.h>
  27 #include <linux/types.h>
  28 #include <linux/kernel.h>
  29 #include <linux/sched.h>
  30 #include <linux/string.h>
  31 #include <linux/socket.h>
  32 #include <linux/in.h>
  33 #include "inet.h"
  34 #include "devinet.h"
  35 #include "ip.h"
  36 #include "protocol.h"
  37 #include "tcp.h"
  38 #include "socket/skbuff.h"
  39 #include "sockinet.h"
  40 #include "icmp.h"
  41 #include "udp.h"
  42 
  43 
  44 static struct inet_protocol tcp_protocol = 
  45 {
  46         tcp_rcv,                /* TCP handler          */
  47         NULL,                   /* No fragment handler (and won't be for a long time) */
  48         tcp_err,                /* TCP error control    */
  49         NULL,                   /* next                 */
  50         IPPROTO_TCP,            /* protocol ID          */
  51         0,                      /* copy                 */
  52         NULL,                   /* data                 */
  53         "TCP"                   /* name                 */
  54 };
  55 
  56 
  57 static struct inet_protocol udp_protocol = 
  58 {
  59         udp_rcv,                /* UDP handler          */
  60         NULL,                   /* Will be UDP fraglist handler */
  61         udp_err,                /* UDP error control    */
  62         &tcp_protocol,  /* next                 */
  63         IPPROTO_UDP,            /* protocol ID          */
  64         0,                      /* copy                 */
  65         NULL,                   /* data                 */
  66         "UDP"                   /* name                 */
  67 };
  68 
  69 
  70 static struct inet_protocol icmp_protocol = 
  71 {
  72         icmp_rcv,               /* ICMP handler         */
  73         NULL,                   /* ICMP never fragments anyway */
  74         NULL,                   /* ICMP error control   */
  75         &udp_protocol,          /* next                 */
  76         IPPROTO_ICMP,           /* protocol ID          */
  77         0,                      /* copy                 */
  78         NULL,                   /* data                 */
  79         "ICMP"                  /* name                 */
  80 };
  81 
  82 
  83 struct inet_protocol *inet_protocol_base = &icmp_protocol;
  84 
  85 struct inet_protocol *inet_protos[MAX_INET_PROTOS] = 
  86 {
  87         NULL
  88 };
  89 
  90 
  91 struct inet_protocol *inet_get_protocol(unsigned char prot)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93         unsigned char hash;
  94         struct inet_protocol *p;
  95 
  96         DPRINTF((DBG_PROTO, "get_protocol (%d)\n ", prot));
  97         hash = prot & (MAX_INET_PROTOS - 1);
  98         for (p = inet_protos[hash] ; p != NULL; p=p->next) 
  99         {
 100                 DPRINTF((DBG_PROTO, "trying protocol %d\n", p->protocol));
 101                 if (p->protocol == prot) 
 102                         return((struct inet_protocol *) p);
 103         }
 104         return(NULL);
 105 }
 106 
 107 
 108 void inet_add_protocol(struct inet_protocol *prot)
     /* [previous][next][first][last][top][bottom][index][help] */
 109 {
 110         unsigned char hash;
 111         struct inet_protocol *p2;
 112 
 113         hash = prot->protocol & (MAX_INET_PROTOS - 1);
 114         prot ->next = inet_protos[hash];
 115         inet_protos[hash] = prot;
 116         prot->copy = 0;
 117 
 118         /* Set the copy bit if we need to. */
 119         p2 = (struct inet_protocol *) prot->next;
 120         while(p2 != NULL) 
 121         {
 122                 if (p2->protocol == prot->protocol) 
 123                 {
 124                         prot->copy = 1;
 125                         break;
 126                 }
 127                 p2 = (struct inet_protocol *) prot->next;
 128         }
 129 }
 130 
 131 
 132 int inet_del_protocol(struct inet_protocol *prot)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134         struct inet_protocol *p;
 135         struct inet_protocol *lp = NULL;
 136         unsigned char hash;
 137         
 138         hash = prot->protocol & (MAX_INET_PROTOS - 1);
 139         if (prot == inet_protos[hash]) 
 140         {
 141                 inet_protos[hash] = (struct inet_protocol *) inet_protos[hash]->next;
 142                 return(0);
 143         }
 144 
 145         p = (struct inet_protocol *) inet_protos[hash];
 146         while(p != NULL) 
 147         {
 148                 /*
 149                  * We have to worry if the protocol being deleted is
 150                  * the last one on the list, then we may need to reset
 151                  * someones copied bit.
 152                  */
 153                 if (p->next != NULL && p->next == prot) 
 154                 {
 155                         /*
 156                          * if we are the last one with this protocol and
 157                          * there is a previous one, reset its copy bit.
 158                          */
 159                         if (p->copy == 0 && lp != NULL) 
 160                                 lp->copy = 0;
 161                         p->next = prot->next;
 162                         return(0);
 163                 }       
 164 
 165                 if (p->next != NULL && p->next->protocol == prot->protocol) 
 166                 {
 167                         lp = p;
 168                 }
 169 
 170                 p = (struct inet_protocol *) p->next;
 171         }
 172         return(-1);
 173 }

/* [previous][next][first][last][top][bottom][index][help] */