📄 ip.c
字号:
/* IP functions
NOTE: replace sizeof(ARPKT) with ARPLEN!!
Debug option to send IP datagrams with a dummy 'options' field */
#define BIGHEAD 0 /* Set non-zero to send datagrams with larger IP hdrs */
#define ARPLEN 28
#define IPHDRLEN 20
#define ICMPHDRLEN 8
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "ether.h"
#include "netutil.h"
#include "ip.h"
#define IP_TTL 100 /* Time To Live for an outgoing IP datagram */
#define FRAGTRIES 8 /* Number of attempts to match a fragment */
#define NFRAGS 4 /* No of fragments in buffer */
typedef struct { /* Fragment buffer structure */
int tries; /* Number of times to attempt a match */
WORD ident; /* IP ident field */
LWORD sipp; /* Source IP address */
WORD oset; /* Offset in IP data area */
WORD len; /* Length of fragment */
BYTE data[MAXIP]; /* Fragment data */
} FRAG;
FRAG frags[NFRAGS]; /* Fragment buffer */
extern int netdebug; /* Debug flag: net packet display */
extern WORD swapw(WORD w);
extern LWORD swapl(LWORD lw);
extern void *getframe_datap(GENFRAME *gfp);
/* Upcall function pointer: 0 if unused */
NODE *(*get_locnode_n)(int n); /* Func ptr for local node locator upcall */
/* Private prototypes */
int defrag_ip(IPKT *ip, int dlen);
/* Check ARP packet, swap bytes, return -1, 0 if not ARP */
int is_arp(GENFRAME *gfp, int len)
{
WORD pcol;
BYTE *temparp;
int dlen=0;
ARPKT *arp;
arp=&arpkt;
pcol = getframe_pcol(gfp); /* ARP only on Ether */
if (pcol==PCOL_ARP && len>=sizeof(ARPKT))
{ /* If protocol OK.. */
temparp =(BYTE * )getframe_datap(gfp);
//memcpy((BYTE *)arp,temparp,ARPLEN);//sizeof(ARPKT));
memcpy((BYTE *)(&(arp->hrd)),&temparp[0],sizeof(WORD));
memcpy((BYTE *)(&(arp->pro)),&temparp[2],sizeof(WORD));
memcpy((BYTE *)(&(arp->hln)),&temparp[4],sizeof(BYTE));
memcpy((BYTE *)(&(arp->pln)),&temparp[5],sizeof(BYTE));
memcpy((BYTE *)(&(arp->op)),&temparp[6],sizeof(WORD));
memcpy(arp->smac,&temparp[8],MACLEN);
memcpy((BYTE *)(&(arp->sip)),&temparp[8+MACLEN],sizeof(LWORD));
memcpy(arp->dmac,&temparp[12+MACLEN],MACLEN);
memcpy((BYTE *)(&(arp->dip)),&temparp[12+2*MACLEN],sizeof(LWORD));
swap_arp(gfp); /* ..check ARP data */
//arp = getframe_datap(gfp);
if (arp->hrd==HTYPE && arp->pro==ARPPRO)
dlen = -1; /* Return non-zero if OK */
else
{
dlen = 0; /* Swap back if not OK */
swap_arp(gfp);
}
}
return(dlen);
}
/* Make an ARP packet, return its total length */
int make_arp(GENFRAME *gfp, NODE *srcep, NODE *destp, WORD code)
{
//ARPKT *arp;
BYTE *temparp;
LWORD templ;
gfp->g.fragoff = 0; /* No fragmentation */
temparp = (BYTE *)getframe_datap(gfp);
memcpy(&temparp[8], srcep->mac, MACLEN); /* Srce ARP ether addr */
memcpy(&temparp[12+MACLEN], destp->mac, MACLEN); /* Dest ARP ether addr */
temparp[0] = HTYPE>>8; /* Hware & protocol types */
temparp[1] = HTYPE&0xff;
temparp[2] = ARPPRO>>8;
temparp[3] = ARPPRO&0xff;
temparp[4] = MACLEN; /* Hardware addr len */
temparp[5] = sizeof(LWORD); /* IP addr len */
temparp[6] = code>>8; /* ARP opcode */
temparp[7] = code&0xff;
templ = srcep->ip; /* Source IP addr */
temparp[8+MACLEN] = (BYTE)((templ>>24)&0x000000ff);
temparp[9+MACLEN] = (BYTE)((templ>>16)&0x000000ff);
temparp[10+MACLEN] = (BYTE)((templ>>8)&0x000000ff);
temparp[11+MACLEN] = (BYTE)(templ&0x000000ff);
templ = gate_ip(destp, srcep); /* Dest ip addr (maybe gateway) */
temparp[12+2*MACLEN] = (BYTE)((templ>>24)&0x000000ff);
temparp[13+2*MACLEN] = (BYTE)((templ>>16)&0x000000ff);
temparp[14+2*MACLEN] = (BYTE)((templ>>8)&0x000000ff);
temparp[15+2*MACLEN] = (BYTE)(templ&0x000000ff);
//swap_arp(gfp);
//Uart_Printf("\n");
/*for(i=0;i<ARPLEN;i++)
Uart_Printf("%x,",temparp[i]);*/
return(make_frame(gfp, destp->mac, PCOL_ARP, sizeof(ARPKT)));
}
/* Swap byte order of ints in ARP header */
void swap_arp(GENFRAME *gfp)
{
ARPKT *arp;
arp=&arpkt;
arp->hrd = swapw(arp->hrd);
arp->pro = swapw(arp->pro);
arp->op = swapw(arp->op);
arp->sip = swapl(arp->sip);
arp->dip = swapl(arp->dip);
}
/* Check frame is IP/SLIP, checksum & byte-swap, return data len */
int is_ip(GENFRAME *gfp, int len)
{
int ver, dlen=0, hlen;
WORD pcol, sum;
IPKT *ip;
BYTE *tempip;
ip=&ipkt;
//Uart_Printf("\nis_ip");
pcol = getframe_pcol(gfp);
if ((pcol==PCOL_IP || pcol==0) && len>=sizeof(IPHDR))
{
// ip = getframe_datap(gfp); /* Get pointer to IP frame */
// Uart_Printf("\nParse the received IP packet:");
tempip=(BYTE *)getframe_datap(gfp);
/*for(i=0;i<60;i++)
Uart_Printf("%x,",tempip[i]);*/
//-----------------------------------------------------------------------
memcpy((BYTE *)(&(ip->i.vhl)),&tempip[0],sizeof(BYTE));
memcpy((BYTE *)(&(ip->i.service)),&tempip[1],sizeof(BYTE));
memcpy((BYTE *)(&(ip->i.len)),&tempip[2],sizeof(WORD));
memcpy((BYTE *)(&(ip->i.ident)),&tempip[4],sizeof(WORD));
memcpy((BYTE *)(&(ip->i.frags)),&tempip[6],sizeof(WORD));
memcpy((BYTE *)(&(ip->i.ttl)),&tempip[8],sizeof(BYTE));
memcpy((BYTE *)(&(ip->i.pcol)),&tempip[9],sizeof(BYTE));
memcpy((BYTE *)(&(ip->i.check)),&tempip[10],sizeof(WORD));
memcpy((BYTE *)(&(ip->i.sip)),&tempip[12],sizeof(LWORD));
memcpy((BYTE *)(&(ip->i.dip)),&tempip[16],sizeof(LWORD));
//-----------------------------------------------------------------------
/*Uart_Printf("\nIP->vhl=%x",ip->i.vhl);
Uart_Printf("\nIP->service=%x",ip->i.service);
Uart_Printf("\nIP->len=%x",ip->i.len);
Uart_Printf("\nIP->ident=%x",ip->i.ident);
Uart_Printf("\nIP->frags=%x",ip->i.frags);
Uart_Printf("\nIP->ttl=%x",ip->i.ttl);
Uart_Printf("\nIP->pcol=%x",ip->i.pcol);
Uart_Printf("\nIP->check=%x",ip->i.check);
Uart_Printf("\nIP->sip=%x",ip->i.sip);
Uart_Printf("\nIP->dip=%x",ip->i.dip); */
ver = ip->i.vhl >> 4; /* Get IP version & hdr len */
hlen = (ip->i.vhl & 0xf) << 2;
sum = ~csum(&ip->i, (WORD)hlen); /* Do checksum */
if ((ver==4) && (len>=hlen) && (sum==0)) /* If OK.. */
{
swap_ip(gfp); /* Do byte-swaps */
dlen = mini(ip->i.len, len) - hlen;
//Uart_Printf("\nIPHEADER's len=%x",sizeof(IPHDR));
{ // ..delete them, move data down
memmove(&tempip[20], &tempip[20+hlen-IPHDRLEN], len);
dlen -= hlen-IPHDRLEN;
}
memcpy((BYTE *)(&(ip->data)),&tempip[20],dlen);
if ((ip->i.frags & 0x3fff)!=0) /* If a fragment.. */
dlen = defrag_ip(ip, dlen); /* ..call defragmenter */
}
else if (netdebug)
Uart_Printf("Invalid datagram, ver %u len %u sum %u\n", ver, len, sum);
}
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) */
int make_ip(GENFRAME *gfp, NODE *srcep, NODE *destp, BYTE pcol, WORD dlen)
{
IPKT *ip;//, *ip2;
int len, sublen=0, fhlen, mtu;
static WORD ident=1, oset=0;
GENFRAME *sfp;
BYTE *tempip;
BYTE *tempip2;
//ip = getframe_datap(gfp); /* Get pointer to IP datagram */
ip=&ipkt;
tempip=getframe_datap(gfp);
//Uart_Printf("\nMake an IP packet:");
ip->i.ident = ident; /* Set datagram ident */
//Uart_Printf("\nIP->i.ident=%x",ip->i.ident);
ip->i.frags = oset >> 3; /* Frag offset in units of 8 bytes */
//Uart_Printf("\nIP->i.frags=%x",ip->i.frags);
gfp->g.fragoff = 0; /* ..assuming no more frags */
mtu = (getframe_mtu(gfp)-IPHDRLEN) & 0xfff8; /* MTU rounded down 8 */
//Uart_Printf("\nMTU=%x",mtu);
len = mini(dlen, mtu); /* Size of this frame (this fragment) */
if (dlen > len) /* If fragmentation required.. */
{ /* Create new frag within this frame */
//Uart_Printf("\ndlen>len");
fhlen = dtype_hdrlen(gfp->g.dtype); /* Frame hdr len */
gfp->g.fragoff = len + IPHDRLEN + fhlen; /* Subframe offset */
sfp = (GENFRAME *)&gfp->buff[gfp->g.fragoff]; /* Subframe ptr */
ip->i.frags = (oset>>3)+0x2000; /* Show there is frag */
oset += len; /* New data offset */
//ip2 = (IPKT*)((BYTE*)sfp+sizeof(GENHDR)+fhlen); /* Ptr to 2nd IP frag */
tempip2= (BYTE*)((BYTE*)sfp+sizeof(GENHDR)+fhlen);
//memmove(ip2->data, &ip->data[oset], dlen-len); /* Copy data 1st->2nd */
memmove(&tempip2[20],&tempip[20],dlen-len);
sfp->g.dtype = gfp->g.dtype; /* Copy driver type into subframe */
//sublen = make_ip(sfp, srcep, destp, pcol, (WORD)(dlen-len));
} /* Recursive call to make frag */
ip->i.vhl = 0x40+(IPHDRLEN>>2);/* Version 4, header len 5 LWORDs */
//Uart_Printf("\nIP->i.vhl=%x",ip->i.vhl);
ip->i.service = 0; /* Routine message */
//Uart_Printf("\nIP->i.service=%x",ip->i.service);
ip->i.ttl = IP_TTL; /* Time To Live */
//Uart_Printf("\nIP->i.ttl=%x",ip->i.ttl);
ip->i.pcol = pcol; /* Set IP protocol */
//Uart_Printf("\nIP->i.pcol=%x",ip->i.pcol);
ip->i.sip = srcep->ip; /* Srce, dest IP addrs */
//Uart_Printf("\nIP->i.sip=%x",ip->i.vhl);
ip->i.dip = destp->ip;
//Uart_Printf("\nIP->i.dip=%x",ip->i.vhl);
#if BIGHEAD
ip->i.option = 0; /* Null options if oversized header */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -