00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00070 #include <inet/debug.h>
00071 #include <inet/datatypes.h>
00072 #include <inet/ethernet.h>
00073 #include <inet/arp.h>
00074 #include <inet/ip.h>
00075 #include <inet/system.h>
00076
00077
00085 struct ip_frame received_ip_packet;
00086
00095 struct ip_frame send_ip_packet;
00096
00097 UINT16 ip_id;
00115 INT16 process_ip_in (struct ethernet_frame* frame)
00116 {
00117
00118 UINT8 olen;
00119 UINT8 i;
00120
00121
00122
00123 IP_DEBUGOUT("Checking if IP Protocol\n\r");
00124
00125 if( frame->protocol != PROTOCOL_IP )
00126 return(-1);
00127
00128
00129 IP_DEBUGOUT("It's IP\n\r");
00130
00131 if( frame->frame_size < ETH_HEADER_LEN )
00132 return(-1);
00133
00134 if( (frame->frame_size - ETH_HEADER_LEN) < IP_HLEN )
00135 return(-1);
00136
00137
00138
00139 NETWORK_RECEIVE_INITIALIZE(frame->buf_index);
00140
00141 received_ip_packet.vihl = RECEIVE_NETWORK_B();
00142
00143
00144
00145 if( (received_ip_packet.vihl & 0xF0) != 0x40 ) {
00146 IP_DEBUGOUT("ERROR: IP is not version 4!\n\r");
00147 return(-1);
00148 }
00149
00150 IP_DEBUGOUT("IP Version 4 OK!\n\r");
00151
00152 received_ip_packet.tos = RECEIVE_NETWORK_B();
00153
00154 received_ip_packet.tlen = ((UINT16)RECEIVE_NETWORK_B()) << 8;
00155 received_ip_packet.tlen |= RECEIVE_NETWORK_B();
00156
00157 received_ip_packet.id = RECEIVE_NETWORK_B() << 8;
00158 received_ip_packet.id |= RECEIVE_NETWORK_B();
00159
00160 received_ip_packet.frags = ((UINT16)RECEIVE_NETWORK_B()) << 8;
00161 received_ip_packet.frags |= RECEIVE_NETWORK_B();
00162
00163 received_ip_packet.ttl= RECEIVE_NETWORK_B();
00164
00165 received_ip_packet.protocol= RECEIVE_NETWORK_B();
00166
00167 received_ip_packet.checksum = ((UINT16)RECEIVE_NETWORK_B()) << 8;
00168 received_ip_packet.checksum |= RECEIVE_NETWORK_B();
00169
00170 received_ip_packet.sip = (((UINT32)RECEIVE_NETWORK_B()) << 24);
00171 received_ip_packet.sip |= (((UINT32)RECEIVE_NETWORK_B()) << 16);
00172 received_ip_packet.sip |= (((UINT32)RECEIVE_NETWORK_B()) << 8);
00173 received_ip_packet.sip |= RECEIVE_NETWORK_B();
00174
00175 received_ip_packet.dip = (((UINT32)RECEIVE_NETWORK_B()) << 24);
00176 received_ip_packet.dip |= (((UINT32)RECEIVE_NETWORK_B()) << 16);
00177 received_ip_packet.dip |= (((UINT32)RECEIVE_NETWORK_B()) << 8);
00178 received_ip_packet.dip |= RECEIVE_NETWORK_B();
00179
00180
00181
00182
00183 if((received_ip_packet.dip != localmachine.localip )&&
00184 (received_ip_packet.dip != IP_BROADCAST_ADDRESS)) {
00185
00186
00187
00188
00189 IP_DEBUGOUT("IP address does not match!\n\r");
00190
00191 if( received_ip_packet.protocol != IP_ICMP)
00192 return(-1);
00193
00194
00195
00196 for(i=0; i<PHY_ADR_LEN; i++)
00197 {
00198 if(frame->destination[i] != localmachine.localHW[i])
00199 return(-1);
00200 }
00201
00202 }
00203
00204
00205
00206
00207 olen = ((received_ip_packet.vihl & 0x0F) << 2) - IP_MIN_HLEN;
00208
00209
00210
00211 if(olen > MAX_IP_OPTLEN) {
00212 IP_DEBUGOUT("ERROR:Size of maximum allowed IP option lengt exceeded!\n\r");
00213 return(-1);
00214 }
00215
00216 if( olen > (frame->frame_size - ETH_HEADER_LEN - IP_HLEN) ) {
00217 IP_DEBUGOUT("ERROR:IP option field too long!\n\r");
00218 return(-1);
00219 }
00220
00221 for( i=0; i < olen; i++ ) {
00222 received_ip_packet.opt[i] = RECEIVE_NETWORK_B();
00223 IP_DEBUGOUT("IP Options..\n\r");
00224 }
00225
00226 if(received_ip_packet.tlen > (frame->frame_size - ETH_HEADER_LEN) ) {
00227 IP_DEBUGOUT("ERROR: Total len too long\r\n");
00228 return(-1);
00229 }
00230
00231
00232
00233 IP_DEBUGOUT("Validating the IP checksum..\n\r");
00234
00235 if ( ip_check_cs(&received_ip_packet) != TRUE ) {
00236 IP_DEBUGOUT("IP Checksum Corrupted..\n\r");
00237 return(-1);
00238 }
00239
00240 IP_DEBUGOUT("..Checksum OK!\n\r");
00241
00242
00243
00244 if( received_ip_packet.sip != IP_BROADCAST_ADDRESS)
00245 arp_add( received_ip_packet.sip, &frame->source[0], ARP_TEMP_IP);
00246
00247
00248
00249 received_ip_packet.buf_index = frame->buf_index + IP_HLEN + olen;
00250
00251
00252
00253
00254
00255 if( received_ip_packet.frags & (IP_MOREFRAGS | IP_FRAGOFF) ) {
00256 IP_DEBUGOUT("Fragmented IP packet\r\n");
00257 return(-1);
00258 }
00259
00260
00261
00262
00263
00264
00265
00266 IP_DEBUGOUT("Leaving IP succesfully..\n\r");
00267
00268 return(received_ip_packet.tlen - IP_HLEN - olen);
00269
00270 }
00271
00300 INT16 process_ip_out (UINT32 ipadr, UINT8 pcol, UINT8 tos, UINT8 ttl, UINT8* dat, UINT16 len)
00301 {
00302 struct arp_entry *qstruct;
00303 UINT16 i;
00304
00305
00306
00307 qstruct = arp_find(ipadr, &localmachine, ARP_TEMP_IP);
00308
00309 if( qstruct == 0 )
00310 return(-2);
00311
00312
00313
00314
00315
00316 switch(pcol) {
00317 case IP_ICMP:
00318
00319 NETWORK_SEND_INITIALIZE(ICMP_BUF);
00320 IP_DEBUGOUT("Assembling IP packet to ICMP buffer\n\r");
00321
00322 break;
00323
00324 case IP_UDP:
00325
00326 NETWORK_SEND_INITIALIZE(UDP_BUF);
00327 IP_DEBUGOUT("Assembling IP packet to UDP buffer\n\r");
00328
00329 break;
00330
00331 case IP_TCP:
00332
00333 NETWORK_SEND_INITIALIZE(TCP_BUF);
00334 IP_DEBUGOUT("Assembling IP packet to TCP buffer\n\r");
00335
00336 break;
00337
00338 default:
00339 return(-1);
00340 }
00341
00342
00343
00344 for( i=0; i<MAXHWALEN; i++) {
00345 send_frame.destination[i] = qstruct->hwadr[i];
00346 send_frame.source[i] = localmachine.localHW[i];
00347 }
00348
00349 send_frame.protocol = PROTOCOL_IP;
00350
00351 NETWORK_ADD_DATALINK(&send_frame);
00352
00353
00354
00355 send_ip_packet.vihl = IP_DEF_VIHL;
00356 send_ip_packet.tos = tos;
00357 send_ip_packet.tlen = IP_HLEN + len;
00358 send_ip_packet.id = ip_id++;
00359 send_ip_packet.frags = 0;
00360 send_ip_packet.ttl = ttl;
00361 send_ip_packet.protocol = pcol;
00362 send_ip_packet.checksum = 0;
00363 send_ip_packet.sip = localmachine.localip;
00364 send_ip_packet.dip = ipadr;
00365
00366
00367
00368 send_ip_packet.checksum = ip_construct_cs( &send_ip_packet );
00369
00370
00371
00372 SEND_NETWORK_B(send_ip_packet.vihl);
00373 SEND_NETWORK_B(send_ip_packet.tos);
00374 SEND_NETWORK_B( (UINT8)(send_ip_packet.tlen >> 8) );
00375 SEND_NETWORK_B( (UINT8)send_ip_packet.tlen );
00376 SEND_NETWORK_B( (UINT8)(send_ip_packet.id >> 8) );
00377 SEND_NETWORK_B( (UINT8)send_ip_packet.id );
00378 SEND_NETWORK_B( (UINT8)(send_ip_packet.frags >> 8) );
00379 SEND_NETWORK_B( (UINT8)send_ip_packet.frags );
00380 SEND_NETWORK_B(send_ip_packet.ttl);
00381 SEND_NETWORK_B(send_ip_packet.protocol);
00382 SEND_NETWORK_B( (UINT8)(send_ip_packet.checksum >> 8) );
00383 SEND_NETWORK_B( (UINT8)send_ip_packet.checksum );
00384 SEND_NETWORK_B( (UINT8)(send_ip_packet.sip >> 24) );
00385 SEND_NETWORK_B( (UINT8)(send_ip_packet.sip >> 16) );
00386 SEND_NETWORK_B( (UINT8)(send_ip_packet.sip >> 8) );
00387 SEND_NETWORK_B( (UINT8)send_ip_packet.sip );
00388 SEND_NETWORK_B( (UINT8)(send_ip_packet.dip >> 24) );
00389 SEND_NETWORK_B( (UINT8)(send_ip_packet.dip >> 16) );
00390 SEND_NETWORK_B( (UINT8)(send_ip_packet.dip >> 8) );
00391 SEND_NETWORK_B( (UINT8)send_ip_packet.dip );
00392
00393
00394
00395 for(i=0; i<len; i++) {
00396 SEND_NETWORK_B(*dat++);
00397 }
00398
00399
00400
00401 NETWORK_COMPLETE_SEND( send_ip_packet.tlen );
00402
00403 return(len);
00404
00405
00406 }
00407
00419 UINT32 ip_construct_cs (struct ip_frame* frame)
00420 {
00421 UINT16 ip_cs;
00422 UINT8 cs_cnt;
00423 UINT8 olen;
00424 UINT8 i;
00425
00426 ip_cs = 0;
00427 cs_cnt = 0;
00428
00429 ip_cs = ip_checksum(ip_cs, frame->vihl, cs_cnt++);
00430 ip_cs = ip_checksum(ip_cs, frame->tos, cs_cnt++);
00431 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->tlen >> 8), cs_cnt++);
00432 ip_cs = ip_checksum(ip_cs, (UINT8)frame->tlen, cs_cnt++);
00433 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->id >> 8), cs_cnt++);
00434 ip_cs = ip_checksum(ip_cs, (UINT8)frame->id, cs_cnt++);
00435 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->frags >> 8), cs_cnt++);
00436 ip_cs = ip_checksum(ip_cs, (UINT8)frame->frags, cs_cnt++);
00437 ip_cs = ip_checksum(ip_cs, frame->ttl, cs_cnt++);
00438 ip_cs = ip_checksum(ip_cs, frame->protocol, cs_cnt++);
00439 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->sip >> 24), cs_cnt++);
00440 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->sip >> 16), cs_cnt++);
00441 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->sip >> 8), cs_cnt++);
00442 ip_cs = ip_checksum(ip_cs, (UINT8)frame->sip, cs_cnt++);
00443 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->dip >> 24), cs_cnt++);
00444 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->dip >> 16), cs_cnt++);
00445 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->dip >> 8), cs_cnt++);
00446 ip_cs = ip_checksum(ip_cs, (UINT8)frame->dip, cs_cnt++);
00447
00448
00449
00450 olen = ((frame->vihl & 0x0F) << 2) - IP_MIN_HLEN;
00451
00452 for( i=0; i<olen; i++)
00453 ip_cs = ip_checksum(ip_cs, (UINT8)frame->opt[i], cs_cnt++);
00454
00455
00456
00457 ip_cs = ~ ip_cs;
00458
00459 return(ip_cs);
00460
00461 }
00462
00476 UINT8 ip_check_cs (struct ip_frame* frame)
00477 {
00478 UINT16 ip_cs;
00479 UINT8 cs_cnt;
00480 UINT8 olen;
00481 UINT8 i;
00482
00483 ip_cs = 0;
00484 cs_cnt = 0;
00485
00486 ip_cs = ip_checksum(ip_cs, frame->vihl, cs_cnt++);
00487 ip_cs = ip_checksum(ip_cs, frame->tos, cs_cnt++);
00488 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->tlen >> 8), cs_cnt++);
00489 ip_cs = ip_checksum(ip_cs, (UINT8)frame->tlen, cs_cnt++);
00490 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->id >> 8), cs_cnt++);
00491 ip_cs = ip_checksum(ip_cs, (UINT8)frame->id, cs_cnt++);
00492 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->frags >> 8), cs_cnt++);
00493 ip_cs = ip_checksum(ip_cs, (UINT8)frame->frags, cs_cnt++);
00494 ip_cs = ip_checksum(ip_cs, frame->ttl, cs_cnt++);
00495 ip_cs = ip_checksum(ip_cs, frame->protocol, cs_cnt++);
00496 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->checksum >> 8), cs_cnt++);
00497 ip_cs = ip_checksum(ip_cs, (UINT8)frame->checksum, cs_cnt++);
00498 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->sip >> 24), cs_cnt++);
00499 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->sip >> 16), cs_cnt++);
00500 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->sip >> 8), cs_cnt++);
00501 ip_cs = ip_checksum(ip_cs, (UINT8)frame->sip, cs_cnt++);
00502 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->dip >> 24), cs_cnt++);
00503 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->dip >> 16), cs_cnt++);
00504 ip_cs = ip_checksum(ip_cs, (UINT8)(frame->dip >> 8), cs_cnt++);
00505 ip_cs = ip_checksum(ip_cs, (UINT8)frame->dip, cs_cnt++);
00506
00507
00508
00509 olen = ((frame->vihl & 0x0F) << 2) - IP_MIN_HLEN;
00510
00511 for( i=0; i<olen; i++)
00512 ip_cs = ip_checksum(ip_cs, (UINT8)frame->opt[i], cs_cnt++);
00513
00514
00515
00516 ip_cs = ~ ip_cs;
00517
00518 if(ip_cs == IP_GOOD_CS)
00519 return 1;
00520
00521
00522
00523 return 0;
00524
00525
00526 }
00527
00541 UINT16 ip_checksum (UINT16 cs, UINT8 dat, UINT8 count)
00542 {
00543 UINT8 b = dat;
00544 UINT8 cs_l;
00545 UINT8 cs_h;
00546
00547 cs_h = (UINT8)(cs >> 8);
00548 cs_l = (UINT8)cs;
00549
00550 if( count & 0x01 ) {
00551
00552
00553 if( (cs_l = cs_l + b) < b ) {
00554 if( ++cs_h == 0 )
00555 cs_l++;
00556 }
00557
00558 } else {
00559
00560
00561 if( (cs_h = cs_h + b) < b ) {
00562 if( ++cs_l == 0 )
00563 cs_h++;
00564 }
00565 }
00566
00567 return( ( (UINT16)cs_h << 8 ) + cs_l);
00568
00569 }
00570