⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip.c

📁 44B0+8019系统
💻 C
字号:
//-----------------------------------------------------------------------------
// Net IP.C
// This module is the IP layer
// Refer to RFC 791, 1122, and RFC 815 (fragmentation)
//-----------------------------------------------------------------------------
#include <string.h>

#include "rtl8019.h"
#include "net.h"
#include "cksum.h"
#include "arp.h"
#include "icmp.h"
#include "udp.h"
#include "tcp.h"
#include "ip.h"

extern unsigned int my_ipaddr;
WAIT wait;

//========================================================================
void ip_getHader(void *inbuf,void *h)
{
   unsigned char *pinbuf = (unsigned char*)inbuf;
   unsigned char *pBuf;
   IP_HEADER *ph = (IP_HEADER*)h;

   //=========================================
   ph->ver_len = pinbuf[14];
   ph->type_of_service = pinbuf[15];

   //=========================================
   //pBuf = (unsigned char *)&ph->total_length;
   //pBuf[1] = pinbuf[16];
   //pBuf[0] = pinbuf[17];
   ph->total_length = get__int16(pinbuf+16);
   
   //=========================================
   //pBuf = (unsigned char *)&ph->identifier;
   //pBuf[1] = pinbuf[18];
   //pBuf[0] = pinbuf[19];
   ph->identifier = get__int16(pinbuf+18);
   //=========================================
   //pBuf = (unsigned char *)&ph->fragment_info;
   //pBuf[1] = pinbuf[20];
   //pBuf[0] = pinbuf[21];
   ph->fragment_info = get__int16(pinbuf+20);
   //=========================================
   ph->time_to_live = pinbuf[22];
   ph->protocol_id = pinbuf[23];

   //=========================================
   //pBuf = (unsigned char *)&ph->header_cksum;
   //pBuf[1] = pinbuf[24];
   //pBuf[0] = pinbuf[25];
   ph->header_cksum = get__int16(pinbuf+24);
   //=========================================
   //memcpy((unsigned char*)&ph->source_ipaddr,pinbuf+26,4);
   ph->source_ipaddr = get__int32(pinbuf+26);
   //=========================================
   //memcpy((unsigned char*)&ph->dest_ipaddr,pinbuf+30,4);
   ph->dest_ipaddr = get__int32(pinbuf+30);
}

void ip_setHader(void *inbuf,void *h)
{
   unsigned char *pinbuf = (unsigned char*)inbuf;
   unsigned char *pBuf;
   IP_HEADER *ph = (IP_HEADER*)h;

   //=========================================
   pinbuf[14] = ph->ver_len;
   pinbuf[15] = ph->type_of_service;

   //=========================================
   //pBuf = (unsigned char *)&ph->total_length;
   //pinbuf[16] = pBuf[1];
   //pinbuf[17] = pBuf[0];
   set__int16(pinbuf+16,ph->total_length);
   //=========================================
   //pBuf = (unsigned char *)&ph->identifier;
   //pinbuf[18] = pBuf[1];
   //pinbuf[19] = pBuf[0];
   set__int16(pinbuf+18,ph->identifier);
   //=========================================
   //pBuf = (unsigned char *)&ph->fragment_info;
   //pinbuf[20] = pBuf[1];
   //pinbuf[21] = pBuf[0];
   set__int16(pinbuf+20,ph->fragment_info);
   //=========================================
   pinbuf[22] = ph->time_to_live;
   pinbuf[23] = ph->protocol_id;

   //=========================================
   //pBuf = (unsigned char *)&ph->header_cksum;
   //pinbuf[24] = pBuf[1];
   //pinbuf[25] = pBuf[0];
   set__int16(pinbuf+24,ph->header_cksum);
   //=========================================
   //memcpy(pinbuf+26,(unsigned char*)&ph->source_ipaddr,4);
   set__int32(pinbuf+26,ph->source_ipaddr);
   //=========================================
   //memcpy(pinbuf+30,(unsigned char*)&ph->dest_ipaddr,4);
   set__int32(pinbuf+30,ph->dest_ipaddr);
}

