📄 udp.c
字号:
/* Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group *//* See file COPYING 'GNU General Public Licence' for copyright details */#include <ctype.h>#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 <dinet.h>#include <nw.h>#endif#include "udp.h"typedef struct _HDR HDR;typedef struct _HDR_PSEUDO HDR_PSEUDO;struct _HDR_PSEUDO{ DWORD src; DWORD dst; BYTE zero; BYTE prot; WORD length;};struct _HDR{ WORD src; WORD dst; WORD length; WORD check;};static WORD Wildcards(UDP_DESCR *udp);static UDP_DESCR *DescrFind(UDP_HDR *udpHdr, IP_HDR *ipHdr);static BOOLEAN PortInUse(WORD port);#ifdef UNIXstatic void Rcve(NW_DG *dg, char *addr, BYTE *frame, int length, void *parm);static BOOLEAN Addr2HostPort(char *addr, ULONG *host, USHORT *port);#elsestatic BOOLEAN Rcve(CHAIN *chain, IP_HDR *ipHdr);static WORD HdrCheck(CHAIN *chain, IP_HDR *ipHdr);static CHAIN *HdrEncode(CHAIN *chain, UDP_HDR *udpHdr, IP_HDR *ipHdr);static CHAIN *HdrDecode(CHAIN *chain, UDP_HDR *udpHdr, IP_HDR *ipHdr);#endif#ifdef OS2IP_PROT udpIp ={ Rcve, IP_PROT_UDP};#endifUDP_DESCR *udpDescrList = 0;UDP_STAT udpStat;WORD udpPort = 1024;BOOLEAN UdpInit(void){#ifdef UNIX return TRUE;#else static BOOLEAN init = FALSE; if (!init) { init = IpProtRegister(&udpIp); } return init;#endif}BOOLEAN UdpRegister(UDP_DESCR *udp){ UDP_DESCR **p; #ifdef UNIX BYTE addr[32]; sprintf(addr,"udp:*:%d",udp->locPort); udp->nw=NwDgAccept(addr, Rcve, udp); if (udp->nw==0) return FALSE;#endif for (p=&udpDescrList; *p!=0; p=&(*p)->next) { if (Wildcards(*p) > Wildcards(udp)) break; } udp->next = *p; *p = udp; return TRUE;}BOOLEAN UdpRemove(UDP_DESCR *udp){ UDP_DESCR **p; #ifdef UNIX NwDgClose(udp->nw);#endif for (p=&udpDescrList; *p!=0; p=&(*p)->next) { if (*p == udp) { *p = udp->next; return TRUE; } } return FALSE;}UDP_STAT *UdpStatistics(void){ return &udpStat;}BOOLEAN UdpSend(CHAIN *chain, UDP_HDR *udpHdr, IP_HDR *ipHdr, UDP_DESCR *descr){#ifdef UNIX BOOLEAN success = FALSE; BYTE *frame; BYTE addr[32]; int length; NW_DG *nw; if (descr != 0) nw = descr->nw; else nw = 0; length = ChainLength(chain); frame = DnpapMalloc(length); if (frame!=0) { if (ChainCopy(chain, frame, length)) { sprintf(addr,"udp:%s:%d",Inet_NtoA(htonl(ipHdr->dst)),udpHdr->dst); if (NwDgSendTo(nw, addr, frame, length)) success = TRUE; } DnpapFree(frame); }#else CHAIN *new; BOOLEAN success = FALSE; if (udpHdr->src == UDP_PORT_ANY) udpHdr->src = 2222; new = HdrEncode(chain, udpHdr, ipHdr); if (new != 0) { ipHdr->prot = IP_PROT_UDP; ipHdr->offset = 0; ipHdr->flags = 0; ipHdr->tos = 0; if(IpSend(new, ipHdr)) { success = TRUE; } if (new != chain) /* DMW 300393 */ ChainFree(new); }#endif if (success) udpStat.outDatagrams++; else udpStat.outErrors++; return success; } WORD UdpAnyPort(VOID){#ifdef UNIX return 0; #else WORD i; for (i=udpPort+1;i!=udpPort;i++) { if (i<1024 || i==UDP_PORT_ANY) i=1024; if (!PortInUse(i)) { udpPort=i; return i; } } return UDP_PORT_ANY; #endif}static BOOLEAN PortInUse(WORD port){ UDP_DESCR *p; for (p=udpDescrList;p!=0;p=p->next) { if (p->locPort==port) return TRUE; } return FALSE;} static UDP_DESCR *DescrFind(UDP_HDR *udpHdr, IP_HDR *ipHdr){ UDP_DESCR *p; for (p=udpDescrList; p!=0; p=p->next) { if ( (p->locAddr==UDP_ADDR_ANY || p->locAddr==ipHdr->dst) && (p->locPort==UDP_PORT_ANY || p->locPort==udpHdr->dst) && (p->remAddr==UDP_ADDR_ANY || p->remAddr==ipHdr->src) && (p->remPort==UDP_PORT_ANY || p->remPort==udpHdr->src) ) { return p; } } return 0;}static WORD Wildcards(UDP_DESCR *udp){ WORD n=0; if (udp->locAddr == UDP_ADDR_ANY) n++; if (udp->remAddr == UDP_ADDR_ANY) n++; if (udp->locPort == UDP_PORT_ANY) n++; if (udp->remPort == UDP_PORT_ANY) n++; return n;}#ifdef UNIXstatic void Rcve(NW_DG *dg, char *addr, BYTE *frame, int length, void *parm){ UDP_HDR udpHdr; IP_HDR ipHdr; CHAIN *chain; UDP_DESCR *descr = (UDP_DESCR *) parm; BOOLEAN success = FALSE; if (Addr2HostPort(addr, &(ipHdr.src), &(udpHdr.src))) { ipHdr.dst=descr->locAddr; udpHdr.dst=descr->locPort; chain=ChainAlloc(0, frame, length, length, 0, 0); if (chain!=0) { if(descr->Rcve(descr, chain, &udpHdr, &ipHdr)) { success = TRUE; } ChainFree(chain); } } if (success) udpStat.inDatagrams++; else udpStat.inErrors++;}static BOOLEAN Addr2HostPort(char *addr, ULONG *host, USHORT *port){ char *p,*q; char string[32]; struct hostent *ent; p=addr; q=string; while(*p!=':' && *p!=0) *q++=tolower(*p++); *q++=0; if (strcmp(string,"udp")!=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, UDP_ERROR, "can't resolve host"); return FALSE; } } if (*p++!=':') return FALSE; q=string; while(*p!=':' && *p!=0) *q++=*p++; *q++=0; *port=atoi(string); return TRUE;}#elsestatic BOOLEAN Rcve(CHAIN *chain, IP_HDR *ipHdr){ UDP_HDR udpHdr; UDP_DESCR *descr; CHAIN *new; BOOLEAN success = FALSE; new = HdrDecode(chain, &udpHdr, ipHdr); if (new != 0) { descr = DescrFind(&udpHdr, ipHdr); if(descr) { if(descr->Rcve(descr, chain, &udpHdr, ipHdr)) { success = TRUE; } } else { udpStat.noPorts++; } if (new != chain) ChainFree(new); } if (success) udpStat.inDatagrams++; else udpStat.inErrors++; return success;} #endif#ifndef UNIXstatic CHAIN *HdrEncode(CHAIN *chain, UDP_HDR *udpHdr, IP_HDR *ipHdr){ HDR *h; udpHdr->length = sizeof(HDR) + ChainLength(chain); h = (HDR *)ChainPush(&chain, sizeof(HDR)); if (h==0) return 0; h->src = IpH2NWord(udpHdr->src); h->dst = IpH2NWord(udpHdr->dst); h->length = IpH2NWord(udpHdr->length); h->check = 0; h->check = HdrCheck(chain, ipHdr); if (h->check == 0) h->check = 0xffff; return chain;}static CHAIN *HdrDecode(CHAIN *chain, UDP_HDR *udpHdr, IP_HDR *ipHdr){ HDR *h; h = (HDR *)ChainPop(&chain, sizeof(HDR)); if (h==0) return 0; udpHdr->src = IpN2HWord(h->src); udpHdr->dst = IpN2HWord(h->dst); udpHdr->length = IpN2HWord(h->length); udpHdr->check = IpN2HWord(h->check); if(h->check != 0) { ChainPush(&chain, sizeof(HDR)); if (HdrCheck(chain, ipHdr) != 0) return 0; ChainPop(&chain, sizeof(HDR)); } return chain;}static WORD HdrCheck(CHAIN *chain, IP_HDR *ipHdr){ CHAIN new; HDR_PSEUDO pseudo; ChainAlloc(&new, (BYTE *)&pseudo, sizeof(pseudo), sizeof(pseudo), 0, chain); pseudo.src = IpH2NDWord(ipHdr->src); pseudo.dst = IpH2NDWord(ipHdr->dst); pseudo.zero = 0; pseudo.prot = IP_PROT_UDP; pseudo.length = IpH2NWord(ChainLength(chain)); return IpHdrCheck(&new, pseudo.length);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -