T168_111\system\Ethernet\net:第1~14

arpcache.c  、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ARPCACHE_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"

#include "if_var.h"
#include "if_ether.h"
#include "inet.h"

#ifdef NUTDEBUG
#include "netdebug.h"
#endif

#if 0
/* Use for local debugging. */
#define NUTDEBUG
#include <stdio.h>
#define __tcp_trs stdout
static u_char __tcp_trf = 1;
#endif

#if defined(NUTNET)

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

/*! \brief Maximum age of an entry in the ARP cache in minutes.
 *
 * Outdated entries will be regularly removed, forcing the Ethernet 
 * interface to generate new ARP requests. This way MAC address
 * changes are detected.
 *
 * \showinitializer
 */
#ifndef MAX_ARPAGE
#define MAX_ARPAGE 9
#endif

/*! \brief Maximum number of ARP requests generated per query.
 *
 * If no ARP response is received after sending out the specified
 * number of request, the related IP address is considered unreachable.
 *
 * \showinitializer
 */
#ifndef MAX_ARPREQUESTS
#define MAX_ARPREQUESTS 1
#endif

/*! \brief Minimum wait before sending out a new ARP request.
 *
 * The specified number of milliseconds will be doubled on each retry.
 *
 * \showinitializer
 */
#ifndef MIN_ARPWAIT
#define MIN_ARPWAIT 500
#endif

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/


/*!
 * \brief Remove all entries marked for removal.
 *
 * \param ifn The network interface.
 */
static void ArpCacheFlush(IFNET * ifn)
{
    ARPENTRY *ae = ifn->arpTable;
    ARPENTRY **aep = &ifn->arpTable;

    while (ae) {
        if (ae->ae_flags & ATF_REM) {
            /* Remove all waiting threads from the queue of this
               entry, but do not give up the CPU. If some other
               thread takes over and deals with ARP, we are dead. */
            NutEventBroadcastAsync(&ae->ae_tq);
#ifdef NUTDEBUG
            if (__tcp_trf) {
                fprintf(__tcp_trs, "[ARP-DEL %s]", inet_ntoa(ae->ae_ip));
            }
#endif
            *aep = ae->ae_next;
            NutHeapFree(ae);
            ae = *aep;
        } else {
            aep = &ae->ae_next;
            ae = ae->ae_next;
        }
    }
}

/*!
 * \brief Update the age of all ARP entries of all Ethernet devices.
 *
 * Increments the age of all ARP entries. Any entry with an age above
 * \ref MAX_ARPAGE will be removed.
 *
 * If less less than one minute elapsed since the last update, the
 * routine will return without updating any entry.
 */
static void ArpCacheAging(void)
{
    static u_long last_update;
    NUTDEVICE *dev;

    if (NutGetSeconds() - last_update >= 60) {
        last_update = NutGetSeconds();

        /*
         * Loop through the list of all registered devices.
         */
        for (dev = nutDeviceList; dev; dev = dev->dev_next) {

            /* Process network devices only. */
            if (dev->dev_type == IFTYP_NET) {
                IFNET *ifn = dev->dev_icb;

                /* Process Ethernet interfaces only. */
                if (ifn && ifn->if_type == IFT_ETHER) {
                    ARPENTRY *ae;
                    u_char rmf = 0;

                    /* Loop through all ARP entries of this interface. */
                    for (ae = ifn->arpTable; ae; ae = ae->ae_next) {
                        if ((ae->ae_flags & ATF_PERM) == 0 &&   /* Not permanent. */
                            ae->ae_outdated++ >= MAX_ARPAGE) {  /* Outdated. */
                            ae->ae_flags |= ATF_REM;
                        }
                        rmf |= ae->ae_flags;
#ifdef NUTDEBUG
                        if (__tcp_trf) {
                            fprintf(__tcp_trs, "[ARP-AGE %s %u]",       /* */
                                    inet_ntoa(ae->ae_ip), ae->ae_outdated);
                        }
#endif
                    }
                    if (rmf & ATF_REM) {
                        ArpCacheFlush(ifn);
                    }
                }
            }
        }
    }
}

/*!
 * \brief Locate an interface's ARP entry for a given IP address.
 *
 * \param ifn Pointer to the network interface.
 * \param ip  IP address to search, given in network byte order.
 *
 * \return Pointer to the ARP cache entry, if found, or NULL if no 
 *         entry exists.
 */
static ARPENTRY *ArpCacheLookup(IFNET * ifn, u_long ip)
{
    ARPENTRY *entry;

    for (entry = ifn->arpTable; entry; entry = entry->ae_next) {
        if (entry->ae_ip == ip)
            break;
    }
    return entry;
}


/*!
 * \brief Create a new entry in the interface's ARP cache.
 *
 * The new entry is added on top of the cache list.
 *
 * \param ifn Pointer to the network interface.
 * \param ip  IP address of the new entry, given in network byte order.
 * \param ha  Pointer to the MAC address. If NULL, an incomplete entry
 *            will be created.
 *
 * \return Pointer to the new entry or NULL if not enough memory is 
 *         available.
 */
static ARPENTRY *ArpCacheNew(IFNET * ifn, u_long ip, u_char * ha)
{
    ARPENTRY *entry;

    /* Remove outdated entries before adding a new one. */
    ArpCacheAging();

    if ((entry = NutHeapAlloc(sizeof(ARPENTRY))) != 0) {
        memset(entry, 0, sizeof(ARPENTRY));
        entry->ae_ip = ip;
        if (ha) {
            memcpy(entry->ae_ha, ha, 6);
            entry->ae_flags = ATF_COM;
        }
        entry->ae_next = ifn->arpTable;
        ifn->arpTable = entry;

#ifdef NUTDEBUG
        if (__tcp_trf) {
            fprintf(__tcp_trs, "\n[ARP-NEW %s", inet_ntoa(ip));
            if (ha) {
                fprintf(__tcp_trs, " %02x%02x%02x%02x%02x%02x", /* */
                        ha[0], ha[1], ha[2], ha[3], ha[4], ha[5]);
            }
            fputc(']', __tcp_trs);
        }
#endif
    }
    return entry;
}

/*!
 * \brief Update an ARP entry.
 *
 * If an entry with the same IP address exists, then this entry is 
 * updated. If no entry exists, a new one is created. All threads 
 * waiting for address resolution are woken up.
 *
 * \note This function is automatically called on each incoming
 *       ARP telegram. Applications typically do not call this 
 *       function.
 *
 * \param dev Identifies the device.
 * \param ip  Requested IP address in network byte order.
 * \param ha  Pointer to a buffer which receives the MAC address.
 *
 */
void NutArpCacheUpdate(NUTDEVICE * dev, u_long ip, u_char * ha)
{
    ARPENTRY *entry;

    /*
     * If an entry with this IP exists, wake up waiting threads. If the
     * entry is not permanent, then update it and mark it completed first.
     */
    if ((entry = ArpCacheLookup(dev->dev_icb, ip)) != 0) {

#ifdef NUTDEBUG
        if (__tcp_trf) {
            fprintf(__tcp_trs, "[ARP-UPD %s", inet_ntoa(ip));
            if (ha) {
                fprintf(__tcp_trs, " %02x%02x%02x%02x%02x%02x", /* */
                        ha[0], ha[1], ha[2], ha[3], ha[4], ha[5]);
            }
            fputc(']', __tcp_trs);
        }
#endif

        if ((entry->ae_flags & ATF_PERM) == 0) {
            entry->ae_outdated = 0;
            memcpy(entry->ae_ha, ha, 6);
            entry->ae_flags |= ATF_COM;
        }
        NutEventBroadcast(&entry->ae_tq);
    }

    /* 
     * If no entry with this IP exists, then create a new completed one. 
     */
    else {
        ArpCacheNew(dev->dev_icb, ip, ha);
    }
}

/*!
 * \brief Query MAC address for a specified IP address.
 *
 * If no entry is available in the ARP cache, an incomplete entry is
 * created and ARP requests are generated on increasing time intervals.
 * The calling thread is suspended until a matching ARP response is
 * received or until a number of requests have been generated without
 * receiving a response.
 *
 * \note This function is automatically called on each outgoing
 *       IP packet. Applications typically do not call this function.
 *
 * \param dev  Identifies the device.
 * \param ip   IP address of which the caller asked the MAC address.
 * \param mac  Buffer for the retrieved MAC address.
 *
 * \return 0 if address resolved, -1 otherwise.
 */
int NutArpCacheQuery(NUTDEVICE * dev, CONST u_long ip, u_char * mac)
{
    int rc = -1;
    ARPENTRY *entry;
    IFNET *ifn = dev->dev_icb;
    NETBUF *nb = 0;
    u_char retries = MAX_ARPREQUESTS;
    u_long tmo = MIN_ARPWAIT;

    /* Aging the cache on each query adds some processing to the path 
     * which we want to be as fast as possible. But when calling this 
     * function in NutArpCacheNew only, we will never detect when a 
     * node changes its MAC address. Anyway, the previous solution of 
     * running a timer thread consumed too much RAM.
     */
    ArpCacheAging();

    /*
     * Search a matching entry. If none exists, create a new incomplete 
     * entry and a request packet. If another thread has entered this 
     * routine, an incomplete entry exists and the current thread will 
     * not create a request packet and send out requests.
     */
    if ((entry = ArpCacheLookup(ifn, ip)) == 0) {
        if ((entry = ArpCacheNew(ifn, ip, 0)) == 0) {
            return -1;
        }
        if ((nb = NutArpAllocNetBuf(ARPOP_REQUEST, ip, 0)) == 0) {
            entry->ae_flags |= ATF_REM;
            ArpCacheFlush(ifn);
            return -1;
        }
    }

    /*
     * We enter a loop, which will send ARP requests on increasing 
     * time intervals until our ARP entry gets completed. Give up 
     * after a configured number of retries.
     */
    for (;;) {
        /* If completed, provide the MAC address and exit. */
        if (entry->ae_flags & ATF_COM) {
            //Work around for GCC 3.4.3 bug #18251
            //memcpy(mac, entry->ae_ha, 6);
            //rc = 0;
            rc = 6;
            do {
                rc--;
                mac[rc] = entry->ae_ha[rc];
            } while(rc);
            break;
        }
#ifdef NUTDEBUG
        if (__tcp_trf) {
            fprintf(__tcp_trs, "[%u.ARP-%s %s]",        /* */
                    MAX_ARPREQUESTS - retries + 1,      /* */
                    nb ? "QRY" : "WAIT",        /* */
                    inet_ntoa(ip));
        }
#endif

        /* Give up on too many retries. */
        if (retries-- == 0) {
            break;
        }
        /* Mark buffer released and remove incomplete entry on transmit errors. */
        if (nb && NutArpOutput(dev, nb)) {
            nb = 0;
            /* Even if the transmit failed, we may have received a response in the meantime. */
            if ((entry = ArpCacheLookup(ifn, ip)) != NULL && (entry->ae_flags & ATF_COM) == 0) {
                entry->ae_flags |= ATF_REM;
                ArpCacheFlush(ifn);
            }
            break;
        }
        /* Sleep until woken up by an update of this ARP entry
           or until timeout. Double the timeout on each retry. */
        NutEventWait(&entry->ae_tq, tmo);
        tmo += tmo;

        /* During our sleep, another thread, which created the
           incomplete entry, may have given up and removed the entry. 
           In this case we should also return an error. */
        if ((entry = ArpCacheLookup(ifn, ip)) == 0) {
            break;
        }
    }

    /* Only the thread that created the entry, allocated a request 
       packet. If this thread fails, it should also remove the entry. */
    if (nb) {
        NutNetBufFree(nb);
        /* Play save and check, if the entry still exists. */
        if (rc && entry) {
            entry->ae_flags |= ATF_REM;
            ArpCacheFlush(ifn);
        }
    }
    return rc;
}

#endif

arpin.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ARPIN_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"

#include "if_var.h"
#include "if_ether.h"
#include "in.h"

#if defined(NUTNET)

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/*!
 * \brief Handle incoming ARP packets.
 *
 * Packets not destined to us or packets with unsupported 
 * address type or item length are silently discarded.
 *
 * \note This routine is called by the Ethernet layer on
 *       incoming ARP packets. Applications typically do
 *       not call this function.
 *
 * \param dev Identifies the device that received the packet.
 * \param nb  Pointer to a network buffer structure containing 
 *            the ARP packet.
 */
void NutArpInput(NUTDEVICE * dev, NETBUF * nb)
{
    ETHERARP *ea;
    ARPHDR *ah;
    IFNET *nif;

    if (nb->nb_nw.sz < sizeof(ETHERARP)) {
        NutNetBufFree(nb);
        return;
    }

    ea = (ETHERARP *) nb->nb_nw.vp;
    ah = (ARPHDR *) & ea->ea_hdr;

    /*
     * Silently discard packets with unsupported
     * address types and lengths.
     */
    if (ntohs(ah->ar_hrd) != ARPHRD_ETHER ||
        ntohs(ah->ar_pro) != ETHERTYPE_IP ||
        ah->ar_hln != 6 || ah->ar_pln != 4) {
        NutNetBufFree(nb);
        return;
    }

    /*
     * Silently discard packets for other destinations.
     */
    nif = dev->dev_icb;
    if (ea->arp_tpa != nif->if_local_ip) {
        NutNetBufFree(nb);
        return;
    }

    /*
     * TODO: Silently discard packets with our own 
     * source address.
     */

    /*
     * TODO: Discard packets with broadcast source
     * address.
     */

    /*
     * TODO: Discard packets if source IP address
     * equals our address. We should send a reply.
     */

    /*
     * Add the sender to our arp cache. Note, that we don't do
     * this with replies only, but also with requests on our
     * address. The assumption is that if someone is requesting
     * our address, they are probably intending to talk to us,
     * so it saves time if we cache their address.
     */
    NutArpCacheUpdate(dev, ea->arp_spa, ea->arp_sha);

    /*
     * Reply to ARP requests.
     */
    if (htons(ea->ea_hdr.ar_op) == ARPOP_REQUEST) {
        NETBUF *nbr =
            NutArpAllocNetBuf(ARPOP_REPLY, ea->arp_spa, ea->arp_sha);

        if (nbr) {
            if (!NutArpOutput(dev, nbr))
                NutNetBufFree(nbr);
        }
    }
    NutNetBufFree(nb);
}

#endif

arpout.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ARPOUT_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"

#include "if_var.h"
#include "if_ether.h"
#include "ether.h"
#include "in.h"

#if defined(NUTNET)

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/


/*!
 * \brief Allocate an ARP network buffer structure.
 *
 * \param type Type of ARP packet.
 * \param ip   Target IP address.
 * \param mac  Target MAC address, null pointer for broadcast.
 *
 * \return Pointer to the allocated network buffer structure 
 *         or 0 on failure.
 */
NETBUF *NutArpAllocNetBuf(u_short type, u_long ip, u_char * mac)
{
    NETBUF *nb;
    ETHERARP *ea;
    ARPHDR *ah;

    if ((nb = NutNetBufAlloc(0, NBAF_NETWORK, sizeof(ETHERARP))) == 0)
        return 0;

    ea = nb->nb_nw.vp;
    ah = (ARPHDR *) & ea->ea_hdr;

    /*
     * Set ARP header.
     */
    ah->ar_hrd = htons(ARPHRD_ETHER);
    ah->ar_pro = htons(ETHERTYPE_IP);
    ah->ar_hln = 6;
    ah->ar_pln = 4;
    ah->ar_op = htons(type);

    /*
     * Set ARP destination data.
     */
    if (mac)
        memcpy(ea->arp_tha, mac, 6);
    else
        memset(ea->arp_tha, 0xff, 6);
    ea->arp_tpa = ip;

    return nb;
}

/*!
 * \brief Send an ARP packet.
 *
 * \note Applications typically do not call this function.
 *
 * \param dev   Identifies the device to use.
 * \param nb    Network buffer structure containing the packet to be sent.
 *              The structure must have been allocated by a previous
 *              call NutNetBufAlloc().
 *
 * \return 0 on success, -1 in case of any errors.
 */
int NutArpOutput(NUTDEVICE * dev, NETBUF * nb)
{
    ETHERARP *ea;
    IFNET *nif;

    ea = nb->nb_nw.vp;

    /*
     * Set ARP source data.
     */
    nif = dev->dev_icb;
    memcpy(ea->arp_sha, nif->if_mac, 6);
    ea->arp_spa = nif->if_local_ip;

    return (*nif->if_output)(dev, ETHERTYPE_ARP, ea->arp_tha, nb);
}

#endif

confnet.c   。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define CONFNET_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <string.h>
#include <time.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XVarBank.h"
#include "XADC.h"

#include "inet.h"
#include "confnet.h"

#if defined(NUTNET)

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#define DEF_OUI          {0x00,0x1B,0x82}

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/*!
 * \brief Random number generator.
 *
 * \return Random number between 0 and (num-1).
 */
static int NutNetRandom(int num)
{
    int bit = 0, acc = 0, multi = 0;
    int i;

    for ( i = 0 ; i < 0x8 ; i++ )
    {
        StartADConvert(i);
        acc += ReadAD(i);
        
        bit |= ((acc & 0x1) << i);
        multi *= bit;
    }
    //debug_printf("%s:%d\n", __FUNCTION__,i);

    return ((bit + acc + multi) % num);
}

/*!
 * \brief Return the unique Ethernet MAC address.
 *
 * \return Pointer to the MAC
 */
