📄 nwtcp.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: nwtcp.c** SYSTEM NAME: nw** ORIGINAL AUTHOR(S): Jan van Oorschot** VERSION NUMBER: 1.00** CREATION DATE: 24 march 1993**** DESCRIPTION: TCP interface for the Network library** This module creates TCP sockets and uses** the blocking library to be notified when** something happens on the socket.** The NW layer will be notified by** this layer when frames are received and** connections are opened/closed.*************************************************************************** CHANGE INFORMATION ***************************** REVISION: $Revision$** WORKFILE: $Workfile$** LOGINFO: $Log$*************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <dnpap.h>#include <config.h>#include <block.h>#include <dinet.h>#include "../nw.h"#include "nwtcp.h"/* structure containing pointers to the current connections */TCPCONN *TCPList;/* static variables */static int ServerSocket;static BLOCK ServerBlock;static struct sockaddr_in tcp_server;TCPPARAM TCPDefaultParam ={ 1, /* use the server port */ 2001 /* default server port */};/* status vars passed by the upper layer */static int (*TCPCBOpen)(NWCONN *,char *);static int (*TCPCBClose)(NWCONN *);static int (*TCPCBDgramRec)(NWCONN *,BYTE *,int); /* never used */static TCPPARAM *TCPParam;static char TCPEntry[32];/* local procedures prototypes*/static int CBTcpServerBlock(BLOCK *blk, int reason,void *param);static int CBTcpSocketBlock(BLOCK *blk, int reason,void *param);static int ConnectRequest(void); /************************************************************************** NAME: TCPInit** SYNOPSIS: int TCPInit(** int (*CBOpen)(NWCONN *,char *),** int (*CBClose)(NWCONN *),** int (*CBDgramRec)(NWCONN *,BYTE *,int),** void *param);** ** DESCRIPTION: Initialises the TCP iface. The callback** functions will be called by the TCP iface** layer when a connection is opened/closed** by an other network node.** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/int TCPInit( int (*CBOpen)(NWCONN *,char *), int (*CBClose)(NWCONN *), int (*CBDgramRec)(NWCONN *,BYTE *,int), void *param){ SHORT shrt; char tbuf[256]; int iret; struct hostent *hostnm; if ( sock_init() != 0) return(NW_ERROR+2); TCPCBOpen = CBOpen; TCPCBClose = CBClose; TCPCBDgramRec = CBDgramRec; /* never used */ if(param != NULL) TCPParam = param; else { /* try to find values from the configuration file */ TCPParam = &TCPDefaultParam; if(ConfigGetShort("tcp.serverport",&shrt)) TCPParam->ServerPort = (int) &shrt; if(ConfigGetShort("tcp.server",&shrt)) TCPParam->server = 1; /* use the server port */ if(ConfigGetShort("tcp.noserver",&shrt)) TCPParam->server = 0; /* use the server port */ } TCPList = NULL; /* no current connections */ if(TCPParam->server != 0) { /* create the server socket */ if ((ServerSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { DnpapMessage(DMC_WARNING,NW_ERROR+3,"can't create server socket"); return NW_ERROR+3; } tcp_server.sin_family = AF_INET; tcp_server.sin_port = htons(TCPParam->ServerPort); tcp_server.sin_addr.s_addr = INADDR_ANY; if (bind(ServerSocket, (struct sockaddr *) &tcp_server, sizeof(tcp_server)) < 0) { DnpapMessage(DMC_WARNING,NW_ERROR+4,"can't bind server socket"); return NW_ERROR+4; } if (listen(ServerSocket, 5) != 0) { DnpapMessage(DMC_WARNING,NW_ERROR+5, "can't listen to server socket"); return NW_ERROR+5; } /* create the block on the server port */ ServerBlock.sckt = ServerSocket; if( (iret = BlockRegister( &ServerBlock, &ServerBlock, CBTcpServerBlock)) != 0) { DnpapMessage(DMC_WARNING,NW_ERROR+6, "failed to register server block"); return NW_ERROR+6; } } /* remember this entry for reporting purposes */ strcpy(TCPEntry,"tcp:"); gethostname(tbuf,256); hostnm = gethostbyname(tbuf); strcat(TCPEntry,Inet_NtoA(hostnm->h_addr)); strcat(TCPEntry,":"); sprintf(tbuf,"%03d",ntohs(tcp_server.sin_port)); strcat(TCPEntry,tbuf); return 0;}/************************************************************************** NAME: TCPExit** SYNOPSIS: int TCPExit(void)** ** DESCRIPTION: Terminates the TCP layer.** RETURNS: 0 --> no error** else error code** RETURNS: void*************************************************************************/int TCPExit(void){ TCPCONN *ptr,*cptr; /* close the server socket */ if(TCPParam->server != 0) { BlockDeRegister(&ServerBlock); soclose(ServerSocket); } /* close all open TCP connections */ ptr = TCPList; while (ptr != NULL) { cptr = ptr; ptr = ptr->next; TCPClose((NWCONN *) cptr); } return 0;}/************************************************************************** NAME: TCPOpen** SYNOPSIS: NWCONN *TCPOpen(** char *ConnInfo,** int (*CBReceive)(NWCONN *,BYTE *,len));** ** DESCRIPTION: Opens a tcp connection and returns the ** connection pointer.** The info needed to build the TCP connection is** in <ConnInfo>.** The callback function <CBReceive> will be** called when a frame is received through this** connection.** RETURNS: NULL can't open connection** else connection structure*************************************************************************/NWCONN *TCPOpen(char *ConnInfo,int (*CBReceive)(NWCONN *,BYTE *,int)){ TCPCONN *con; BLOCK *blk; char *cptr; int iret; struct hostent *hostnm; unsigned long inaddr; char tbuf[256]; /* allocate and the structures needed for a connection */ if((con = DnpapMalloc(sizeof(TCPCONN)))==NULL) return NULL; if((con->nwinfo.ConnInfo = DnpapMalloc(32)) == NULL) { DnpapFree(con); return NULL; } if((blk = DnpapMalloc(sizeof(BLOCK))) == NULL) { DnpapFree(con->nwinfo.ConnInfo); DnpapFree(con); return NULL; } con->tcpinfo.CBRec = CBReceive; /* create the TCP socket */ strcpy(tbuf,ConnInfo); cptr = tbuf; while(*cptr != ':' && *cptr != '\0') cptr++; if(*cptr == '\0') { DnpapFree(con->nwinfo.ConnInfo); DnpapFree(con); DnpapFree(blk); DnpapMessage(DMC_WARNING,NW_ERROR+20,"no port number to connect to"); return NULL; } *cptr = '\0'; con->tcpinfo.conPort = atoi(cptr+1); /* create socket, check for consistency */ if ((con->tcpinfo.sckt = socket(AF_INET, SOCK_STREAM, 0)) < 0) { DnpapFree(con->nwinfo.ConnInfo); DnpapFree(con); DnpapFree(blk); DnpapMessage(DMC_WARNING,NW_ERROR+23,"can't create socket"); return NULL; } /* read message-discard mode */ ioctl(con->tcpinfo.sckt,I_SRDOPT,(caddr_t)RMSGD); /* 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) { soclose(con->tcpinfo.sckt); DnpapFree(con->nwinfo.ConnInfo); DnpapFree(con); DnpapFree(blk); DnpapMessage(DMC_WARNING,NW_ERROR+21,"gethostbyname failed"); return NULL; } } con->tcpinfo.addr.sin_addr.s_addr = /* ulong */ *((unsigned long *)(hostnm->h_addr)); con->tcpinfo.addr.sin_family = AF_INET; con->tcpinfo.addr.sin_port = htons(con->tcpinfo.conPort); /* finaly, do the connect */ if (connect(con->tcpinfo.sckt, (struct sockaddr *) &(con->tcpinfo.addr), sizeof(con->tcpinfo.addr)) < 0) { soclose(con->tcpinfo.sckt); DnpapFree(con->nwinfo.ConnInfo); DnpapFree(con); DnpapFree(blk); DnpapMessage(DMC_WARNING,NW_ERROR+23,"can't connect"); return NULL; } /* create the BLOCK and attach block and connection*/ blk->sckt = con->tcpinfo.sckt; con->tcpinfo.blk = blk; if( (iret = BlockRegister(blk,con,CBTcpSocketBlock)) != 0) { soclose(con->tcpinfo.sckt); DnpapFree(con->nwinfo.ConnInfo); DnpapFree(con); DnpapFree(blk); DnpapMessage(DMC_WARNING,NW_ERROR+24,"can't register socket block"); return NULL; } /* termine a correct connection string */ con->nwinfo.ConnInfo = DnpapMalloc(32); strcpy(con->nwinfo.ConnInfo,"tcp:");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -