⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip.c

📁 杭州立宇泰豪华型44B0开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 + -