📄 ip.c
字号:
/************************************************************
* File name : Ip.c *
* By : hugang, hgx2000@mail.china.com *
************************************************************/
#include "armnet.h"
#include "..\inc\44blib.h"
#include <string.h>
extern NODE locnode; //本机的节点信息结构(mac,ip,mask,port)
/********************************************************************************************************
* Check frame is IP, checksum & byte-swap, return data len *
********************************************************************************************************/
short IsIp(ETHERFRAME *efp, short len)
{
short ver, dlen=0, hlen;
unsigned short sum;
IPKT *ip;
if (efp->e.ptype==PCOL_IP && len>=sizeof(IPHDR))
{
ip = (IPKT *)(efp->edata); /* Get pointer to IP frame */
ver = ip->i.vhl >> 4; /* Get IP version & hdr len */
hlen = (ip->i.vhl & 0xf) << 2;
sum = ~csum((unsigned char *)&ip->i, (unsigned short)hlen); /* Do checksum */
if (ver==4 && len>=hlen && sum==0) /* If OK.. */
{
SwapIp(efp);
dlen = min(ip->i.len, len);
dlen -= hlen;
if (hlen > sizeof(IPHDR)) /* If IP options present.. */
{ /* ..delete them, move data down */
memmove((unsigned char *)ip->ipdata, (unsigned char *)&ip->ipdata[hlen-sizeof(IPHDR)], len);
dlen -= hlen-sizeof(IPHDR);
}
}
}
return(dlen);
}
/********************************************************************************************************
* Make an IP packet, if greater than the MTU, also make fragment (subframe) in *
* this frame. Return total length of frame and subframes (if any) *
********************************************************************************************************/
short MakeIp(ETHERFRAME *efp, NODE *srcep, NODE *destp, unsigned char pcol, unsigned short dlen)
{
IPKT *ip;
static unsigned short ident = 1;
ip = (IPKT *)(efp->edata); // Get pointer to IP datagram
ip->i.ident = ident; // Set datagram ident
ip->i.frags = 0; // Frag offset in units of 8 bytes
ip->i.vhl = 0x40+(sizeof(IPHDR)>>2); // Version 4, header len 5 LWORDs
ip->i.service = 0; // Routine message
ip->i.ttl = IP_TTL; // Time To Live
ip->i.pcol = pcol; // Set IP protocol
ip->i.sip = srcep->ip; // Srce, dest IP addrs
ip->i.dip = destp->ip;
ip->i.len = dlen + sizeof(IPHDR); // Data length
SwapIp(efp);
ip->i.check = 0; // Clear checksum
ip->i.check = ~csum((unsigned char *)ip, sizeof(IPHDR)); // ..then set to calc value
ident++; // Increment datagram ident
return(MakeFrame(efp, srcep->mac,destp->mac, PCOL_IP, (unsigned short)dlen + sizeof(IPHDR)));
}
/********************************************************************************************************
* Swap byte order of ints in IP header *
********************************************************************************************************/
void SwapIp(ETHERFRAME *efp)
{
IPKT *ip;
ip = (IPKT *)(efp->edata);
ip->i.len = swapw(ip->i.len);
ip->i.ident = swapw(ip->i.ident);
ip->i.frags = swapw(ip->i.frags);
ip->i.sip = swapl(READ_PACKED(ip->i.sip));
ip->i.dip = swapl(READ_PACKED(ip->i.dip));
}
/********************************************************************************************************
* Get the frame driver type, source IP and Ethernet addresses *
* Returned data does not include port number, netmask or gateway addr *
********************************************************************************************************/
void GetIpSrce(ETHERFRAME *efp, NODE *np)
{
IPKT *ip;
memcpy(np->mac, (unsigned char *)efp->e.srce, MACLEN);
ip = (IPKT *)efp->edata;
np->ip = READ_PACKED(ip->i.sip);
}
/********************************************************************************************************
* Get the frame driver type, destination IP and Ethernet addresses *
* Returned data does not include port number, netmask or gateway addr *
********************************************************************************************************/
void GetIpDest(ETHERFRAME *efp, NODE *np)
{
IPKT *ip;
memcpy(np->mac, (unsigned char *)efp->e.dest, MACLEN);
ip = (IPKT *)efp->edata;
np->ip = READ_PACKED(ip->i.dip);
}
/********************************************************************************************************
* Get local node data corresponding to a frame destination IP address *
* Data does not include port number. Return 0 if no matching local node *
********************************************************************************************************/
unsigned short GetIPLocdest(ETHERFRAME *efp, NODE *np)
{
IPHDR *iph;
unsigned short ok = 0;
iph =(IPHDR *)(efp->edata);
if (iph->dip==locnode.ip)
{
*np = locnode;
ok = 1;
}
return (ok);
}
/********************************************************************************************************
* Check a remote address to see if it is on the local subnet. *
* If so (or no gateway), return it. If not, return the gateway IP address *
********************************************************************************************************/
unsigned int GateIp(NODE *remp, NODE *locp)
{
return((locp->gate==0 || OnSubnet(remp->ip, locp)) ? remp->ip : locp->gate);
}
/********************************************************************************************************
* Check an IP address to see if it is on a subnet, return 0 if not *
********************************************************************************************************/
short OnSubnet(unsigned int remip, NODE *locp)
{
return(((remip ^ locp->ip) & locp->mask) == 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -