📄 nwudp.c
字号:
/* Beholder RMON ethernet network monitor,Copyright (C) 1993 DNPAP group *//* See file COPYING 'GNU General Public Licence' for copyright details *//************************************************************************** MODULE INFORMATION************************* FILE NAME: nwudp.c** SYSTEM NAME: nw** ORIGINAL AUTHOR(S): Jan van Oorschot** VERSION NUMBER: 1.00** CREATION DATE: 24 march 1993**** DESCRIPTION: UDP interface for the Network library**** This module implements the UDP** datagrams services. As such,** none of the connection oriented ** services are supported.** It is fully included in the blocking system.*************************************************************************** CHANGE INFORMATION ***************************** REVISION: $Revision$** WORKFILE: $Workfile$** LOGINFO: $Log$*************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#ifndef BSD_SELECT#define BSD_SELECT#endif#ifdef OS2#include <types.h>#include <netlib.h>#include <sys/select.h> /* contains FD_*** macros */#else#include <sys/types.h> #define sock_init() 0#define soclose(x) close(x)#endif#include <netdb.h>#include <sys/time.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/socket.h>#include <dinet.h>#include <stropts.h>#include <errno.h>int socket(int domain,int type,int protocol);int bind(int s,struct sockaddr *name, int namelen);int listen(int s,int backlog);int close(int fd);struct hostent *gethostbyname(char *name);struct hostent *gethostbyaddr(char *addr, int len, int type);int connect(int s,struct sockaddr *name, int namelen);int send(int s, char *msg,int len,int flags);int accept(int s, struct sockaddr *name, int *namelen);int ioctl(int fd,int request,caddr_t arg);int read(int fd,char *buf,int nbyte);int gethostname(char *name,int namelen);int sendto(int s,char *msg,int len,int flags,struct sockaddr *to,int tolen);int recvfrom(int s,char *buf,int len,int flags,struct sockaddr *from, int *fromlen);#include <dnpap.h>#include <config.h>#include <block.h>#include "../nw.h"#include "nwudp.h"#include "nwudpprt.h"/* static variables */static int ServerPort;static int SendSocket;static int ServerSocket;static BLOCK ServerBlock;static struct sockaddr_in udp_server;static int (*UDPCBOpen)(NWCONN *,char *);static int (*UDPCBClose)(NWCONN *);static int (*UDPCBDgramRec)(NWCONN *,BYTE *,int);static char UDPEntry[32];/* local procedures prototypes*/static int CBUdpServerBlock(BLOCK *blk, int reason); /************************************************************************** NAME: UDPInit** SYNOPSIS: int UDPInit(** int (*CBOpen)(NWCONN *,char *),** int (*CBClose)(NWCONN *),** int (*CBDgramRec)(NWCONN *,BYTE *,int));** ** DESCRIPTION: Initialises the UDP iface.** The <CBDgamrRec> will be called when a** datagram is received. The ** other callbacks are ignored.** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/int UDPInit( int (*CBOpen)(NWCONN *,char *), int (*CBClose)(NWCONN *), int (*CBDgramRec)(NWCONN *,BYTE *,int)){ SHORT shrt; char tbuf[256]; int iret; struct hostent *hostnm; UDPCBOpen = CBOpen; UDPCBClose = CBClose; UDPCBDgramRec = CBDgramRec; if(!ConfigGetShort("udp.serverport",&shrt)) { ServerPort = 2001; } else { ServerPort = shrt; } if ( sock_init() != 0) { return(NW_ERROR+2); } if ((SendSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { DnpapMessage(DMC_WARNING,NW_ERROR+3,"can't create send socket"); return NW_ERROR+3; } if ((ServerSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { DnpapMessage(DMC_WARNING,NW_ERROR+3,"can't create server socket"); return NW_ERROR+3; } udp_server.sin_family = AF_INET; udp_server.sin_port = htons(ServerPort); udp_server.sin_addr.s_addr = INADDR_ANY; if (bind(ServerSocket, (struct sockaddr *) &udp_server, sizeof(udp_server)) < 0) { DnpapMessage(DMC_WARNING,NW_ERROR+4,"can't bind server socket"); return NW_ERROR+4; } /* create the block on the server port */ ServerBlock.sckt = ServerSocket; ServerBlock.cb = CBUdpServerBlock; /* server callback */ if( (iret = BlockRegister(&ServerBlock)) != 0) { DnpapMessage(DMC_WARNING,NW_ERROR+6,"failed to register server block"); return NW_ERROR+6; } /* remember this entry for reporting purposes */ strcpy(UDPEntry,"udp:"); gethostname(tbuf,256); hostnm = gethostbyname(tbuf); strcat(UDPEntry,Inet_NtoA(hostnm->h_addr)); strcat(UDPEntry,":"); sprintf(tbuf,"%03d",ntohs(udp_server.sin_port)); strcat(UDPEntry,tbuf); return 0;}/************************************************************************** NAME: UDPExit** SYNOPSIS: int UDPExit(void)** ** DESCRIPTION: Terminates the UDP layer.** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/int UDPExit(void){ /* close the server socket */ BlockDeRegister(&ServerBlock); soclose(ServerSocket); return 0;}/************************************************************************** NAME: UDPGetEntry** SYNOPSIS: char *UDPGetEntry()** DESCRIPTION: Report the connection entry of this layer. Should** be in such a format that other node can use ** this entry to connect to this iface.** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/char *UDPGetEntry(void){ return UDPEntry;}/************************************************************************** NAME: UDPDgramSend** SYNOPSIS: int UDPDgramSend(char *ConnInfo,BYTE *frame,int len);** DESCRIPTION: Sends a datagram to destination <ConnInfo>.** <ConnInfo> should have a format like:** dutepp0:8008**** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/int UDPDgramSend(char *ConnInfo,BYTE *frame,int len){ struct sockaddr_in dest; struct hostent *hostnm; unsigned long inaddr; unsigned short port; char tbuf[256]; int cnt; /* split hostname and portnumber */ for(cnt=0;ConnInfo[cnt]!=':' && ConnInfo[cnt]!='\0';cnt++) tbuf[cnt] = ConnInfo[cnt]; if(ConnInfo[cnt]=='\0') return NW_ERROR+22; port = htons(atoi((ConnInfo+cnt+1))); tbuf[cnt] = '\0'; /* determine address, first dotted, then fullname */ inaddr = inet_addr(tbuf); if((hostnm = gethostbyaddr((char *) &inaddr,4,2)) == NULL) { /* normal hostname */ hostnm = gethostbyname(tbuf); if (hostnm == NULL) { DnpapMessage(DMC_WARNING,NW_ERROR+21,"gethostbyname failed"); return NW_ERROR+21; } } dest.sin_family = AF_INET; dest.sin_port = port; dest.sin_addr.s_addr = inaddr; /* Send the message in buf to the server */ if (sendto( SendSocket, frame, len , 0, (struct sockaddr *)&dest, sizeof(struct sockaddr)) < 0) { DnpapMessage(DMC_WARNING,NW_ERROR+23,"failed to send datagram"); return NW_ERROR+23; } return 0;}/************************************************************************** NAME: UDPDgramRepl** SYNOPSIS: int UDPDgramRepl(NWCONN *con,BYTE *frame,int len)** DESCRIPTION: Replies a datagram.** This function should only be called from within** a DgramRec callback function.** This will garanty that <con> contains** a valid reply address to the requestor.**** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/int UDPDgramRepl(NWCONN *con,BYTE *frame,int len){ UDPCONN *ucon; ucon = (UDPCONN *) con; /* the con structure should contain correct address */ if (sendto( SendSocket, frame, len , 0, (struct sockaddr *)&(ucon->udpinfo.client), ucon->udpinfo.size) < 0) { DnpapMessage(DMC_WARNING,NW_ERROR+23,"failed to send reply datagram"); return NW_ERROR+24; } return 0;}static BYTE buf[4096]; /* static receive buffer */static int CBUdpServerBlock(BLOCK *blk, int reason){ int rlen; UDPCONN *con; if(blk != &ServerBlock) { DnpapMessage(DMC_WARNING,NW_ERROR+7,"wrong server block"); return NW_ERROR+7; } switch(reason) { case BLOCKEVENT_READ: /* datagram receive */ /* build a NWCONN structure so the application can reply */ con = DnpapMalloc(sizeof(UDPCONN)); con->nwinfo.type = NWUDP; con->nwinfo.ConnInfo = NULL; con->nwinfo.CBAppReceive = NULL; con->udpinfo.size = sizeof(con->udpinfo.client); memset(buf,'.',sizeof(buf)); if((rlen= recvfrom( ServerSocket, buf, sizeof(buf), 0, (struct sockaddr *) &(con->udpinfo.client), &(con->udpinfo.size))) <0) { DnpapMessage(DMC_WARNING,NW_ERROR+34,"recvfrom error"); return NW_ERROR+34; } /* call datagram callback function */ UDPCBDgramRec((NWCONN *)con,buf,rlen); DnpapFree(con); break; case BLOCKEVENT_WRITE: /* ignore these events */ DnpapMessage(DMC_WARNING,NW_ERROR+30,"BLOCKEVENT_WRITE on serverport"); break; case BLOCKEVENT_EXCEPT: /* ignore these events */ DnpapMessage(DMC_WARNING,NW_ERROR+30,"BLOCKEVENT_EXCEPTon serverport"); break; default: DnpapMessage(DMC_WARNING,NW_ERROR+8,"unknown block event"); return NW_ERROR+8; break; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -