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

📄 arp.c

📁 嵌入式RMON,RMON为Remote monitor的缩写,基于SNMP为网络提供主动监控及错误告警,智能交换路由必备协议
💻 C
字号:
/* Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group *//* See file COPYING 'GNU General Public Licence' for copyright details   */#include <stdio.h>#include <memory.h>#include <timer.h>#include <ip.h>#include "arp.h"#define ARP_OPCODE_REQUEST  1#define ARP_OPCODE_REPLY    2typedef struct _ARP_FRAME   ARP_FRAME;typedef struct _FRAME       FRAME;struct _ARP_FRAME{    WORD    typeHard;    WORD    typeProt;    BYTE    lengthHard;    BYTE    lengthProt;    WORD    opcode;    BYTE    *senderHard;    BYTE    *senderProt;    BYTE    *targetHard;    BYTE    *targetProt;};struct _FRAME{    WORD    typeHard;    WORD    typeProt;    BYTE    lengthHard;    BYTE    lengthProt;    WORD    opcode;};static ARP_DESCR    *DescrFind(MAC_IFACE *iface, WORD prot);static ARP_ENTRY    *EntryFind(ARP_DESCR *descr, BYTE *addr);static ARP_ENTRY    *EntryUpdate(ARP_DESCR *descr,                        BYTE *addrProt, BYTE *addrHard);static ARP_ENTRY    *EntryCreate(ARP_DESCR *descr, BYTE *addrProt,                                        BYTE *addrHard, BOOLEAN dynamic);static void         EntryClean(TIMER_DESCR *timer, ULONG now, void *parm);static BOOLEAN      RequestReply(ARP_DESCR *descr, BYTE *addr, ARP_ENTRY *entry);static void         RequestTimeout(TIMER_DESCR *timer, ULONG now, void *parm);static ARP_REQUEST  *RequestCreate(ARP_DESCR *descr, BYTE *addr);static ARP_REQUEST  *RequestFind(ARP_DESCR *descr, BYTE *addr);static BOOLEAN      Rcve(MAC_IFACE *iface, CHAIN *chain, MAC_HDR *hdr);static BOOLEAN      Send(ARP_DESCR *descr, WORD opcode,                            BYTE *addrProt, BYTE *addrHard);static CHAIN        *FrameEncode(CHAIN *chain, ARP_FRAME *arp);static CHAIN        *FrameDecode(CHAIN *chain, ARP_FRAME *arp);static void         Dump(ARP_DESCR *d);MAC_PROT arpMac ={    Rcve,    MAC_PROT_ARP};ARP_DESCR   *arpDescrList = 0;TIMER_DESCR *arpCleanTimer = 0;BOOLEAN ArpInit(void){    static BOOLEAN init = FALSE;        if (!init)    {        if (MacProtRegister(&arpMac))        {            arpCleanTimer = TimerRegister(EntryClean, 0, ARP_ENTRY_TIMEOUT,                TIMER_FOREVER, TIMER_TYPE_SKIP);            if (arpCleanTimer != 0)                init = TRUE;        }    }    return init;}BOOLEAN ArpRegister(ARP_DESCR *arp){    arp->requestList    = 0;    arp->entryList      = 0;    arp->next           = arpDescrList;    arpDescrList        = arp;    return TRUE;}void ArpRemove(ARP_DESCR *arp){    ARP_DESCR **p;    for (p=&arpDescrList; *p!=0; p=&(*p)->next)    {        if (*p==arp)        {            *p = (*p)->next;        }    }}BOOLEAN ArpRequest(MAC_IFACE *iface, WORD prot, BYTE *addr,                ARP_REPLY Reply, void *specific){    ARP_DESCR   *d;    ARP_REQUEST *r;    ARP_QUE     *q;        d = DescrFind(iface, prot);    if (d==0)        return FALSE;    r = RequestFind(d, addr);    if (r == 0)    {        r = RequestCreate(d, addr);        if (r == 0)            return FALSE;    }    q = DnpapMalloc(sizeof(ARP_QUE));    if (q == 0)        return FALSE;    q->Reply    = Reply;    q->specific = specific;    q->next     = r->queList;    r->queList  = q;    return TRUE;}ARP_ENTRY *ArpFind(MAC_IFACE *iface, WORD prot, BYTE *addr){    ARP_DESCR   *d;    ARP_ENTRY   *e;    d = DescrFind(iface, prot);    if (d==0)        return 0;    e = EntryFind(d, addr);    return e;}static ARP_DESCR *DescrFind(MAC_IFACE *iface, WORD prot){    ARP_DESCR *d;    for (d=arpDescrList; d!=0; d=d->next)    {        if (d->prot == prot && d->iface == iface)            break;    }    return d;}static ARP_ENTRY *EntryFind(ARP_DESCR *descr, BYTE *addr){    ARP_ENTRY *e;        for (e=descr->entryList; e!=0; e=e->next)    {        if (memcmp(e->addrProt, addr, descr->addrLength) == 0)            break;    }    return e;}static ARP_ENTRY *EntryUpdate(ARP_DESCR *descr,                        BYTE *addrProt, BYTE *addrHard){    ARP_ENTRY *e;    for (e=descr->entryList; e!=0; e=e->next)    {        if (memcmp(e->addrProt, addrProt, descr->addrLength) == 0)            break;    }    if (e==0 || !e->dynamic)        return 0;    memcpy(e->addrHard, addrHard, descr->iface->addrLength);    e->update = TRUE;    return e;        }static ARP_ENTRY *EntryCreate(ARP_DESCR *descr, BYTE *addrProt,                                        BYTE *addrHard, BOOLEAN dynamic){    ARP_ENTRY *e;    for (e=descr->entryList; e!=0; e=e->next)    {        if (memcmp(e->addrProt, addrProt, descr->addrLength) == 0)            break;    }    if (e==0)    {        e=DnpapMalloc(sizeof(ARP_ENTRY));        if (e==0)            return 0;        memcpy(e->addrProt, addrProt, descr->addrLength);        e->next = descr->entryList;        descr->entryList = e;    }    memcpy(e->addrHard, addrHard, descr->iface->addrLength);    e->dynamic = dynamic;    e->update = TRUE;    return e;}static void EntryClean(TIMER_DESCR *timer, ULONG now, void *parm){    ARP_DESCR *d;    ARP_ENTRY **p, *e;    for (d=arpDescrList; d!=0; d=d->next)    {        p=&d->entryList;        while (*p!=0)        {            e = *p;            if (e->dynamic)            {                if (e->update)                {                    e->update = FALSE;                    p=&(*p)->next;                }                else                {                    *p=(*p)->next;                    DnpapFree(e);                }            }        }    }}static BOOLEAN RequestReply(ARP_DESCR *descr, BYTE *addr, ARP_ENTRY *entry){    ARP_REQUEST **p, *request;    ARP_QUE     *q, *que;        for (p=&descr->requestList; *p!=0; p=&(*p)->next)    {        if (memcmp((*p)->addr, addr, descr->addrLength)==0)            break;    }    request = *p;    if (request==0)        return FALSE;        TimerRemove(request->timer);    q=request->queList;    while (q!=0)    {        que = q;        q = q->next;        if (que->Reply!=0)            que->Reply(descr->iface, entry, que->specific);        DnpapFree(que);    }    *p=(*p)->next;    DnpapFree(request);    return FALSE;}static ARP_REQUEST *RequestCreate(ARP_DESCR *descr, BYTE *addr){    ARP_REQUEST *r;        if (!Send(descr, ARP_OPCODE_REQUEST, addr, 0))        return 0;    r = DnpapMalloc(sizeof(ARP_REQUEST));    if (r==0)        return 0;    memcpy(r->addr, addr, descr->addrLength);    r->retry            = ARP_REQUEST_RETRIES;    r->queList          = 0;    r->timer            = TimerRegister(RequestTimeout, r,        ARP_REQUEST_TIMEOUT, TIMER_FOREVER, TIMER_TYPE_SKIP);    r->descr            = descr;    r->next             = descr->requestList;    descr->requestList  = r;            return r;}static ARP_REQUEST *RequestFind(ARP_DESCR *descr, BYTE *addr){    ARP_REQUEST *r;        for (r=descr->requestList; r!=0; r=r->next)    {        if (memcmp(r->addr, addr, descr->addrLength)==0)            break;    }    return r;}static void RequestTimeout(TIMER_DESCR *timer, ULONG now, void *parm){    ARP_REQUEST *r;    r = parm;    if (--r->retry != 0)    {        Send(r->descr, ARP_OPCODE_REQUEST, r->addr, 0);    }    else    {        RequestReply(r->descr, r->addr, 0);    }}static void Dump(ARP_DESCR *d){    ARP_ENTRY   *e;    ARP_REQUEST *r;    printf("ARP table for iface %s\n", d->iface->descr);    for (e = d->entryList; e!=0; e=e->next)    {        printf("%d.%d.%d.%d = %02x:%02x:%02x:%02x:%02x:%02x\n",            e->addrProt[0],            e->addrProt[1],            e->addrProt[2],            e->addrProt[3],            e->addrHard[0],            e->addrHard[1],            e->addrHard[2],            e->addrHard[3],            e->addrHard[4],            e->addrHard[5]);    }                                  for (r = d->requestList; r!=0; r=r->next)    {        printf("%d.%d.%d.%d  %d\n",            r->addr[0],            r->addr[1],            r->addr[2],            r->addr[3],            r->retry);    }                              }static BOOLEAN Rcve(MAC_IFACE *iface, CHAIN *chain, MAC_HDR *hdr){    ARP_FRAME arp;    ARP_DESCR *d;    ARP_ENTRY *e;    CHAIN     *new;    BOOLEAN   success = TRUE;        new = FrameDecode(chain, &arp);    if (new != 0)    {        if (arp.typeHard == iface->arp)        {            d = DescrFind(iface, arp.typeProt);            if (d != 0)            {                e = EntryUpdate(d, arp.senderProt, arp.senderHard);                if (memcmp(d->addr, arp.targetProt, d->addrLength)==0)                {                    if (e==0)                    {                        e = EntryCreate(d, arp.senderProt, arp.senderHard, TRUE);                    }                    if (arp.opcode == ARP_OPCODE_REQUEST)                        success = Send(d, ARP_OPCODE_REPLY, arp.senderProt, arp.senderHard);                    else                        success = RequestReply(d, e->addrProt, e);                }            }        }        if (new != chain)            ChainFree(new);    }    return success;}static BOOLEAN Send(ARP_DESCR *descr, WORD opcode,                            BYTE *addrProt, BYTE *addrHard){    ARP_FRAME arp;    MAC_HDR   hdr;    CHAIN     *chain;    BOOLEAN   success = FALSE;    arp.typeHard    = descr->iface->arp;    arp.typeProt    = descr->prot;    arp.lengthHard  = (BYTE)descr->iface->addrLength;    arp.lengthProt  = (BYTE)descr->addrLength;    arp.opcode      = opcode;    arp.senderHard  = descr->iface->addr;    arp.senderProt  = descr->addr;    arp.targetProt  = addrProt;        hdr.src         = descr->iface->addr;    hdr.type        = MAC_PROT_ARP;        if (opcode == ARP_OPCODE_REQUEST)    {        arp.targetHard  = descr->iface->addrBroadcast;        hdr.dst         = descr->iface->addrBroadcast;    }    else    {        arp.targetHard  = addrHard;        hdr.dst         = addrHard;    }    chain = FrameEncode(0, &arp);    if (chain!=0)    {        success = MacSend(descr->iface, chain, &hdr);        ChainFree(chain);    }    return success;}static CHAIN *FrameEncode(CHAIN *chain, ARP_FRAME *arp){    FRAME *f;    BYTE  *p;    f = (FRAME *)ChainPush(&chain,        sizeof(FRAME)+ 2*arp->lengthProt+ 2*arp->lengthHard);    if (f == 0)        return 0;    f->typeHard   = IpH2NWord(arp->typeHard);    f->typeProt   = IpH2NWord(arp->typeProt);    f->lengthHard = arp->lengthHard;    f->lengthProt = arp->lengthProt;    f->opcode     = IpH2NWord(arp->opcode);    p = (BYTE *)f + sizeof(FRAME);    memcpy(p, arp->senderHard, arp->lengthHard);    p+=arp->lengthHard;    memcpy(p, arp->senderProt, arp->lengthProt);    p+=arp->lengthProt;    memcpy(p, arp->targetHard, arp->lengthHard);    p+=arp->lengthHard;    memcpy(p, arp->targetProt, arp->lengthProt);        return chain;}static CHAIN *FrameDecode(CHAIN *chain, ARP_FRAME *arp){    FRAME   *f;    BYTE    *p;    f = (FRAME *)ChainPop(&chain, sizeof(FRAME));    if (f == 0)        return 0;    arp->typeHard   = IpN2HWord(f->typeHard);       arp->typeProt   = IpN2HWord(f->typeProt);       arp->lengthHard = f->lengthHard;     arp->lengthProt = f->lengthProt;     arp->opcode     = IpH2NWord(f->opcode);        p = (BYTE *)ChainPop(&chain, 2*arp->lengthProt+ 2*arp->lengthHard);    arp->senderHard = p;    p+=arp->lengthHard;    arp->senderProt = p;    p+=arp->lengthProt;    arp->targetHard = p;    p+=arp->lengthHard;    arp->targetProt = p;        return chain;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -