home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / N / TCPIP / NETKIT-A.06 / NETKIT-A / NetKit-A-0.06 / tcp_wrapper-6.3 / tli-sequent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-27  |  6.0 KB  |  223 lines

  1.  /*
  2.   * tli_host() determines the type of transport (connected, connectionless),
  3.   * the name and address of the host at the other end of a network link. In
  4.   * case of an IP service, tli_host() also determines the local address and
  5.   * port, and the remote username if username lookups are done irrespective
  6.   * of client. All results are in static memory.
  7.   * 
  8.   * The return status is (-1) if the remote host pretends to have someone elses
  9.   * name, or if the remote host name is available but could not be verified;
  10.   * in either case the hostname will be ignored. The return status is zero in
  11.   * all other cases (the hostname is unavailable, or the host name double
  12.   * check succeeds).
  13.   * 
  14.   * Diagnostics are reported through syslog(3).
  15.   * 
  16.   * Warning - this relies heavily on the TLI implementation in PTX 2.X
  17.   * and will probably not work under PTX 4.
  18.   *
  19.   * Author: Tim Wright, Sequent Computer Systems Ltd., UK.
  20.   */
  21.  
  22. #ifndef lint
  23. static char sccsid[] = "@(#) tli-sequent.c 1.0 94/02/11 10:20:30";
  24. #endif
  25.  
  26. #ifdef TLI_SEQUENT
  27.  
  28. /* System libraries. */
  29.  
  30. #include <sys/types.h>
  31. #include <sys/param.h>
  32. #include <sys/stat.h>
  33. #include <sys/tiuser.h>
  34. #include <sys/stream.h>
  35. #include <sys/stropts.h>
  36. #include <sys/tihdr.h>
  37. #include <sys/timod.h>
  38. #include <sys/socket.h>
  39. #include <netinet/in.h>
  40. #include <stdio.h>
  41. #include <syslog.h>
  42. #include <errno.h>
  43.  
  44. extern char *strncpy();
  45.  
  46.  /* Some systems versions advertise a too small MAXHOSTNAMELEN value. */
  47.  
  48. #if (MAXHOSTNAMELEN < 64)
  49. #undef MAXHOSTNAMELEN
  50. #endif
  51.  
  52.  /* In case not defined in <sys/param.h>. */
  53.  
  54. #ifndef MAXHOSTNAMELEN
  55. #define MAXHOSTNAMELEN    256        /* storage for host name */
  56. #endif
  57.  
  58. extern int errno;
  59. extern char *sys_errlist[];
  60. extern int sys_nerr;
  61. extern int t_errno;
  62. extern char *t_errlist[];
  63. extern int t_nerr;
  64.  
  65. /* Local stuff. */
  66.  
  67. #include "log_tcp.h"
  68. #include "tli-sequent.h"
  69.  
  70. /* Forward declarations. */
  71.  
  72. static char *tli_error();
  73. static void tli_sink();
  74.  
  75. /* tli_host - determine endpoint info */
  76.  
  77. int     tli_host(client, fd)
  78. struct client_info *client;
  79. int     fd;
  80. {
  81.     static struct sockaddr_in rmt_sin;
  82.     static struct sockaddr_in our_sin;
  83.     struct _ti_user *tli_state_ptr;
  84.     union  T_primitives *TSI_prim_ptr;
  85.     struct strpeek peek;
  86.     int     len;
  87.  
  88.     /*
  89.      * Initialize the result with suitable defaults.
  90.      */
  91.  
  92.     init_client(client);
  93.     client->fd = fd;
  94.  
  95.     /*
  96.      * Find out the client address using getpeerinaddr(). This call is the
  97.      * TLI equivalent to getpeername() under Dynix/ptx.
  98.      */
  99.  
  100.     len = sizeof(rmt_sin);
  101.     t_sync(client->fd);
  102.     if (getpeerinaddr(client->fd, &rmt_sin, len) < 0) {
  103.     syslog(LOG_ERR, "error: can't get client address: %s", tli_error());
  104.     return (0);                /* address and name unknown */
  105.     }
  106.     client->rmt_sin = &rmt_sin;
  107.  
  108.     /* Call TLI utility routine to get information on endpoint */
  109.     if ((tli_state_ptr = _t_checkfd(fd)) == NULL)
  110.     return(0);
  111.  
  112.     if (tli_state_ptr->ti_servtype == T_CLTS) {
  113.     /* UDP - may need to get address the hard way */
  114.     if (rmt_sin.sin_addr.s_addr == 0) {
  115.         /* The UDP endpoint is not connected so we didn't get the */
  116.         /* remote address - get it the hard way ! */
  117.  
  118.         /* Look at the control part of the top message on the stream */
  119.         /* we don't want to remove it from the stream so we use I_PEEK */
  120.         peek.ctlbuf.maxlen = tli_state_ptr->ti_ctlsize;
  121.         peek.ctlbuf.len = 0;
  122.         peek.ctlbuf.buf = tli_state_ptr->ti_ctlbuf;
  123.         /* Don't even look at the data */
  124.         peek.databuf.maxlen = -1;
  125.         peek.databuf.len = 0;
  126.         peek.databuf.buf = 0;
  127.         peek.flags = 0;
  128.  
  129.         switch (ioctl(client->fd, I_PEEK, &peek)) {
  130.         case -1:
  131.         syslog(LOG_ERR, "error: can't peek at endpoint: %s", tli_error());
  132.         return(0);
  133.         case 0:
  134.         /* No control part - we're hosed */
  135.         syslog(LOG_ERR, "error: can't get UDP info: %s", tli_error());
  136.         return(0);
  137.         default:
  138.         /* FALL THROUGH */
  139.         ;
  140.         }
  141.         /* Can we even check the PRIM_type ? */
  142.         if (peek.ctlbuf.len < sizeof(long)) {
  143.         syslog(LOG_ERR, "error: UDP control info garbage");
  144.         return(0);
  145.         }
  146.         TSI_prim_ptr = (union T_primitives *) peek.ctlbuf.buf;
  147.         if (TSI_prim_ptr->type != T_UNITDATA_IND) {
  148.         syslog(LOG_ERR, "error: wrong type for UDP control info");
  149.         return(0);
  150.         }
  151.         /* Validate returned unitdata indication packet */
  152.         if ((peek.ctlbuf.len < sizeof(struct T_unitdata_ind)) ||
  153.         ((TSI_prim_ptr->unitdata_ind.OPT_length != 0) &&
  154.          (peek.ctlbuf.len <
  155.             TSI_prim_ptr->unitdata_ind.OPT_length +
  156.             TSI_prim_ptr->unitdata_ind.OPT_offset))) {
  157.         syslog(LOG_ERR, "error: UDP control info garbaged");
  158.         return(0);
  159.         }
  160.         /* Extract the address */
  161.         memcpy(&rmt_sin,
  162.         peek.ctlbuf.buf + TSI_prim_ptr->unitdata_ind.SRC_offset,
  163.         TSI_prim_ptr->unitdata_ind.SRC_length);
  164.     }
  165.     client->sink = tli_sink;
  166.     }
  167.  
  168.     if (getmyinaddr(client->fd, &our_sin, len) < 0)
  169.     syslog(LOG_ERR, "error: can't get local address: %s", tli_error());
  170.     else
  171.     client->our_sin = &our_sin;
  172.     return (sock_names(client));
  173. }
  174.  
  175. /* tli_error - convert tli error number to text */
  176.  
  177. static char *tli_error()
  178. {
  179.     static char buf[40];
  180.  
  181.     if (t_errno != TSYSERR) {
  182.     if (t_errno < 0 || t_errno >= t_nerr) {
  183.         sprintf(buf, "Unknown TLI error %d", t_errno);
  184.         return (buf);
  185.     } else {
  186.         return (t_errlist[t_errno]);
  187.     }
  188.     } else {
  189.     if (errno < 0 || errno >= sys_nerr) {
  190.         sprintf(buf, "Unknown UNIX error %d", errno);
  191.         return (buf);
  192.     } else {
  193.         return (sys_errlist[errno]);
  194.     }
  195.     }
  196. }
  197.  
  198. /* tli_sink - absorb unreceived datagram */
  199.  
  200. static void tli_sink(fd)
  201. int     fd;
  202. {
  203.     struct t_unitdata *unit;
  204.     int     flags;
  205.  
  206.     /*
  207.      * Something went wrong. Absorb the datagram to keep inetd from looping.
  208.      * Allocate storage for address, control and data. If that fails, sleep
  209.      * for a couple of seconds in an attempt to keep inetd from looping too
  210.      * fast.
  211.      */
  212.  
  213.     if ((unit = (struct t_unitdata *) t_alloc(fd, T_UNITDATA, T_ALL)) == 0) {
  214.     syslog(LOG_ERR, "error: t_alloc: %s", tli_error());
  215.     sleep(5);
  216.     } else {
  217.     (void) t_rcvudata(fd, unit, &flags);
  218.     t_free((void *) unit, T_UNITDATA);
  219.     }
  220. }
  221.  
  222. #endif /* TLI_SEQUENT */
  223.