source: trunk/third/tcp_wrappers/tli-sequent.c @ 11717

Revision 11717, 4.9 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r11716, which included commits to RCS files with non-trunk default branches.
Line 
1 /*
2  * Warning - this relies heavily on the TLI implementation in PTX 2.X and will
3  * probably not work under PTX 4.
4  *
5  * Author: Tim Wright, Sequent Computer Systems Ltd., UK.
6  *
7  * Modified slightly to conform to the new internal interfaces - Wietse
8  */
9
10#ifndef lint
11static char sccsid[] = "@(#) tli-sequent.c 1.1 94/12/28 17:42:51";
12#endif
13
14#ifdef TLI_SEQUENT
15
16/* System libraries. */
17
18#include <sys/types.h>
19#include <sys/param.h>
20#include <sys/stat.h>
21#include <sys/tiuser.h>
22#include <sys/stream.h>
23#include <sys/stropts.h>
24#include <sys/tihdr.h>
25#include <sys/timod.h>
26#include <sys/socket.h>
27#include <netinet/in.h>
28#include <stdio.h>
29#include <syslog.h>
30#include <errno.h>
31#include <string.h>
32
33extern int errno;
34extern char *sys_errlist[];
35extern int sys_nerr;
36extern int t_errno;
37extern char *t_errlist[];
38extern int t_nerr;
39
40/* Local stuff. */
41
42#include "tcpd.h"
43#include "tli-sequent.h"
44
45/* Forward declarations. */
46
47static char *tli_error();
48static void tli_sink();
49
50/* tli_host - determine endpoint info */
51
52int     tli_host(request)
53struct request_info *request;
54{
55    static struct sockaddr_in client;
56    static struct sockaddr_in server;
57    struct _ti_user *tli_state_ptr;
58    union T_primitives *TSI_prim_ptr;
59    struct strpeek peek;
60    int     len;
61
62    /*
63     * Use DNS and socket routines for name and address conversions.
64     */
65
66    sock_methods(request);
67
68    /*
69     * Find out the client address using getpeerinaddr(). This call is the
70     * TLI equivalent to getpeername() under Dynix/ptx.
71     */
72
73    len = sizeof(client);
74    t_sync(request->fd);
75    if (getpeerinaddr(request->fd, &client, len) < 0) {
76        tcpd_warn("can't get client address: %s", tli_error());
77        return;
78    }
79    request->client->sin = &client;
80
81    /* Call TLI utility routine to get information on endpoint */
82    if ((tli_state_ptr = _t_checkfd(request->fd)) == NULL)
83        return;
84
85    if (tli_state_ptr->ti_servtype == T_CLTS) {
86        /* UDP - may need to get address the hard way */
87        if (client.sin_addr.s_addr == 0) {
88            /* The UDP endpoint is not connected so we didn't get the */
89            /* remote address - get it the hard way ! */
90
91            /* Look at the control part of the top message on the stream */
92            /* we don't want to remove it from the stream so we use I_PEEK */
93            peek.ctlbuf.maxlen = tli_state_ptr->ti_ctlsize;
94            peek.ctlbuf.len = 0;
95            peek.ctlbuf.buf = tli_state_ptr->ti_ctlbuf;
96            /* Don't even look at the data */
97            peek.databuf.maxlen = -1;
98            peek.databuf.len = 0;
99            peek.databuf.buf = 0;
100            peek.flags = 0;
101
102            switch (ioctl(request->fd, I_PEEK, &peek)) {
103            case -1:
104                tcpd_warn("can't peek at endpoint: %s", tli_error());
105                return;
106            case 0:
107                /* No control part - we're hosed */
108                tcpd_warn("can't get UDP info: %s", tli_error());
109                return;
110            default:
111                /* FALL THROUGH */
112                ;
113            }
114            /* Can we even check the PRIM_type ? */
115            if (peek.ctlbuf.len < sizeof(long)) {
116                tcpd_warn("UDP control info garbage");
117                return;
118            }
119            TSI_prim_ptr = (union T_primitives *) peek.ctlbuf.buf;
120            if (TSI_prim_ptr->type != T_UNITDATA_IND) {
121                tcpd_warn("wrong type for UDP control info");
122                return;
123            }
124            /* Validate returned unitdata indication packet */
125            if ((peek.ctlbuf.len < sizeof(struct T_unitdata_ind)) ||
126                ((TSI_prim_ptr->unitdata_ind.OPT_length != 0) &&
127                 (peek.ctlbuf.len <
128                  TSI_prim_ptr->unitdata_ind.OPT_length +
129                  TSI_prim_ptr->unitdata_ind.OPT_offset))) {
130                tcpd_warn("UDP control info garbaged");
131                return;
132            }
133            /* Extract the address */
134            memcpy(&client,
135                   peek.ctlbuf.buf + TSI_prim_ptr->unitdata_ind.SRC_offset,
136                   TSI_prim_ptr->unitdata_ind.SRC_length);
137        }
138        request->sink = tli_sink;
139    }
140    if (getmyinaddr(request->fd, &server, len) < 0)
141        tcpd_warn("can't get local address: %s", tli_error());
142    else
143        request->server->sin = &server;
144}
145
146/* tli_error - convert tli error number to text */
147
148static char *tli_error()
149{
150    static char buf[40];
151
152    if (t_errno != TSYSERR) {
153        if (t_errno < 0 || t_errno >= t_nerr) {
154            sprintf(buf, "Unknown TLI error %d", t_errno);
155            return (buf);
156        } else {
157            return (t_errlist[t_errno]);
158        }
159    } else {
160        if (errno < 0 || errno >= sys_nerr) {
161            sprintf(buf, "Unknown UNIX error %d", errno);
162            return (buf);
163        } else {
164            return (sys_errlist[errno]);
165        }
166    }
167}
168
169/* tli_sink - absorb unreceived datagram */
170
171static void tli_sink(fd)
172int     fd;
173{
174    struct t_unitdata *unit;
175    int     flags;
176
177    /*
178     * Something went wrong. Absorb the datagram to keep inetd from looping.
179     * Allocate storage for address, control and data. If that fails, sleep
180     * for a couple of seconds in an attempt to keep inetd from looping too
181     * fast.
182     */
183
184    if ((unit = (struct t_unitdata *) t_alloc(fd, T_UNITDATA, T_ALL)) == 0) {
185        tcpd_warn("t_alloc: %s", tli_error());
186        sleep(5);
187    } else {
188        (void) t_rcvudata(fd, unit, &flags);
189        t_free((void *) unit, T_UNITDATA);
190    }
191}
192
193#endif /* TLI_SEQUENT */
Note: See TracBrowser for help on using the repository browser.