📄 icmp.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 + -