int main(int argc, char *argv[] ) { int length, i; char sendbuffer[4096] ; int tfd; struct t_call *callptr; struct sockaddr_in serv_addr; pname = argv[0]; /* * Create a TCP transport endpoint and bind it. */ if ( (tfd = t_open(DEV_TCP, O_RDWR, 0)) < 0) { printf("client: can't t_open %s........\n", DEV_TCP); exit(1); } if (t_bind(tfd, (struct t_bind *) 0, (struct t_bind *) 0) < 0) { printf("client: t_bind error.....\n"); exit(1); } /* * Fill in the structure "serv_addr" with the address of the * server that we want to connect with. */ bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr(SERV_HOST_ADDR); serv_addr.sin_port = htons(SERV_TCP_PORT); /* * Allocate a t_call structure, and initialize it. * Let t_alloc() initialize the addr structure of the t_call structure. */ if ( (callptr = (struct t_call *) t_alloc(tfd, T_CALL, T_ADDR)) == NULL) { printf("client: t_alloc error.......\n"); } callptr->addr.maxlen = sizeof(serv_addr); callptr->addr.len = sizeof(serv_addr); callptr->addr.buf = (char *) &serv_addr; callptr->opt.len = 0; /* no options */ callptr->udata.len = 0; /* no user data with connect */ /* get raw usage data */ if(get_raw_usage_data(sendbuffer, length) != FALSE) { process_client_service(tfd, callptr, sendbuffer, length); } if(*sendbuffer) free(sendbuffer); close(tfd); exit(1); }
p_stack stack_new() { p_stack ret; ret = (p_stack)t_alloc( sizeof( s_stack ) ); ret->top = NULL; return ret; }
int nfslib_bindit(struct netconfig *nconf, struct netbuf **addr, struct nd_hostserv *hs, int backlog) { int fd; struct t_bind *ntb; struct t_bind tb; struct nd_addrlist *addrlist; struct t_optmgmt req, resp; struct opthdr *opt; char reqbuf[128]; bool_t use_any = FALSE; bool_t gzone = TRUE; if ((fd = nfslib_transport_open(nconf)) == -1) { syslog(LOG_ERR, "cannot establish transport service over %s", nconf->nc_device); return (-1); } addrlist = (struct nd_addrlist *)NULL; /* nfs4_callback service does not used a fieed port number */ if (strcmp(hs->h_serv, "nfs4_callback") == 0) { tb.addr.maxlen = 0; tb.addr.len = 0; tb.addr.buf = 0; use_any = TRUE; gzone = (getzoneid() == GLOBAL_ZONEID); } else if (netdir_getbyname(nconf, hs, &addrlist) != 0) { syslog(LOG_ERR, "Cannot get address for transport %s host %s service %s", nconf->nc_netid, hs->h_host, hs->h_serv); (void) t_close(fd); return (-1); } if (strcmp(nconf->nc_proto, "tcp") == 0) { /* * If we're running over TCP, then set the * SO_REUSEADDR option so that we can bind * to our preferred address even if previously * left connections exist in FIN_WAIT states. * This is somewhat bogus, but otherwise you have * to wait 2 minutes to restart after killing it. */ if (reuseaddr(fd) == -1) { syslog(LOG_WARNING, "couldn't set SO_REUSEADDR option on transport"); } } else if (strcmp(nconf->nc_proto, "udp") == 0) { /* * In order to run MLP on UDP, we need to handle creds. */ if (recvucred(fd) == -1) { syslog(LOG_WARNING, "couldn't set SO_RECVUCRED option on transport"); } } /* * Make non global zone nfs4_callback port MLP */ if (use_any && is_system_labeled() && !gzone) { if (anonmlp(fd) == -1) { /* * failing to set this option means nfs4_callback * could fail silently later. So fail it with * with an error message now. */ syslog(LOG_ERR, "couldn't set SO_ANON_MLP option on transport"); (void) t_close(fd); return (-1); } } if (nconf->nc_semantics == NC_TPI_CLTS) tb.qlen = 0; else tb.qlen = backlog; /* LINTED pointer alignment */ ntb = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL); if (ntb == (struct t_bind *)NULL) { syslog(LOG_ERR, "t_alloc failed: t_errno %d, %m", t_errno); (void) t_close(fd); netdir_free((void *)addrlist, ND_ADDRLIST); return (-1); } /* * XXX - what about the space tb->addr.buf points to? This should * be either a memcpy() to/from the buf fields, or t_alloc(fd,T_BIND,) * should't be called with T_ALL. */ if (addrlist) tb.addr = *(addrlist->n_addrs); /* structure copy */ if (t_bind(fd, &tb, ntb) == -1) { syslog(LOG_ERR, "t_bind failed: t_errno %d, %m", t_errno); (void) t_free((char *)ntb, T_BIND); netdir_free((void *)addrlist, ND_ADDRLIST); (void) t_close(fd); return (-1); } /* make sure we bound to the right address */ if (use_any == FALSE && (tb.addr.len != ntb->addr.len || memcmp(tb.addr.buf, ntb->addr.buf, tb.addr.len) != 0)) { syslog(LOG_ERR, "t_bind to wrong address"); (void) t_free((char *)ntb, T_BIND); netdir_free((void *)addrlist, ND_ADDRLIST); (void) t_close(fd); return (-1); } /* * Call nfs4svc_setport so that the kernel can be * informed what port number the daemon is listing * for incoming connection requests. */ if ((nconf->nc_semantics == NC_TPI_COTS || nconf->nc_semantics == NC_TPI_COTS_ORD) && Mysvc4 != NULL) (*Mysvc4)(fd, NULL, nconf, NFS4_SETPORT, &ntb->addr); *addr = &ntb->addr; netdir_free((void *)addrlist, ND_ADDRLIST); if (strcmp(nconf->nc_proto, "tcp") == 0) { /* * Disable the Nagle algorithm on TCP connections. * Connections accepted from this listener will * inherit the listener options. */ /* LINTED pointer alignment */ opt = (struct opthdr *)reqbuf; opt->level = IPPROTO_TCP; opt->name = TCP_NODELAY; opt->len = sizeof (int); /* LINTED pointer alignment */ *(int *)((char *)opt + sizeof (*opt)) = 1; req.flags = T_NEGOTIATE; req.opt.len = sizeof (*opt) + opt->len; req.opt.buf = (char *)opt; resp.flags = 0; resp.opt.buf = reqbuf; resp.opt.maxlen = sizeof (reqbuf); if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) { syslog(LOG_ERR, "couldn't set NODELAY option for proto %s: t_errno = %d, %m", nconf->nc_proto, t_errno); } } return (fd); }
/* * Called to read and interpret the event on a connectionless descriptor. * Returns 0 if successful, or a UNIX error code if failure. */ static int do_poll_clts_action(int fd, int conn_index) { int error; int ret; int flags; struct netconfig *nconf = &conn_polled[conn_index].nc; static struct t_unitdata *unitdata = NULL; static struct t_uderr *uderr = NULL; static int oldfd = -1; struct nd_hostservlist *host = NULL; struct strbuf ctl[1], data[1]; /* * We just need to have some space to consume the * message in the event we can't use the TLI interface to do the * job. * * We flush the message using getmsg(). For the control part * we allocate enough for any TPI header plus 32 bytes for address * and options. For the data part, there is nothing magic about * the size of the array, but 256 bytes is probably better than * 1 byte, and we don't expect any data portion anyway. * * If the array sizes are too small, we handle this because getmsg() * (called to consume the message) will return MOREDATA|MORECTL. * Thus we just call getmsg() until it's read the message. */ char ctlbuf[sizeof (union T_primitives) + 32]; char databuf[256]; /* * If this is the same descriptor as the last time * do_poll_clts_action was called, we can save some * de-allocation and allocation. */ if (oldfd != fd) { oldfd = fd; if (unitdata) { (void) t_free((char *)unitdata, T_UNITDATA); unitdata = NULL; } if (uderr) { (void) t_free((char *)uderr, T_UDERROR); uderr = NULL; } } /* * Allocate a unitdata structure for receiving the event. */ if (unitdata == NULL) { /* LINTED pointer alignment */ unitdata = (struct t_unitdata *)t_alloc(fd, T_UNITDATA, T_ALL); if (unitdata == NULL) { if (t_errno == TSYSERR) { /* * Save the error code across * syslog(), just in case * syslog() gets its own error * and therefore overwrites errno. */ error = errno; (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/transport %s, T_UNITDATA) failed: %m", fd, nconf->nc_proto); return (error); } (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/transport %s, T_UNITDATA) failed TLI error %d", fd, nconf->nc_proto, t_errno); goto flush_it; } } try_again: flags = 0; /* * The idea is we wait for T_UNITDATA_IND's. Of course, * we don't get any, because rpcmod filters them out. * However, we need to call t_rcvudata() to let TLI * tell us we have a T_UDERROR_IND. * * algorithm is: * t_rcvudata(), expecting TLOOK. * t_look(), expecting T_UDERR. * t_rcvuderr(), expecting success (0). * expand destination address into ASCII, * and dump it. */ ret = t_rcvudata(fd, unitdata, &flags); if (ret == 0 || t_errno == TBUFOVFLW) { (void) syslog(LOG_WARNING, "t_rcvudata(file descriptor %d/transport %s) got unexpected data, %d bytes", fd, nconf->nc_proto, unitdata->udata.len); /* * Even though we don't expect any data, in case we do, * keep reading until there is no more. */ if (flags & T_MORE) goto try_again; return (0); } switch (t_errno) { case TNODATA: return (0); case TSYSERR: /* * System errors are returned to caller. * Save the error code across * syslog(), just in case * syslog() gets its own error * and therefore overwrites errno. */ error = errno; (void) syslog(LOG_ERR, "t_rcvudata(file descriptor %d/transport %s) %m", fd, nconf->nc_proto); return (error); case TLOOK: break; default: (void) syslog(LOG_ERR, "t_rcvudata(file descriptor %d/transport %s) TLI error %d", fd, nconf->nc_proto, t_errno); goto flush_it; } ret = t_look(fd); switch (ret) { case 0: return (0); case -1: /* * System errors are returned to caller. */ if (t_errno == TSYSERR) { /* * Save the error code across * syslog(), just in case * syslog() gets its own error * and therefore overwrites errno. */ error = errno; (void) syslog(LOG_ERR, "t_look(file descriptor %d/transport %s) %m", fd, nconf->nc_proto); return (error); } (void) syslog(LOG_ERR, "t_look(file descriptor %d/transport %s) TLI error %d", fd, nconf->nc_proto, t_errno); goto flush_it; case T_UDERR: break; default: (void) syslog(LOG_WARNING, "t_look(file descriptor %d/transport %s) returned %d not T_UDERR (%d)", fd, nconf->nc_proto, ret, T_UDERR); } if (uderr == NULL) { /* LINTED pointer alignment */ uderr = (struct t_uderr *)t_alloc(fd, T_UDERROR, T_ALL); if (uderr == NULL) { if (t_errno == TSYSERR) { /* * Save the error code across * syslog(), just in case * syslog() gets its own error * and therefore overwrites errno. */ error = errno; (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/transport %s, T_UDERROR) failed: %m", fd, nconf->nc_proto); return (error); } (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/transport %s, T_UDERROR) failed TLI error: %d", fd, nconf->nc_proto, t_errno); goto flush_it; } } ret = t_rcvuderr(fd, uderr); if (ret == 0) { /* * Save the datagram error in errno, so that the * %m argument to syslog picks up the error string. */ errno = uderr->error; /* * Log the datagram error, then log the host that * probably triggerred. Cannot log both in the * same transaction because of packet size limitations * in /dev/log. */ (void) syslog((errno == ECONNREFUSED) ? LOG_DEBUG : LOG_WARNING, "NFS response over <file descriptor %d/transport %s> generated error: %m", fd, nconf->nc_proto); /* * Try to map the client's address back to a * name. */ ret = netdir_getbyaddr(nconf, &host, &uderr->addr); if (ret != -1 && host && host->h_cnt > 0 && host->h_hostservs) { (void) syslog((errno == ECONNREFUSED) ? LOG_DEBUG : LOG_WARNING, "Bad NFS response was sent to client with host name: %s; service port: %s", host->h_hostservs->h_host, host->h_hostservs->h_serv); } else { int i, j; char *buf; char *hex = "0123456789abcdef"; /* * Mapping failed, print the whole thing * in ASCII hex. */ buf = (char *)malloc(uderr->addr.len * 2 + 1); for (i = 0, j = 0; i < uderr->addr.len; i++, j += 2) { buf[j] = hex[((uderr->addr.buf[i]) >> 4) & 0xf]; buf[j+1] = hex[uderr->addr.buf[i] & 0xf]; } buf[j] = '\0'; (void) syslog((errno == ECONNREFUSED) ? LOG_DEBUG : LOG_WARNING, "Bad NFS response was sent to client with transport address: 0x%s", buf); free((void *)buf); } if (ret == 0 && host != NULL) netdir_free((void *)host, ND_HOSTSERVLIST); return (0); }
static int TRANS(TLITLIBindLocal)(int fd, int family, char *port) { struct sockaddr_un *sunaddr=NULL; struct t_bind *req=NULL; prmsg(2, "TLITLIBindLocal(%d,%d,%s)\n", fd, family, port); if( family == AF_UNIX ) { if( (req=(struct t_bind *)t_alloc(fd,T_BIND,0)) == NULL ) { prmsg(1, "TLITLIBindLocal() failed to allocate a t_bind\n"); return -1; } if( (sunaddr=(struct sockaddr_un *) malloc(sizeof(struct sockaddr_un))) == NULL ) { prmsg(1, "TLITLIBindLocal: failed to allocate a sockaddr_un\n"); t_free((char *)req,T_BIND); return -1; } sunaddr->sun_family=AF_UNIX; #ifdef nuke if( *port == '/' ) { /* A full pathname */ (void) strcpy(sunaddr->sun_path, port); } else { (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port ); } #endif /*NUKE*/ (void) sprintf(sunaddr->sun_path,"%s%d", TLINODENAME, getpid()^time(NULL) ); prmsg(4, "TLITLIBindLocal: binding to %s\n", sunaddr->sun_path); req->addr.buf=(char *)sunaddr; req->addr.len=sizeof(*sunaddr); req->addr.maxlen=sizeof(*sunaddr); } if( t_bind(fd, req, NULL) < 0 ) { prmsg(1, "TLIBindLocal: Unable to bind TLI device to %s\n", port); if (sunaddr) free((char *) sunaddr); if (req) t_free((char *)req,T_BIND); return -1; } return 0; }
static XtransConnInfo TRANS(TLIAccept)(XtransConnInfo ciptr, int *status) { struct t_call *call; XtransConnInfo newciptr; int i; prmsg(2,"TLIAccept(%x->%d)\n", ciptr, ciptr->fd); if( (call=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL ) { prmsg(1, "TLIAccept() failed to allocate a t_call\n"); *status = TRANS_ACCEPT_BAD_MALLOC; return NULL; } if( t_listen(ciptr->fd,call) < 0 ) { extern char *t_errlist[]; extern int t_errno; prmsg(1, "TLIAccept() t_listen() failed\n"); prmsg(1, "TLIAccept: %s\n", t_errlist[t_errno]); t_free((char *)call,T_CALL); *status = TRANS_ACCEPT_MISC_ERROR; return NULL; } /* * Now we need to set up the new endpoint for the incoming connection. */ i=ciptr->index; /* Makes the next line more readable */ if( (newciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL ) { prmsg(1, "TLIAccept() failed to open a new endpoint\n"); t_free((char *)call,T_CALL); *status = TRANS_ACCEPT_MISC_ERROR; return NULL; } if( TRANS(TLITLIBindLocal)(newciptr->fd,TLItrans2devtab[i].family,"") < 0 ) { prmsg(1, "TLIAccept: TRANS(TLITLIBindLocal)() failed: %d\n", errno); t_free((char *)call,T_CALL); t_close(newciptr->fd); free(newciptr); *status = TRANS_ACCEPT_MISC_ERROR; return NULL; } if( t_accept(ciptr->fd,newciptr->fd,call) < 0 ) { extern char *t_errlist[]; extern int t_errno; prmsg(1, "TLIAccept() t_accept() failed\n"); prmsg(1, "TLIAccept: %s\n", t_errlist[t_errno]); if( t_errno == TLOOK ) { int evtype = t_look(ciptr->fd); prmsg(1, "TLIAccept() t_look() returned %d\n", evtype); switch( evtype ) { case T_DISCONNECT: if( t_rcvdis(ciptr->fd, NULL) < 0 ) { prmsg(1, "TLIAccept() t_rcvdis() failed\n"); prmsg(1, "TLIAccept: %s\n", t_errlist[t_errno]); } break; default: break; } } t_free((char *)call,T_CALL); t_close(newciptr->fd); free(newciptr); *status = TRANS_ACCEPT_FAILED; return NULL; } t_free((char *)call,T_CALL); if( TRANS(TLIGetAddr)(newciptr) < 0 ) { prmsg(1, "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n", errno); t_close(newciptr->fd); free(newciptr); *status = TRANS_ACCEPT_MISC_ERROR; return NULL; } if( TRANS(TLIGetPeerAddr)(newciptr) < 0 ) { prmsg(1, "TLIAccept: TRANS(TLIGetPeerAddr)() failed: %d\n", errno); t_close(newciptr->fd); free(newciptr->addr); free(newciptr); *status = TRANS_ACCEPT_MISC_ERROR; return NULL; } if( ioctl(newciptr->fd, I_POP,"timod") < 0 ) { prmsg(1, "TLIAccept() ioctl(I_POP, \"timod\") failed %d\n", errno); t_close(newciptr->fd); free(newciptr->addr); free(newciptr); *status = TRANS_ACCEPT_MISC_ERROR; return NULL; } if( ioctl(newciptr->fd, I_PUSH,"tirdwr") < 0 ) { prmsg(1, "TLIAccept() ioctl(I_PUSH,\"tirdwr\") failed %d\n", errno); t_close(newciptr->fd); free(newciptr->addr); free(newciptr); *status = TRANS_ACCEPT_MISC_ERROR; return NULL; } *status = 0; return newciptr; }
int gtcm_bgn_net(omi_conn_ll *cll) { extern int4 omi_nxact, omi_nerrs, omi_brecv, omi_bsent; omi_fd fd; int i; int save_errno; int rc; #ifdef NET_TCP struct servent *se; unsigned short port; char port_buffer[NI_MAXSERV]; #endif /* defined(NET_TCP) */ #ifdef BSD_TCP struct addrinfo *ai_ptr, hints; const boolean_t reuseaddr = TRUE; int errcode; #else /* defined(BSD_TCP) */ #ifdef SYSV_TCP struct t_bind *bind; #endif /* defined(SYSV_TCP) */ #endif /* !defined(BSD_TCP) */ /* The linked list of connections */ cll->head = cll->tail = (omi_conn *)0; /* The statistics */ cll->stats.conn = cll->stats.clos = cll->stats.disc = 0; cll->st_cn.bytes_recv = 0; cll->st_cn.bytes_send = 0; cll->st_cn.start = 0; for (i = 0; i < OMI_OP_MAX; i++) cll->st_cn.xact[i] = 0; for (i = 0; i < OMI_ER_MAX; i++) cll->st_cn.errs[i] = 0; omi_nxact = omi_nerrs = omi_brecv = omi_bsent = 0; /* Fall back on a compile time constant */ if (!omi_service) omi_service = SRVC_NAME; #ifdef NET_TCP /* NET_TCP is defined only when BSD_TCP is defined or SYSV_TCP is defined, but SYSV_TCP is never defined (a bug?) * so we move the code of obtaining port information from service down to #ifdef BSD_TCP */ #ifdef SYSV_TCP GTMASSERT; #endif #endif /* defined(NET_TCP) */ #ifdef BSD_TCP /* Create a socket always tries IPv6 first */ SERVER_HINTS(hints, ((GTM_IPV6_SUPPORTED && !ipv4_only) ? AF_INET6 : AF_INET)); if ((fd = socket(hints.ai_family, SOCK_STREAM, 0)) < 0) { if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { save_errno = errno; return save_errno; } hints.ai_family = AF_INET; } /* Bind an address to the socket */ if (0 != (errcode = getaddrinfo(NULL, omi_service, &hints, &ai_ptr))) { RTS_ERROR_ADDRINFO(NULL, ERR_GETADDRINFO, errcode); return errcode; } if (ISDIGIT_ASCII(*omi_service)) port = atoi(omi_service); else { if (0 != (errcode = getnameinfo(ai_ptr->ai_addr, ai_ptr->ai_addrlen, NULL, 0, port_buffer, NI_MAXSERV, NI_NUMERICSERV))) { assert(FALSE); RTS_ERROR_ADDRINFO(NULL, ERR_GETNAMEINFO, errcode); return errcode; } port = atoi(port_buffer); } /* Reuse a specified address */ if (port && setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&reuseaddr, SIZEOF(reuseaddr)) < 0) { save_errno = errno; CLOSEFILE_RESET(fd, rc); /* resets "fd" to FD_INVALID */ return save_errno; } if (bind(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen) < 0) { save_errno = errno; CLOSEFILE_RESET(fd, rc); /* resets "fd" to FD_INVALID */ return save_errno; } /* Initialize the listen queue */ if (listen(fd, 5) < 0) { save_errno = errno; CLOSEFILE_RESET(fd, rc); /* resets "fd" to FD_INVALID */ return save_errno; } /* set up raw socket for use with pinging option */ if (ping_keepalive) psock = init_ping(); /* Store the file descriptor away for use later */ cll->nve = fd; OMI_DBG_STMP; OMI_DBG((omi_debug, "%s: socket registered at port %d\n", SRVR_NAME, (int)port)); #ifdef GTCM_RC OMI_DBG((omi_debug, "RC server ID %d, Process ID %d\n", rc_server_id, omi_pid)); #endif if (authenticate) OMI_DBG((omi_debug, "Password verification on OMI connections enabled.\n")); if (!one_conn_per_inaddr) OMI_DBG((omi_debug, "Multiple connections from the same internet address allowed.\n")); if (psock > 0) OMI_DBG((omi_debug, "Keepalive option (-ping) enabled.\n")); return 0; #else /* defined(BSD_TCP) */ #ifdef SYSV_TCP GTMASSERT; if ((fd = t_open(SYSV_TCP, O_RDWR, NULL)) < 0) { save_errno = errno; return save_errno; } if (!(bind = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL))) { save_errno = errno; (void) t_close(fd); return save_errno; } bind->qlen = 5; bind->addr.len = 0; bind->addr.buf = 0; if (t_bind(fd, bind, bind) < 0) { save_errno = errno; (void) t_free(bind, T_BIND); (void) t_close(fd); return save_errno; } /* Store the file descriptor away for use later */ cll->nve = fd; OMI_DBG_STMP; OMI_DBG((omi_debug, "%s: socket registered at port %d\n", SRVR_NAME, (int)port)); #ifdef GTCM_RC OMI_DBG((omi_debug, "RC server ID %d\n", rc_server_id)); #endif return 0; #else /* defined(SYSV_TCP) */ cll->nve = FD_INVALID; return -1; #endif /* !defined(SYSV_TCP) */ #endif /* !defined(BSD_TCP) */ }
/* * How to bind to reserved ports. * (port-only) version. */ int bind_resv_port2(u_short *pp) { int td, rc = -1, port; struct t_bind *treq, *tret; struct sockaddr_in *sin; extern char *t_errlist[]; extern int t_errno; struct netconfig *nc = (struct netconfig *) NULL; voidp nc_handle; if ((nc_handle = setnetconfig()) == (voidp) NULL) { plog(XLOG_ERROR, "Cannot rewind netconfig: %s", nc_sperror()); return -1; } /* * Search the netconfig table for INET/UDP. * This loop will terminate if there was an error in the /etc/netconfig * file or if you reached the end of the file without finding the udp * device. Either way your machine has probably far more problems (for * example, you cannot have nfs v2 w/o UDP). */ while (1) { if ((nc = getnetconfig(nc_handle)) == (struct netconfig *) NULL) { plog(XLOG_ERROR, "Error accessing getnetconfig: %s", nc_sperror()); endnetconfig(nc_handle); return -1; } if (STREQ(nc->nc_protofmly, NC_INET) && STREQ(nc->nc_proto, NC_UDP)) break; } /* * This is the primary reason for the getnetconfig code above: to get the * correct device name to udp, and t_open a descriptor to be used in * t_bind below. */ td = t_open(nc->nc_device, O_RDWR, (struct t_info *) 0); endnetconfig(nc_handle); if (td < 0) { plog(XLOG_ERROR, "t_open failed: %d: %s", t_errno, t_errlist[t_errno]); return -1; } treq = (struct t_bind *) t_alloc(td, T_BIND, T_ADDR); if (!treq) { plog(XLOG_ERROR, "t_alloc req"); return -1; } tret = (struct t_bind *) t_alloc(td, T_BIND, T_ADDR); if (!tret) { t_free((char *) treq, T_BIND); plog(XLOG_ERROR, "t_alloc ret"); return -1; } memset((char *) treq->addr.buf, 0, treq->addr.len); sin = (struct sockaddr_in *) treq->addr.buf; sin->sin_family = AF_INET; treq->qlen = 0; treq->addr.len = treq->addr.maxlen; errno = EADDRINUSE; port = IPPORT_RESERVED; do { --port; sin->sin_port = htons(port); rc = t_bind(td, treq, tret); if (rc < 0) { plog(XLOG_ERROR, "t_bind for port %d: %s", port, t_errlist[t_errno]); } else { if (memcmp(treq->addr.buf, tret->addr.buf, tret->addr.len) == 0) break; else t_unbind(td); } } while ((rc < 0 || errno == EADDRINUSE) && (int) port > IPPORT_RESERVED / 2); if (pp && rc == 0) *pp = port; t_free((char *) tret, T_BIND); t_free((char *) treq, T_BIND); return rc; }
enum error proto_make_listener(Var desc, int *fd, Var * canon, const char **name) { struct sockaddr_in req_addr, rec_addr; struct t_bind requested, received; int s, port; static Stream *st = 0; if (!st) st = new_stream(20); if (desc.type != TYPE_INT) return E_TYPE; port = desc.v.num; s = t_open((void *) "/dev/tcp", O_RDWR, 0); if (s < 0) { log_ti_error("Creating listening endpoint"); return E_QUOTA; } req_addr.sin_family = AF_INET; req_addr.sin_addr.s_addr = bind_local_ip; req_addr.sin_port = htons(port); requested.addr.maxlen = sizeof(req_addr); requested.addr.len = sizeof(req_addr); requested.addr.buf = (void *) &req_addr; requested.qlen = 5; received.addr.maxlen = sizeof(rec_addr); received.addr.len = sizeof(rec_addr); received.addr.buf = (void *) &rec_addr; if (t_bind(s, &requested, &received) < 0) { enum error e = E_QUOTA; log_ti_error("Binding to listening address"); t_close(s); if (t_errno == TACCES || (t_errno == TSYSERR && errno == EACCES)) e = E_PERM; return e; } else if (port != 0 && rec_addr.sin_port != htons(port)) { errlog("Can't bind to requested port!\n"); t_close(s); return E_QUOTA; } if (!call) call = (struct t_call *) t_alloc(s, T_CALL, T_ADDR); if (!call) { log_ti_error("Allocating T_CALL structure"); t_close(s); return E_QUOTA; } canon->type = TYPE_INT; canon->v.num = ntohs(rec_addr.sin_port); stream_printf(st, "port %d", canon->v.num); *name = reset_stream(st); *fd = s; return E_NONE; }
/* * Bind a fd to a privileged IP port. * This is slightly different from the code in netdir_options * because it has a different interface - main thing is that it * needs to know its own address. We also wanted to set the qlen. * t_getname() can be used for those purposes and perhaps job can be done. */ int __rpc_bindresvport_ipv6(int fd, struct sockaddr *sin, int *portp, int qlen, char *fmly) { int res; static in_port_t port, *sinport; struct sockaddr_in6 myaddr; int i; struct t_bind tbindstr, *tres; struct t_info tinfo; extern mutex_t portnum_lock; /* VARIABLES PROTECTED BY portnum_lock: port */ #define STARTPORT 600 #define ENDPORT (IPPORT_RESERVED - 1) #define NPORTS (ENDPORT - STARTPORT + 1) if (sin == 0 && fmly == 0) { errno = EINVAL; return (-1); } if (geteuid()) { errno = EACCES; return (-1); } if ((i = t_getstate(fd)) != T_UNBND) { if (t_errno == TBADF) errno = EBADF; if (i != -1) errno = EISCONN; return (-1); } if (sin == 0) { sin = (struct sockaddr *)&myaddr; get_myaddress_ipv6(fmly, sin); } if (sin->sa_family == AF_INET) { /* LINTED pointer cast */ sinport = &((struct sockaddr_in *)sin)->sin_port; } else if (sin->sa_family == AF_INET6) { /* LINTED pointer cast */ sinport = &((struct sockaddr_in6 *)sin)->sin6_port; } else { errno = EPFNOSUPPORT; return (-1); } /* Transform sockaddr to netbuf */ if (t_getinfo(fd, &tinfo) == -1) { return (-1); } /* LINTED pointer cast */ tres = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR); if (tres == NULL) return (-1); tbindstr.qlen = qlen; tbindstr.addr.buf = (char *)sin; tbindstr.addr.len = tbindstr.addr.maxlen = __rpc_get_a_size(tinfo.addr); /* LINTED pointer cast */ sin = (struct sockaddr *)tbindstr.addr.buf; res = -1; (void) mutex_lock(&portnum_lock); if (port == 0) port = (getpid() % NPORTS) + STARTPORT; for (i = 0; i < NPORTS; i++) { *sinport = htons(port++); if (port > ENDPORT) port = STARTPORT; res = t_bind(fd, &tbindstr, tres); if (res == 0) { if ((tbindstr.addr.len == tres->addr.len) && (memcmp(tbindstr.addr.buf, tres->addr.buf, (int)tres->addr.len) == 0)) break; (void) t_unbind(fd); res = -1; } else if (t_errno != TSYSERR || errno != EADDRINUSE) break; } (void) mutex_unlock(&portnum_lock); if ((portp != NULL) && (res == 0)) *portp = *sinport; (void) t_free((char *)tres, T_BIND); return (res); }
void dfa_to_table( const p_dfa pa, int** weight_list, int *weight_size, int** state_table, int *state_size ) { p_nodelist pnl; p_node pn; p_edgelist pel; p_edge pe; int weight_map[256]; int i, j; for (i = 0; i < 256; i ++) weight_map[i] = 0; j = 1; *state_size = 0; pnl = pa->pnl_f; while (pnl != NULL) { pn = pnl->element; pel = pn->pel_f; while (pel != NULL) { pe = pel->element; weight_map[pe->weight] = 1; pel = pel->next; } pnl = pnl->next; (*state_size) ++; } for (i = 0, j = 1; i < 256; i ++) { if (weight_map[i] == 1) weight_map[i] = j++; } *weight_size = j; *weight_list = (int*)t_alloc( sizeof(int)*(*weight_size) ); (*weight_list)[0] = 0; for (i = 0; i < 256; i ++) { if (weight_map[i] > 0) { (*weight_list)[weight_map[i]] = i; } } *state_table = (int*)t_alloc( sizeof(int) * ((*state_size) * (*weight_size) ) ); for (i = 0; i < (*state_size)*(*weight_size); i ++) (*state_table)[i] = 0; i = 0; pnl = pa->pnl_f; while (pnl != NULL) { pn = pnl->element; (*state_table)[i * (*weight_size) + 0] = pn->id; pel = pn->pel_f; while (pel != NULL) { pe = pel->element; (*state_table)[i * (*weight_size) + weight_map[pe->weight]] = pe->dest->id; pel = pel->next; } i++; pnl = pnl->next; } /* dump the id */ /* id_map = (int*)t_alloc( sizeof(int)*state_size ); i = 0; pnl = pa->pnl_f; while (pnl != NULL) { id_map[i++] = pnl->element->id; pnl = pnl->next; } t_free( id_map ); */ }
static int get_tcp_socket( char *machine, /* remote host */ char *service, /* nttp/smtp etc. */ unsigned short port) /* tcp port number */ { int s = -1; int save_errno = 0; struct sockaddr_in sock_in; # ifdef TLI /* Transport Level Interface */ char device[20]; char *env_device; extern int t_errno; extern struct hostent *gethostbyname(); struct hostent *hp; struct t_call *callptr; /* * Create a TCP transport endpoint. */ if ((env_device = getenv("DEV_TCP")) != NULL) /* SCO uses DEV_TCP, most other OS use /dev/tcp */ STRCPY(device, env_device); else strcpy(device, "/dev/tcp"); if ((s = t_open(device, O_RDWR, (struct t_info *) 0)) < 0){ t_error(txt_error_topen); return -EPROTO; } if (t_bind(s, (struct t_bind *) 0, (struct t_bind *) 0) < 0) { t_error("t_bind"); t_close(s); return -EPROTO; } memset((char *) &sock_in, '\0', sizeof(sock_in)); sock_in.sin_family = AF_INET; sock_in.sin_port = htons(port); if (!isdigit((unsigned char)*machine) || # ifdef HAVE_INET_ATON !inet_aton(machine, &sock_in) # else # ifdef HAVE_INET_ADDR (long) (sock_in.sin_addr.s_addr = inet_addr(machine)) == INADDR_NONE) # endif /* HAVE_INET_ADDR */ # endif /* HAVE_INET_ATON */ { if ((hp = gethostbyname(machine)) == NULL) { my_fprintf(stderr, _(txt_gethostbyname), "gethostbyname() ", machine); t_close(s); return -EHOSTUNREACH; } memcpy((char *) &sock_in.sin_addr, hp->h_addr, hp->h_length); } /* * Allocate a t_call structure and initialize it. * Let t_alloc() initialize the addr structure of the t_call structure. */ if ((callptr = (struct t_call *) t_alloc(s, T_CALL, T_ADDR)) == NULL){ t_error("t_alloc"); t_close(s); return -EPROTO; } callptr->addr.maxlen = sizeof(sock_in); callptr->addr.len = sizeof(sock_in); callptr->addr.buf = (char *) &sock_in; callptr->opt.len = 0; /* no options */ callptr->udata.len = 0; /* no user data with connect */ /* * Connect to the server. */ if (t_connect(s, callptr, (struct t_call *) 0) < 0) { save_errno = t_errno; if (save_errno == TLOOK) fprintf(stderr, _(txt_error_server_unavailable)); else t_error("t_connect"); t_free((char *) callptr, T_CALL); t_close(s); return -save_errno; } /* * Now replace the timod module with the tirdwr module so that * standard read() and write() system calls can be used on the * descriptor. */ t_free((char *) callptr, T_CALL); if (ioctl(s, I_POP, (char *) 0) < 0) { perror("I_POP(timod)"); t_close(s); return -EPROTO; } if (ioctl(s, I_PUSH, "tirdwr") < 0) { perror("I_PUSH(tirdwr)"); t_close(s); return -EPROTO; } # else # ifndef EXCELAN struct servent *sp; struct hostent *hp; # ifdef h_addr int x = 0; char **cp; static char *alist[2] = {0, 0}; # endif /* h_addr */ static struct hostent def; static struct in_addr defaddr; static char namebuf[256]; # ifdef HAVE_GETSERVBYNAME if ((sp = (struct servent *) getservbyname(service, "tcp")) == NULL) { my_fprintf(stderr, _(txt_error_unknown_service), service); return -EHOSTUNREACH; } # else sp = my_malloc(sizeof(struct servent)); sp->s_port = htons(IPPORT_NNTP); # endif /* HAVE_GETSERVBYNAME */ /* If not a raw ip address, try nameserver */ if (!isdigit((unsigned char) *machine) || # ifdef HAVE_INET_ATON !inet_aton(machine, &defaddr) # else # ifdef HAVE_INET_ADDR (long) (defaddr.s_addr = (long) inet_addr(machine)) == -1 # endif /* HAVE_INET_ADDR */ # endif /* HAVE_INET_ATON */ ) { hp = gethostbyname(machine); } else { /* Raw ip address, fake */ STRCPY(namebuf, machine); def.h_name = (char *) namebuf; # ifdef h_addr def.h_addr_list = alist; # endif /* h_addr */ def.h_addr = (char *) &defaddr; def.h_length = sizeof(struct in_addr); def.h_addrtype = AF_INET; def.h_aliases = 0; hp = &def; } if (hp == NULL) { my_fprintf(stderr, _(txt_gethostbyname), "\n", machine); return -EHOSTUNREACH; } memset((char *) &sock_in, '\0', sizeof(sock_in)); sock_in.sin_family = hp->h_addrtype; sock_in.sin_port = htons(port); /* sock_in.sin_port = sp->s_port; */ # else memset((char *) &sock_in, '\0', sizeof(sock_in)); sock_in.sin_family = AF_INET; # endif /* !EXCELAN */ /* * The following is kinda gross. The name server under 4.3 * returns a list of addresses, each of which should be tried * in turn if the previous one fails. However, 4.2 hostent * structure doesn't have this list of addresses. * Under 4.3, h_addr is a #define to h_addr_list[0]. * We use this to figure out whether to include the NS specific * code... */ # ifdef h_addr /* * Get a socket and initiate connection -- use multiple addresses */ for (cp = hp->h_addr_list; cp && *cp; cp++) { # if defined(__hpux) && defined(SVR4) unsigned long socksize, socksizelen; # endif /* __hpux && SVR4 */ if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) { perror("socket"); return -errno; } memcpy((char *) &sock_in.sin_addr, *cp, hp->h_length); # ifdef HAVE_INET_NTOA if (x < 0) my_fprintf(stderr, _(txt_trying), (char *) inet_ntoa(sock_in.sin_addr)); # endif /* HAVE_INET_NTOA */ # if defined(__hpux) && defined(SVR4) /* recommended by [email protected] */ # define HPSOCKSIZE 0x8000 getsockopt(s, SOL_SOCKET, SO_SNDBUF, /* (caddr_t) */ &socksize, /* (caddr_t) */ &socksizelen); if (socksize < HPSOCKSIZE) { socksize = HPSOCKSIZE; setsockopt(s, SOL_SOCKET, SO_SNDBUF, /* (caddr_t) */ &socksize, sizeof(socksize)); } socksize = 0; socksizelen = sizeof(socksize); getsockopt(s, SOL_SOCKET, SO_RCVBUF, /* (caddr_t) */ &socksize, /* (caddr_t) */ &socksizelen); if (socksize < HPSOCKSIZE) { socksize = HPSOCKSIZE; setsockopt(s, SOL_SOCKET, SO_RCVBUF, /* (caddr_t) */ &socksize, sizeof(socksize)); } # endif /* __hpux && SVR4 */ if ((x = connect(s, (struct sockaddr *) &sock_in, sizeof(sock_in))) == 0) break; save_errno = errno; /* Keep for later */ # ifdef HAVE_INET_NTOA my_fprintf(stderr, _(txt_connection_to), (char *) inet_ntoa(sock_in.sin_addr)); perror(""); # endif /* HAVE_INET_NTOA */ (void) s_close(s); } if (x < 0) { my_fprintf(stderr, _(txt_giving_up)); return -save_errno; /* Return the last errno we got */ } # else # ifdef EXCELAN if ((s = socket(SOCK_STREAM, (struct sockproto *) NULL, &sock_in, SO_KEEPALIVE)) < 0) { perror("socket"); return -errno; } /* set up addr for the connect */ memset((char *) &sock_in, '\0', sizeof(sock_in)); sock_in.sin_family = AF_INET; sock_in.sin_port = htons(IPPORT_NNTP); if ((sock_in.sin_addr.s_addr = rhost(&machine)) == -1) { my_fprintf(stderr, _(txt_gethostbyname), "\n", machine); return -1; } /* And connect */ if (connect(s, (struct sockaddr *) &sock_in) < 0) { save_errno = errno; perror("connect"); (void) s_close(s); return -save_errno; } # else if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return -errno; } /* And then connect */ memcpy((char *) &sock_in.sin_addr, hp->h_addr, hp->h_length); if (connect(s, (struct sockaddr *) &sock_in, sizeof(sock_in)) < 0) { save_errno = errno; perror("connect"); (void) s_close(s); return -save_errno; } # endif /* !EXCELAN */ # endif /* !h_addr */ # endif /* !TLI */ return s; }
/* * Bind to preferred AMQ port. */ static int bind_preferred_amq_port(u_short pref_port, const struct netconfig *ncp, struct t_bind **tretpp) { int td = -1, rc = -1; struct t_bind *treq; struct sockaddr_in *sin, *sin2; extern char *t_errlist[]; extern int t_errno; if (!ncp) { plog(XLOG_ERROR, "null ncp"); return -1; } td = t_open(ncp->nc_device, O_RDWR, (struct t_info *) NULL); if (td < 0) { plog(XLOG_ERROR, "t_open failed: %d: %s", t_errno, t_errlist[t_errno]); return -1; } treq = (struct t_bind *) t_alloc(td, T_BIND, T_ADDR); if (!treq) { plog(XLOG_ERROR, "t_alloc req"); return -1; } *tretpp = (struct t_bind *) t_alloc(td, T_BIND, T_ADDR); if (!*tretpp) { t_free((char *) treq, T_BIND); plog(XLOG_ERROR, "t_alloc tretpp"); return -1; } memset((char *) treq->addr.buf, 0, treq->addr.len); sin = (struct sockaddr_in *) treq->addr.buf; sin->sin_family = AF_INET; treq->qlen = 64; /* must be greater than 0 to work for TCP connections */ treq->addr.len = treq->addr.maxlen; if (pref_port > 0) { sin->sin_port = htons(pref_port); sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* XXX: may not be needed */ rc = t_bind(td, treq, *tretpp); if (rc < 0) { plog(XLOG_ERROR, "t_bind return err %d", rc); goto out; } /* check if we got the port we asked for */ sin2 = (struct sockaddr_in *) (*tretpp)->addr.buf; if (sin->sin_port != sin2->sin_port) { plog(XLOG_ERROR, "asked for port %d, got different one (%d)", ntohs(sin->sin_port), ntohs(sin2->sin_port)); t_errno = TNOADDR; /* XXX: is this correct? */ rc = -1; goto out; } if (sin->sin_addr.s_addr != sin2->sin_addr.s_addr) { plog(XLOG_ERROR, "asked for address %x, got different one (%x)", (int) ntohl(sin->sin_addr.s_addr), (int) ntohl(sin2->sin_addr.s_addr)); t_errno = TNOADDR; /* XXX: is this correct? */ rc = -1; goto out; } } out: t_free((char *) treq, T_BIND); return (rc < 0 ? rc : td); }