//------------------------------------------------------------------------
// This handles outgoing IP datagrams.  It adds the 20 byte IP header
// and checksum then forwards the IP datagram to the Ethernet layer
// for sending. See "TCP/IP Illustrated, Volume 1" Sect 3.2
//------------------------------------------------------------------------
void ip_send(unsigned char *outbuf, unsigned int ipaddr, unsigned char proto_id, unsigned short len)
{

   //unsigned char dto_hwaddr[6] = {0x00,0xe0,0x4c,0xe0,0xc1,0xc7};
   IP_HEADER *ip,iph;
   unsigned char *hwaddr;
   static unsigned short int ip_ident = 0;
   
   ip = &iph;
   ip->ver_len = 0x45;              // IPv4 with 20 byte header
   ip->type_of_service = 0;
   ip->total_length = 20 + len;
   ip->identifier = ip_ident++;     // sequential identifier
   ip->fragment_info = 0;           // not fragmented
   ip->time_to_live = 32;           // max hops
   ip->protocol_id = proto_id;      // type of payload
   ip->header_cksum = 0;
   ip->source_ipaddr = my_ipaddr;
   
   // Outgoing IP address
   ip->dest_ipaddr = ipaddr;

   // Compute and insert complement of checksum of ip header
   // Outgoing ip header length is always 20 bytes
   ip_setHader(outbuf,ip);		//将ip报封装成太帧
   ip->header_cksum = ~cksum(outbuf + 14, 20);
   
   // Use ARP to get hardware address to send this to
   hwaddr = arp_resolve(ip->dest_ipaddr);//找到于目标ip对应的物理地址
	
	// Null means that the ARP resolver did not find the IP address
	// in its cache so had to send an ARP request
	if (hwaddr == NULL)
	{
		// Fill in the destination information so ehrn the ARP response
		 //arrives we can identify it and know what to do when we get it
      memcpy(wait.buf , outbuf, 20 + len + 14);
		wait.ipaddr = ip->dest_ipaddr;
		wait.proto_id = proto_id;
		wait.len = len;
		wait.timer = ARP_TIMEOUT; 
        return;
	}	
   
    //hwaddr = (unsigned char *)dto_hwaddr;	
	ip_setHader(outbuf,ip);
   while( !ETH_Send(outbuf, hwaddr, IP_PACKET, 20 + len) );
}



//------------------------------------------------------------------------
// This handles incoming IP datagrams from the Ethernet layer
// See "TCP/IP Illustrated, Volume 1" Sect 3.2
//------------------------------------------------------------------------
void ip_rcve(unsigned char *inbuf)
{
	IP_HEADER *ip,iph;
	unsigned short int header_len, payload_len;
   unsigned int i;

   //ip = (IP_HEADER *)(inbuf + 14);
   ip = &iph;

   ip_getHader( inbuf , ip);
            
   // Make sure it is addressed to my IP address
   if (ip->dest_ipaddr != my_ipaddr) return;

   // Validate checksum of ip header
	header_len = 4 * (0x0F & ip->ver_len);
	payload_len = ip->total_length - header_len;
   if (cksum(inbuf + 14, header_len) != 0xFFFF)
	{
	   return; 
   }
	
	// Make sure incoming message is IP version 4
	if ((ip->ver_len >> 4) != 0x04)
	{
   	return;
	}

	// Make sure incoming message is not fragmented because
   // we cannot handle fragmented messages
   if ((ip->fragment_info & 0x3FFF) != 0)
   {
 	   return; 
   }

   // At this point we have received a valid IP datagram addressed
   // to me.  We do not use header options, and do not forward
   // messages, so in the unlikely event there are header options,
   // delete them and shift the data down. The advantage is that
   // layers such as UDP and TCP know where their data starts
	if (header_len > 20)
	{
     // Use memmove because of overlap
      memmove(inbuf + 34, inbuf + 14 + header_len, payload_len);

		// Adjust info to reflect the move
		header_len = 20;
		ip->ver_len = 0x45;
		ip->total_length = 20 + payload_len;
	}
	
	
	// Look at protocol ID byte and call the appropriate
   // function to handle the received message.  See 
   // "TCP/IP Illustrated, Volume 1" Sect 1.7 and RFC 791
   // for values for various protocols
   switch (ip->protocol_id)
	{
      case ICMP_TYPE:
      {
         icmp_rcve(inbuf, payload_len);
         break;
      }

      case IGMP_TYPE:
      {
		   // We cannot handle IGMP messages
		   //if (debug) serial_send("IP:  Error, IGMP pkt rcvd\r");
         break;
      }
		  
      case UDP_TYPE:
      {
         udp_rcve(inbuf, payload_len);
         break;
      }

      case TCP_TYPE:   
      {
         tcp_rcve(inbuf, payload_len);
         break;
      }

      default:
      {
         //if (debug) serial_send("IP:  Unknown IP proto id rcvd\r");
         break;
      }
   }
}


//void mytt_ip()
//{
//   mytt();
//}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -