1 | /* |
---|
2 | * This part for NCR UNIX with is from Andrew Maffei (arm@aqua.whoi.edu). It |
---|
3 | * assumes TLI throughout. In order to look up endpoint address information |
---|
4 | * we must talk to the "timod" streams module. For some reason "timod" wants |
---|
5 | * to sit directly on top of the device driver. Therefore we pop off all |
---|
6 | * streams modules except the driver, install the "timod" module so that we |
---|
7 | * can figure out network addresses, and then restore the original state. |
---|
8 | */ |
---|
9 | |
---|
10 | #ifndef lint |
---|
11 | static char sccsid[] = "@(#) ncr.c 1.1 94/12/28 17:42:34"; |
---|
12 | #endif |
---|
13 | |
---|
14 | #include <sys/types.h> |
---|
15 | #include <stdio.h> |
---|
16 | #include <syslog.h> |
---|
17 | #include <sys/tiuser.h> |
---|
18 | #include <stropts.h> |
---|
19 | #include <sys/conf.h> |
---|
20 | |
---|
21 | #include "tcpd.h" |
---|
22 | |
---|
23 | #define MAX_MODULE_COUNT 10 /* XXX */ |
---|
24 | |
---|
25 | /* fromhost - tear down the streams stack then rebuild it */ |
---|
26 | |
---|
27 | void fromhost(request) |
---|
28 | struct request_info *request; |
---|
29 | { |
---|
30 | int i; |
---|
31 | int num_mod; |
---|
32 | struct str_list str_list; |
---|
33 | struct str_mlist mod_buffer[MAX_MODULE_COUNT]; |
---|
34 | int fd = request->fd; |
---|
35 | |
---|
36 | str_list.sl_nmods = MAX_MODULE_COUNT; |
---|
37 | str_list.sl_modlist = &mod_buffer[0]; |
---|
38 | |
---|
39 | /* |
---|
40 | * On systems with WIN streams support we have to be careful about what |
---|
41 | * is on the stream we are passed. This code POPs off all modules above |
---|
42 | * the pseudo driver, pushes timod, gets the host address information, |
---|
43 | * pops timod and then pushes all modules back on the stream. |
---|
44 | * |
---|
45 | * Some state may be lost in this process. /usr/etc/tlid seems to do special |
---|
46 | * things to the stream depending on the TCP port being serviced. (not a |
---|
47 | * very nice thing to do!). It is unclear what to do if this code breaks |
---|
48 | * - the stream may be left in an unknown condition. |
---|
49 | */ |
---|
50 | if ((num_mod = ioctl(fd, I_LIST, NULL)) < 0) |
---|
51 | tcpd_warn("fromhost: LIST failed: %m"); |
---|
52 | if (ioctl(fd, I_LIST, &str_list) < 0) |
---|
53 | tcpd_warn("fromhost: LIST failed: %m"); |
---|
54 | |
---|
55 | /* |
---|
56 | * POP stream modules except for the driver. |
---|
57 | */ |
---|
58 | for (i = 0; i < num_mod - 1; i++) |
---|
59 | if (ioctl(fd, I_POP, 0) < 0) |
---|
60 | tcpd_warn("fromhost: POP %s: %m", mod_buffer[i].l_name); |
---|
61 | |
---|
62 | /* |
---|
63 | * PUSH timod so that host address ioctls can be executed. |
---|
64 | */ |
---|
65 | if (ioctl(fd, I_PUSH, "timod") < 0) |
---|
66 | tcpd_warn("fromhost: PUSH timod: %m"); |
---|
67 | tli_host(request); |
---|
68 | |
---|
69 | /* |
---|
70 | * POP timod, we're done with it now. |
---|
71 | */ |
---|
72 | if (ioctl(fd, I_POP, 0) < 0) |
---|
73 | tcpd_warn("fromhost: POP timod: %m"); |
---|
74 | |
---|
75 | /* |
---|
76 | * Restore stream modules. |
---|
77 | */ |
---|
78 | for (i = num_mod - 2; i >= 0; i--) |
---|
79 | if (ioctl(fd, I_PUSH, mod_buffer[i].l_name) < 0) |
---|
80 | tcpd_warn("fromhost: PUSH %s: %m", mod_buffer[i].l_name); |
---|
81 | } |
---|