?? ip.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);//找到于目標(biāo)ip對應(yīng)的物理地址
// 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();
//}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -