144743Smarkm /* 244743Smarkm * The Dynix/PTX TLI implementation is not quite compatible with System V 344743Smarkm * Release 4. Some important functions are not present so we are limited to 444743Smarkm * IP-based services. 544743Smarkm * 644743Smarkm * Diagnostics are reported through syslog(3). 744743Smarkm * 844743Smarkm * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands. 944743Smarkm */ 1044743Smarkm 1144743Smarkm#ifndef lint 1244743Smarkmstatic char sccsid[] = "@(#) ptx.c 1.3 94/12/28 17:42:38"; 1344743Smarkm#endif 1444743Smarkm 1544743Smarkm#ifdef PTX 1644743Smarkm 1744743Smarkm/* System libraries. */ 1844743Smarkm 1944743Smarkm#include <sys/types.h> 2044743Smarkm#include <sys/tiuser.h> 2144743Smarkm#include <sys/socket.h> 2244743Smarkm#include <stropts.h> 2344743Smarkm#include <netinet/in.h> 2444743Smarkm#include <netdb.h> 2544743Smarkm#include <stdio.h> 2644743Smarkm#include <syslog.h> 2744743Smarkm 2844743Smarkm/* Local stuff. */ 2944743Smarkm 3044743Smarkm#include "tcpd.h" 3144743Smarkm 3244743Smarkm/* Forward declarations. */ 3344743Smarkm 3444743Smarkmstatic void ptx_sink(); 3544743Smarkm 3644743Smarkm/* tli_host - determine TLI endpoint info, PTX version */ 3744743Smarkm 3844743Smarkmvoid tli_host(request) 3944743Smarkmstruct request_info *request; 4044743Smarkm{ 4144743Smarkm static struct sockaddr_in client; 4244743Smarkm static struct sockaddr_in server; 4344743Smarkm 4444743Smarkm /* 4544743Smarkm * getpeerinaddr() was suggested by someone at Sequent. It seems to work 4644743Smarkm * with connection-oriented (TCP) services such as rlogind and telnetd, 4744743Smarkm * but it returns 0.0.0.0 with datagram (UDP) services. No problem: UDP 4844743Smarkm * needs special treatment anyway, in case we must refuse service. 4944743Smarkm */ 5044743Smarkm 5144743Smarkm if (getpeerinaddr(request->fd, &client, sizeof(client)) == 0 5244743Smarkm && client.sin_addr.s_addr != 0) { 5344743Smarkm request->client->sin = &client; 5444743Smarkm if (getmyinaddr(request->fd, &server, sizeof(server)) == 0) { 5544743Smarkm request->server->sin = &server; 5644743Smarkm } else { 5744743Smarkm tcpd_warn("warning: getmyinaddr: %m"); 5844743Smarkm } 5944743Smarkm sock_methods(request); 6044743Smarkm 6144743Smarkm } else { 6244743Smarkm 6344743Smarkm /* 6444743Smarkm * Another suggestion was to temporarily switch to the socket 6544743Smarkm * interface, identify the endpoint addresses with socket calls, then 6644743Smarkm * to switch back to TLI. This seems to works OK with UDP services, 6744743Smarkm * which is exactly what we should be looking at right now. 6844743Smarkm */ 6944743Smarkm 7044743Smarkm#define SWAP_MODULE(f, old, new) (ioctl(f, I_POP, old), ioctl(f, I_PUSH, new)) 7144743Smarkm 7244743Smarkm if (SWAP_MODULE(request->fd, "timod", "sockmod") != 0) 7344743Smarkm tcpd_warn("replace timod by sockmod: %m"); 7444743Smarkm sock_host(request); 7544743Smarkm if (SWAP_MODULE(request->fd, "sockmod", "timod") != 0) 7644743Smarkm tcpd_warn("replace sockmod by timod: %m"); 7744743Smarkm if (request->sink != 0) 7844743Smarkm request->sink = ptx_sink; 7944743Smarkm } 8044743Smarkm} 8144743Smarkm 8244743Smarkm/* ptx_sink - absorb unreceived IP datagram */ 8344743Smarkm 8444743Smarkmstatic void ptx_sink(fd) 8544743Smarkmint fd; 8644743Smarkm{ 8744743Smarkm char buf[BUFSIZ]; 8844743Smarkm struct sockaddr sa; 8944743Smarkm int size = sizeof(sa); 9044743Smarkm 9144743Smarkm /* 9244743Smarkm * Eat up the not-yet received datagram. Where needed, switch to the 9344743Smarkm * socket programming interface. 9444743Smarkm */ 9544743Smarkm 9644743Smarkm if (ioctl(fd, I_FIND, "timod") != 0) 9744743Smarkm ioctl(fd, I_POP, "timod"); 9844743Smarkm if (ioctl(fd, I_FIND, "sockmod") == 0) 9944743Smarkm ioctl(fd, I_PUSH, "sockmod"); 10044743Smarkm (void) recvfrom(fd, buf, sizeof(buf), 0, &sa, &size); 10144743Smarkm} 10244743Smarkm 10344743Smarkm#endif /* PTX */ 104