📄 ip.c
字号:
#include "necfg.h"
#include "ne2000.h"
#include "ip.h"
#include "..\inc\44blib.h"
#include <string.h>
extern NODE locnode; //本机的节点信息结构(mac,ip,mask,port)
/********************************************************************************************************
* Check ARP packet, swap bytes, return -1, 0 if not ARP *
********************************************************************************************************/
short Is_ARP(ETHERFRAME *efp, short len)
{
ARPKT *arp;
short dlen=0;
if (efp->e.ptype==PCOL_ARP && len>=sizeof(ARPKT))
{ /* If protocol OK.. */
Swap_ARP(efp);
arp = (ARPKT *)(efp->edata);
if (arp->hrd==HTYPE && arp->pro==ARPPRO)
dlen = -1; /* Return non-zero if OK */
else
dlen = 0;
}
return(dlen);
}
/********************************************************************************************************
* Make an ARP packet, return its total length *
********************************************************************************************************/
short Make_ARP(ETHERFRAME *efp, NODE *srcep, NODE *destp, unsigned short codetype)
{
unsigned char i;
ARPKT *arp;
arp = (ARPKT *)(efp->edata);
for(i=0;i<MACLEN;i++)
{
arp->smac[i] = srcep->mac[i]; // Srce ARP ether addr
arp->dmac[i] = destp->mac[i]; // Dest ARP ether addr
}
arp->hrd = HTYPE; // Hware & protocol types
arp->pro = ARPPRO;
arp->hln = MACLEN; // Hardware addr len
arp->pln = sizeof(unsigned int); // IP addr len
arp->op = codetype; // ARP opcode
arp->dip = Gate_IP(destp, srcep); // Dest ip addr (maybe gateway)
arp->sip = srcep->ip; // Source IP addr
Swap_ARP(efp);
return(Make_Frame(efp,srcep->mac,destp->mac, PCOL_ARP, sizeof(ARPKT)));
}
/********************************************************************************************************
* Swap byte order of ints in ARP header *
********************************************************************************************************/
void Swap_ARP(ETHERFRAME *efp)
{
ARPKT *arp;
unsigned char *p_dip, *p_sip;
unsigned int i_dip, i_sip;
arp = (ARPKT *)(efp->edata);
p_sip = (unsigned char *)&arp->sip;
p_dip = (unsigned char *)&arp->dip;
i_sip = p_sip[3] + ((unsigned int)p_sip[2]<<8) + ((unsigned int)p_sip[1]<<16) + ((unsigned int)p_sip[0]<<24);
i_dip = p_dip[3] + ((unsigned int)p_dip[2]<<8) + ((unsigned int)p_dip[1]<<16) + ((unsigned int)p_dip[0]<<24);
arp->hrd = swapw(arp->hrd);
arp->pro = swapw(arp->pro);
arp->op = swapw(arp->op);
arp->sip = i_sip;
arp->dip = i_dip;
}
/********************************************************************************************************
*Get destination IP *
********************************************************************************************************/
unsigned int Get_ARP_Destip(ARPKT *arp)
{
unsigned char *p_dip;
unsigned int i_dip;
p_dip = (unsigned char *)&arp->dip;
i_dip = p_dip[0] + ((unsigned int)p_dip[1]<<8) + ((unsigned int)p_dip[2]<<16) + ((unsigned int)p_dip[3]<<24);
return(i_dip);
}
/********************************************************************************************************
*Get source IP *
********************************************************************************************************/
unsigned int Get_ARP_Srceip(ARPKT *arp)
{
unsigned char *p_sip;
unsigned int i_sip;
p_sip = (unsigned char *)&arp->sip;
i_sip = p_sip[0] + ((unsigned int)p_sip[1]<<8) + ((unsigned int)p_sip[2]<<16) + ((unsigned int)p_sip[3]<<24);
return(i_sip);
}
/********************************************************************************************************
* Check frame is IP, checksum & byte-swap, return data len *
********************************************************************************************************/
short Is_IP(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.. */
{
Swap_IP(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 Make_IP(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
Swap_IP(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(Make_Frame(efp, srcep->mac,destp->mac, PCOL_IP, (unsigned short)dlen + sizeof(IPHDR)));
}
/********************************************************************************************************
* Swap byte order of ints in IP header *
********************************************************************************************************/
void Swap_IP(ETHERFRAME *efp)
{
IPKT *ip;
unsigned char *p_dip, *p_sip;
unsigned int i_dip, i_sip;
ip = (IPKT *)(efp->edata);
p_sip = (unsigned char *)&ip->i.sip;
p_dip = (unsigned char *)&ip->i.dip;
i_sip = p_sip[3] + ((unsigned int)p_sip[2]<<8) + ((unsigned int)p_sip[1]<<16) + ((unsigned int)p_sip[0]<<24);
i_dip = p_dip[3] + ((unsigned int)p_dip[2]<<8) + ((unsigned int)p_dip[1]<<16) + ((unsigned int)p_dip[0]<<24);
ip->i.len = swapw(ip->i.len);
ip->i.ident = swapw(ip->i.ident);
ip->i.frags = swapw(ip->i.frags);
ip->i.sip = i_sip;
ip->i.dip = i_dip;
}
/********************************************************************************************************
*Get destination IP *
********************************************************************************************************/
unsigned int Get_IP_Destip(IPKT *ip)
{
unsigned char *p_dip;
unsigned int i_dip;
p_dip = (unsigned char *)&ip->i.dip;
i_dip = p_dip[0] + ((unsigned int)p_dip[1]<<8) + ((unsigned int)p_dip[2]<<16) + ((unsigned int)p_dip[3]<<24);
return(i_dip);
}
/********************************************************************************************************
*Get source IP *
********************************************************************************************************/
unsigned int Get_IP_Srceip(IPKT *ip)
{
unsigned char *p_sip;
unsigned int i_sip;
p_sip = (unsigned char *)&ip->i.sip;
i_sip = p_sip[0] + ((unsigned int)p_sip[1]<<8) + ((unsigned int)p_sip[2]<<16) + ((unsigned int)p_sip[3]<<24);
return(i_sip);
}
/********************************************************************************************************
* Get the frame driver type, source IP and Ethernet addresses *
* Returned data does not include port number, netmask or gateway addr *
********************************************************************************************************/
void Get_IP_Srce(ETHERFRAME *efp, NODE *np)
{
IPKT *ip;
memcpy(np->mac, (unsigned char *)efp->e.srce, MACLEN);
ip = (IPKT *)efp->edata;
np->ip = Get_IP_Srceip(ip);
}
/********************************************************************************************************
* Get the frame driver type, destination IP and Ethernet addresses *
* Returned data does not include port number, netmask or gateway addr *
********************************************************************************************************/
void Get_IP_Dest(ETHERFRAME *efp, NODE *np)
{
IPKT *ip;
memcpy(np->mac, (unsigned char *)efp->e.dest, MACLEN);
ip = (IPKT *)efp->edata;
np->ip = Get_IP_Destip(ip);
}
/********************************************************************************************************
* Return ICMP data length (-1 if no data), 0 if not ICMP *
********************************************************************************************************/
short Is_ICMP(IPKT *ip, short len)
{
ICMPKT *icmp;
unsigned short sum;
short dlen = 0;
if (ip->i.pcol==PICMP && len>=sizeof(ICMPHDR))
{
icmp = (ICMPKT *)ip;
if ((sum=csum((unsigned char *)&icmp->c, (unsigned short)len)) == 0xffff)
{
Swap_ICMP(icmp);
dlen = len>sizeof(ICMPHDR) ? len-sizeof(ICMPHDR) : -1;
}
}
return(dlen);
}
/********************************************************************************************************
* Make an ICMP packet *
********************************************************************************************************/
short Make_ICMP(ETHERFRAME *efp, NODE *srcep, NODE *destp, unsigned char type, unsigned char codetype, unsigned short ident, unsigned short seq, unsigned short dlen)
{
ICMPKT *icmp;
unsigned short len;
icmp = (ICMPKT *)(efp->edata);
icmp->c.type = type;
icmp->c.codetype = codetype;
icmp->c.ident = ident;
icmp->c.seq = seq;
Swap_ICMP(icmp);
icmp->c.check = 0;
len = (unsigned short)(dlen + sizeof(ICMPHDR));
icmp->c.check = ~csum((unsigned char *)&icmp->c, len);
return(Make_IP(efp, srcep, destp, PICMP, len));
}
/********************************************************************************************************
* Swap byte order of ints in ICMP header *
********************************************************************************************************/
void Swap_ICMP(ICMPKT *icmp)
{
icmp->c.ident = swapw(icmp->c.ident);
icmp->c.seq = swapw(icmp->c.seq);
}
/********************************************************************************************************
* 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 Get_IP_Locdest(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 Gate_IP(NODE *remp, NODE *locp)
{
return((locp->gate==0 || On_Subnet(remp->ip, locp)) ? remp->ip : locp->gate);
}
/********************************************************************************************************
* Check an IP address to see if it is on a subnet, return 0 if not *
********************************************************************************************************/
short On_Subnet(unsigned int remip, NODE *locp)
{
return(((remip ^ locp->ip) & locp->mask) == 0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -