00001
00002
00003 #include <sys/types.h>
00004 #include <sys/ioctl.h>
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <fcntl.h>
00008 #include <string.h>
00009 #include <unistd.h>
00010 #include <errno.h>
00011 #include <signal.h>
00012 #include <net/netlib.h>
00013 #include <net/hton.h>
00014 #include <net/gen/netdb.h>
00015 #include <net/gen/in.h>
00016 #include <net/gen/inet.h>
00017 #include <net/gen/tcp.h>
00018 #include <net/gen/tcp_io.h>
00019 #include <net/gen/udp.h>
00020 #include <net/gen/udp_io.h>
00021 #include <net/gen/udp_hdr.h>
00022
00023 #include "talk.h"
00024 #include "net.h"
00025
00026 _PROTOTYPE(void TimeOut, (int sig));
00027
00028 static unsigned char buffer[8192];
00029
00030 static int udp_ctl;
00031 int tcp_fd;
00032
00033 static udpport_t ntalk_port;
00034
00035 char luser[USER_SIZE+1], ruser[USER_SIZE+1];
00036 char lhost[HOST_SIZE+1], rhost[HOST_SIZE+1];
00037 char ltty[TTY_SIZE+1], rtty[TTY_SIZE+1];
00038 udpport_t ctlport;
00039 tcpport_t dataport;
00040 ipaddr_t laddr, raddr;
00041
00042 int NetInit()
00043 {
00044 int s;
00045 struct servent *servent;
00046 char *udp_device;
00047 char *tcp_device;
00048 nwio_udpopt_t udpopt;
00049 nwio_tcpconf_t tcpconf;
00050
00051 if((udp_device = getenv("UDP_DEVICE")) == (char *)NULL)
00052 udp_device = UDP_DEVICE;
00053
00054 if((udp_ctl = open(udp_device, O_RDWR)) < 0) {
00055 fprintf(stderr, "talk: Could not open %s: %s\n",
00056 udp_device, strerror(errno));
00057 return(-1);
00058 }
00059
00060 if((servent = getservbyname("ntalk", "udp")) == (struct servent *)NULL) {
00061 fprintf(stderr, "talk: Could not find ntalk udp service\n");
00062 close(udp_ctl);
00063 return(-1);
00064 }
00065
00066 ntalk_port = (udpport_t)servent->s_port;
00067
00068 udpopt.nwuo_flags = NWUO_NOFLAGS;
00069 udpopt.nwuo_flags |= NWUO_COPY | NWUO_LP_SEL | NWUO_EN_LOC;
00070 udpopt.nwuo_flags |= NWUO_DI_BROAD | NWUO_RP_SET | NWUO_RA_SET;
00071 udpopt.nwuo_flags |= NWUO_RWDATONLY | NWUO_DI_IPOPT;
00072 udpopt.nwuo_remaddr = raddr;
00073 udpopt.nwuo_remport = ntalk_port;
00074
00075 s = ioctl(udp_ctl, NWIOSUDPOPT, &udpopt);
00076 if(s < 0) {
00077 perror("talk: ioctl NWIOSUDPOPT");
00078 close(udp_ctl);
00079 return(-1);
00080 }
00081
00082 s = ioctl(udp_ctl, NWIOGUDPOPT, &udpopt);
00083 if(s < 0) {
00084 perror("talk: ioctl NWIOGUDPOPT");
00085 close(udp_ctl);
00086 return(-1);
00087 }
00088 laddr = udpopt.nwuo_locaddr;
00089 ctlport = udpopt.nwuo_locport;
00090
00091 if((tcp_device = getenv("TCP_DEVICE")) == (char *)NULL)
00092 tcp_device = TCP_DEVICE;
00093
00094 if((tcp_fd = open(tcp_device, O_RDWR)) < 0) {
00095 fprintf(stderr, "talk: Could not open %s: %s\n",
00096 tcp_device, strerror(errno));
00097 close(udp_ctl);
00098 return(-1);
00099 }
00100
00101 tcpconf.nwtc_flags = NWTC_NOFLAGS;
00102 tcpconf.nwtc_flags |= NWTC_LP_SEL | NWTC_SET_RA | NWTC_UNSET_RP;
00103 tcpconf.nwtc_remaddr = raddr;
00104
00105 s = ioctl(tcp_fd, NWIOSTCPCONF, &tcpconf);
00106 if(s < 0) {
00107 perror("talk: ioctl NWIOSTCPCONF");
00108 close(udp_ctl);
00109 close(tcp_fd);
00110 return(-1);
00111 }
00112
00113 s = ioctl(tcp_fd, NWIOGTCPCONF, &tcpconf);
00114 if(s < 0) {
00115 perror("talk: ioctl NWIOGTCPCONF");
00116 close(udp_ctl);
00117 close(tcp_fd);
00118 return(-1);
00119 }
00120
00121 dataport = tcpconf.nwtc_locport;
00122
00123 return(0);
00124 }
00125
00126 int getreply(reply, timeout)
00127 struct talk_reply *reply;
00128 int timeout;
00129 {
00130 int s;
00131 int terrno;
00132 udp_io_hdr_t *udp_io_hdr;
00133
00134 signal(SIGALRM, TimeOut);
00135 alarm(timeout);
00136 s = read(udp_ctl, buffer, sizeof(buffer));
00137 terrno = errno;
00138 alarm(0);
00139 errno = terrno;
00140 if(s < 0 && errno == EINTR)
00141 return(1);
00142 if(s < 0) {
00143 perror("talk: Read error in getreply");
00144 return(-1);
00145 }
00146
00147 if(s == sizeof(struct talk_reply))
00148 memcpy((char *)reply, buffer, s);
00149
00150 return(0);
00151 }
00152
00153 int sendrequest(request, here)
00154 struct talk_request *request;
00155 int here;
00156 {
00157 int s;
00158 nwio_udpopt_t udpopt;
00159 udp_io_hdr_t *udp_io_hdr;
00160
00161 udpopt.nwuo_flags = NWUO_NOFLAGS;
00162 udpopt.nwuo_flags |= NWUO_COPY | NWUO_LP_SET | NWUO_EN_LOC;
00163 udpopt.nwuo_flags |= NWUO_DI_BROAD | NWUO_RP_SET | NWUO_RA_SET;
00164 udpopt.nwuo_flags |= NWUO_RWDATONLY | NWUO_DI_IPOPT;
00165 udpopt.nwuo_locport = ctlport;
00166 if(here)
00167 udpopt.nwuo_remaddr = laddr;
00168 else
00169 udpopt.nwuo_remaddr = raddr;
00170 udpopt.nwuo_remport = ntalk_port;
00171
00172 s = ioctl(udp_ctl, NWIOSUDPOPT, &udpopt);
00173 if(s < 0) {
00174 perror("talk: ioctl NWIOSUDPOPT");
00175 return(-1);
00176 }
00177
00178 s = ioctl(udp_ctl, NWIOGUDPOPT, &udpopt);
00179 if(s < 0) {
00180 perror("talk: ioctl NWIOGUDPOPT");
00181 return(-1);
00182 }
00183
00184 s = write(udp_ctl, request, sizeof(struct talk_request));
00185 if(s < 0) {
00186 perror("talk: write error in sendrequest");
00187 return(-1);
00188 }
00189
00190 if(s != sizeof(struct talk_request)) {
00191 fprintf(stderr, "talk: sendrequest size mismatch %d %d\n", s, sizeof(struct talk_request));
00192 return(-1);
00193 }
00194
00195 return(0);
00196 }
00197
00198 void TimeOut(sig)
00199 int sig;
00200 {
00201 }
00202
00203 int NetConnect(port)
00204 u16_t port;
00205 {
00206 int s;
00207 nwio_tcpconf_t tcpconf;
00208 nwio_tcpcl_t tcpcopt;
00209
00210 tcpconf.nwtc_flags = NWTC_NOFLAGS;
00211 tcpconf.nwtc_flags |= NWTC_LP_SET | NWTC_SET_RA | NWTC_SET_RP;
00212 tcpconf.nwtc_locport = dataport;
00213 tcpconf.nwtc_remaddr = raddr;
00214 tcpconf.nwtc_remport = port;
00215
00216 s = ioctl(tcp_fd, NWIOSTCPCONF, &tcpconf);
00217 if(s < 0) {
00218 perror("talk: ioctl NWIOSTCPCONF");
00219 return(-1);
00220 }
00221
00222 s = ioctl(tcp_fd, NWIOGTCPCONF, &tcpconf);
00223 if(s < 0) {
00224 perror("talk: ioctl NWIOGTCPCONF");
00225 return(-1);
00226 }
00227
00228 tcpcopt.nwtcl_flags = 0;
00229
00230 s = ioctl(tcp_fd, NWIOTCPCONN, &tcpcopt);
00231 if(s < 0 && errno == ECONNREFUSED)
00232 return(1);
00233 if(s < 0) {
00234 perror("talk: ioctl NWIOTCPCONN");
00235 return(-1);
00236 }
00237
00238 return(0);
00239 }
00240
00241 int NetListen(timeout)
00242 int timeout;
00243 {
00244 int s;
00245 nwio_tcpcl_t tcplopt;
00246 int terrno;
00247
00248 tcplopt.nwtcl_flags = 0;
00249
00250 signal(SIGALRM, TimeOut);
00251 alarm(timeout);
00252 s = ioctl(tcp_fd, NWIOTCPLISTEN, &tcplopt);
00253 terrno = errno;
00254 alarm(0);
00255 errno = terrno;
00256
00257 if(s < 0 && errno == EINTR)
00258 return(1);
00259
00260 if(s < 0) {
00261 perror("talk: ioctl NWIOTCPLISTEN");
00262 return(-1);
00263 }
00264
00265 return(0);
00266 }