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

📄 icmp.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 <stdlib.h>#include <stdio.h>#ifdef UNIX#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <netinet/in.h>#include <chain.h>  #include <dinet.h>#include <nw.h>#endif#include <ip.h>#include "icmp.h"typedef struct _HDR         HDR;typedef struct _HDR_EXTRA   HDR_EXTRA;struct _HDR{    BYTE        type;    BYTE        code;    WORD        check;};struct _HDR_EXTRA{    WORD        id;    WORD        seqnr;};static CHAIN        *HdrDecode(CHAIN *chain, ICMP_HDR *icmpHdr);static CHAIN        *HdrEncode(CHAIN *chain, ICMP_HDR *icmpHdr);static ICMP_DESCR   *DescrFind(ICMP_HDR *icmpHdr, IP_HDR *ipHdr);static WORD         Wildcards(ICMP_DESCR *icmp);static BOOLEAN      IdInUse(WORD id);#ifdef UNIXstatic void         Rcve(NW_DG *dg, char *addr, BYTE *frame, int length, void *parm);static BOOLEAN      Addr2Host(char *addr, ULONG *host);#elsestatic BOOLEAN      Rcve(CHAIN *chain, IP_HDR *ipHdr);#endif#ifdef OS2IP_PROT icmpIp ={    Rcve,    IP_PROT_ICMP};#endifICMP_DESCR *icmpDescrList = 0;WORD        icmpId = 0;#ifdef UNIXNW_DG       *icmpNw=0;#endif                      BOOLEAN IcmpInit(void){    static BOOLEAN init = FALSE;        if (!init)    { #ifdef UNIX            icmpNw=NwDgAccept("icmp", Rcve, 0);        init=(icmpNw!=0); #else        init = IpProtRegister(&icmpIp);#endif    }    return init;}BOOLEAN IcmpRegister(ICMP_DESCR *icmp){    ICMP_DESCR **p;    for (p=&icmpDescrList; *p!=0; p=&(*p)->next)    {        if (Wildcards(*p) > Wildcards(icmp))            break;    }    icmp->next = *p;    *p = icmp;    return TRUE;}BOOLEAN IcmpRemove(ICMP_DESCR *icmp){    ICMP_DESCR **p;    for (p=&icmpDescrList; *p!=0; p=&(*p)->next)    {        if (*p == icmp)        {            *p = icmp->next;            return TRUE;        }    }    return FALSE;}BOOLEAN IcmpSend(CHAIN *chain, ICMP_HDR *icmpHdr, IP_HDR *ipHdr){ #ifdef UNIX    CHAIN       *new;    BYTE        addr[32];    int         length;    BYTE        *frame;    BOOLEAN     success = FALSE;        new = HdrEncode(chain, icmpHdr);    if (new != 0)    {        length = ChainLength(chain);        frame = DnpapMalloc(length);          if (frame!=0)        {            if (ChainCopy(chain, frame, length))            {                sprintf(addr,"icmp:%s",Inet_NtoA(htonl(ipHdr->dst)));                             if (NwDgSendTo(0, addr, frame, length))                    success = TRUE;            }            DnpapFree(frame);        }     }    return success;  #else    CHAIN       *new;    BOOLEAN     success = FALSE;        new = HdrEncode(chain, icmpHdr);    if (new != 0)    {        ipHdr->prot     = IP_PROT_ICMP;        ipHdr->offset   = 0;        ipHdr->flags    = 0;        ipHdr->tos      = 0;        if(IpSend(new, ipHdr))        {            success = TRUE;        }        if (new != chain)            ChainFree(new);    }        return success;#endif}WORD IcmpAnyId(VOID){    WORD i;        for (i=icmpId+1;i!=icmpId;i++)    {        if (i==ICMP_ID_ANY)            i++;        if (!IdInUse(i))        {            icmpId=i;            return i;        }    }    return ICMP_ID_ANY;}static BOOLEAN IdInUse(WORD id){    ICMP_DESCR *p;        for (p=icmpDescrList;p!=0;p=p->next)    {        if (p->id==id)            return TRUE;    }    return FALSE;}static CHAIN *HdrDecode(CHAIN *chain, ICMP_HDR *icmpHdr){    HDR *h;    if (IpHdrCheck(chain, ChainLength(chain)) != 0)        return 0;        h = (HDR *)ChainPop(&chain, sizeof(HDR));    if (h==0)        return 0;        icmpHdr->type  = h->type;    icmpHdr->code  = h->code;    icmpHdr->check = IpN2HWord(h->check);    switch(icmpHdr->type)    {        case ICMP_UNREACHABLE:        case ICMP_QUENCH:        case ICMP_TIME_EXCEEDED:        case ICMP_REDIRECT:        case ICMP_PARM_PROBLEM:        {            icmpHdr->id    = ICMP_ID_ANY;            icmpHdr->seqnr = ICMP_SEQNR_ANY;            break;        }        case ICMP_STAMP_REQUEST:        case ICMP_STAMP_REPLY:        case ICMP_ECHO_REQUEST:        case ICMP_ECHO_REPLY:        case ICMP_INFO_REQUEST:        case ICMP_INFO_REPLY:        {            HDR_EXTRA *e;            e = (HDR_EXTRA *)ChainPop(&chain, sizeof(HDR_EXTRA));            if (e==0)                return 0;            icmpHdr->id    = IpN2HWord(e->id);            icmpHdr->seqnr = IpN2HWord(e->seqnr);            break;        }    }    return chain;}static CHAIN *HdrEncode(CHAIN *chain, ICMP_HDR *icmpHdr){    HDR *h;        switch(icmpHdr->type)    {    case ICMP_UNREACHABLE:    case ICMP_QUENCH:    case ICMP_TIME_EXCEEDED:    case ICMP_REDIRECT:    case ICMP_PARM_PROBLEM:        {            h = (HDR *)ChainPush(&chain, sizeof(HDR));            if (h==0)                return 0;            break;        }    case ICMP_STAMP_REQUEST:    case ICMP_STAMP_REPLY:    case ICMP_ECHO_REQUEST:    case ICMP_ECHO_REPLY:    case ICMP_INFO_REQUEST:    case ICMP_INFO_REPLY:        {            HDR_EXTRA *e;            h = (HDR *)ChainPush(&chain, sizeof(HDR) + sizeof(HDR_EXTRA));            if (h==0)                return 0;            e = (HDR_EXTRA *)((BYTE *)h + sizeof(HDR));            e->id    = IpH2NWord(icmpHdr->id);            e->seqnr = IpH2NWord(icmpHdr->seqnr);            break;		}	default:		h = NULL;		break;    }        h->type     = icmpHdr->type;      h->code     = icmpHdr->code;      h->check    = 0;    h->check    = IpHdrCheck(chain, ChainLength(chain));        return chain;}static ICMP_DESCR *DescrFind(ICMP_HDR *icmpHdr, IP_HDR *ipHdr){    ICMP_DESCR *p;    for (p=icmpDescrList; p!=0; p=p->next)    {        if (                 (p->locAddr==ICMP_ADDR_ANY || p->locAddr==ipHdr->dst)    &&                 (p->remAddr==ICMP_ADDR_ANY || p->remAddr==ipHdr->src)    &&                (p->type==ICMP_TYPE_ANY    || p->type==icmpHdr->type)    &&                (p->code==ICMP_CODE_ANY    || p->code==icmpHdr->code)    &&                (p->id==ICMP_ID_ANY        || p->id==icmpHdr->id)        &&                (p->seqnr==ICMP_SEQNR_ANY  || p->seqnr==icmpHdr->seqnr)           )         {            return p;        }    }       return 0;}                                 static WORD Wildcards(ICMP_DESCR *icmp){    WORD n=0;    if (icmp->locAddr == ICMP_ADDR_ANY)        n++;    if (icmp->remAddr == ICMP_ADDR_ANY)        n++;    if (icmp->type == ICMP_TYPE_ANY)        n++;    if (icmp->code == ICMP_CODE_ANY)        n++;    if (icmp->id == ICMP_ID_ANY)        n++;    if (icmp->seqnr == ICMP_SEQNR_ANY)        n++;    return n;}#ifdef UNIXstatic void Rcve(NW_DG *dg, char *addr, BYTE *frame, int length, void *parm){    CHAIN       *new, *chain;    ICMP_HDR    icmpHdr;    IP_HDR      ipHdr;    ICMP_DESCR  *descr;    BOOLEAN     success = FALSE;                                    if (Addr2Host(addr, &(ipHdr.src)))    {        chain=ChainAlloc(0, frame, length, length, 0, 0);         if (chain!=0)        {             new = HdrDecode(chain, &icmpHdr);            if (new != 0)            {                     descr = DescrFind(&icmpHdr, &ipHdr);                if(descr)                {                    if(descr->Rcve(descr, chain, &icmpHdr, &ipHdr))                    {                        success = TRUE;                    }                }                if (new != chain)                    ChainFree(new);             }               ChainFree(chain);        }     }}static BOOLEAN Addr2Host(char *addr, ULONG *host){    char                        *p,*q;     char                        string[32];     struct hostent              *ent;        p=addr;        q=string;    while(*p!=':' && *p!=0)        *q++=*p++;    *q++=0;         if (strcmp(string,"icmp")!=0)        return FALSE;        if (*p++!=':')         return FALSE;            q=string;    while(*p!=':' && *p!=0)        *q++=*p++;    *q++=0;             *host=ntohl(inet_addr(string));    if (*host == -1)    {        ent=gethostbyname(string);        if (ent!=0)          {            *host=ntohl(((struct in_addr *)ent->h_addr_list[0])->s_addr);         }        else        {                DnpapMessage(DMC_ERROR, ICMP_ERROR, "can't resolve host");               return FALSE;        }    }        return TRUE;}#elsestatic BOOLEAN Rcve(CHAIN *chain, IP_HDR *ipHdr){    CHAIN       *new;    ICMP_HDR    icmpHdr;    ICMP_DESCR  *descr;    BOOLEAN     success = FALSE;        new = HdrDecode(chain, &icmpHdr);    if (new != 0)    {        descr = DescrFind(&icmpHdr, ipHdr);        if(descr)        {            if(descr->Rcve(descr, chain, &icmpHdr, ipHdr))            {                success = TRUE;            }        }        if (new != chain)            ChainFree(new);    }        return success;}#endif

⌨️ 快捷键说明

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