u_char *NutNetGetMAC(void)
{
    _PrintRecord *prnrec = GrabPrintRecord();

    static const u_char oui[3] = DEF_OUI;
    static u_char mac[6];

    /*
     * Load the unique Ethernet MAC
     */
    memcpy(mac, prnrec->UniqueMAC, sizeof(mac));

    /*
     * Is it the effective MAC ?
     */
    if (memcmp(mac, oui, 3) != 0) {

        /*
         * Produce MAC at random
         */
        memcpy(mac, oui, 3);
        mac[3] = (u_char)0xFF;
        mac[4] = (u_char)time(_NULL);
        mac[5] = (u_char)NutNetRandom(0x100);

        /*
         * Restore the unique Ethernet MAC
         */
        memcpy(prnrec->UniqueMAC, mac, sizeof(prnrec->UniqueMAC));
    }

    return (u_char *)mac;
}

/*!
 * \brief The port number that the printer should use for it's RAW data.
 *
 * \return Base raw port number
 */
u_short NutNetGetPort(void)
{
    _PrintCfg *prncfg = GrabPrintConfig();

    return (u_short)prncfg->NetRawPort;
}

/*!
 * \brief Load network configuration from non-volatile memory.
 *
 * If no configuration is available in EEPROM, all configuration
 * parameters are cleared to zero. Except the MAC address, which
 * is set to the Ethernet broadcast address.
 *
 * \param name Name of the device.
 *
 * \return 0 if configuration has been read. Otherwise the
 *         return value is -1.
 */
int NutNetLoadConfig(CONST char *name)
{
    _PrintCfg *prncfg = GrabPrintConfig();

    confnet = prncfg->confnet;
    if (confnet.cd_size == sizeof(CONFNET) && strcmp(confnet.cd_name, name) == 0) {
        return 0;
    }

    memset(&confnet, 0, sizeof(confnet));

    /*
     * Set initial MAC address to broadcast. Thanks to Tomohiro
     * Haraikawa, who pointed out that all zeroes is occupied by
     * Xerox and should not be used.
     */
    memset(confnet.cdn_mac, 0xFF, sizeof(confnet.cdn_mac));

    return -1;
}

/*!
 * \brief Save network configuration in non-volatile memory.
 *
 * \return 0 if OK, -1 on failures.
 */
int NutNetSaveConfig(void)
{
    _PrintCfg *prncfg = GrabPrintConfig();

    confnet.cd_size = sizeof(CONFNET);
    prncfg->confnet = confnet;
    return 0;
}

#endif

confnet.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#ifndef CONFNET_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define CONFNET_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif    /* __cplusplus */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

/*!
 * \brief Non-volatile memory location.
 *
 * Offset into non-volatile memory, where Nut/Net stores the network
 * configuration. The default may be overridden by the Configurator.
 */
#ifndef CONFNET_EE_OFFSET
#define CONFNET_EE_OFFSET   64
#endif

#ifndef CONFNET_MAX_IF
#define CONFNET_MAX_IF      1
#endif

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

/*!
 * \brief Network configuration type.
 */
typedef struct _CONFNET CONFNET;

/*!
 * \struct _CONFNET confnet.h sys/confnet.h
 * \brief Network configuration structure.
 *
 * Applications may directly access the global variable \ref confnet to
 * read or modify the current network configuration.
 */
#if defined(__ICCARM__)
#pragma diag_suppress = Pa039    // Use of address of unaligned structure member
#pragma pack ( 1 )
#endif

struct _CONFNET {
    /*! \brief Size of this structure.
     *
     * Used by Nut/Net to verify, that the structure contents is valid
     * after reading it from non-volatile memory.
     */
    u_char cd_size;

    /*! \brief Magic cookie.
     *
     * Contains the device name of the network interface.
     */
    char cd_name[9];

    /*! \brief Ethernet MAC address.
     *
     * Unique Ethernet address of the network interface.
     */
    u_char cdn_mac[6];

    /*! \brief Last used IP address. 
     *
     * Each time Nut/Net receives an IP address during boot, it
     * will store the address in here.
     *
     * If no fixed IP address has been configured (cdn_cip_addr
     * contains 0.0.0.0) and if no DHCP server is available, then
     * Nut/Net will use this one, if it is not 0.0.0.0.
     */
    u_long cdn_ip_addr;

    /*! \brief IP netmask.
     *
     * The netmask is used to determine which machines are
     * available in the local network.
     */
    u_long cdn_ip_mask;

    /*! \brief Default route. 
     *
     * Nut/Net will redirect IP packets to this node, if the
     * target IP is not located in the local network.
     */
    u_long cdn_gateway;

    /*! \brief Configured IP address. 
     *
     * If this address is set to 0.0.0.0, Nut/Net will try
     * to obtain one from the DHCP server.
     */
    u_long cdn_cip_addr;

    /*! \brief Primary DNS IP address. 
     */
    u_long cdn_pdns;

    /*! \brief Secondary DNS IP address. 
     */
    u_long cdn_sdns;
};

#if defined(__ICCARM__)
#pragma pack ( )
#endif

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

#ifdef CONFNET_C
#define EXTERN
#else
#define EXTERN extern
#endif

/*!
 * \brief Global network configuration structure.
 *
 * Contains the current network configuration. Nut/Net will load
 * this structure from non-volatile memory during initialization.
 */
EXTERN CONFNET confnet;

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/

u_char *NutNetGetMAC(void);
u_short NutNetGetPort(void);

#undef EXTERN

#ifdef __cplusplus
}                       /* End of extern "C" { */
#endif    /* __cplusplus */

#endif

errno.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#ifndef ERRNO_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ERRNO_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif    /* __cplusplus */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

#define    EPERM           1        /* Operation not permitted */
#define    ENOENT          2        /* No such file or directory */
#define    ESRCH           3        /* No such process */
#define    EINTR           4        /* Interrupted system call */
#define    EIO             5        /* Input/output error */
#define    ENXIO           6        /* Device not configured */
#define    E2BIG           7        /* Argument list too long */
#define    ENOEXEC         8        /* Exec format error */
#define    EBADF           9        /* Bad file descriptor */
#define    ECHILD          10        /* No child processes */
#define    EDEADLK         11        /* Resource deadlock avoided */
                                /* 11 was EAGAIN */
#define    ENOMEM          12        /* Cannot allocate memory */
#define    EACCES          13        /* Permission denied */
#define    EFAULT          14        /* Bad address */
#define    ENOTBLK         15        /* Block device required */
#define    EBUSY           16        /* Device busy */
#define    EEXIST          17        /* File exists */
#define    EXDEV           18        /* Cross-device link */
#define    ENODEV          19        /* Operation not supported by device */
#define    ENOTDIR         20        /* Not a directory */
#define    EISDIR          21        /* Is a directory */
#define    EINVAL          22        /* Invalid argument */
#define    ENFILE          23        /* Too many open files in system */
#define    EMFILE          24        /* Too many open files */
#define    ENOTTY          25        /* Inappropriate ioctl for device */
#define    ETXTBSY         26        /* Text file busy */
#define    EFBIG           27        /* File too large */
#define    ENOSPC          28        /* No space left on device */
#define    ESPIPE          29        /* Illegal seek */
#define    EROFS           30        /* Read-only file system */
#define    EMLINK          31        /* Too many links */
#define    EPIPE           32        /* Broken pipe */

/* math software */
#define    EDOM            33        /* Numerical argument out of domain */
#define    ERANGE          34        /* Result too large */

/* non-blocking and interrupt i/o */
#define    EAGAIN          35        /* Resource temporarily unavailable */
#define    EWOULDBLOCK     EAGAIN    /* Operation would block */
#define    EINPROGRESS     36        /* Operation now in progress */
#define    EALREADY        37        /* Operation already in progress */

/* ipc/network software -- argument errors */
#define    ENOTSOCK        38        /* Socket operation on non-socket */
#define    EDESTADDRREQ    39        /* Destination address required */
#define    EMSGSIZE        40        /* Message too long */
#define    EPROTOTYPE      41        /* Protocol wrong type for socket */
#define    ENOPROTOOPT     42        /* Protocol not available */
#define    EPROTONOSUPPORT 43        /* Protocol not supported */
#define    ESOCKTNOSUPPORT 44        /* Socket type not supported */
#define    EOPNOTSUPP      45        /* Operation not supported */
#define    EPFNOSUPPORT    46        /* Protocol family not supported */
#define    EAFNOSUPPORT    47        /* Address family not supported by protocol family */
#define    EADDRINUSE      48        /* Address already in use */
#define    EADDRNOTAVAIL   49        /* Can't assign requested address */

/* ipc/network software -- operational errors */
#define    ENETDOWN        50        /* Network is down */
#define    ENETUNREACH     51        /* Network is unreachable */
#define    ENETRESET       52        /* Network dropped connection on reset */
#define    ECONNABORTED    53        /* Software caused connection abort */
#define    ECONNRESET      54        /* Connection reset by peer */
#define    ENOBUFS         55        /* No buffer space available */
#define    EISCONN         56        /* Socket is already connected */
#define    ENOTCONN        57        /* Socket is not connected */
#define    ESHUTDOWN       58        /* Can't send after socket shutdown */
#define    ETOOMANYREFS    59        /* Too many references: can't splice */
#define    ETIMEDOUT       60        /* Operation timed out */
#define    ECONNREFUSED    61        /* Connection refused */

#define    ELOOP           62        /* Too many levels of symbolic links */
#define    ENAMETOOLONG    63        /* File name too long */

/* should be rearranged */
#define    EHOSTDOWN       64        /* Host is down */
#define    EHOSTUNREACH    65        /* No route to host */
#define    ENOTEMPTY       66        /* Directory not empty */

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/


#ifdef __cplusplus
}                       /* End of extern "C" { */
#endif    /* __cplusplus */

#endif

ether.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#ifndef ETHER_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ETHER_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "netbuf.h"
#include "if_var.h"

#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif    /* __cplusplus */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/

void NutEtherInput(NUTDEVICE *dev, NETBUF *nb);
int NutEtherOutput(NUTDEVICE *dev, u_short type, u_char *ha, NETBUF *nb);

#ifdef __cplusplus
}                       /* End of extern "C" { */
#endif    /* __cplusplus */

#endif

ethin.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ETHIN_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"

#include "if_ether.h"
#include "ip.h"
#include "in.h"
#include "ether.h"

#if defined(NUTNET)

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/


/*!
 * \brief Handle incoming Ethernet frames.
 *
 * Splits the Ethernet frame into the data link and the
 * network part. Then the frame is routed to the proper
 * handler, based on the type field in the Ethernet header.
 *
 * If the frame neither contains an IP nor an ARP type
 * telegram, then it is silently discarded.
 *
 * \note This routine is called by the device driver on
 *       incoming ethernet packets. Applications typically do
 *       not call this function.
 *
 * \param dev Identifies the device that received the frame.
 * \param nb  Pointer to a network buffer structure containing 
 *            the ethernet frame.
 */
void NutEtherInput(NUTDEVICE * dev, NETBUF * nb)
{
    ETHERHDR *eh;

    /*
     * Split the Ethernet frame.
     */
    eh = (ETHERHDR *) nb->nb_dl.vp;
    nb->nb_nw.vp = eh + 1;
    nb->nb_nw.sz = nb->nb_dl.sz - sizeof(ETHERHDR);
    nb->nb_dl.sz = sizeof(ETHERHDR);

    /*
     * Route frame to the correct handler.
     */
    switch (ntohs(eh->ether_type)) {
    case ETHERTYPE_IP:
        NutIpInput(dev, nb);
        break;
    case ETHERTYPE_ARP:
        NutArpInput(dev, nb);
        break;
    default:
        NutNetBufFree(nb);
        break;
    }
}

#endif

ethout.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ETHEROUT_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"

#include "if_ether.h"
#include "in.h"
#include "ether.h"

#if defined(NUTNET)

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/


/*!
 * \brief Send Ethernet frame.
 *
 * Send an Ethernet frame of a given type using the specified device.
 *
 * \param dev   Identifies the device to use.
 * \param type  Type of this frame, either ETHERTYPE_IP or ETHERTYPE_ARP.
 * \param ha    MAC address of the destination, set null for broadcasts.
 * \param nb    Network buffer structure containing the packet to be sent.
 *              The structure must have been allocated by a previous
 *              call NutNetBufAlloc() and will be freed if this function
 *              returns with an error.
 *
 * \return 0 on success, -1 in case of any errors.
 */
int NutEtherOutput(NUTDEVICE * dev, u_short type, u_char * ha, NETBUF * nb)
{
    ETHERHDR *eh;
    IFNET *nif;

    if (NutNetBufAlloc(nb, NBAF_DATALINK, sizeof(ETHERHDR)) == 0)
        return -1;

    eh = (ETHERHDR *) nb->nb_dl.vp;
    nif = dev->dev_icb;
    memcpy(eh->ether_shost, nif->if_mac, 6);
    if (ha)
        memcpy(eh->ether_dhost, ha, 6);
    else
        memset(eh->ether_dhost, 0xff, 6);
    eh->ether_type = htons(type);

    /*
     * Call the network device output routine.
     */
    if((*nif->if_send) (dev, nb)) {
        NutNetBufFree(nb);
        return -1;
    }
    return 0;
}

#endif

icmp.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#ifndef ICMP_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ICMP_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "netbuf.h"
#include "if_var.h"

#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif    /* __cplusplus */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/

void NutIcmpInput(NUTDEVICE *dev, NETBUF *nb);
int NutIcmpOutput(u_char type, u_long dest, NETBUF *nb);
int NutIcmpReply(u_char type, u_char code, u_long spec, u_long dest, NETBUF *nb);
int NutIcmpResponse(u_char type, u_char code, u_long spec, NETBUF * nb);

#ifdef __cplusplus
}                       /* End of extern "C" { */
#endif    /* __cplusplus */

#endif

icmpin.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ICMPIN_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"

#include "ip_icmp.h"
#include "ipcsum.h"
#include "icmp.h"
#include "socket.h"
#include "tcp.h"
#include "udp.h"
#include "in.h"
#include "errno.h"

#if defined(NUTNET)

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/*!
 * \brief Translation table from icmp error code to errno.
 */ 

static CONST int icmp_code2errno[16] = 
{
    ENETUNREACH,
    EHOSTUNREACH,
    ENOPROTOOPT,
    ECONNREFUSED,    
    EMSGSIZE,
    EOPNOTSUPP,
    ENETUNREACH,
    EHOSTDOWN,
    ENETUNREACH,
    ENETUNREACH,
    EHOSTUNREACH,
    ENETUNREACH,
    EHOSTUNREACH,
    EHOSTUNREACH,
    EHOSTUNREACH,
    EHOSTUNREACH,
};

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/


/*
 * Send out ICMP echo response.
 */
static int NutIcmpReflect(NUTDEVICE * dev, u_char type, NETBUF * nb)
{
    IPHDR *ip;
    u_long dest;
    IFNET *nif;

    ip = nb->nb_nw.vp;
    dest = ip->ip_src;
    nif = dev->dev_icb;
    ip->ip_src = nif->if_local_ip;
    ip->ip_ttl = MAXTTL;

    return NutIcmpOutput(type, dest, nb);
}

/*
 * Process incoming ICMP messages for destination unreachable.
 */
static int NutIcmpUnreach(NETBUF * nb, int icmp_code)
{
    IPHDR *ih;

    if (nb->nb_ap.sz < sizeof(IPHDR) + 8)
        return -1;

    ih = nb->nb_ap.vp;

    switch (ih->ip_p) {
        case IPPROTO_TCP: 
        {
            TCPHDR *th;
            TCPSOCKET *sock_tcp;

            th = (TCPHDR *) ((char *) ih) + sizeof(IPHDR);
            sock_tcp = NutTcpFindSocket(th->th_dport, th->th_sport, ih->ip_src);
            if (sock_tcp == 0)
                return -1;

            if (sock_tcp->so_state != TCPS_SYN_SENT && sock_tcp->so_state != TCPS_ESTABLISHED)
                return -1;

            NutTcpAbortSocket(sock_tcp, icmp_code2errno[icmp_code]);
        }
        break;

#ifdef NUT_UDP_ICMP_SUPPORT
        case IPPROTO_UDP:
        {
            UDPHDR *uh;
            UDPSOCKET *sock_udp;

            uh = (UDPHDR *) (((char *) ih) + sizeof(IPHDR));
            sock_udp = NutUdpFindSocket(uh->uh_dport);

            if (sock_udp == NULL)
                return -1;

            if (NutUdpSetSocketError(sock_udp, ih->ip_dst, uh->uh_dport, icmp_code2errno[icmp_code]))
                return -1;
        }
        break;
#endif

        default:
            return -1;
    }


    return 0;
}

/*!
 * \brief Handle incoming ICMP packets.
 *
 * Incoming ICMP packets are processed in the background.
 * NutNet currently handles echo request and destination
 * unreachable packets. Any other packet type is silently 
 * discarded.
 *
 * \note This routine is called by the IP layer on incoming 
 *       ICMP datagrams. Applications typically do not call 
 *       this function.
 *
 * \param dev Identifies the device that received the packet.
 * \param nb  Pointer to a network buffer structure containing 
 *            the ICMP datagram.
 */
void NutIcmpInput(NUTDEVICE * dev, NETBUF * nb)
{
    ICMPHDR *icp = (ICMPHDR *) nb->nb_tp.vp;

    /* Silently discard packets, which are too small. */
    if (icp == NULL || nb->nb_tp.sz < sizeof(ICMPHDR)) {
        NutNetBufFree(nb);
        return;
    }

    nb->nb_ap.sz = nb->nb_tp.sz - sizeof(ICMPHDR);
    if (nb->nb_ap.sz) {
        nb->nb_ap.vp = icp + 1;
        nb->nb_tp.sz = sizeof(ICMPHDR);
    }

    switch (icp->icmp_type) {
    case ICMP_ECHO:
        if (NutIcmpReflect(dev, ICMP_ECHOREPLY, nb)) {
            break;
        }
    case ICMP_UNREACH:
        NutIcmpUnreach(nb, icp->icmp_code);
    default:
        NutNetBufFree(nb);
    }
}

#endif

icmpout.c  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define ICMPOUT_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"

#include "in.h"
#include "ip_icmp.h"
#include "ipcsum.h"
#include "icmp.h"

#if defined(NUTNET)

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/*!
 * \brief Send an ICMP datagram.
 *
 * Known ICMP types are:
 *
 * - #ICMP_ECHOREPLY Echo reply
 * - #ICMP_UNREACH Destination unreachable
 * - #ICMP_SOURCEQUENCH Packet lost
 * - #ICMP_REDIRECT Shorter route
 * - #ICMP_ECHO Echo reply
 * - #ICMP_ROUTERADVERT Router advertisement
 * - #ICMP_ROUTERSOLICIT Router solicitation
 * - #ICMP_TIMXCEED Time exceeded
 * - #ICMP_PARAMPROB Bad IP header
 * - #ICMP_TSTAMP Timestamp request
 * - #ICMP_TSTAMPREPLY Timestamp reply
 * - #ICMP_IREQ Information request
 * - #ICMP_IREQREPLY Information reply
 * - #ICMP_MASKREQ Address mask request
 * - #ICMP_MASKREPLY Address mask reply
 *
 * \param type Type of the ICMP message.
 * \param dest Destination IP address.
 * \param nb   Network buffer structure containing the datagram.
 *
 * \return 0 on success, -1 otherwise.
 */
int NutIcmpOutput(u_char type, u_long dest, NETBUF * nb)
{
    ICMPHDR *icp;
    u_short csum;

    icp = (ICMPHDR *) nb->nb_tp.vp;
    icp->icmp_type = type;
    icp->icmp_cksum = 0;

    csum = NutIpChkSumPartial(0, nb->nb_tp.vp, nb->nb_tp.sz);
    icp->icmp_cksum = NutIpChkSum(csum, nb->nb_ap.vp, nb->nb_ap.sz);

    return NutIpOutput(IPPROTO_ICMP, dest, nb);
}

/*!
 * \brief Send an ICMP message to a given destination.
 *
 * \param type Type of the ICMP message. See NutIcmpOutput() for 
 *             a list of valid types.
 * \param code Type subcode.
 * \param spec Type specific data item.
 * \param dest IP address of the target.
 * \param nb   Network buffer structure containing the message to be sent.
 *             The structure must have been allocated by a previous
 *             call NutNetBufAlloc() and will be freed if this function
 *             returns with an error.
 *
 * \return 0 on success, -1 otherwise.
 */
int NutIcmpReply(u_char type, u_char code, u_long spec, u_long dest, NETBUF * nb)
{
    ICMPHDR *icp;

    if ((nb = NutNetBufAlloc(nb, NBAF_TRANSPORT, sizeof(ICMPHDR))) == 0)
        return -1;

    icp = (ICMPHDR *) nb->nb_tp.vp;
    icp->icmp_code = code;
    icp->icmp_spec = spec;

    return NutIcmpOutput(type, dest, nb);
}

/*!
 * \brief Send an ICMP message as a response to a given destination.
 *
 * \param type Type of the ICMP message. See NutIcmpOutput() for 
 *             a list of valid types.
 * \param code Type subcode.
 * \param spec Type specific data item.
 * \param nb   Network buffer structure containing the previously recevied
 *             network packet. According to RFC792 the complete ip header 
 *             and the first 8 bytes of the transport netbuf is used as the
 *             application data for the response. If this function returns 
 *             with an error, the buffer is freed. The destination addess is
 *             taken from the ip header.
 *
 * \return 0 on success, -1 otherwise.
 */
int NutIcmpResponse(u_char type, u_char code, u_long spec, NETBUF * nb)
{
    IPHDR *ip;
    u_long dest;

    ip = nb->nb_nw.vp;
    dest = ip->ip_src;

    if ((nb = NutNetBufAlloc(nb, NBAF_APPLICATION, sizeof(IPHDR) + 8)) == 0)
        return -1;

    memcpy(nb->nb_ap.vp, nb->nb_nw.vp, sizeof(IPHDR));
    memcpy((u_char *)nb->nb_ap.vp + sizeof(IPHDR), nb->nb_tp.vp, 8);

    return NutIcmpReply(type, code, spec, dest, nb);
}

#endif

if_arp.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#ifndef IF_ARP_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define IF_ARP_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif    /* __cplusplus */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

#define ARPHRD_ETHER    1   /*!< \brief ethernet hardware format */

#define ARPOP_REQUEST   1   /*!< \brief request to resolve address */
#define ARPOP_REPLY     2   /*!< \brief response to previous request */

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

/*!
 * \typedef ARPHDR
 * \brief ARP packet header type.
 */
#if defined(__ICCARM__)
#pragma diag_suppress = Pa039    // Use of address of unaligned structure member
#pragma pack ( 1 )
#endif

typedef struct arphdr {
    u_short ar_hrd;    /*!< \brief Format of hardware address. 
                        *   Nut/Net supports ARPHRD_ETHER only. 
                        */
    u_short ar_pro;    /*!< \brief Format of protocol address.
                        *   Only ETHERTYPE_IP is supported by Nut/Net.
                        */
    u_char  ar_hln;    /*!< \brief Length of hardware address. */
    u_char  ar_pln;    /*!< \brief Length of protocol address. */
    u_short ar_op;     /*!< \brief ARP operation.
                        *   May be either ARPOP_REQUEST or ARPOP_REPLY.
                        */
} ARPHDR;

#if defined(__ICCARM__)
#pragma pack ( )
#endif

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/

#ifdef __cplusplus
}                       /* End of extern "C" { */
#endif    /* __cplusplus */

#endif

if_ether.h  。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

#ifndef IF_ETHER_H

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define IF_ETHER_H

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "if_var.h"
#include "if_arp.h"

#ifdef __cplusplus
extern "C" {            /* Assume C declarations for C++ */
#endif    /* __cplusplus */

/******************************************************************************
 *                                                                            *
 *                        G L O B A L   D E F I N E S                         *
 *                                                                            *
 ******************************************************************************/

/*! \brief Length of an Ethernet address. */
#define    ETHER_ADDR_LEN      6

/*! \brief Length of the Ethernet type field. */
#define    ETHER_TYPE_LEN      2

/*! \brief Length of the Ethernet CRC. */
#define    ETHER_CRC_LEN       4

/*! \brief Length of an Ethernet header. */
#define    ETHER_HDR_LEN       (ETHER_ADDR_LEN + ETHER_ADDR_LEN + ETHER_TYPE_LEN)

#ifndef ETHER_MIN_LEN
/*! \brief Minimum frame length, including CRC. */
#define    ETHER_MIN_LEN       64
#endif

#ifndef ETHER_MAX_LEN
/*! \brief Maximum frame length, including CRC. */
#define    ETHER_MAX_LEN       1518
#endif


/*! \brief Ethernet maximum transfer unit.
 *
 * Must be checked by the hardware driver.
 */
#define ETHERMTU    (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)

/*! \brief Ethernet minimum transfer unit. 
 *
 * Must be checked by the hardware driver.
 */
#define ETHERMIN    (ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)

#define ETHERTYPE_IP    0x0800  /*!< \brief IP protocol */
#define ETHERTYPE_ARP   0x0806  /*!< \brief Address resolution protocol */

/*! 
 * \brief Determine if a given Ethernet address is zero.
 *
 * \param ea Pointer to a character array containing the address.
 *
 * Return 1 if the address is zero. Otherwise 0 is returned.
 */
#define    ETHER_IS_ZERO(ea) (((ea)[0] | (ea)[1] | (ea)[2] | (ea)[3] | (ea)[4] | (ea)[5]) == 0)

/*! 
 * \brief Determine if a given Ethernet address is a broadcast address.
 *
 * \param ea Pointer to a character array containing the address.
 *
 * Return 1 if the address is a broadcast address. Otherwise 0 is returned.
 */
#define    ETHER_IS_BROADCAST(ea) (((ea)[0] & (ea)[1] & (ea)[2] & (ea)[3] & (ea)[4] & (ea)[5]) == 0xFF)

/*! 
 * \brief Determine if a given Ethernet address is a multicast address.
 *
 * The broadcast address is defined as a special multicast address.
 *
 * \param ea Pointer to a character array containing the address.
 *
 * Return 1 if the address is a multicast address. Otherwise 0 is returned.
 */
#define    ETHER_IS_MULTICAST(ea) ((ea)[0] & 1) 

/*! 
 * \brief Determine if a given Ethernet address is a unicast address.
 *
 * By definition, an address with all zeros is not a valid unicast address.
 *
 * \param ea Pointer to a character array containing the address.
 *
 * Return 1 if the address is a unicast address. Otherwise 0 is returned.
 */
#define    ETHER_IS_UNICAST(ea) (!ETHER_IS_ZERO(ea) && !ETHER_IS_MULTICAST(ea)) 

/******************************************************************************
 *                                                                            *
 *                 S T R U C T U R E   D E F I N I T I O N S                  *
 *                                                                            *
 ******************************************************************************/

/*!
 * \typedef ETHERHDR
 * \brief Ethernet protocol header type.
 */
#if defined(__ICCARM__)
#pragma diag_suppress = Pa039    // Use of address of unaligned structure member
#pragma pack ( 1 )
#endif

typedef struct ether_header {
    /*! \brief Destination MAC address. */
    u_char  ether_dhost[ETHER_ADDR_LEN];
    /*! \brief Source MAC address. */
    u_char  ether_shost[ETHER_ADDR_LEN];
    /*! \brief Protocol type. */
    u_short ether_type;
} ETHERHDR;

/*!
 * \typedef ETHERARP
 * \brief Ethernet ARP protocol type.
 */
#if defined(__ICCARM__)
#pragma diag_suppress = Pa039    // Use of address of unaligned structure member
#pragma pack ( 1 )
#endif

typedef struct ether_arp {
    ARPHDR ea_hdr;     /*!< \brief Fixed-size header. */
    u_char arp_sha[6]; /*!< \brief Source hardware address. */
    u_long arp_spa;    /*!< \brief Source protocol address. */
    u_char arp_tha[6]; /*!< \brief Target hardware address. */
    u_long arp_tpa;    /*!< \brief Target protocol address. */
} ETHERARP;

#if defined(__ICCARM__)
#pragma pack ( )
#endif

/******************************************************************************
 *                                                                            *
 *    G L O B A L   V A R I A B L E S   -   N O   I N I T I A L I Z E R S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *       G L O B A L   V A R I A B L E S   -   I N I T I A L I Z E R S        *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                   F U N C T I O N   P R O T O T Y P E S                    *
 *                                                                            *
 ******************************************************************************/

u_char *ether_aton(CONST char *str);
char *ether_ntoa(CONST u_char *mac);

void NutArpInput(NUTDEVICE *dev, NETBUF *nb);

NETBUF *NutArpAllocNetBuf(u_short type, u_long ip, u_char *mac);
int NutArpOutput(NUTDEVICE *dev, NETBUF *nb);

void NutArpCacheUpdate(NUTDEVICE *dev, u_long ip, u_char *ha);

int NutArpCacheQuery(NUTDEVICE *dev, u_long ip, u_char *mac);

#ifdef __cplusplus
}                       /* End of extern "C" { */
#endif    /* __cplusplus */

#endif

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值