📄 ip.c
字号:
#include "C:\wql\tcpipsocket\tcpip.h"
#include <stdlib.h>
#include <string.h>
#include "C:\wql\tcpipsocket\func.h"
#include "C:\wql\tcpipsocket\ether.h"
INT16 IP_Ident;
extern UINT8 MY_IP[4];
// the in_buffer of IP(from up layer)
IP_frame IP_IN;
/****************************************************************************
*
* FUNCTION
*
* IP_Interpret
*
* DESCRIPTION
*
* Called by the packet demuxer to interpret a new ip packet. Checks
* the validity of the packet (checksum, flags) and then passes it
* on to the appropriate protocol handler.
*
* INPUTS
*
* pkt - the pointer to the IP packet header
* buffer - pointer to the IP packet entry structure
* buffer_size - the net buffer structure size
*
* OUTPUTS
* 1 -- err
* 0 -- normal
*
****************************************************************************/
UINT8 IP_Interpret (IPLAYER *pkt, UINT8 * BUFFER, UINT16 BUFFER_SIZE)
{
UINT16 iplen;
UINT16 hlen;
UINT8 j;
struct pseudotcp tcp_chk;
//if((pkt->ip_frags & IP_DF)==0) return 1; //定义了分片,不处理
iplen = pkt->ip_tlen;
hlen = ((pkt ->ip_versionandhdrlen) & 0x0f) << 2;
if ((hlen != sizeof(IPLAYER)) /* Header too small */
|| (iplen < hlen) /* Header inconsistent */
|| (iplen > 1400)) /* WAY too big */
{
return (1); /* drop packet */
} /* end if */
if (iplen <= hlen)
{
return (1);
}
if (hlen > sizeof (IPLAYER))
{
return (1);
} /* end if */
j=memcmp(pkt->ip_dest, MY_IP,4);
if (j != 0)
{
return (1);
}
/* Create the pseudo tcp header for upper layer protocols to
compute their checksum */
/* The GET32 macro automatically puts the addresses in the native
architectures byte order. In this case we wish to keep the addresses in
big endian or network byte order. So swap the values returned by GET32. */
memcp(tcp_chk.source, pkt->ip_src, 4) ;
memcp(tcp_chk.dest,pkt->ip_dest,4);
tcp_chk.z = 0;
tcp_chk.proto = pkt->ip_protocol;
tcp_chk.tcplen = iplen - 20 ; //GET THE UDP OR TCP LENGTH
/* which protocol to handle this packet? */
switch (pkt->ip_protocol)
{
case IP_UDP_PROT:
//UDP_Interpret(BUFFER, &tcp_chk);
return (0);
case IP_TCP_PROT:
TCP_Interpret(BUFFER, &tcp_chk);
return (0);
break;
case IP_ICMP_PROT:
/* Increment the number of IP packets successfully delivered. */
ICMP_Interpret(BUFFER,BUFFER_SIZE,pkt->ip_src);
return (0);
case IP_IGMP_PROT : //IGMP
/* Increment the number of IP packets successfully delivered. */
//return (0);
case IP_RAW_PROT :
case IP_HELLO_PROT :
case IP_OSPF_PROT :
/** Any additional Raw IP protocols that are supported in the
future must have a case here ***/
return (0);
default:
return (1);
} /* end switch */
} /* IP_Interpret */
/***********************************************************************
*
* FUNCTION
*
* IP_Send
*
* DESCRIPTION
*
* Send an IP packet.
*
* INPUTS
*
* buf_ptr - pointer to the Buffer structure (from up layer)
* dest_ip - the destination IP address
* ttl - the ttl for this IP
* PRO_TYPE - the protocol for the IP
* buf_len - the length of buffer
*
*************************************************************************/
void IP_Send(UINT8 *buf_ptr, UINT16 buf_len, UINT8 *DES_IP,UINT8 PRO_TYPE,UINT8 TTL)
{
UINT8 MAC_DEST[6];
UINT8 *TEMP;
UINT8 i;
IP_IN.IP_HEADER.ip_ttl = TTL;
IP_IN.IP_HEADER.ip_protocol = PRO_TYPE;
IP_IN.IP_HEADER.ip_versionandhdrlen = 0X45;
IP_IN.IP_HEADER.ip_service = 0;
IP_IN.IP_HEADER.ip_tlen = buf_len + 20;
IP_IN.IP_HEADER.ip_frags = 0x4000; //don't frag
IP_IN.IP_HEADER.ip_ident = IP_Ident++;
IP_IN.IP_HEADER.ip_check = 0;
for(i=0;i<4;i++)
{
IP_IN.IP_HEADER.ip_dest[i] = DES_IP[i];
IP_IN.IP_HEADER.ip_src[i] = MY_IP[i];
}
//memcp(IP_IN.IP_HEADER.ip_dest, DES_IP,4);
//memcp(IP_IN.IP_HEADER.ip_src, MY_IP,4);
TEMP = (UINT8 *) (&(IP_IN.IP_HEADER));
IP_IN.IP_HEADER.ip_check = ~(Check_sum( TEMP,20));
IP_IN.PRO_BUF_LEN = buf_len;
memcp(IP_IN.PRO_BUF ,buf_ptr,buf_len); //这里可以省略掉,可以在上层直接写入。
// now IP Packet is filled.
// if find the dest mac addr in arp cache then send the packet
// else put it in the ip_cache and send a arp request . when received a rply ,send the ip packet again.
if(ARP_Resolve(&IP_IN.IP_HEADER.ip_dest, MAC_DEST, (UINT8 *)&IP_IN, IP_IN.IP_HEADER.ip_tlen) == 1)
{
Ether_output(MAC_DEST,IP_IN.IP_HEADER.ip_tlen,(UINT8 *)&IP_IN,0x0800); // ether_output is in the ethernet.c
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -