📄 ts2udp.c
字号:
/* **************************************************************** * * * HULA project * * * * program: ts2udp.c * * author: kurt dobbins * * date: 1/89 * * * * This program contains the routines to provide datagram * * transport service over UDP/IP. They drive the EXCELAN 205T * * card using DATAGRAM sockets. Datagrams over udp provide * * message transfer with non-confirmed service and no * * reliabilty of delivery. * * * * entry points: * * * * udpinit (tb) * * udp_open (tb, local, remote, option) * * udp_start_client (sock, opt1, opt2) * * udp_join_server (sd, sock, opt1, opt2) * * udp_read_socket (fd, q) * * udp_write_socket (fd, data, len) * * udp_selecrt_socket() * * udp_close (fd) * * * **************************************************************** *//* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */#include <errno.h>#include <stdio.h>#include "general.h"#include "manifest.h"#include "tpkt.h"#include "tsap.h"#include "uderrors.h"/* */#ifdef HULA#ifdef UDP#include "internet.h"extern int errno;/* *//* this structure is allocated for each socket device */struct udpconn { int udp_parent; struct sockaddr_in udp_peer; struct qbuf udp_queue; };static int maxpeers = 0;static struct udpconn *peers = NULL; /* *//* ********************************************************** * * * udpinit * * * * This routine inializes the udp transport block. * * * ********************************************************** */int udpinit (tb)register struct tsapblk *tb;{#ifdef HULADEBUG printf ("\n in udpinit \n");#endif tb -> tb_flags |= (TB_CLNS | TB_UDP); tb -> tb_tsdusize = MAXUDP; /* * Set the UNITDATA service entry points. */ tb -> tb_UnitDataStart = udp_open; tb -> tb_UnitDataRead = udp_read_socket; tb -> tb_UnitDataWrite = udp_write_socket; tb -> tb_UnitDataIndication = NULLIFP; tb -> tb_UnitDataSelect = NULLIFP; tb -> tb_UnitDataClose = udp_close;}/* *//* ********************************************************** * * * udp_open * * * * This routine sets up the client or server socket for * * the remote address. Client sockets are bound to * * remote address whereas the server sockets are not. * * * * returns: OK, NOTOK * * also updates the tsapblk fd for the socket * ********************************************************** */int udp_open (tb, local, remote, option, td)register struct tsapblk *tb;struct NSAPaddr *local, *remote;int option;struct TSAPdisconnect *td;{ int fd; struct sockaddr_in lo_socket, in_socket; register struct sockaddr_in *lsock = &lo_socket, *isock = &in_socket; register struct hostent *hp; register struct servent *sp;/* * Check if we are creating a new socket or just rebinding * a new remote addr on an existing socket. */if (option == TUNITDATA_START) { /* * Setup the local socket. The host internet address must be zero. */ bzero ((char *) lsock, sizeof *lsock); if (local && local -> na_domain[0]) { if ((hp = gethostbystring (local -> na_domain)) == NULL) tusaplose (td, DR_ADDRESS, NULLCP, TuErrString(UDERR_LHOST_UNKNOWN)); if ( (remote && remote -> na_domain[0]) && (lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family) tusaplose (td, DR_ADDRESS, NULLCP, TuErrString(UDERR_ADDR_FAMILY_MISMATCH)); bcopy (hp -> h_addr, (char *) &lsock -> sin_addr, hp -> h_length); }#if FALSE else lsock = NULL;#endif /* * Create the local socket. Use the specified port * if it is there. */ if (local && local -> na_port != 0) { lsock -> sin_port = local -> na_port; lsock -> sin_family = AF_INET; } else lsock -> sin_family = AF_INET; errno = 0; if ((fd = udp_start_client (lsock, 0, 0)) == NOTOK) tusaplose (td, DR_OPERATION, NULLCP,TuErrString(UDERR_START_CLIENT_FAILED)); #ifdef HULADEBUG printf ("\n socket = %d \n", fd);#endif /* * Update the tsap block with the socket descriptor. */ tb -> tb_fd = fd; } /* end TUNITDATA_START *//* * If the remote host was specified, BIND the address pair. * Otherwise, we will have to use 'sendto' semantics on * on each datagram send later on. */ if (remote && remote -> na_domain[0]) { /* * Setup the remote socket address. */ bzero ((char *) isock, sizeof *isock); /* * If the remote port is not specified, try to * default to the port for the tsap daemon. */ if (remote -> na_port == 0) { if ((sp = getservbyname ("tsap", "tcp")) == NULL) tusaplose (td, DR_ADDRESS, NULLCP, TuErrString(UDERR_TSAP_SERVICE_UNKNOWN)); isock -> sin_port = sp -> s_port;#ifdef HULADEBUG printf ("\n defaulting REMOTE port to tsap service\n");#endif } else isock -> sin_port = remote -> na_port; /* * Lookup the remote host. */ if ((hp = gethostbystring (remote -> na_domain)) == NULL) tusaplose (td, DR_ADDRESS, NULLCP, TuErrString(UDERR_RHOST_UNKNOWN)); (void) strncpy (remote -> na_domain, hp -> h_name, sizeof remote -> na_domain); isock -> sin_family = hp -> h_addrtype; bcopy (hp -> h_addr, (char *) &isock -> sin_addr, hp -> h_length); /* * Now do the actual bind of the remote addr to the socket. */ if ((udp_join_server (tb -> tb_fd, isock, 0, 0)) == NOTOK) tusaplose (td, DR_OPERATION, NULLCP, TuErrString(UDERR_JOIN_SRVR_FAILED)); } return OK;}/* *//* ********************************************************** * * * udp start client * * * * This routine creates the initial DATAGRAM socket for * * server code and allocates the udp conn structs to * * track logical connections over the socket devices. * * * * returns: socket descriptor * * * ********************************************************** */#ifdef EXOSint udp_start_client (sock, opt1, opt2)struct sockaddr_in *sock;int opt1, opt2;{ register int port; int sd; int i; register struct hostent *hp; register struct udpconn *up; #ifdef HULADEBUG printf ("\n in start udp client \n");#endif/* * Initialize the queue of udp conn structs. One exists for * each socket device. It will be stored as an array indexed * by socket descriptor. */ if (peers == NULL) { maxpeers = getdtablesize ();#ifdef HULADEBUG printf ("\n allocating the peers array \n"); printf ("\n maxpeers = %d \n ", maxpeers);#endif peers = (struct udpconn *) calloc ( (unsigned) maxpeers, sizeof(struct udpconn) ); if (peers == NULL) return NOTOK;#ifdef HULADEBUG printf ("\n initializing the peers array \n");#endif for (i=0; i < maxpeers; i++) { peers[i].udp_parent = NOTOK; peers[i].udp_queue.qb_forw = peers[i].udp_queue.qb_back = &peers[i].udp_queue; } }/* * Create the local DATAGRAM socket. Implies UDP/IP protocol * stack. Remember, the socket call justs creates an endpoint * for communication for the specified port. */#ifdef HULADEBUG printf ("\n formatting the local DATAGRAM socket \n");#endif if (sock -> sin_addr.s_addr == 0) {#ifdef HULADEBUG printf ("\n get local host name \n");#endif if ((hp = gethostbyname ("localhost")) == NULL) { errno = EADDRNOTAVAIL; return NOTOK; } sock -> sin_family = AF_INET;#if FALSE sock -> sin_family = hp -> h_addrtype; bcopy (hp -> h_addr, (char *) &sock -> sin_addr, hp -> h_length);#endif } if (sock -> sin_port != 0) { /* * Create the local socket for a spcific port. */#ifdef HULADEBUG printf ("\n creating the local DATAGRAM socket \n"); printf ("\n family = %d", sock -> sin_family); printf ("\n port = %d", ntohs(sock -> sin_port)); printf ("\n addr = %d %d %d %d", sock -> sin_addr.s_net, sock -> sin_addr.s_host, sock -> sin_addr.s_lh, sock -> sin_addr.s_impno);#endif if ((sd = socket (SOCK_DGRAM, (struct sockproto *) 0, (struct sockaddr *) sock, SO_LARGE)) != NOTOK) /* * Save the socket descriptor in the peers array and * return the socket descriptor for the local socket. */ return (peers[sd].udp_parent = sd); } else { /* * Generate a unique source port number. */#ifdef HULADEBUG printf ("\n generate unique port # \n");#endif for (port = IPPORT_RESERVED ;; port++) { sock -> sin_port = htons ((u_short) port);#ifdef HULADEBUG printf ("\n creating the local DATAGRAM socket \n"); printf ("\n family = %d", sock -> sin_family); printf ("\n port = %d", ntohs(sock -> sin_port)); printf ("\n addr = %d %d %d %d", sock -> sin_addr.s_net, sock -> sin_addr.s_host, sock -> sin_addr.s_lh, sock -> sin_addr.s_impno);#endif if ((sd = socket (SOCK_DGRAM, (struct sockproto *) 0, (struct sockaddr *) sock, SO_LARGE)) != NOTOK) /* * Save the socket descriptor in the peers array and * return the socket descriptor for the local socket. */ return (peers[sd].udp_parent = sd); switch (errno) { case EADDRINUSE: continue; case EADDRNOTAVAIL: case EAFNOSUPPORT: case ENOBUFS: case EPROTONOSUPPORT: default: #ifdef EXOS return NOTOK; } /* end switch */ #else return NOTOK; } /* end switch */#endif } /* end for port number */ } /* end if port specified */ }/* *//* ********************************************************** * * * udp join server * * * * This routine does the actual binding of remote socket.* * * * returns: OK, NOTOK * * * ********************************************************** */int udp_join_server (sd, sock, opt1, opt2)int sd;struct sockaddr_in *sock;int opt1, opt2;{/* * Bind the socket to the socket name. The socket name is * made up of a 32-bit internet address and a 16-bit port number. * This is done for the specified port sock -> sin_port. */#ifdef HULADEBUG printf ("\n binding the socket to remote address %d %d %d %d ", sock -> sin_addr.s_net, sock -> sin_addr.s_host, sock -> sin_addr.s_lh, sock -> sin_addr.s_impno); printf (" and port %d \n", ntohs (sock -> sin_port) ); #endif errno = 0; if (sock -> sin_port != 0) { if (connect (sd, (struct sockaddr *) sock) != NOTOK) return OK; switch (errno) { case EISCONN: /* * Trying to rebind the existing socket is ok * since it may be a server rebinding to another * request from the previously-bound remote socket. */ return OK; default: (void) udp_close (sd); return NOTOK; } } return NOTOK;}#endif /* if EXOS */#if FALSE/* */ /* ********************************************************** * * * join udp aux * * * ********************************************************** */int join_udp_aux (fd, sock, newfd)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -