ip_lib.c

Go to the documentation of this file.
00001 /*
00002 ip_lib.c
00003 
00004 Copyright 1995 Philip Homburg
00005 */
00006 
00007 #include "inet.h"
00008 #include "buf.h"
00009 #include "event.h"
00010 #include "type.h"
00011 
00012 #include "assert.h"
00013 #include "io.h"
00014 #include "ip_int.h"
00015 
00016 THIS_FILE
00017 
00018 PUBLIC ipaddr_t ip_get_netmask (hostaddr)
00019 ipaddr_t hostaddr;
00020 {
00021         return ip_netmask(ip_nettype(hostaddr));
00022 }
00023 
00024 PUBLIC int ip_chk_hdropt (opt, optlen)
00025 u8_t *opt;
00026 int optlen;
00027 {
00028         int i, security_present= FALSE, lose_source_present= FALSE,
00029                 strict_source_present= FALSE, record_route_present= FALSE,
00030                 timestamp_present= FALSE;
00031 
00032         assert (!(optlen & 3));
00033         i= 0;
00034         while (i<optlen)
00035         {
00036                 DBLOCK(2, printf("*opt= %d\n", *opt));
00037 
00038                 switch (*opt)
00039                 {
00040                 case IP_OPT_EOL:        /* End of Option list */
00041                         return NW_OK;
00042                 case IP_OPT_NOP:        /* No Operation */
00043                         i++;
00044                         opt++;
00045                         break;
00046                 case IP_OPT_SEC:        /* Security */
00047                         if (security_present)
00048                                 return EINVAL;
00049                         security_present= TRUE;
00050                         if (opt[1] != 11)
00051                                 return EINVAL;
00052                         i += opt[1];
00053                         opt += opt[1];
00054                         break;
00055                 case IP_OPT_LSRR:       /* Lose Source and Record Route */
00056                         if (lose_source_present)
00057                         {
00058                                 DBLOCK(1, printf("2nd lose soruce route\n"));
00059                                 return EINVAL;
00060                         }
00061                         lose_source_present= TRUE;
00062                         if (opt[1]<3)
00063                         {
00064                                 DBLOCK(1,
00065                                 printf("wrong length in source route\n"));
00066                                 return EINVAL;
00067                         }
00068                         i += opt[1];
00069                         opt += opt[1];
00070                         break;
00071                 case IP_OPT_SSRR:       /* Strict Source and Record Route */
00072                         if (strict_source_present)
00073                                 return EINVAL;
00074                         strict_source_present= TRUE;
00075                         if (opt[1]<3)
00076                                 return EINVAL;
00077                         i += opt[1];
00078                         opt += opt[1];
00079                         break;
00080                 case IP_OPT_RR:         /* Record Route */
00081                         if (record_route_present)
00082                                 return EINVAL;
00083                         record_route_present= TRUE;
00084                         if (opt[1]<3)
00085                                 return EINVAL;
00086                         i += opt[1];
00087                         opt += opt[1];
00088                         break;
00089                 case IP_OPT_TS:         /* Timestamp */
00090                         if (timestamp_present)
00091                                 return EINVAL;
00092                         timestamp_present= TRUE;
00093                         if (opt[1] != 4)
00094                                 return EINVAL;
00095                         switch (opt[3] & 0xff)
00096                         {
00097                         case 0:
00098                         case 1:
00099                         case 3:
00100                                 break;
00101                         default:
00102                                 return EINVAL;
00103                         }
00104                         i += opt[1];
00105                         opt += opt[1];
00106                         break;
00107                 case IP_OPT_RTRALT:
00108                         if (opt[1] != 4)
00109                                 return EINVAL;
00110                         i += opt[1];
00111                         opt += opt[1];
00112                         break;
00113                 default:
00114                         return EINVAL;
00115                 }
00116         }
00117         if (i > optlen)
00118         {
00119                 DBLOCK(1, printf("option of wrong length\n"));
00120                 return EINVAL;
00121         }
00122         return NW_OK;
00123 }
00124 
00125 PUBLIC void ip_print_frags(acc)
00126 acc_t *acc;
00127 {
00128 #if DEBUG
00129         ip_hdr_t *ip_hdr;
00130         int first;
00131 
00132         if (!acc)
00133                 printf("(null)");
00134 
00135         for (first= 1; acc; acc= acc->acc_ext_link, first= 0)
00136         {
00137 assert (acc->acc_length >= IP_MIN_HDR_SIZE);
00138                 ip_hdr= (ip_hdr_t *)ptr2acc_data(acc);
00139                 if (first)
00140                 {
00141                         writeIpAddr(ip_hdr->ih_src);
00142                         printf(" > ");
00143                         writeIpAddr(ip_hdr->ih_dst);
00144                 }
00145                 printf(" {%x:%d@%d%c}", ntohs(ip_hdr->ih_id),
00146                         ntohs(ip_hdr->ih_length), 
00147                         (ntohs(ip_hdr->ih_flags_fragoff) & IH_FRAGOFF_MASK)*8,
00148                         (ntohs(ip_hdr->ih_flags_fragoff) & IH_MORE_FRAGS) ?
00149                         '+' : '\0');
00150         }
00151 #endif
00152 }
00153 
00154 PUBLIC ipaddr_t ip_get_ifaddr(port_nr)
00155 int port_nr;
00156 {
00157         assert(port_nr >= 0 && port_nr < ip_conf_nr);
00158 
00159         return ip_port_table[port_nr].ip_ipaddr;
00160 }
00161 
00162 PUBLIC nettype_t ip_nettype(ipaddr)
00163 ipaddr_t ipaddr;
00164 {
00165         u8_t highbyte;
00166         nettype_t nettype;
00167 
00168         ipaddr= ntohl(ipaddr);
00169         highbyte= (ipaddr >> 24) & 0xff;
00170         if (highbyte == 0)
00171         {
00172                 if (ipaddr == 0)
00173                         nettype= IPNT_ZERO;
00174                 else
00175                         nettype= IPNT_MARTIAN;
00176         }
00177         else if (highbyte < 127)
00178                 nettype= IPNT_CLASS_A;
00179         else if (highbyte == 127)
00180                 nettype= IPNT_LOCAL;
00181         else if (highbyte < 192)
00182                 nettype= IPNT_CLASS_B;
00183         else if (highbyte < 224)
00184                 nettype= IPNT_CLASS_C;
00185         else if (highbyte < 240)
00186                 nettype= IPNT_CLASS_D;
00187         else if (highbyte < 248)
00188                 nettype= IPNT_CLASS_E;
00189         else if (highbyte < 255)
00190                 nettype= IPNT_MARTIAN;
00191         else
00192         {
00193                 if (ipaddr == (ipaddr_t)-1)
00194                         nettype= IPNT_BROADCAST;
00195                 else
00196                         nettype= IPNT_MARTIAN;
00197         }
00198         return nettype;
00199 }
00200 
00201 PUBLIC ipaddr_t ip_netmask(nettype)
00202 nettype_t nettype;
00203 {
00204         switch(nettype)
00205         {
00206         case IPNT_ZERO:         return HTONL(0x00000000);
00207         case IPNT_CLASS_A:
00208         case IPNT_LOCAL:        return HTONL(0xff000000);
00209         case IPNT_CLASS_B:      return HTONL(0xffff0000);
00210         case IPNT_CLASS_C:      return HTONL(0xffffff00);
00211         default:                return HTONL(0xffffffff);
00212         }
00213 }
00214 
00215 #if 0
00216 PUBLIC char *ip_nettoa(nettype)
00217 nettype_t nettype;
00218 {
00219         switch(nettype)
00220         {
00221         case IPNT_ZERO:         return "zero";
00222         case IPNT_CLASS_A:      return "class A";
00223         case IPNT_LOCAL:        return "local";
00224         case IPNT_CLASS_B:      return "class B";
00225         case IPNT_CLASS_C:      return "class C";
00226         case IPNT_CLASS_D:      return "class D";
00227         case IPNT_CLASS_E:      return "class E";
00228         case IPNT_MARTIAN:      return "martian";
00229         case IPNT_BROADCAST:    return "broadcast";
00230         default:                return "<unknown>";
00231         }
00232 }
00233 #endif
00234 
00235 /*
00236  * $PchId: ip_lib.c,v 1.10 2002/06/08 21:35:52 philip Exp $
00237  */

Generated on Fri Apr 14 22:57:30 2006 for minix by  doxygen 1.4.6