00001
00002
00003
00004
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:
00041 return NW_OK;
00042 case IP_OPT_NOP:
00043 i++;
00044 opt++;
00045 break;
00046 case IP_OPT_SEC:
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:
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:
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:
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:
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
00237