1 /*
2  *  ser2net - A program for allowing telnet connection to serial ports
3  *  Copyright (C) 2001  Corey Minyard <minyard@acm.org>
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 
20 /* This code handles the actual transfer of data between the serial
21    ports and the TCP ports. */
22 
23 
24 #include <sys/time.h>
25 #include <arpa/inet.h>
26 #include <stdlib.h>
27 #include <stdbool.h>
28 #include <unistd.h>
29 #include <stdio.h>
30 #include <netinet/in.h>
31 #include <netinet/tcp.h>
32 #include <errno.h>
33 #include <syslog.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <time.h>
37 #include <fcntl.h>
38 
39 #include "ser2net.h"
40 #include "dataxfer.h"
41 #include "selector.h"
42 #include "utils.h"
43 #include "telnet.h"
44 #include "devio.h"
45 #include "buffer.h"
46 #include "locking.h"
47 #include "led.h"
48 
49 #define SERIAL "term"
50 #define NET    "tcp "
51 
52 /** BASED ON sshd.c FROM openssh.com */
53 #ifdef HAVE_TCPD_H
54 #include <tcpd.h>
55 static char *progname = "ser2net";
56 #endif /* HAVE_TCPD_H */
57 
58 /* States for the net_to_dev_state and dev_to_net_state. */
59 #define PORT_UNCONNECTED		0 /* The TCP port is not connected
60                                              to anything right now. */
61 #define PORT_WAITING_INPUT		1 /* Waiting for input from the
62 					     input side. */
63 #define PORT_WAITING_OUTPUT_CLEAR	2 /* Waiting for output to clear
64 					     so I can send data. */
65 #define PORT_CLOSING			3 /* Waiting for output close
66 					     string to be sent. */
67 char *state_str[] = { "unconnected", "waiting input", "waiting output",
68 		      "closing" };
69 
70 #define PORT_DISABLED		0 /* The port is not open. */
71 #define PORT_RAW		1 /* Port will not do telnet negotiation. */
72 #define PORT_RAWLP		2 /* Port will not do telnet negotiation and
73                                      termios setting, open for output only. */
74 #define PORT_TELNET		3 /* Port will do telnet negotiation. */
75 char *enabled_str[] = { "off", "raw", "rawlp", "telnet" };
76 
77 typedef struct trace_info_s
78 {
79     int  hexdump;     /* output each block as a hexdump */
80     int  timestamp;   /* preceed each line with a timestamp */
81     char *filename;   /* open file.  NULL if not used */
82     int  fd;          /* open file.  -1 if not used */
83 } trace_info_t;
84 
85 typedef struct port_info port_info_t;
86 typedef struct net_info net_info_t;
87 
88 struct net_info {
89     port_info_t	   *port;		/* My port. */
90 
91     bool	   closing;		/* Is the connection in the process
92 					   of closing? */
93 
94     int            fd;			/* When connected, the file
95                                            descriptor for the network
96                                            port used for I/O. */
97     bool remote_fixed;			/* Tells if the remote address was
98 					   set in the configuration, and
99 					   cannot be changed. */
100     struct sockaddr_storage remote;	/* The socket address of who
101 					   is connected to this port. */
102     struct sockaddr *raddr;		/* Points to remote, for convenience. */
103     socklen_t raddrlen;
104     struct sockaddr *udpraddr;		/* Points to remote, only for UDP,
105 					   so sendto's addr will be NULL on
106 					   TCP. */
107     socklen_t udpraddrlen;
108 
109     unsigned int bytes_received;	/* Number of bytes read from the
110 					   network port. */
111     unsigned int bytes_sent;		/* Number of bytes written to the
112 					   network port. */
113 
114     struct sbuf *banner;		/* Outgoing banner */
115 
116     unsigned int write_pos;		/* Our current position in the
117 					   output buffer where we need
118 					   to start writing next. */
119     bool data_to_write;			/* There is data to write on
120 					   this network port. */
121 
122     void (*write_handler)(port_info_t *, net_info_t *);
123 
124     /* Data for the telnet processing */
125     telnet_data_t tn_data;
126     bool sending_tn_data; /* Are we sending tn data at the moment? */
127 
128     int            timeout_left;	/* The amount of time left (in
129 					   seconds) before the timeout
130 					   goes off. */
131 
132     sel_runner_t *runshutdown;		/* Used to run things at the
133 					   base context.  This way we
134 					   don't have to worry that we
135 					   are running inside a
136 					   handler context that needs
137 					   to be waited for exit. */
138 
139     /*
140      * If a user gets kicked, store the information for the new user
141      * here since we have already accepted the connection or received
142      * the packet, we have to store it someplace.
143      */
144     int new_fd;
145     struct sockaddr_storage new_remote;
146     socklen_t new_raddrlen;
147     unsigned char *new_buf;
148     int new_buf_len;
149 };
150 
151 struct port_remaddr
152 {
153     char *name;
154     struct sockaddr_storage addr;
155     socklen_t addrlen;
156     bool is_port_set;
157     struct port_remaddr *next;
158 };
159 
160 struct port_info
161 {
162     DEFINE_LOCK(, lock)
163     int            enabled;		/* If PORT_DISABLED, the port
164 					   is disabled and the TCP
165 					   accept port is not
166 					   operational.  If PORT_RAW,
167 					   the port is enabled and
168 					   will not do any telnet
169 					   negotiations.  If
170 					   PORT_RAWLP, the port is enabled
171 					   only for output without any
172 					   termios setting - it allows
173 					   to redirect /dev/lpX devices If
174 					   PORT_TELNET, the port is
175 					   enabled and it will do
176 					   telnet negotiations. */
177 
178     int            timeout;		/* The number of seconds to
179 					   wait without any I/O before
180 					   we shut the port down. */
181 
182     sel_timer_t *timer;			/* Used to timeout when the no
183 					   I/O has been seen for a
184 					   certain period of time. */
185 
186     sel_timer_t *send_timer;		/* Used to delay a bit when
187 					   waiting for characters to
188 					   batch up as many characters
189 					   as possible. */
190     bool send_timer_running;
191 
192 
193     sel_runner_t *runshutdown;		/* Used to run things at the
194 					   base context.  This way we
195 					   don't have to worry that we
196 					   are running inside a
197 					   handler context that needs
198 					   to be waited for exit. */
199 
200     int chardelay;                      /* The amount of time to wait after
201 					   receiving a character before
202 					   sending it, unless we receive
203 					   another character.  Based on
204 					   bit rate. */
205 
206     int bps;				/* Bits per second rate. */
207     int bpc;				/* Bits per character. */
208 
209     bool enable_chardelay;
210 
211     int  chardelay_scale;		/* The number of character
212 					   periods to wait for the
213 					   next character, in tenths of
214 					   a character period. */
215     int  chardelay_min;			/* The minimum chardelay, in
216 					   microseconds. */
217     int  chardelay_max;			/* Maximum amount of time to
218 					   wait before sending the data. */
219     struct timeval send_time;		/* When using chardelay, the
220 					   time when we will send the
221 					   data, no matter what, set
222 					   by chardelay_max. */
223 
224     int (*netread)(int fd, port_info_t *port, int *readerr,
225 		   net_info_t **netcon);
226 
227     struct port_remaddr *remaddrs;
228     bool remaddr_set;
229 
230     /* Information about the network port. */
231     char               *portname;       /* The name given for the port. */
232     int                is_stdio;	/* Do stdio on the port? */
233     struct addrinfo    *ai;		/* The address list for the portname. */
234     bool               dgram;		/* Is this a datagram (UDP) port? */
235     struct opensocks   *acceptfds;	/* The file descriptor used to
236 					   accept connections on the
237 					   TCP port. */
238     unsigned int   nr_acceptfds;
239     waiter_t       *accept_waiter;      /* Wait for accept changes. */
240 
241     unsigned int max_connections;	/* Maximum number of TCP connections
242 					   we can accept at a time for this
243 					   port. */
244     net_info_t *netcons;
245 
246     unsigned int dev_bytes_received;    /* Number of bytes read from the
247 					   device. */
248     unsigned int dev_bytes_sent;        /* Number of bytes written to the
249 					   device. */
250     /* Information use when transferring information from the network port
251        to the terminal device. */
252     int            net_to_dev_state;		/* State of transferring
253 						   data from the network port
254                                                    to the device. */
255     int            net_to_dev_bufsize;
256     struct sbuf    net_to_dev;			/* Buffer struct for
257 						   network to device
258 						   transfers. */
259     struct controller_info *net_monitor; /* If non-null, send any input
260 					    received from the network port
261 					    to this controller port. */
262     struct sbuf *devstr;		 /* Outgoing string */
263 
264     /* Information use when transferring information from the terminal
265        device to the network port. */
266     int            dev_to_net_state;		/* State of transferring
267 						   data from the device to
268                                                    the network port. */
269     int            dev_to_net_bufsize;
270     struct sbuf    dev_to_net;			/* Buffer struct for
271 						   device to network
272 						   transfers. */
273     struct controller_info *dev_monitor; /* If non-null, send any input
274 					    received from the device
275 					    to this controller port. */
276 
277     struct port_info *next;		/* Used to keep a linked list
278 					   of these. */
279 
280     int config_num; /* Keep track of what configuration this was last
281 		       updated under.  Setting to -1 means to delete
282 		       the port when the current session is done. */
283 
284     struct port_info *new_config; /* If the port is reconfigged while
285 				     open, this will hold the new
286 				     configuration that should be
287 				     loaded when the current session
288 				     is done. */
289 
290     /* Is RFC 2217 mode enabled? */
291     int is_2217;
292 
293     /* Masks for RFC 2217 */
294     unsigned char linestate_mask;
295     unsigned char modemstate_mask;
296     unsigned char last_modemstate;
297 
298     /* Allow RFC 2217 mode */
299     int allow_2217;
300 
301     /* Send a break if we get a sync command? */
302     int telnet_brk_on_sync;
303 
304     /* kickolduser mode */
305     int kickolduser_mode;
306 
307     /* Banner to display at startup, or NULL if none. */
308     char *bannerstr;
309 
310     /* RFC 2217 signature. */
311     char *signaturestr;
312 
313     /* String to send to device at startup, or NULL if none. */
314     char *openstr;
315 
316     /* String to send to device at close, or NULL if none. */
317     char *closestr;
318 
319     /*
320      * Close on string to shutdown connection when received from
321      * serial side, or NULL if none.
322      */
323     char *closeon;
324     unsigned int closeon_pos;
325     unsigned int closeon_len;
326 
327     /*
328      * Close the session when all the output has been written to the
329      * network port.
330      */
331     bool close_on_output_done;
332 
333     /*
334      * File to read/write trace, NULL if none.  If the same, then
335      * trace information is in the same file, only one open is done.
336      */
337     trace_info_t trace_read;
338     trace_info_t trace_write;
339     trace_info_t trace_both;
340 
341     /*
342      * Pointers to the above, that way if two are the same file we can just
343      * set up one and point both to it.
344      */
345     trace_info_t *tr;
346     trace_info_t *tw;
347     trace_info_t *tb;
348 
349     struct devio io; /* For handling I/O operation to the device */
350     void (*dev_write_handler)(port_info_t *);
351 
352     /*
353      * devname as specified on the line, not the substituted version.  Only
354      *non-null if devname was substituted.
355      */
356     char *orig_devname;
357 
358 #if HAVE_DECL_TIOCSRS485
359     struct serial_rs485 *rs485conf;
360 #endif
361 
362     /*
363      * LED to flash for serial traffic
364      */
365     struct led_s *led_tx;
366     struct led_s *led_rx;
367 };
368 
369 #define for_each_connection(port, netcon) \
370     for (netcon = port->netcons;				\
371 	 netcon < &(port->netcons[port->max_connections]);	\
372 	 netcon++)
373 
374 DEFINE_LOCK_INIT(static, ports_lock)
375 port_info_t *ports = NULL; /* Linked list of ports. */
376 
377 static void shutdown_one_netcon(net_info_t *netcon, char *reason);
378 static void shutdown_port(port_info_t *port, char *reason);
379 static void disable_accept_ports(port_info_t *port);
380 static void enable_accept_ports(port_info_t *port);
381 
382 /* The init sequence we use. */
383 static unsigned char telnet_init_seq[] = {
384     TN_IAC, TN_WILL, TN_OPT_SUPPRESS_GO_AHEAD,
385     TN_IAC, TN_WILL, TN_OPT_ECHO,
386     TN_IAC, TN_DONT, TN_OPT_ECHO,
387     TN_IAC, TN_DO,   TN_OPT_BINARY_TRANSMISSION,
388     TN_IAC, TN_WILL, TN_OPT_BINARY_TRANSMISSION,
389 };
390 
391 /* Our telnet command table. */
392 static void com_port_handler(void *cb_data, unsigned char *option, int len);
393 static int com_port_will(void *cb_data);
394 
395 static struct telnet_cmd telnet_cmds[] =
396 {
397     /*                        I will,  I do,  sent will, sent do */
398     { TN_OPT_SUPPRESS_GO_AHEAD,	   0,     1,          1,       0, },
399     { TN_OPT_ECHO,		   0,     1,          1,       1, },
400     { TN_OPT_BINARY_TRANSMISSION,  1,     1,          1,       1, },
401     { TN_OPT_COM_PORT,		   1,     1,          0,       0, 0, 0,
402       com_port_handler, com_port_will },
403     { TELNET_CMD_END_OPTION }
404 };
405 
406 static int
syslog_eprint(struct absout * e,const char * str,...)407 syslog_eprint(struct absout *e, const char *str, ...)
408 {
409     va_list ap;
410 
411     va_start(ap, str);
412     vsyslog(LOG_ERR, str, ap);
413     va_end(ap);
414     return 0;
415 }
416 
417 static struct absout syslog_eout = {
418     .out = syslog_eprint,
419 };
420 
421 static void
add_usec_to_timeval(struct timeval * tv,int usec)422 add_usec_to_timeval(struct timeval *tv, int usec)
423 {
424     tv->tv_usec += usec;
425     while (usec >= 1000000) {
426 	usec -= 1000000;
427 	tv->tv_sec += 1;
428     }
429 }
430 
431 static int
sub_timeval_us(struct timeval * left,struct timeval * right)432 sub_timeval_us(struct timeval *left,
433 	       struct timeval *right)
434 {
435     struct timeval dest;
436 
437     dest.tv_sec = left->tv_sec - right->tv_sec;
438     dest.tv_usec = left->tv_usec - right->tv_usec;
439     while (dest.tv_usec < 0) {
440 	dest.tv_usec += 1000000;
441 	dest.tv_sec--;
442     }
443 
444     return (dest.tv_sec * 1000000) + dest.tv_usec;
445 }
446 
447 
448 /*
449  * Generic output function for using a controller output for
450  * abstract I/O.
451  */
452 static int
cntrl_absout(struct absout * o,const char * str,...)453 cntrl_absout(struct absout *o, const char *str, ...)
454 {
455     va_list ap;
456     int rv;
457 
458     va_start(ap, str);
459     rv = controller_voutputf(o->data, str, ap);
460     va_end(ap);
461     return rv;
462 }
463 
464 /*
465  * Like above but does a new line at the end of the output, generally
466  * for error output.
467  */
468 static int
cntrl_abserrout(struct absout * o,const char * str,...)469 cntrl_abserrout(struct absout *o, const char *str, ...)
470 {
471     va_list ap;
472     int rv;
473 
474     va_start(ap, str);
475     rv = controller_voutputf(o->data, str, ap);
476     va_end(ap);
477     rv += controller_outputf(o->data, "\r\n");
478     return rv;
479 }
480 
481 static int
num_connected_net(port_info_t * port,bool include_closing)482 num_connected_net(port_info_t *port, bool include_closing)
483 {
484     net_info_t *netcon;
485     int count = 0;
486 
487     for_each_connection(port, netcon) {
488 	if (!include_closing && netcon->closing)
489 	    continue;
490 	if (netcon->fd != -1)
491 	    count++;
492     }
493 
494     return count;
495 }
496 
497 static net_info_t *
first_live_net_con(port_info_t * port)498 first_live_net_con(port_info_t *port)
499 {
500     net_info_t *netcon;
501 
502     for_each_connection(port, netcon) {
503 	if (netcon->fd != -1)
504 	    return netcon;
505     }
506 
507     return NULL;
508 }
509 
510 static int
init_port_data(port_info_t * port)511 init_port_data(port_info_t *port)
512 {
513     port->enabled = PORT_DISABLED;
514 
515     port->net_to_dev_state = PORT_UNCONNECTED;
516     port->dev_to_net_state = PORT_UNCONNECTED;
517     port->trace_read.fd = -1;
518     port->trace_write.fd = -1;
519     port->trace_both.fd = -1;
520 #if HAVE_DECL_TIOCSRS485
521     port->rs485conf = NULL;
522 #endif
523 
524     port->allow_2217 = find_default_int("remctl");
525     port->telnet_brk_on_sync = find_default_int("telnet_brk_on_sync");
526     port->kickolduser_mode = find_default_int("kickolduser");
527     port->enable_chardelay = find_default_int("chardelay");
528     port->chardelay_scale = find_default_int("chardelay-scale");
529     port->chardelay_min = find_default_int("chardelay-min");
530     port->chardelay_max = find_default_int("chardelay-max");
531     port->dev_to_net_bufsize = find_default_int("dev-to-net-bufsize");
532     port->net_to_dev_bufsize = find_default_int("net-to-dev-bufsize");
533     port->max_connections = find_default_int("max-connections");
534 
535     if (buffer_init(&port->net_to_dev, NULL, port->net_to_dev_bufsize))
536 	return ENOMEM;
537     if (buffer_init(&port->dev_to_net, NULL, port->dev_to_net_bufsize))
538 	return ENOMEM;
539 
540     port->led_tx = NULL;
541     port->led_rx = NULL;
542 
543     return 0;
544 }
545 
546 static void
reset_timer(net_info_t * netcon)547 reset_timer(net_info_t *netcon)
548 {
549     netcon->timeout_left = netcon->port->timeout;
550 }
551 
552 
553 static int
timestamp(trace_info_t * t,char * buf,int size)554 timestamp(trace_info_t *t, char *buf, int size)
555 {
556     time_t result;
557     if (!t->timestamp)
558         return 0;
559     result = time(NULL);
560     return strftime(buf, size, "%Y/%m/%d %H:%M:%S ", localtime(&result));
561 }
562 
563 static int
trace_write_end(char * out,int size,unsigned char * start,int col)564 trace_write_end(char *out, int size, unsigned char *start, int col)
565 {
566     int pos = 0, w;
567 
568     strncat(out, " |", size - pos);
569     pos += 2;
570     for(w = 0; w < col; w++) {
571         pos += snprintf(out + pos, size - pos, "%c",
572 			isprint(start[w]) ? start[w] : '.');
573     }
574     strncat(out + pos, "|\n", size - pos);
575     pos += 2;
576     return pos;
577 }
578 
579 int
trace_write(port_info_t * port,trace_info_t * t,unsigned char * buf,unsigned int buf_len,char * prefix)580 trace_write(port_info_t *port, trace_info_t *t, unsigned char *buf,
581 	    unsigned int buf_len, char *prefix)
582 {
583     int rv = 0, w, col = 0, pos, file = t->fd;
584     unsigned int q;
585     static char out[1024];
586     unsigned char *start;
587 
588     if (buf_len == 0)
589         return 0;
590 
591     if (!t->hexdump)
592         return write(file, buf, buf_len);
593 
594     pos = timestamp(t, out, sizeof(out));
595     pos += snprintf(out + pos, sizeof(out) - pos, "%s ", prefix);
596 
597     start = buf;
598     for (q = 0; q < buf_len; q++) {
599         pos += snprintf(out + pos, sizeof(out) - pos, "%02x ", buf[q]);
600         col++;
601         if (col >= 8) {
602             trace_write_end(out + pos, sizeof(out) - pos, start, col);
603             rv = write(file, out, strlen(out));
604             if (rv < 0)
605                 return rv;
606             pos = timestamp(t, out, sizeof(out));
607             pos += snprintf(out + pos, sizeof(out) - pos, "%s ", prefix);
608             col = 0;
609             start = buf + q + 1;
610         }
611     }
612     if (col > 0) {
613         for (w = 8; w > col; w--) {
614             strncat(out + pos, "   ", sizeof(out) - pos);
615             pos += 3;
616         }
617         trace_write_end(out + pos, sizeof(out) - pos, start, col);
618         rv = write(file, out, strlen(out));
619         if (rv < 0)
620             return rv;
621     }
622     return buf_len;
623 }
624 
625 static void
do_trace(port_info_t * port,trace_info_t * t,unsigned char * buf,unsigned int buf_len,char * prefix)626 do_trace(port_info_t *port, trace_info_t *t, unsigned char *buf,
627 	 unsigned int buf_len, char *prefix)
628 {
629     int rv;
630 
631     while (buf_len > 0) {
632     retry_write:
633 	rv = trace_write(port, t, buf, buf_len, prefix);
634 	if (rv == -1) {
635 	    char errbuf[128];
636 	    int err = errno;
637 
638 	    if (err == EINTR)
639 		goto retry_write;
640 
641 	    /* Fatal error writing to the file, log it and close the file. */
642 
643 	    if (strerror_r(err, errbuf, sizeof(errbuf)) == -1)
644 		syslog(LOG_ERR, "Unable write to trace file on port %s: %d",
645 		       port->portname, err);
646 	    else
647 		syslog(LOG_ERR, "Unable to write to trace file on port %s: %s",
648 		       port->portname, errbuf);
649 
650 	    close(t->fd);
651 	    t->fd = -1;
652 	    return;
653 	}
654 
655 	/* Handle a partial write */
656 	buf_len -= rv;
657 	buf += rv;
658     }
659 }
660 
661 static void
hf_out(port_info_t * port,char * buf,int len)662 hf_out(port_info_t *port, char *buf, int len)
663 {
664     if (port->tr && port->tr->timestamp)
665         write_ignore_fail(port->tr->fd, buf, len);
666 
667     /* don't output to write file if it's the same as read file */
668     if (port->tw && port->tw != port->tr && port->tw->timestamp)
669         write_ignore_fail(port->tw->fd, buf, len);
670 
671     /* don't output to both file if it's the same as read or write file */
672     if (port->tb && port->tb != port->tr && port->tb != port->tw
673 		&& port->tb->timestamp)
674         write_ignore_fail(port->tb->fd, buf, len);
675 }
676 
677 static void
header_trace(port_info_t * port,net_info_t * netcon)678 header_trace(port_info_t *port, net_info_t *netcon)
679 {
680     static char buf[1024];
681     static trace_info_t tr = { 1, 1, NULL, -1 };
682     int len = 0, err;
683     char portstr[NI_MAXSERV];
684 
685     len += timestamp(&tr, buf, sizeof(buf));
686     len += snprintf(buf + len, sizeof(buf) - len, "OPEN (");
687     err = getnameinfo(netcon->raddr, netcon->raddrlen,
688 		      buf + len, sizeof(buf) - len,
689 		      portstr, sizeof(portstr), NI_NUMERICHOST);
690     if (err) {
691 	len += snprintf(buf + len, sizeof(buf) - len,
692 			"unknown:%s\n", gai_strerror(err));
693     } else {
694 	len += strlen(buf + len);
695 	if ((sizeof(buf) - len) > 2) {
696 	    buf[len] = ':';
697 	    len++;
698 	}
699 	strncpy(buf + len, portstr, sizeof(buf) - len);
700 	len += strlen(buf + len);
701     }
702     len += snprintf(buf + len, sizeof(buf) - len, ")\n");
703 
704     hf_out(port, buf, len);
705 }
706 
707 static void
footer_trace(port_info_t * port,char * type,char * reason)708 footer_trace(port_info_t *port, char *type, char *reason)
709 {
710     static char buf[1024];
711     static trace_info_t tr = { 1, 1, NULL, -1 };
712     int len = 0;
713 
714     len += timestamp(&tr, buf, sizeof(buf));
715     len += snprintf(buf + len, sizeof(buf), "CLOSE %s (%s)\n", type, reason);
716 
717     hf_out(port, buf, len);
718 }
719 
720 static bool
any_net_data_to_write(port_info_t * port)721 any_net_data_to_write(port_info_t *port)
722 {
723     net_info_t *netcon;
724 
725     for_each_connection(port, netcon) {
726 	if (netcon->data_to_write)
727 	    return true;
728     }
729     return false;
730 }
731 
732 static void
handle_net_send_one(port_info_t * port,net_info_t * netcon)733 handle_net_send_one(port_info_t *port, net_info_t *netcon)
734 {
735     int count = 0;
736 
737     if (netcon->sending_tn_data || netcon->banner)
738 	/* We are sending telnet or banner data, stop the reader for now. */
739 	goto no_send;
740 
741  retry_write:
742     count = net_write(netcon->fd,
743 		      port->dev_to_net.buf, port->dev_to_net.cursize,
744 		      0, netcon->udpraddr, netcon->udpraddrlen);
745     if (count == -1) {
746 	if (errno == EINTR) {
747 	    /* EINTR means we were interrupted, just retry. */
748 	    goto retry_write;
749 	}
750 
751 	if (errno == EAGAIN || errno == EWOULDBLOCK) {
752 	    /* This was due to O_NONBLOCK, we need to shut off the reader
753 	       and start the writer monitor. */
754 	    count = 0;
755 	    goto no_send;
756 	} else if (errno == EPIPE) {
757 	    shutdown_one_netcon(netcon, "EPIPE");
758 	} else {
759 	    /* Some other bad error. */
760 	    syslog(LOG_ERR, "The network write for port %s had error: %m",
761 		   port->portname);
762 	    shutdown_one_netcon(netcon, "network write error");
763 	}
764     } else {
765 	netcon->bytes_sent += count;
766 	if (port->dev_to_net.cursize != count) {
767 	    /* We didn't write all the data, shut off the reader and
768                start the write monitor. */
769 	no_send:
770 	    netcon->write_pos = count;
771 	    netcon->data_to_write = true;
772 	    port->io.f->read_handler_enable(&port->io, 0);
773 	    sel_set_fd_write_handler(ser2net_sel, netcon->fd,
774 				     SEL_FD_HANDLER_ENABLED);
775 	    port->dev_to_net_state = PORT_WAITING_OUTPUT_CLEAR;
776 	} else if (port->close_on_output_done) {
777 	    shutdown_one_netcon(netcon, "closeon sequence found");
778 	}
779     }
780 
781     reset_timer(netcon);
782 }
783 
784 static void
handle_net_send(port_info_t * port)785 handle_net_send(port_info_t *port)
786 {
787     net_info_t *netcon;
788 
789     for_each_connection(port, netcon) {
790 	if (netcon->fd == -1)
791 	    continue;
792 	handle_net_send_one(port, netcon);
793     }
794     if (!any_net_data_to_write(port))
795 	port->dev_to_net.cursize = 0;
796 }
797 
798 void
send_timeout(struct selector_s * sel,sel_timer_t * timer,void * data)799 send_timeout(struct selector_s  *sel,
800 	     sel_timer_t *timer,
801 	     void        *data)
802 {
803     port_info_t *port = (port_info_t *) data;
804 
805     LOCK(port->lock);
806 
807     if (port->dev_to_net_state == PORT_CLOSING) {
808 	UNLOCK(port->lock);
809 	return;
810     }
811 
812     port->send_timer_running = false;
813     if (port->dev_to_net.cursize > 0)
814 	handle_net_send(port);
815     UNLOCK(port->lock);
816 }
817 
818 static void
disable_all_net_read(port_info_t * port)819 disable_all_net_read(port_info_t *port)
820 {
821     net_info_t *netcon;
822 
823     for_each_connection(port, netcon) {
824 	if (netcon->fd != -1)
825 	    sel_set_fd_read_handler(ser2net_sel, netcon->fd,
826 				    SEL_FD_HANDLER_DISABLED);
827     }
828     if (port->dgram)
829 	disable_accept_ports(port);
830 }
831 
832 static void
enable_all_net_read(port_info_t * port)833 enable_all_net_read(port_info_t *port)
834 {
835     net_info_t *netcon;
836 
837     for_each_connection(port, netcon) {
838 	if (netcon->fd != -1)
839 	    sel_set_fd_read_handler(ser2net_sel, netcon->fd,
840 				    SEL_FD_HANDLER_ENABLED);
841     }
842     if (port->dgram)
843 	enable_accept_ports(port);
844 }
845 
846 /* Data is ready to read on the serial port. */
847 static void
handle_dev_fd_read(struct devio * io)848 handle_dev_fd_read(struct devio *io)
849 {
850     port_info_t *port = (port_info_t *) io->user_data;
851     int count;
852     int curend;
853     bool send_now = false;
854 
855     LOCK(port->lock);
856     curend = port->dev_to_net.cursize;
857     if (port->enabled == PORT_TELNET) {
858 	/* Leave room for IACs. */
859 	count = port->io.f->read(&port->io, port->dev_to_net.buf + curend,
860 				 (port->dev_to_net.maxsize - curend) / 2);
861     } else {
862 	count = port->io.f->read(&port->io, port->dev_to_net.buf + curend,
863 				 port->dev_to_net.maxsize - curend);
864     }
865 
866     if (count <= 0) {
867 	if (curend != 0) {
868 	    /* We still have data to send. */
869 	    send_now = true;
870 	    count = 0;
871 	    goto do_send;
872 	}
873 
874 	if (count < 0) {
875 	    if (errno == EAGAIN || errno == EWOULDBLOCK)
876 		/* Nothing to read, just return. */
877 		goto out_unlock;
878 
879 	    /* Got an error on the read, shut down the port. */
880 	    syslog(LOG_ERR, "dev read error for device %s: %m", port->portname);
881 	    shutdown_port(port, "dev read error");
882 	} else if (count == 0) {
883 	    /* The port got closed somehow, shut it down. */
884 	    shutdown_port(port, "closed port");
885 	}
886 	goto out_unlock;
887     }
888 
889     if (port->dev_monitor != NULL && count > 0) {
890 	controller_write(port->dev_monitor,
891 			 (char *) port->dev_to_net.buf + curend,
892 			 count);
893     }
894 
895  do_send:
896     if (port->closeon) {
897 	int i;
898 
899 	for (i = curend; i < curend + count; i++) {
900 	    if (port->dev_to_net.buf[i] == port->closeon[port->closeon_pos]) {
901 		port->closeon_pos++;
902 		if (port->closeon_pos >= port->closeon_len) {
903 		    port->close_on_output_done = true;
904 		    /* Ignore everything after the closeon string */
905 		    count = i - curend + 1;
906 		    break;
907 		}
908 	    } else {
909 		port->closeon_pos = 0;
910 	    }
911 	}
912     }
913 
914     if (port->tr)
915 	/* Do read tracing, ignore errors. */
916 	do_trace(port, port->tr, port->dev_to_net.buf + curend, count, SERIAL);
917     if (port->tb)
918 	/* Do both tracing, ignore errors. */
919 	do_trace(port, port->tb, port->dev_to_net.buf + curend, count, SERIAL);
920 
921     if (port->led_rx) {
922 	led_flash(port->led_rx);
923     }
924 
925     port->dev_bytes_received += count;
926 
927     if (port->enabled == PORT_TELNET) {
928 	int i, j;
929 
930 	/* Double the IACs on a telnet stream.  This will always fit because
931 	   we only use half the buffer for telnet connections. */
932 	for (i = curend; i < curend + count; i++) {
933 	    if (port->dev_to_net.buf[i] == TN_IAC) {
934 		for (j = curend + count; j > i; j--)
935 		    port->dev_to_net.buf[j] = port->dev_to_net.buf[j - 1];
936 		/* Last copy above will duplicate the IAC */
937 		count++;
938 		i++;
939 	    }
940 	}
941     }
942 
943     port->dev_to_net.cursize += count;
944 
945     if (send_now || port->dev_to_net.cursize == port->dev_to_net.maxsize ||
946 		port->chardelay == 0) {
947     send_it:
948 	handle_net_send(port);
949     } else {
950 	struct timeval then;
951 	int delay;
952 
953 	sel_get_monotonic_time(&then);
954 	if (port->send_timer_running) {
955 	    sel_stop_timer(port->send_timer);
956 	} else {
957 	    port->send_time = then;
958 	    add_usec_to_timeval(&port->send_time, port->chardelay_max);
959 	}
960 	delay = sub_timeval_us(&port->send_time, &then);
961 	if (delay > port->chardelay)
962 	    delay = port->chardelay;
963 	else if (delay < 0) {
964 	    port->send_timer_running = false;
965 	    goto send_it;
966 	}
967 	add_usec_to_timeval(&then, delay);
968 	sel_start_timer(port->send_timer, &then);
969 	port->send_timer_running = true;
970     }
971  out_unlock:
972     UNLOCK(port->lock);
973 }
974 
975 /* The serial port has room to write some data.  This is only activated
976    if a write fails to complete, it is deactivated as soon as writing
977    is available again. */
978 static void
dev_fd_write(port_info_t * port,struct sbuf * buf)979 dev_fd_write(port_info_t *port, struct sbuf *buf)
980 {
981     int reterr, buferr;
982 
983     reterr = buffer_io_write(&port->io, buf, &buferr);
984     if (reterr == -1) {
985 	syslog(LOG_ERR, "The dev write for port %s had error: %m",
986 	       port->portname);
987 	shutdown_port(port, "dev write error");
988 	return;
989     }
990 
991     if (buffer_cursize(buf) == 0) {
992 	/* We are done writing, turn the reader back on. */
993 	enable_all_net_read(port);
994 	port->io.f->write_handler_enable(&port->io, 0);
995 	port->net_to_dev_state = PORT_WAITING_INPUT;
996     }
997 }
998 
999 static void
handle_dev_fd_normal_write(port_info_t * port)1000 handle_dev_fd_normal_write(port_info_t *port)
1001 {
1002     dev_fd_write(port, &port->net_to_dev);
1003 }
1004 
1005 static void
handle_dev_fd_write(struct devio * io)1006 handle_dev_fd_write(struct devio *io)
1007 {
1008     port_info_t *port = (port_info_t *) io->user_data;
1009 
1010     LOCK(port->lock);
1011     port->dev_write_handler(port);
1012     UNLOCK(port->lock);
1013 }
1014 
1015 /* Handle an exception from the serial port. */
1016 static void
handle_dev_fd_except(struct devio * io)1017 handle_dev_fd_except(struct devio *io)
1018 {
1019     port_info_t *port = (port_info_t *) io->user_data;
1020 
1021     LOCK(port->lock);
1022     syslog(LOG_ERR, "Select exception on device for port %s",
1023 	   port->portname);
1024     shutdown_port(port, "fd exception");
1025     UNLOCK(port->lock);
1026 }
1027 
1028 /* Output the devstr buffer */
1029 static void
handle_dev_fd_devstr_write(port_info_t * port)1030 handle_dev_fd_devstr_write(port_info_t *port)
1031 {
1032     dev_fd_write(port, port->devstr);
1033     if (buffer_cursize(port->devstr) == 0) {
1034 	port->dev_write_handler = handle_dev_fd_normal_write;
1035 	free(port->devstr->buf);
1036 	free(port->devstr);
1037 	port->devstr = NULL;
1038 
1039 	/* Send out any data we got on the TCP port. */
1040 	handle_dev_fd_normal_write(port);
1041     }
1042 }
1043 
1044 static void
net_fd_read2(port_info_t * port,net_info_t * netcon,int count)1045 net_fd_read2(port_info_t *port, net_info_t *netcon, int count)
1046 {
1047     port->net_to_dev.cursize = count;
1048 
1049     netcon->bytes_received += count;
1050 
1051     if (port->enabled == PORT_TELNET) {
1052 	port->net_to_dev.cursize = process_telnet_data(port->net_to_dev.buf,
1053 						       count,
1054 						       &netcon->tn_data);
1055 	if (netcon->tn_data.error) {
1056 	    shutdown_one_netcon(netcon, "telnet output error");
1057 	    return;
1058 	}
1059 	if (port->net_to_dev.cursize == 0) {
1060 	    /* We are out of characters; they were all processed.  We
1061 	       don't want to continue with 0, because that will mess
1062 	       up the other processing and it's not necessary. */
1063 	    return;
1064 	}
1065     }
1066 
1067     if (port->net_monitor != NULL) {
1068 	controller_write(port->net_monitor,
1069 			 (char *) port->net_to_dev.buf,
1070 			 port->net_to_dev.cursize);
1071     }
1072 
1073     if (port->tw)
1074 	/* Do write tracing, ignore errors. */
1075 	do_trace(port, port->tw,
1076 		 port->net_to_dev.buf, port->net_to_dev.cursize, NET);
1077     if (port->tb)
1078 	/* Do both tracing, ignore errors. */
1079 	do_trace(port, port->tb,
1080 		 port->net_to_dev.buf, port->net_to_dev.cursize, NET);
1081 
1082  retry_write:
1083     /*
1084      * Don't write anything to the device until devstr is written.
1085      * This can happen on UDP ports, we get the first packet before
1086      * the port is enabled, so there will be data in the output buffer
1087      * but there will also possibly be devstr data.  We want the
1088      * devstr data to go out first.
1089      */
1090     if (port->devstr)
1091 	goto stop_write;
1092 
1093     count = port->io.f->write(&port->io, port->net_to_dev.buf,
1094 			      port->net_to_dev.cursize);
1095     if (count == -1) {
1096 	if (errno == EINTR) {
1097 	    /* EINTR means we were interrupted, just retry. */
1098 	    goto retry_write;
1099 	}
1100 
1101 	if (errno == EAGAIN || errno == EWOULDBLOCK) {
1102 	    /* This was due to O_NONBLOCK, we need to shut off the reader
1103 	       and start the writer monitor. */
1104 	stop_write:
1105 	    disable_all_net_read(port);
1106 	    port->io.f->write_handler_enable(&port->io, 1);
1107 	    port->net_to_dev_state = PORT_WAITING_OUTPUT_CLEAR;
1108 	} else {
1109 	    /* Some other bad error. */
1110 	    syslog(LOG_ERR, "The dev write for port %s had error: %m",
1111 		   port->portname);
1112 	    shutdown_port(port, "dev write error");
1113 	    return;
1114 	}
1115     } else {
1116 	if (port->led_tx) {
1117 	    led_flash(port->led_tx);
1118 	}
1119 	port->dev_bytes_sent += count;
1120 	port->net_to_dev.cursize -= count;
1121 	if (port->net_to_dev.cursize != 0) {
1122 	    /* We didn't write all the data, shut off the reader and
1123                start the write monitor. */
1124 	    port->net_to_dev.pos = count;
1125 	    disable_all_net_read(port);
1126 	    port->io.f->write_handler_enable(&port->io, 1);
1127 	    port->net_to_dev_state = PORT_WAITING_OUTPUT_CLEAR;
1128 	}
1129     }
1130 
1131     reset_timer(netcon);
1132 }
1133 
1134 /* Data is ready to read on the network port. */
1135 static void
handle_net_fd_read(int fd,void * data)1136 handle_net_fd_read(int fd, void *data)
1137 {
1138     net_info_t *netcon = data;
1139     port_info_t *port = netcon->port;
1140     int count, readerr = 0;
1141     char *reason;
1142 
1143     LOCK(port->lock);
1144     if (port->net_to_dev_state == PORT_WAITING_OUTPUT_CLEAR)
1145 	/* Catch a race here. */
1146 	goto out_unlock;
1147 
1148     port->net_to_dev.pos = 0;
1149     /*
1150      * Note that netcon->fd can be -1 in this case, if it's an
1151      * unconnected UDP port.  That's why we read from "fd" here.  If
1152      * it's UDP, the fd will be duplicated.
1153      */
1154     count = port->netread(fd, port, &readerr, &netcon);
1155     if (count < 0) {
1156 	if (readerr == EAGAIN || readerr == EWOULDBLOCK)
1157 	    /* Nothing to read, just return. */
1158 	    goto out_unlock;
1159 
1160 	/* Got an error on the read, shut down the port. */
1161 	syslog(LOG_ERR, "read error for port %s: %s", port->portname,
1162 	       strerror(readerr));
1163 	reason = "network read error";
1164 	goto out_shutdown;
1165     } else if (count == 0 && !port->dgram) {
1166 	/* The other end closed the port, shut it down. */
1167 	reason = "network read close";
1168 	goto out_shutdown;
1169     }
1170 
1171     net_fd_read2(port, netcon, count);
1172 
1173  out_unlock:
1174     UNLOCK(port->lock);
1175     return;
1176 
1177  out_shutdown:
1178     shutdown_one_netcon(netcon, reason);
1179     goto out_unlock;
1180 }
1181 
io_enable_read_handler(port_info_t * port)1182 void io_enable_read_handler(port_info_t *port)
1183 {
1184     port->io.f->read_handler_enable(&port->io,
1185 				    port->enabled != PORT_RAWLP);
1186 }
1187 
1188 /*
1189  * The network fd has room to write some data.  This is only activated
1190  * if a write fails to complete, it is deactivated as soon as writing
1191  * is available again.
1192  */
1193 static void
net_fd_write(port_info_t * port,net_info_t * netcon,struct sbuf * buf,unsigned int * pos)1194 net_fd_write(port_info_t *port, net_info_t *netcon,
1195 	     struct sbuf *buf, unsigned int *pos)
1196 {
1197     telnet_data_t *td = &netcon->tn_data;
1198     int buferr, reterr, to_send;
1199 
1200     if (netcon->sending_tn_data) {
1201     send_tn_data:
1202 	reterr = buffer_sendto(netcon->fd,
1203 			       netcon->udpraddr, netcon->udpraddrlen,
1204 			       &td->out_telnet_cmd, &buferr);
1205 	if (reterr == -1) {
1206 	    if (buferr == EPIPE) {
1207 		shutdown_one_netcon(netcon, "EPIPE");
1208 		return;
1209 	    } else {
1210 		/* Some other bad error. */
1211 		syslog(LOG_ERR, "The network write for port %s had error: %m",
1212 		       port->portname);
1213 		shutdown_one_netcon(netcon, "network write error");
1214 		return;
1215 	    }
1216 	}
1217 
1218 	if (buffer_cursize(&td->out_telnet_cmd) > 0) {
1219 	    /* If we have more telnet command data to send, don't
1220 	       send any real data. */
1221 	    return;
1222 	}
1223 	netcon->sending_tn_data = false;
1224 	if (!any_net_data_to_write(port))
1225 	    io_enable_read_handler(port);
1226     }
1227 
1228     to_send = buf->cursize - *pos;
1229     if (to_send <= 0)
1230 	/* Don't send empty packets, that can confuse UDP clients. */
1231 	return;
1232 
1233     reterr = net_write(netcon->fd, buf->buf + *pos, to_send,
1234 		       0, netcon->udpraddr, netcon->udpraddrlen);
1235     if (reterr == -1) {
1236 	if (errno == EPIPE) {
1237 	    shutdown_one_netcon(netcon, "EPIPE");
1238 	    return;
1239 	} else {
1240 	    /* Some other bad error. */
1241 	    syslog(LOG_ERR, "The network write for port %s had error: %m",
1242 		   port->portname);
1243 	    shutdown_one_netcon(netcon, "network write error");
1244 	    return;
1245 	}
1246     }
1247     *pos += reterr;
1248 
1249     if (*pos >= buf->cursize) {
1250 	netcon->data_to_write = false;
1251 
1252 	/* Start telnet data write when the data write is done. */
1253 	if (buffer_cursize(&td->out_telnet_cmd) > 0) {
1254 	    netcon->sending_tn_data = true;
1255 	    goto send_tn_data;
1256 	}
1257 
1258 	if (any_net_data_to_write(port))
1259 	    goto out;
1260 
1261 	port->dev_to_net.cursize = 0;
1262 
1263 	/* We are done writing, turn the reader back on. */
1264 	io_enable_read_handler(port);
1265 	sel_set_fd_write_handler(ser2net_sel, netcon->fd,
1266 				 SEL_FD_HANDLER_DISABLED);
1267 	port->dev_to_net_state = PORT_WAITING_INPUT;
1268 
1269 	if (port->close_on_output_done) {
1270 	    shutdown_one_netcon(netcon, "closeon sequence found");
1271 	    return;
1272 	}
1273     }
1274  out:
1275     reset_timer(netcon);
1276 }
1277 
1278 /* The network fd has room to write some data.  This is only activated
1279    if a write fails to complete, it is deactivated as soon as writing
1280    is available again. */
1281 static void
handle_net_fd_write(port_info_t * port,net_info_t * netcon)1282 handle_net_fd_write(port_info_t *port, net_info_t *netcon)
1283 {
1284     net_fd_write(port, netcon,
1285 		 &port->dev_to_net, &netcon->write_pos);
1286 }
1287 
1288 static void
handle_net_fd_write_mux(int fd,void * data)1289 handle_net_fd_write_mux(int fd, void *data)
1290 {
1291     net_info_t *netcon = data;
1292     port_info_t *port = netcon->port;
1293 
1294     LOCK(port->lock);
1295     netcon->write_handler(port, netcon);
1296     UNLOCK(port->lock);
1297 }
1298 
1299 /* Handle an exception from the network port. */
1300 static void
handle_net_fd_except(int fd,void * data)1301 handle_net_fd_except(int fd, void *data)
1302 {
1303     net_info_t *netcon = data;
1304     port_info_t *port = netcon->port;
1305     int rv, val;
1306     unsigned char c;
1307     int cmd_pos;
1308 
1309     /* We should have urgent data, a DATA MARK in the stream.  Read
1310        then urgent data (whose contents are irrelevant) then discard
1311        user data until we find the DATA_MARK command. */
1312 
1313     LOCK(port->lock);
1314     while ((rv = recv(fd, &c, 1, MSG_OOB)) > 0)
1315 	;
1316     /* Ignore any errors, they are irrelevant. */
1317 
1318     if (port->enabled != PORT_TELNET)
1319 	goto out;
1320 
1321     /* Flush the data in the local and device queue. */
1322     port->net_to_dev.cursize = 0;
1323     val = 0;
1324     port->io.f->flush(&port->io, &val);
1325 
1326     /* Store it if we last got an IAC, and abort any current
1327        telnet processing. */
1328     cmd_pos = netcon->tn_data.telnet_cmd_pos;
1329     if (cmd_pos != 1)
1330 	cmd_pos = 0;
1331     netcon->tn_data.telnet_cmd_pos = 0;
1332     netcon->tn_data.suboption_iac = 0;
1333 
1334     while ((rv = read(fd, &c, 1)) > 0) {
1335 	if (cmd_pos == 1) {
1336 	    if (c == TN_DATA_MARK) {
1337 		/* Found it. */
1338 		if (port->telnet_brk_on_sync)
1339 		    port->io.f->send_break(&port->io);
1340 		break;
1341 	    }
1342 	    cmd_pos = 0;
1343 	} else if (c == TN_IAC) {
1344 	    cmd_pos = 1;
1345 	}
1346     }
1347  out:
1348     UNLOCK(port->lock);
1349 }
1350 
1351 static void port_net_fd_cleared(int fd, void *cb_data);
1352 
1353 static void
handle_net_fd_banner_write(port_info_t * port,net_info_t * netcon)1354 handle_net_fd_banner_write(port_info_t *port, net_info_t *netcon)
1355 {
1356     net_fd_write(port, netcon, netcon->banner, &netcon->banner->pos);
1357     if (netcon->banner->pos >= netcon->banner->cursize) {
1358 	netcon->write_handler = handle_net_fd_write;
1359 	free(netcon->banner->buf);
1360 	free(netcon->banner);
1361 	netcon->banner = NULL;
1362 
1363 	handle_net_fd_write(port, netcon);
1364     }
1365 }
1366 
1367 static void
telnet_cmd_handler(void * cb_data,unsigned char cmd)1368 telnet_cmd_handler(void *cb_data, unsigned char cmd)
1369 {
1370     net_info_t *netcon = cb_data;
1371     port_info_t *port = netcon->port;
1372 
1373     if ((cmd == TN_BREAK) || (port->telnet_brk_on_sync && cmd == TN_DATA_MARK))
1374 	port->io.f->send_break(&port->io);
1375 }
1376 
1377 /* Called when the telnet code has output ready. */
1378 static void
telnet_output_ready(void * cb_data)1379 telnet_output_ready(void *cb_data)
1380 {
1381     net_info_t *netcon = cb_data;
1382     port_info_t *port = netcon->port;
1383 
1384     /* If we are currently sending some data, wait until it is done.
1385        It might have IACs in it, and we don't want to split those. */
1386     if (buffer_cursize(&port->dev_to_net) != 0)
1387 	return;
1388 
1389     netcon->sending_tn_data = true;
1390     sel_set_fd_write_handler(ser2net_sel, netcon->fd,
1391 			     SEL_FD_HANDLER_ENABLED);
1392 }
1393 
1394 /* Checks to see if some other port has the same device in use.  Must
1395    be called with ports_lock held. */
1396 static int
is_device_already_inuse(port_info_t * check_port)1397 is_device_already_inuse(port_info_t *check_port)
1398 {
1399     port_info_t *port = ports;
1400 
1401     while (port != NULL) {
1402 	if (port != check_port) {
1403 	    if ((strcmp(port->io.devname, check_port->io.devname) == 0)
1404 		&& (port->net_to_dev_state != PORT_UNCONNECTED))
1405 	    {
1406 		return 1;
1407 	    }
1408 	}
1409 	port = port->next;
1410     }
1411 
1412     return 0;
1413 }
1414 
1415 static int
from_hex_digit(char c)1416 from_hex_digit(char c)
1417 {
1418     if ((c >= '0') && (c <= '9'))
1419 	return c - '0';
1420     if ((c >= 'A') && (c <= 'F'))
1421 	return c - 'A' + 10;
1422     if ((c >= 'a') && (c <= 'f'))
1423 	return c - 'a' + 10;
1424     return 0;
1425 }
1426 
1427 static char *smonths[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1428 			   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
1429 static char *sdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
1430 
1431 static void
process_str(port_info_t * port,net_info_t * netcon,struct tm * time,struct timeval * tv,const char * s,void (* op)(void * data,char val),void * data,int isfilename)1432 process_str(port_info_t *port, net_info_t *netcon,
1433 	    struct tm *time, struct timeval *tv,
1434 	    const char *s,
1435 	    void (*op)(void *data, char val), void *data, int isfilename)
1436 {
1437     char val;
1438     char *t, *s2;
1439 
1440     while (*s) {
1441 	if (*s == '\\') {
1442 	    s++;
1443 	    if (!*s)
1444 		return;
1445 	    switch (*s) {
1446 	    /* Standard "C" characters. */
1447 	    case 'a': op(data, 7); break;
1448 	    case 'b': op(data, 8); break;
1449 	    case 'f': op(data, 12); break;
1450 	    case 'n': op(data, 10); break;
1451 	    case 'r': op(data, 13); break;
1452 	    case 't': op(data, 9); break;
1453 	    case 'v': op(data, 11); break;
1454 	    case '\\': op(data, '\\'); break;
1455 	    case '?': op(data, '?'); break;
1456 	    case '\'': op(data, '\''); break;
1457 	    case '"': op(data, '"'); break;
1458 
1459 	    case 'd': /* Actual device name */
1460 	    case 'o': /* Device name on config line */
1461 		/* ser2net device name. */
1462 		if (*s == 'o' && port->orig_devname)
1463 		    s2 = port->orig_devname;
1464 		else
1465 		    s2 = port->io.devname;
1466 
1467 		if (isfilename) {
1468 		    /* Can't have '/' in a filename. */
1469 		    t = strrchr(s2, '/');
1470 		    if (t)
1471 			t++;
1472 		    else
1473 			t = s2;
1474 		} else
1475 		    t = s2;
1476 		for (; *t; t++)
1477 		    op(data, *t);
1478 		break;
1479 
1480 	    case 'p':
1481 		/* ser2net network port. */
1482 		for (t = port->portname; *t; t++)
1483 		    op(data, *t);
1484 		break;
1485 
1486 	    case 's':
1487 		if (isfilename)
1488 		    goto seconds;
1489 		goto serparms;
1490 
1491 	    case 'B':
1492 	    serparms:
1493 		/* ser2net serial parms. */
1494 		{
1495 		    char str[15];
1496 		    port->io.f->serparm_to_str(&port->io, str, sizeof(str));
1497 		    for (t = str; *t; t++)
1498 			op(data, *t);
1499 		}
1500 		break;
1501 
1502 	    case '0': case '1': case '2': case '3': case '4': case '5':
1503 	    case '6': case '7':
1504 		/* Octal digit */
1505 		val = (*s) - '0';
1506 		s++;
1507 		if (!*s) {
1508 		    op(data, val);
1509 		    return;
1510 		}
1511 		if (!isdigit(*s)) {
1512 		    continue;
1513 		}
1514 		val = (val * 8) + (*s) - '0';
1515 		s++;
1516 		if (!*s) {
1517 		    op(data, val);
1518 		    return;
1519 		}
1520 		if (!isdigit(*s)) {
1521 		    continue;
1522 		}
1523 		val = (val * 8) + (*s) - '0';
1524 		op(data, val);
1525 		break;
1526 
1527 	    case 'x':
1528 		/* Hex digit */
1529 		s++;
1530 		if (!*s)
1531 		    return;
1532 		if (!isxdigit(*s))
1533 		    continue;
1534 		val = from_hex_digit(*s);
1535 		s++;
1536 		if (!*s) {
1537 		    op(data, val);
1538 		    return;
1539 		}
1540 		if (!isdigit(*s))
1541 		    continue;
1542 		val = (val * 16) + from_hex_digit(*s);
1543 		op(data, val);
1544 		break;
1545 
1546 	    /* \Y -> year */
1547 	    case 'Y':
1548 	    {
1549 		char d[10], *dp;
1550 		snprintf(d, sizeof(d), "%d", time->tm_year + 1900);
1551 		for (dp = d; *dp; dp++)
1552 		    op(data, *dp);
1553 		break;
1554 	    }
1555 
1556 	    /* \y -> day of the year (days since Jan 1) */
1557 	    case 'y':
1558 	    {
1559 		char d[10], *dp;
1560 		snprintf(d, sizeof(d), "%d", time->tm_yday);
1561 		for (dp = d; *dp; dp++)
1562 		    op(data, *dp);
1563 		break;
1564 	    }
1565 
1566 	    /* \M -> month (Jan, Feb, Mar, etc.) */
1567 	    case 'M':
1568 		if (time->tm_mon >= 12)
1569 		    op(data, '?');
1570 		else {
1571 		    char *dp = smonths[time->tm_mon];
1572 		    for (; *dp; dp++)
1573 			op(data, *dp);
1574 		}
1575 		break;
1576 
1577 	    /* \m -> month (as a number) */
1578 	    case 'm':
1579 	    {
1580 		char d[10], *dp;
1581 		snprintf(d, sizeof(d), "%d", time->tm_mon);
1582 		for (dp = d; *dp; dp++)
1583 		    op(data, *dp);
1584 		break;
1585 	    }
1586 
1587 	    /* \A -> day of the week (Mon, Tue, etc.) */
1588 	    case 'A':
1589 		if (time->tm_wday >= 7)
1590 		    op(data, '?');
1591 		else {
1592 		    char *dp = sdays[time->tm_wday];
1593 		    for (; *dp; dp++)
1594 			op(data, *dp);
1595 		}
1596 		break;
1597 
1598 	    /* \D -> day of the month */
1599 	    case 'D':
1600 	    {
1601 		char d[10], *dp;
1602 		snprintf(d, sizeof(d), "%d", time->tm_mday);
1603 		for (dp = d; *dp; dp++)
1604 		    op(data, *dp);
1605 		break;
1606 	    }
1607 
1608 	    /* \H -> hour (24-hour time) */
1609 	    case 'H':
1610 	    {
1611 		char d[10], *dp;
1612 		snprintf(d, sizeof(d), "%2.2d", time->tm_hour);
1613 		for (dp = d; *dp; dp++)
1614 		    op(data, *dp);
1615 		break;
1616 	    }
1617 
1618 	    /* \h -> hour (12-hour time) */
1619 	    case 'h':
1620 	    {
1621 		char d[10], *dp;
1622 		int v;
1623 
1624 		v = time->tm_hour;
1625 		if (v == 0)
1626 		    v = 12;
1627 		else if (v > 12)
1628 		    v -= 12;
1629 		snprintf(d, sizeof(d), "%2.2d", v);
1630 		for (dp = d; *dp; dp++)
1631 		    op(data, *dp);
1632 		break;
1633 	    }
1634 
1635 	    /* \i -> minute */
1636 	    case 'i':
1637 	    {
1638 		char d[10], *dp;
1639 		snprintf(d, sizeof(d), "%2.2d", time->tm_min);
1640 		for (dp = d; *dp; dp++)
1641 		    op(data, *dp);
1642 		break;
1643 	    }
1644 
1645 	    /* \S -> second */
1646 	    case 'S':
1647 	    seconds:
1648 	    {
1649 		char d[10], *dp;
1650 		snprintf(d, sizeof(d), "%2.2d", time->tm_sec);
1651 		for (dp = d; *dp; dp++)
1652 		    op(data, *dp);
1653 		break;
1654 	    }
1655 
1656 	    /* \q -> am/pm */
1657 	    case 'q':
1658 		if (time->tm_hour < 12) {
1659 		    op(data, 'a');
1660 		} else {
1661 		    op(data, 'p');
1662 		}
1663 		op(data, 'm');
1664 		break;
1665 
1666 	    /* \P -> AM/PM */
1667 	    case 'P':
1668 		if (time->tm_hour < 12) {
1669 		    op(data, 'A');
1670 		} else {
1671 		    op(data, 'P');
1672 		}
1673 		op(data, 'M');
1674 		break;
1675 
1676 	    /* \T -> time (HH:MM:SS) */
1677 	    case 'T':
1678 	    {
1679 		char d[10], *dp;
1680 		snprintf(d, sizeof(d), "%2.2d:%2.2d:%2.2d",
1681 			 time->tm_hour, time->tm_min, time->tm_sec);
1682 		for (dp = d; *dp; dp++)
1683 		    op(data, *dp);
1684 		break;
1685 	    }
1686 
1687 	    /* \e -> epoc (seconds since Jan 1, 1970) */
1688 	    case 'e':
1689 	    {
1690 		char d[30], *dp;
1691 		snprintf(d, sizeof(d), "%ld", tv->tv_sec);
1692 		for (dp = d; *dp; dp++)
1693 		    op(data, *dp);
1694 		break;
1695 	    }
1696 
1697 	    /* \U -> microseconds in the current second */
1698 	    case 'U':
1699 	    {
1700 		char d[10], *dp;
1701 		snprintf(d, sizeof(d), "%6.6ld", tv->tv_usec);
1702 		for (dp = d; *dp; dp++)
1703 		    op(data, *dp);
1704 		break;
1705 	    }
1706 
1707 	    /* \I -> remote IP address (in dot format) */
1708 	    case 'I':
1709 	    {
1710 		char ip[100], *ipp;
1711 
1712 		if (!netcon)
1713 		    netcon = first_live_net_con(port);
1714 		if (!netcon)
1715 		    break;
1716 		if (!getnameinfo(netcon->raddr, netcon->raddrlen,
1717 				 ip, sizeof(ip), NULL, 0, NI_NUMERICHOST))
1718 		    break;
1719 		for (ipp = ip; *ipp; ipp++)
1720 		    op(data, *ipp);
1721 		break;
1722 	    }
1723 
1724 	    default:
1725 		op(data, *s);
1726 	    }
1727 	} else
1728 	    op(data, *s);
1729 	s++;
1730     }
1731 }
1732 
1733 static void
count_op(void * data,char c)1734 count_op(void *data, char c)
1735 {
1736     unsigned int *idata = data;
1737 
1738     (*idata)++;
1739 }
1740 
1741 struct bufop_data {
1742     unsigned int pos;
1743     char *str;
1744 };
1745 
1746 static void
buffer_op(void * data,char c)1747 buffer_op(void *data, char c)
1748 {
1749     struct bufop_data *bufop = data;
1750     bufop->str[bufop->pos] = c;
1751     (bufop->pos)++;
1752 }
1753 
1754 static char *
process_str_to_str(port_info_t * port,net_info_t * netcon,const char * str,struct timeval * tv,unsigned int * lenrv,int isfilename)1755 process_str_to_str(port_info_t *port, net_info_t *netcon,
1756 		   const char *str, struct timeval *tv,
1757 		   unsigned int *lenrv, int isfilename)
1758 {
1759     unsigned int len = 0;
1760     struct tm now;
1761     struct bufop_data bufop;
1762 
1763     localtime_r(&tv->tv_sec, &now);
1764     process_str(port, netcon, &now, tv, str, count_op, &len, isfilename);
1765     if (!lenrv)
1766 	/* If we don't return a length, append a nil char. */
1767 	len++;
1768     bufop.pos = 0;
1769     if (len == 0)
1770 	/* malloc(0) sometimes return NULL */
1771 	bufop.str = malloc(1);
1772     else
1773 	bufop.str = malloc(len);
1774     if (!bufop.str) {
1775 	syslog(LOG_ERR, "Out of memory processing string: %s", port->portname);
1776 	return NULL;
1777     }
1778     process_str(port, netcon, &now, tv, str, buffer_op, &bufop, isfilename);
1779 
1780     if (lenrv)
1781 	*lenrv = len;
1782     else
1783 	bufop.str[bufop.pos] = '\0';
1784 
1785     return bufop.str;
1786 }
1787 
1788 static struct sbuf *
process_str_to_buf(port_info_t * port,net_info_t * netcon,const char * str)1789 process_str_to_buf(port_info_t *port, net_info_t *netcon, const char *str)
1790 {
1791     const char *bstr;
1792     struct sbuf *buf;
1793     unsigned int len;
1794     struct timeval tv;
1795 
1796     if (!str || *str == '\0')
1797 	return NULL;
1798     gettimeofday(&tv, NULL);
1799 
1800     buf = malloc(sizeof(*buf));
1801     if (!buf) {
1802 	syslog(LOG_ERR, "Out of memory processing string: %s", port->portname);
1803 	return NULL;
1804     }
1805     bstr = process_str_to_str(port, netcon, str, &tv, &len, 0);
1806     if (!bstr) {
1807 	free(buf);
1808 	syslog(LOG_ERR, "Error processing string: %s", port->portname);
1809 	return NULL;
1810     }
1811     buffer_init(buf, (unsigned char *) bstr, len);
1812     buf->cursize = len;
1813     return buf;
1814 }
1815 
1816 static void
open_trace_file(port_info_t * port,trace_info_t * t,struct timeval * tv,trace_info_t ** out)1817 open_trace_file(port_info_t *port,
1818                 trace_info_t *t,
1819                 struct timeval *tv,
1820                 trace_info_t **out)
1821 {
1822     int rv;
1823     char *trfile;
1824 
1825     trfile = process_str_to_str(port, NULL, t->filename, tv, NULL, 1);
1826     if (!trfile) {
1827 	syslog(LOG_ERR, "Unable to translate trace file %s", t->filename);
1828 	t->fd = -1;
1829 	return;
1830     }
1831 
1832     rv = open(trfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
1833     if (rv == -1) {
1834 	char errbuf[128];
1835 	int err = errno;
1836 
1837 	if (strerror_r(err, errbuf, sizeof(errbuf)) == -1)
1838 	    syslog(LOG_ERR, "Unable to open trace file %s: %d",
1839 		   trfile, err);
1840 	else
1841 	    syslog(LOG_ERR, "Unable to open trace file %s: %s",
1842 		   trfile, errbuf);
1843     }
1844 
1845     free(trfile);
1846     t->fd = rv;
1847     *out = t;
1848 }
1849 
1850 static void
setup_trace(port_info_t * port)1851 setup_trace(port_info_t *port)
1852 {
1853     struct timeval tv;
1854 
1855     /* Only get the time once so all trace files have consistent times. */
1856     gettimeofday(&tv, NULL);
1857 
1858     port->tw = NULL;
1859     if (port->trace_write.filename)
1860 	open_trace_file(port, &port->trace_write, &tv, &port->tw);
1861 
1862     port->tr = NULL;
1863     if (port->trace_read.filename) {
1864 	trace_info_t *np = &port->trace_read;
1865 	if (port->tw && (strcmp(np->filename, port->tw->filename) == 0))
1866 	    port->tr = port->tw;
1867 	else
1868 	    open_trace_file(port, np, &tv, &port->tr);
1869     }
1870 
1871     port->tb = NULL;
1872     if (port->trace_both.filename) {
1873 	trace_info_t *np = &port->trace_both;
1874 	if (port->tw && (strcmp(np->filename, port->tw->filename) == 0))
1875 	    port->tb = port->tw;
1876 	else if (port->tr && (strcmp(np->filename, port->tr->filename) == 0))
1877 	    port->tb = port->tr;
1878 	else
1879 	    open_trace_file(port, np, &tv, &port->tb);
1880     }
1881 
1882     return;
1883 }
1884 
1885 static void
recalc_port_chardelay(port_info_t * port)1886 recalc_port_chardelay(port_info_t *port)
1887 {
1888     /* delay is (((1 / bps) * bpc) * scale) seconds */
1889     if (!port->enable_chardelay) {
1890 	port->chardelay = 0;
1891 	return;
1892     }
1893 
1894     /* We are working in microseconds here. */
1895     port->chardelay = (port->bpc * 100000 * port->chardelay_scale) / port->bps;
1896     if (port->chardelay < port->chardelay_min)
1897 	port->chardelay = port->chardelay_min;
1898 }
1899 
1900 /* Called to set up a new connection's file descriptor. */
1901 static int
setup_port(port_info_t * port,net_info_t * netcon,bool is_reconfig)1902 setup_port(port_info_t *port, net_info_t *netcon, bool is_reconfig)
1903 {
1904     int options;
1905     struct timeval then;
1906     bool i_am_first = false;
1907 
1908     if (fcntl(netcon->fd, F_SETFL, O_NONBLOCK) == -1) {
1909 	close(netcon->fd);
1910 	netcon->fd = -1;
1911 	syslog(LOG_ERR, "Could not fcntl the tcp port %s: %m", port->portname);
1912 	return -1;
1913     }
1914 
1915     if (!port->dgram) {
1916 	options = 1;
1917 	if (setsockopt(netcon->fd, IPPROTO_TCP, TCP_NODELAY,
1918 		       (char *) &options, sizeof(options)) == -1) {
1919 	    if (port->is_stdio)
1920 		/* Ignore this error on stdio ports. */
1921 		goto end_net_config;
1922 
1923 	    close(netcon->fd);
1924 	    netcon->fd = -1;
1925 	    syslog(LOG_ERR, "Could not enable TCP_NODELAY tcp port %s: %m",
1926 		   port->portname);
1927 	    return -1;
1928 	}
1929 
1930     }
1931  end_net_config:
1932 
1933     if (!is_reconfig) {
1934 	if (netcon->banner) {
1935 	    free(netcon->banner->buf);
1936 	    free(netcon->banner);
1937 	}
1938 	netcon->banner = process_str_to_buf(port, netcon, port->bannerstr);
1939     }
1940     if (netcon->banner)
1941 	netcon->write_handler = handle_net_fd_banner_write;
1942     else
1943 	netcon->write_handler = handle_net_fd_write;
1944 
1945     if (num_connected_net(port, true) == 1) {
1946 	/* We are first, set things up on the device. */
1947 	const char *errstr = NULL;
1948 
1949 	if (port->io.f->setup(&port->io, port->portname, &errstr,
1950 			      &port->bps, &port->bpc) == -1) {
1951 	    if (errstr)
1952 		write_ignore_fail(netcon->fd, errstr, strlen(errstr));
1953 	    close(netcon->fd);
1954 	    netcon->fd = -1;
1955 	    return -1;
1956 	}
1957 	recalc_port_chardelay(port);
1958 	port->is_2217 = 0;
1959 
1960 	if (!is_reconfig) {
1961 	    if (port->devstr) {
1962 		free(port->devstr->buf);
1963 		free(port->devstr);
1964 	    }
1965 	    port->devstr = process_str_to_buf(port, netcon, port->openstr);
1966 	}
1967 	if (port->devstr)
1968 	    port->dev_write_handler = handle_dev_fd_devstr_write;
1969 	else
1970 	    port->dev_write_handler = handle_dev_fd_normal_write;
1971 
1972 	port->io.read_handler = (port->enabled == PORT_RAWLP
1973 				 ? NULL
1974 				 : handle_dev_fd_read);
1975 	port->io.write_handler = handle_dev_fd_write;
1976 	port->io.except_handler = handle_dev_fd_except;
1977 	port->io.f->except_handler_enable(&port->io, 1);
1978 	if (port->devstr)
1979 	    port->io.f->write_handler_enable(&port->io, 1);
1980 	port->dev_to_net_state = PORT_WAITING_INPUT;
1981 	i_am_first = true;
1982     }
1983 
1984     sel_set_fd_handlers(ser2net_sel,
1985 			netcon->fd,
1986 			netcon,
1987 			handle_net_fd_read,
1988 			handle_net_fd_write_mux,
1989 			handle_net_fd_except,
1990 			port_net_fd_cleared);
1991     sel_set_fd_read_handler(ser2net_sel, netcon->fd,
1992 			    SEL_FD_HANDLER_ENABLED);
1993     sel_set_fd_except_handler(ser2net_sel, netcon->fd,
1994 			      SEL_FD_HANDLER_ENABLED);
1995     port->net_to_dev_state = PORT_WAITING_INPUT;
1996 
1997     if (port->enabled == PORT_TELNET) {
1998 	telnet_init(&netcon->tn_data, netcon, telnet_output_ready,
1999 		    telnet_cmd_handler,
2000 		    telnet_cmds,
2001 		    telnet_init_seq, sizeof(telnet_init_seq));
2002 	sel_set_fd_write_handler(ser2net_sel, netcon->fd,
2003 				 SEL_FD_HANDLER_ENABLED);
2004     } else {
2005 	buffer_init(&netcon->tn_data.out_telnet_cmd,
2006 		    netcon->tn_data.out_telnet_cmdbuf, 0);
2007 	if (netcon->banner)
2008 	    sel_set_fd_write_handler(ser2net_sel, netcon->fd,
2009 				     SEL_FD_HANDLER_ENABLED);
2010 	else if (i_am_first)
2011 	    io_enable_read_handler(port);
2012     }
2013 
2014     if (i_am_first)
2015 	setup_trace(port);
2016     header_trace(port, netcon);
2017 
2018     if (i_am_first) {
2019 	sel_get_monotonic_time(&then);
2020 	then.tv_sec += 1;
2021 	sel_start_timer(port->timer, &then);
2022     }
2023 
2024     reset_timer(netcon);
2025 
2026     return 0;
2027 }
2028 
2029 static bool
port_remaddr_ok(port_info_t * port,struct sockaddr * addr,socklen_t addrlen)2030 port_remaddr_ok(port_info_t *port, struct sockaddr *addr, socklen_t addrlen)
2031 {
2032     struct port_remaddr *r = port->remaddrs;
2033 
2034     if (!r)
2035 	return true;
2036 
2037     while (r) {
2038 	if (sockaddr_equal(addr, addrlen,
2039 			   (struct sockaddr *) &r->addr, r->addrlen,
2040 			   r->is_port_set))
2041 	    break;
2042 	r = r->next;
2043     }
2044 
2045     return r != NULL;
2046 }
2047 
2048 /* Returns with the port locked, if non-NULL. */
2049 static port_info_t *
find_rotator_port(char * portname,struct sockaddr * addr,socklen_t addrlen)2050 find_rotator_port(char *portname, struct sockaddr *addr, socklen_t addrlen)
2051 {
2052     port_info_t *port = ports;
2053 
2054     while (port) {
2055 	if (strcmp(port->portname, portname) == 0) {
2056 	    LOCK(port->lock);
2057 	    if (port->dev_to_net_state != PORT_DISABLED &&
2058 			port->dev_to_net_state != PORT_CLOSING &&
2059 			port->net_to_dev_state == PORT_UNCONNECTED &&
2060 			port_remaddr_ok(port, addr, addrlen) &&
2061 			!is_device_already_inuse(port))
2062 		return port;
2063 	    UNLOCK(port->lock);
2064 	}
2065 	port = port->next;
2066     }
2067 
2068     return NULL;
2069 }
2070 
2071 static void
handle_port_accept(port_info_t * port,int new_fd,net_info_t * netcon)2072 handle_port_accept(port_info_t *port, int new_fd, net_info_t *netcon)
2073 {
2074     int optval;
2075 
2076     netcon->fd = new_fd;
2077 
2078     optval = 1;
2079     if (setsockopt(netcon->fd, SOL_SOCKET, SO_KEEPALIVE,
2080 		   (void *)&optval, sizeof(optval)) == -1) {
2081 	close(netcon->fd);
2082 	syslog(LOG_ERR, "Could not enable SO_KEEPALIVE on tcp port %s: %m",
2083 	       port->portname);
2084 	netcon->fd = -1;
2085 	return;
2086     }
2087 
2088     /* XXX log netcon->remote */
2089     setup_port(port, netcon, false);
2090 }
2091 
2092 static const char *
check_tcpd_ok(int new_fd)2093 check_tcpd_ok(int new_fd)
2094 {
2095 #ifdef HAVE_TCPD_H
2096     struct request_info req;
2097 
2098     request_init(&req, RQ_DAEMON, progname, RQ_FILE, new_fd, NULL);
2099     fromhost(&req);
2100 
2101     if (!hosts_access(&req))
2102 	return "Access denied\r\n";
2103 #endif
2104 
2105     return NULL;
2106 }
2107 
2108 typedef struct rotator
2109 {
2110     /* Rotators use the ports_lock for mutex. */
2111     int curr_port;
2112     char **portv;
2113     int portc;
2114 
2115     char *portname;
2116 
2117     struct addrinfo    *ai;		/* The address list for the portname. */
2118     struct opensocks   *acceptfds;	/* The file descriptor used to
2119 					   accept connections on the
2120 					   TCP port. */
2121     unsigned int   nr_acceptfds;
2122     waiter_t       *accept_waiter;
2123 
2124     struct rotator *next;
2125 } rotator_t;
2126 
2127 rotator_t *rotators = NULL;
2128 
2129 /* A connection request has come in on a port. */
2130 static void
handle_rot_port_read(int fd,void * data)2131 handle_rot_port_read(int fd, void *data)
2132 {
2133     rotator_t *rot = (rotator_t *) data;
2134     int i, new_fd;
2135     struct sockaddr_storage addr;
2136     socklen_t addrlen = sizeof(addr);
2137     const char *err;
2138 
2139     /* FIXME - handle remote address interactions? */
2140     new_fd = accept(fd, (struct sockaddr *) &addr, &addrlen);
2141     if (new_fd == -1) {
2142 	if (errno != EAGAIN && errno != EWOULDBLOCK)
2143 	    syslog(LOG_ERR, "Could not accept on rotator %s: %m",
2144 		   rot->portname);
2145 	return;
2146     }
2147 
2148     err = check_tcpd_ok(new_fd);
2149     if (err)
2150 	goto out_err;
2151 
2152     LOCK(ports_lock);
2153     i = rot->curr_port;
2154     do {
2155 	port_info_t *port = find_rotator_port(rot->portv[i],
2156 					(struct sockaddr *) &addr, addrlen);
2157 
2158 	if (++i >= rot->portc)
2159 	    i = 0;
2160 	if (port) {
2161 	    rot->curr_port = i;
2162 	    UNLOCK(ports_lock);
2163 	    handle_port_accept(port, new_fd, &(port->netcons[0]));
2164 	    UNLOCK(port->lock);
2165 	    return;
2166 	}
2167     } while (i != rot->curr_port);
2168     UNLOCK(ports_lock);
2169 
2170     err = "No free port found\r\n";
2171  out_err:
2172     write_ignore_fail(new_fd, err, strlen(err));
2173     close(new_fd);
2174 }
2175 
2176 static void
free_rotator(rotator_t * rot)2177 free_rotator(rotator_t *rot)
2178 {
2179     int i;
2180 
2181     for (i = 0; i < rot->nr_acceptfds; i++) {
2182 	sel_set_fd_read_handler(ser2net_sel,
2183 				rot->acceptfds[i].fd,
2184 				SEL_FD_HANDLER_DISABLED);
2185 	sel_clear_fd_handlers(ser2net_sel, rot->acceptfds[i].fd);
2186 	wait_for_waiter(rot->accept_waiter);
2187 	close(rot->acceptfds[i].fd);
2188     }
2189     if (rot->accept_waiter)
2190 	free_waiter(rot->accept_waiter);
2191     if (rot->portname)
2192 	free(rot->portname);
2193     if (rot->ai)
2194 	freeaddrinfo(rot->ai);
2195     if (rot->acceptfds)
2196 	free(rot->acceptfds);
2197     if (rot->portv)
2198 	str_to_argv_free(rot->portc, rot->portv);
2199     free(rot);
2200 }
2201 
2202 void
free_rotators(void)2203 free_rotators(void)
2204 {
2205     rotator_t *rot, *next;
2206 
2207     rot = rotators;
2208     while (rot) {
2209 	next = rot->next;
2210 	free_rotator(rot);
2211 	rot = next;
2212     }
2213     rotators = NULL;
2214 }
2215 
2216 static void
rotator_fd_cleared(int fd,void * cb_data)2217 rotator_fd_cleared(int fd, void *cb_data)
2218 {
2219     rotator_t *rot = cb_data;
2220 
2221     wake_waiter(rot->accept_waiter);
2222 }
2223 
2224 int
add_rotator(char * portname,char * ports,int lineno)2225 add_rotator(char *portname, char *ports, int lineno)
2226 {
2227     rotator_t *rot;
2228     int rv;
2229     bool is_port_set;
2230 
2231     rot = malloc(sizeof(*rot));
2232     if (!rot)
2233 	return ENOMEM;
2234     memset(rot, 0, sizeof(*rot));
2235 
2236     rot->accept_waiter = alloc_waiter();
2237     if (!rot->accept_waiter) {
2238 	free_rotator(rot);
2239 	return ENOMEM;
2240     }
2241 
2242     rot->portname = strdup(portname);
2243     if (!rot->portname) {
2244 	free_waiter(rot->accept_waiter);
2245 	free_rotator(rot);
2246 	return ENOMEM;
2247     }
2248 
2249     rv = str_to_argv(ports, &rot->portc, &rot->portv, NULL);
2250     if (rv)
2251 	goto out;
2252 
2253     rv = scan_network_port(rot->portname, &rot->ai, NULL, &is_port_set);
2254     if (rv) {
2255 	syslog(LOG_ERR, "port number was invalid on line %d", lineno);
2256 	goto out;
2257     }
2258     if (!is_port_set) {
2259 	syslog(LOG_ERR, "port number was zero on line %d", lineno);
2260 	goto out;
2261     }
2262 
2263     rot->acceptfds = open_socket(rot->ai, handle_rot_port_read, NULL, rot,
2264 				 &rot->nr_acceptfds, rotator_fd_cleared);
2265     if (rot->acceptfds == NULL) {
2266 	syslog(LOG_ERR, "Unable to create TCP socket on line %d", lineno);
2267 	rv = ENOMEM;
2268 	goto out;
2269     }
2270 
2271     rot->next = rotators;
2272     rotators = rot;
2273 
2274  out:
2275     if (rv)
2276 	free_rotator(rot);
2277     return rv;
2278 }
2279 
2280 static void
disable_accept_ports(port_info_t * port)2281 disable_accept_ports(port_info_t *port)
2282 {
2283     int i;
2284 
2285     for (i = 0; i < port->nr_acceptfds; i++)
2286 	sel_set_fd_read_handler(ser2net_sel, port->acceptfds[i].fd,
2287 				SEL_FD_HANDLER_DISABLED);
2288 }
2289 
2290 static void
enable_accept_ports(port_info_t * port)2291 enable_accept_ports(port_info_t *port)
2292 {
2293     int i;
2294 
2295     for (i = 0; i < port->nr_acceptfds; i++)
2296 	sel_set_fd_read_handler(ser2net_sel, port->acceptfds[i].fd,
2297 				SEL_FD_HANDLER_ENABLED);
2298 }
2299 
2300 static void
kick_old_user(port_info_t * port,net_info_t * netcon,int new_fd,int buflen,struct sockaddr_storage * remaddr,socklen_t remaddrlen)2301 kick_old_user(port_info_t *port, net_info_t *netcon, int new_fd, int buflen,
2302 	      struct sockaddr_storage *remaddr, socklen_t remaddrlen)
2303 {
2304     char *err = "kicked off, new user is coming\r\n";
2305 
2306     /* If another user is waiting for a kick, kick that user. */
2307     if (netcon->new_fd) {
2308 	net_write(netcon->new_fd, err, strlen(err), 0,
2309 		  (struct sockaddr *) &netcon->new_remote,
2310 		  netcon->new_raddrlen);
2311 	close(netcon->new_fd);
2312     }
2313 
2314     /* Wait it to be unconnected and clean, restart the process. */
2315     netcon->new_fd = new_fd;
2316     memcpy(&netcon->new_remote, remaddr, remaddrlen);
2317     netcon->new_raddrlen = remaddrlen;
2318     if (port->dgram) {
2319 	memcpy(netcon->new_buf, port->net_to_dev.buf, buflen);
2320 	netcon->new_buf_len = buflen;
2321     }
2322 
2323     shutdown_one_netcon(netcon, err);
2324 }
2325 
2326 static void
check_port_new_fd(port_info_t * port,net_info_t * netcon)2327 check_port_new_fd(port_info_t *port, net_info_t *netcon)
2328 {
2329     int fd;
2330 
2331     if (netcon->new_fd == -1)
2332 	return;
2333 
2334     if (netcon->fd != -1) {
2335 	/* Something snuck in before, kick this one out. */
2336 	char *err = "kicked off, new user is coming\r\n";
2337 
2338 	net_write(netcon->new_fd, err, strlen(err), 0,
2339 		  (struct sockaddr *) &netcon->new_remote,
2340 		  netcon->new_raddrlen);
2341 	close(netcon->new_fd);
2342 	netcon->new_fd = -1;
2343 	return;
2344     }
2345 
2346     fd = netcon->new_fd;
2347     netcon->new_fd = -1;
2348     memcpy(netcon->raddr, &netcon->new_remote, netcon->new_raddrlen);
2349     netcon->raddrlen = netcon->new_raddrlen;
2350     if (port->dgram) {
2351 	netcon->fd = fd;
2352 	netcon->udpraddrlen = netcon->new_raddrlen;
2353 	if (!setup_port(port, netcon, false)) {
2354 	    memcpy(port->net_to_dev.buf, netcon->new_buf, netcon->new_buf_len);
2355 	    net_fd_read2(port, netcon, netcon->new_buf_len);
2356 	}
2357     } else {
2358 	handle_port_accept(port, fd, netcon);
2359     }
2360 }
2361 
2362 /* A connection request has come in on a port. */
2363 static void
handle_accept_port_read(int fd,void * data)2364 handle_accept_port_read(int fd, void *data)
2365 {
2366     port_info_t *port = (port_info_t *) data;
2367     const char *err = NULL;
2368     int i, new_fd;
2369     struct sockaddr_storage addr;
2370     socklen_t addrlen = sizeof(addr);
2371 
2372     LOCK(port->lock);
2373 
2374     if (port->enabled == PORT_DISABLED)
2375 	goto out;
2376 
2377     /* We raced, the shutdown should disable the accept read
2378        until the shutdown is complete. */
2379     if (port->dev_to_net_state == PORT_CLOSING)
2380 	goto out;
2381 
2382     new_fd = accept(fd, (struct sockaddr *) &addr, &addrlen);
2383     if (new_fd == -1) {
2384 	if (errno != EAGAIN && errno != EWOULDBLOCK)
2385 	    syslog(LOG_ERR, "Could not accept on port %s: %m", port->portname);
2386 	goto out;
2387     }
2388 
2389     err = check_tcpd_ok(new_fd);
2390     if (err)
2391 	goto out_err;
2392 
2393     if (!port_remaddr_ok(port, (struct sockaddr *) &addr, addrlen)) {
2394 	err = "Access denied\r\n";
2395 	goto out_err;
2396     }
2397 
2398     for (i = 0; i < port->max_connections; i++) {
2399 	if (port->netcons[i].fd == -1)
2400 	    break;
2401     }
2402 
2403     if (i == port->max_connections) {
2404 	if (port->kickolduser_mode) {
2405 	    /* Kick off user 0. */
2406 	    kick_old_user(port, &port->netcons[0], new_fd, 0,
2407 			  &addr, addrlen);
2408 	    UNLOCK(port->lock);
2409 	    return;
2410 	}
2411 
2412 	err = "Port already in use\r\n";
2413     }
2414 
2415     if (!err && is_device_already_inuse(port))
2416 	err = "Port's device already in use\r\n";
2417 
2418     if (err != NULL) {
2419     out_err:
2420 	UNLOCK(port->lock);
2421 	write_ignore_fail(new_fd, err, strlen(err));
2422 	close(new_fd);
2423 	return;
2424     }
2425 
2426     memcpy(port->netcons[i].raddr, &addr, addrlen);
2427     port->netcons[i].raddrlen = addrlen;
2428     if (port->dgram)
2429 	port->netcons[i].udpraddrlen = addrlen;
2430 
2431     /* We have to hold the ports_lock until after this call so the
2432        device won't get used (from is_device_already_inuse()). */
2433     handle_port_accept(port, new_fd, &(port->netcons[i]));
2434  out:
2435     UNLOCK(port->lock);
2436 }
2437 
2438 static void
port_accept_fd_cleared(int fd,void * cb_data)2439 port_accept_fd_cleared(int fd, void *cb_data)
2440 {
2441     port_info_t *port = cb_data;
2442 
2443     wake_waiter(port->accept_waiter);
2444 }
2445 
2446 static int
tcp_port_read(int fd,port_info_t * port,int * readerr,net_info_t ** rnetcon)2447 tcp_port_read(int fd, port_info_t *port, int *readerr, net_info_t **rnetcon)
2448 {
2449     int rv;
2450 
2451     rv = read(fd, port->net_to_dev.buf, port->net_to_dev.maxsize);
2452     if (rv < 0)
2453 	*readerr = errno;
2454     return rv;
2455 }
2456 
2457 static int
udp_port_read(int fd,port_info_t * port,int * readerr,net_info_t ** rnetcon)2458 udp_port_read(int fd, port_info_t *port, int *readerr, net_info_t **rnetcon)
2459 {
2460     struct sockaddr_storage remaddr;
2461     socklen_t remaddrlen;
2462     int i, rv;
2463     net_info_t *netcon;
2464     char *err = NULL;
2465 
2466     remaddrlen = sizeof(remaddr);
2467     rv = recvfrom(fd, port->net_to_dev.buf, port->net_to_dev.maxsize, 0,
2468 		  (struct sockaddr *) &remaddr, &remaddrlen);
2469     if (rv < 0) {
2470 	*readerr = errno;
2471 	return rv;
2472     }
2473 
2474     for (i = 0; i < port->max_connections; i++) {
2475 	if (port->netcons[i].fd == -1)
2476 	    continue;
2477 	if (!sockaddr_equal((struct sockaddr *) &remaddr, remaddrlen,
2478 			    port->netcons[i].raddr, port->netcons[i].raddrlen,
2479 			    true))
2480 	    continue;
2481 
2482 	/* We found a matching port. */
2483 	*rnetcon = &(port->netcons[i]);
2484 	goto out;
2485     }
2486 
2487     /* No matching port, try a new connection. */
2488     if (port->remaddrs) {
2489 	struct port_remaddr *r = port->remaddrs;
2490 
2491 	while (r) {
2492 	    if (sockaddr_equal((struct sockaddr *) &remaddr, remaddrlen,
2493 			       (struct sockaddr *) &r->addr, r->addrlen,
2494 			       r->is_port_set))
2495 		break;
2496 	    r = r->next;
2497 	}
2498 	if (!r) {
2499 	    err = "Access denied\r\n";
2500 	    goto out_err;
2501 	}
2502     }
2503 
2504     if (i == port->max_connections) {
2505 	for (i = 0; i < port->max_connections; i++) {
2506 	    if (port->netcons[i].fd == -1)
2507 		break;
2508 	}
2509     }
2510 
2511     if (i == port->max_connections && port->kickolduser_mode) {
2512 	for (i = 0; i < port->max_connections; i++) {
2513 	    if (!port->netcons[i].remote_fixed)
2514 		break;
2515 	}
2516     }
2517 
2518     if (i == port->max_connections)
2519 	err = "Port already in use\r\n";
2520 
2521     if (!err && is_device_already_inuse(port))
2522 	err = "Port's device already in use\r\n";
2523 
2524     if (!err) {
2525 	int new_fd = dup(fd);
2526 
2527 	if (new_fd == -1)
2528 	    err = "Unable to dup port fd\r\n";
2529 	netcon = &(port->netcons[i]);
2530 	if (netcon->fd == -1) {
2531 	    netcon->fd = new_fd;
2532 	} else {
2533 	    kick_old_user(port, netcon, new_fd, rv, &remaddr, remaddrlen);
2534 	    goto out_ignore;
2535 	}
2536     }
2537 
2538     if (err) {
2539     out_err:
2540 	net_write(fd, err, strlen(err), 0,
2541 		  (struct sockaddr *) &remaddr, remaddrlen);
2542 	goto out_ignore;
2543     }
2544 
2545     memcpy(netcon->raddr, &remaddr, remaddrlen);
2546     netcon->raddrlen = remaddrlen;
2547     if (port->dgram)
2548 	netcon->udpraddrlen = remaddrlen;
2549 
2550     if (setup_port(port, netcon, false))
2551 	goto out_ignore;
2552 
2553     *rnetcon = netcon;
2554 
2555  out:
2556     if (rv == 0)
2557 	/* zero-length packet. */
2558 	goto out_ignore;
2559 
2560     return rv;
2561 
2562  out_ignore:
2563     *readerr = EAGAIN;
2564     return -1;
2565 }
2566 
2567 static void
handle_udp_net_fd_read(int fd,void * data)2568 handle_udp_net_fd_read(int fd, void *data)
2569 {
2570     port_info_t *port = data;
2571 
2572     handle_net_fd_read(fd, &(port->netcons[0]));
2573 }
2574 
2575 static void
process_remaddr(struct absout * eout,port_info_t * port,struct port_remaddr * r,bool is_reconfig)2576 process_remaddr(struct absout *eout, port_info_t *port, struct port_remaddr *r,
2577 		bool is_reconfig)
2578 {
2579     net_info_t *netcon;
2580 
2581     if (!r->is_port_set || !port->dgram)
2582 	return;
2583 
2584     for_each_connection(port, netcon) {
2585 	int i = 0;
2586 
2587 	if (netcon->remote_fixed)
2588 	    continue;
2589 
2590 	/* Search for a UDP port that matches the remote address family. */
2591 	for (i = 0; i < port->nr_acceptfds; i++) {
2592 	    if (port->acceptfds[i].family == r->addr.ss_family)
2593 		break;
2594 	}
2595 	if (i == port->nr_acceptfds) {
2596 	    eout->out(eout, "remote address '%s' had no socket with"
2597 		      " a matching family", r->name);
2598 	    return;
2599 	}
2600 
2601 	netcon->remote_fixed = true;
2602 	memcpy(netcon->raddr, &r->addr, r->addrlen);
2603 	netcon->raddrlen = r->addrlen;
2604 	if (port->dgram)
2605 	    netcon->udpraddrlen = r->addrlen;
2606 
2607 	netcon->fd = dup(port->acceptfds[i].fd);
2608 	if (netcon->fd == -1) {
2609 	    eout->out(eout,
2610 		      "Unable to duplicate fd for remote address '%s'",
2611 		      r->name);
2612 	    return;
2613 	}
2614 
2615 	if (setup_port(port, netcon, is_reconfig)) {
2616 	    netcon->remote_fixed = false;
2617 	    close(netcon->fd);
2618 	    netcon->fd = -1;
2619 	    eout->out(eout, "Unable to set up port for remote address '%s'",
2620 		      r->name);
2621 	}
2622 
2623 	return;
2624     }
2625 
2626     eout->out(eout, "Too many fixed UDP remote addresses specified for the"
2627 	      " max-connections given");
2628 }
2629 
2630 /* Start monitoring for connections on a specific port. */
2631 static int
startup_port(struct absout * eout,port_info_t * port,bool is_reconfig)2632 startup_port(struct absout *eout, port_info_t *port, bool is_reconfig)
2633 {
2634     void (*readhandler)(int, void *) = handle_accept_port_read;
2635     struct port_remaddr *r;
2636 
2637     if (port->is_stdio) {
2638 	if (is_device_already_inuse(port)) {
2639 	    if (eout)
2640 		eout->out(eout, "Port's device already in use");
2641 	    return -1;
2642 	} else {
2643 	    port->acceptfds = NULL;
2644 	    port->netcons[0].fd = 0; /* stdin */
2645 	    if (setup_port(port, &(port->netcons[0]), false) == -1)
2646 		return -1;
2647 	}
2648 	return 0;
2649     }
2650 
2651     if (port->dgram)
2652 	readhandler = handle_udp_net_fd_read;
2653 
2654     port->acceptfds = open_socket(port->ai, readhandler, NULL, port,
2655 				  &port->nr_acceptfds, port_accept_fd_cleared);
2656     if (port->acceptfds == NULL) {
2657 	if (eout)
2658 	    eout->out(eout, "Unable to create network socket(s)");
2659 	else
2660 	    syslog(LOG_ERR, "Unable to create network socket for port %s: %s",
2661 		   port->portname, strerror(errno));
2662 
2663 	return -1;
2664     }
2665 
2666     for (r = port->remaddrs; r; r = r->next)
2667 	process_remaddr(eout, port, r, is_reconfig);
2668 
2669     return 0;
2670 }
2671 
2672 static void
redo_port_handlers(port_info_t * port)2673 redo_port_handlers(port_info_t *port)
2674 {
2675     unsigned int i;
2676     void (*readhandler)(int, void *) = handle_accept_port_read;
2677 
2678     if (port->dgram)
2679 	readhandler = handle_udp_net_fd_read;
2680 
2681     for (i = 0; i < port->nr_acceptfds; i++) {
2682 	sel_set_fd_handlers(ser2net_sel, port->acceptfds[i].fd, port,
2683 			    readhandler, NULL, NULL,
2684 			    port_accept_fd_cleared);
2685 	wait_for_waiter(port->accept_waiter);
2686     }
2687 }
2688 
2689 int
change_port_state(struct absout * eout,port_info_t * port,int state,bool is_reconfig)2690 change_port_state(struct absout *eout, port_info_t *port, int state,
2691 		  bool is_reconfig)
2692 {
2693     int rv = 0;
2694 
2695     if (port->enabled == state) {
2696 	UNLOCK(port->lock);
2697 	return 0;
2698     }
2699 
2700     if (state == PORT_DISABLED) {
2701 	port->enabled = PORT_DISABLED; /* Stop accepts */
2702 	UNLOCK(port->lock);
2703 
2704 	if (port->acceptfds != NULL) {
2705 	    unsigned int i;
2706 
2707 	    for (i = 0; i < port->nr_acceptfds; i++) {
2708 		sel_set_fd_read_handler(ser2net_sel,
2709 					port->acceptfds[i].fd,
2710 					SEL_FD_HANDLER_DISABLED);
2711 		sel_clear_fd_handlers(ser2net_sel, port->acceptfds[i].fd);
2712 		wait_for_waiter(port->accept_waiter);
2713 		close(port->acceptfds[i].fd);
2714 	    }
2715 	    free(port->acceptfds);
2716 	    port->acceptfds = NULL;
2717 	    port->nr_acceptfds = 0;
2718 	}
2719     } else {
2720 	if (port->enabled == PORT_DISABLED) {
2721 	    if (state == PORT_RAWLP)
2722 		port->io.read_disabled = 1;
2723 	    else
2724 		port->io.read_disabled = 0;
2725 	    rv = startup_port(eout, port, is_reconfig);
2726 	    port->enabled = state;
2727 	}
2728 	UNLOCK(port->lock);
2729     }
2730 
2731     return rv;
2732 }
2733 
2734 static void
free_port(port_info_t * port)2735 free_port(port_info_t *port)
2736 {
2737     net_info_t *netcon;
2738 
2739     for_each_connection(port, netcon) {
2740 	char *err = "Port was deleted\n\r";
2741 	if (netcon->new_fd != -1) {
2742 	    net_write(netcon->new_fd, err, strlen(err), 0,
2743 		      (struct sockaddr *) &netcon->new_remote,
2744 		      netcon->new_raddrlen);
2745 	    close(netcon->new_fd);
2746 	}
2747 	if (netcon->runshutdown)
2748 	    sel_free_runner(netcon->runshutdown);
2749 	if (netcon->new_buf)
2750 	    free(netcon->new_buf);
2751     }
2752 
2753     while (port->remaddrs) {
2754 	struct port_remaddr *r = port->remaddrs;
2755 
2756 	port->remaddrs = r->next;
2757 	free(r->name);
2758 	free(r);
2759     }
2760 
2761     FREE_LOCK(port->lock);
2762     if (port->dev_to_net.buf)
2763 	free(port->dev_to_net.buf);
2764     if (port->net_to_dev.buf)
2765 	free(port->net_to_dev.buf);
2766     if (port->timer)
2767 	sel_free_timer(port->timer);
2768     if (port->send_timer)
2769 	sel_free_timer(port->send_timer);
2770     if (port->runshutdown)
2771 	sel_free_runner(port->runshutdown);
2772     if (port->accept_waiter)
2773 	free_waiter(port->accept_waiter);
2774     if (port->io.f)
2775 	port->io.f->free(&port->io);
2776     if (port->trace_read.filename)
2777 	free(port->trace_read.filename);
2778     if (port->trace_write.filename)
2779 	free(port->trace_write.filename);
2780     if (port->trace_both.filename)
2781 	free(port->trace_both.filename);
2782     if (port->io.devname)
2783 	free(port->io.devname);
2784     if (port->portname)
2785 	free(port->portname);
2786     if (port->new_config)
2787 	free_port(port->new_config);
2788     if (port->ai)
2789 	freeaddrinfo(port->ai);
2790     if (port->acceptfds)
2791 	free(port->acceptfds);
2792     if (port->bannerstr)
2793 	free(port->bannerstr);
2794     if (port->signaturestr)
2795 	free(port->signaturestr);
2796     if (port->openstr)
2797 	free(port->openstr);
2798     if (port->closestr)
2799 	free(port->closestr);
2800     if (port->closeon)
2801 	free(port->closeon);
2802     if (port->netcons)
2803 	free(port->netcons);
2804     if (port->orig_devname)
2805 	free(port->orig_devname);
2806     free(port);
2807 }
2808 
2809 static void
switchout_port(struct absout * eout,port_info_t * new_port,port_info_t * curr,port_info_t * prev)2810 switchout_port(struct absout *eout, port_info_t *new_port,
2811 	       port_info_t *curr, port_info_t *prev)
2812 {
2813     int new_state = new_port->enabled;
2814     waiter_t *tmp_waiter;
2815     int i;
2816 
2817     /* Keep the same accept ports as the old port. */
2818     new_port->enabled = curr->enabled;
2819     new_port->acceptfds = curr->acceptfds;
2820     new_port->nr_acceptfds = curr->nr_acceptfds;
2821 
2822     /*
2823      * The strange switcharoo with the waiter keep the waiter the same
2824      * on the old and new data, otherwise the wakeup and the wait
2825      * would be on different waiters.
2826      */
2827     tmp_waiter = new_port->accept_waiter;
2828     new_port->accept_waiter = curr->accept_waiter;
2829     curr->acceptfds = NULL;
2830     redo_port_handlers(new_port);
2831     curr->accept_waiter = tmp_waiter;
2832 
2833     for (i = 0; i < new_port->max_connections; i++) {
2834 	if (i >= curr->max_connections)
2835 	    break;
2836 	if (curr->netcons[i].new_fd == -1)
2837 	    continue;
2838 	new_port->netcons[i].new_fd = curr->netcons[i].new_fd;
2839 	new_port->netcons[i].new_remote = curr->netcons[i].new_remote;
2840 	new_port->netcons[i].new_raddrlen = curr->netcons[i].new_raddrlen;
2841 	if (new_port->net_to_dev_bufsize < curr->netcons[i].new_buf_len)
2842 	    /* Buffer shrank and data won't fit, just drop the old data. */
2843 	    new_port->netcons[i].new_buf_len = new_port->net_to_dev_bufsize;
2844 	else
2845 	    new_port->netcons[i].new_buf_len = curr->netcons[i].new_buf_len;
2846 	memcpy(new_port->netcons[i].new_buf, curr->netcons[i].new_buf,
2847 	       new_port->netcons[i].new_buf_len);
2848     }
2849 
2850     if (prev == NULL) {
2851 	ports = new_port;
2852     } else {
2853 	prev->next = new_port;
2854     }
2855     new_port->next = curr->next;
2856     UNLOCK(curr->lock);
2857     free_port(curr);
2858     change_port_state(eout, new_port, new_state, true); /* releases lock */
2859 }
2860 
2861 static void
finish_shutdown_port(port_info_t * port)2862 finish_shutdown_port(port_info_t *port)
2863 {
2864     net_info_t *netcon;
2865     struct port_remaddr *r;
2866 
2867     /* At this point nothing can happen on the port, so no need for a lock */
2868 
2869     port->net_to_dev_state = PORT_UNCONNECTED;
2870     buffer_reset(&port->net_to_dev);
2871     if (port->devstr) {
2872 	free(port->devstr->buf);
2873 	free(port->devstr);
2874 	port->devstr = NULL;
2875     }
2876     buffer_reset(&port->dev_to_net);
2877     port->dev_bytes_received = 0;
2878     port->dev_bytes_sent = 0;
2879 
2880     if (port->is_stdio)
2881 	/* This was a zero port (for stdin/stdout), this is only
2882 	   allowed with one port at a time, and we shut down when it
2883 	   closes. */
2884 	exit(0);
2885 
2886     /* If the port has been disabled, then delete it.  Check this before
2887        the new config so the port will be deleted properly and not
2888        reconfigured on a reconfig. */
2889     if (port->config_num == -1) {
2890 	port_info_t *curr, *prev;
2891 
2892 	prev = NULL;
2893 	LOCK(ports_lock);
2894 	curr = ports;
2895 	while ((curr != NULL) && (curr != port)) {
2896 	    prev = curr;
2897 	    curr = curr->next;
2898 	}
2899 	if (curr != NULL) {
2900 	    if (prev == NULL)
2901 		ports = curr->next;
2902 	    else
2903 		prev->next = curr->next;
2904 	}
2905 	UNLOCK(ports_lock);
2906 	free_port(port);
2907 	return; /* We have to return here because we no longer have a port. */
2908     }
2909 
2910     /*
2911      * The configuration for this port has changed, install it now that
2912      * the user has closed the connection.
2913      */
2914     if (port->new_config != NULL) {
2915 	port_info_t *curr, *prev;
2916 
2917 	prev = NULL;
2918 	LOCK(ports_lock);
2919 	curr = ports;
2920 	while ((curr != NULL) && (curr != port)) {
2921 	    prev = curr;
2922 	    curr = curr->next;
2923 	}
2924 	if (curr != NULL) {
2925 	    port = curr->new_config;
2926 	    curr->new_config = NULL;
2927 	    LOCK(curr->lock);
2928 	    LOCK(port->lock);
2929 	    switchout_port(NULL, port, curr, prev); /* Releases locks */
2930 	}
2931 	UNLOCK(ports_lock);
2932     }
2933 
2934     /* Wait until here to let anything start on the port. */
2935     LOCK(port->lock);
2936     port->dev_to_net_state = PORT_UNCONNECTED;
2937     for (r = port->remaddrs; r; r = r->next)
2938 	process_remaddr(&syslog_eout, port, r, true);
2939     enable_accept_ports(port);
2940     for_each_connection(port, netcon)
2941 	check_port_new_fd(port, netcon);
2942     UNLOCK(port->lock);
2943 }
2944 
2945 static void
io_shutdown_done(struct devio * io)2946 io_shutdown_done(struct devio *io)
2947 {
2948     port_info_t *port = io->user_data;
2949 
2950     finish_shutdown_port(port);
2951 }
2952 
2953 static void
shutdown_port_io(sel_runner_t * runner,void * cb_data)2954 shutdown_port_io(sel_runner_t *runner, void *cb_data)
2955 {
2956     port_info_t *port = cb_data;
2957 
2958     if (port->io.f)
2959 	port->io.f->shutdown(&port->io, io_shutdown_done);
2960     else
2961 	finish_shutdown_port(port);
2962 }
2963 
2964 /* Output the devstr buffer */
2965 static void
handle_dev_fd_close_write(port_info_t * port)2966 handle_dev_fd_close_write(port_info_t *port)
2967 {
2968     int reterr, buferr;
2969 
2970     reterr = buffer_io_write(&port->io, port->devstr, &buferr);
2971     if (reterr == -1) {
2972 	syslog(LOG_ERR, "The dev write for port %s had error: %m",
2973 	       port->portname);
2974 	goto closeit;
2975     }
2976 
2977     if (buffer_cursize(port->devstr) != 0)
2978 	return;
2979 
2980 closeit:
2981     sel_run(port->runshutdown, shutdown_port_io, port);
2982 }
2983 
2984 static void
timer_shutdown_done(struct selector_s * sel,sel_timer_t * timer,void * cb_data)2985 timer_shutdown_done(struct selector_s *sel, sel_timer_t *timer, void *cb_data)
2986 {
2987     port_info_t *port = cb_data;
2988 
2989     LOCK(port->lock);
2990     if (port->devstr) {
2991 	free(port->devstr->buf);
2992 	free(port->devstr);
2993     }
2994     port->devstr = process_str_to_buf(port, NULL, port->closestr);
2995     if (port->devstr && (port->net_to_dev_state != PORT_UNCONNECTED)) {
2996 	port->io.f->read_handler_enable(&port->io, 0);
2997 	port->io.f->except_handler_enable(&port->io, 0);
2998 	port->dev_write_handler = handle_dev_fd_close_write;
2999 	port->io.f->write_handler_enable(&port->io, 1);
3000 	UNLOCK(port->lock);
3001     } else {
3002 	UNLOCK(port->lock);
3003 	shutdown_port_io(NULL, port);
3004     }
3005 }
3006 
shutdown_port_timer(sel_runner_t * runner,void * cb_data)3007 static void shutdown_port_timer(sel_runner_t *runner, void *cb_data)
3008 {
3009     port_info_t *port = cb_data;
3010 
3011     sel_stop_timer_with_done(port->timer, timer_shutdown_done, port);
3012 }
3013 
3014 static void
start_shutdown_port(port_info_t * port,char * reason)3015 start_shutdown_port(port_info_t *port, char *reason)
3016 {
3017     if (port->dev_to_net_state == PORT_CLOSING)
3018 	return;
3019 
3020     port->close_on_output_done = false;
3021 
3022     disable_accept_ports(port);
3023 
3024     footer_trace(port, "port", reason);
3025 
3026     if (port->trace_write.fd != -1) {
3027 	close(port->trace_write.fd);
3028 	port->trace_write.fd = -1;
3029     }
3030     if (port->trace_read.fd != -1) {
3031 	close(port->trace_read.fd);
3032 	port->trace_read.fd = -1;
3033     }
3034     if (port->trace_both.fd != -1) {
3035 	close(port->trace_both.fd);
3036 	port->trace_both.fd = -1;
3037     }
3038     port->tw = port->tr = port->tb = NULL;
3039 
3040     port->dev_to_net_state = PORT_CLOSING;
3041 }
3042 
3043 static void
netcon_finish_shutdown(net_info_t * netcon)3044 netcon_finish_shutdown(net_info_t *netcon)
3045 {
3046     port_info_t *port = netcon->port;
3047 
3048     LOCK(port->lock);
3049     netcon->closing = false;
3050     netcon->bytes_received = 0;
3051     netcon->bytes_sent = 0;
3052     netcon->sending_tn_data = false;
3053     netcon->write_pos = 0;
3054     netcon->data_to_write = false;
3055     if (netcon->banner) {
3056 	free(netcon->banner->buf);
3057 	free(netcon->banner);
3058 	netcon->banner = NULL;
3059     }
3060 
3061     if (num_connected_net(port, true) == 0) {
3062 	start_shutdown_port(port, "All network connections free");
3063 	sel_run(port->runshutdown, shutdown_port_timer, port);
3064     } else {
3065 	check_port_new_fd(port, netcon);
3066     }
3067     UNLOCK(port->lock);
3068 }
3069 
3070 static void
port_net_fd_cleared(int fd,void * cb_data)3071 port_net_fd_cleared(int fd, void *cb_data)
3072 {
3073     net_info_t *netcon = cb_data;
3074 
3075     close(netcon->fd);
3076     netcon->fd = -1;
3077     netcon_finish_shutdown(netcon);
3078 }
3079 
shutdown_netcon_clear(sel_runner_t * runner,void * cb_data)3080 static void shutdown_netcon_clear(sel_runner_t *runner, void *cb_data)
3081 {
3082     net_info_t *netcon = cb_data;
3083 
3084     if (netcon->fd != -1)
3085 	sel_clear_fd_handlers(ser2net_sel, netcon->fd);
3086     else
3087 	netcon_finish_shutdown(netcon);
3088 }
3089 
3090 static void
shutdown_port(port_info_t * port,char * reason)3091 shutdown_port(port_info_t *port, char *reason)
3092 {
3093     net_info_t *netcon;
3094     bool some_to_close = false;
3095 
3096     start_shutdown_port(port, reason);
3097 
3098     for_each_connection(port, netcon) {
3099 	if (netcon->fd != -1) {
3100 	    some_to_close = true;
3101 	    shutdown_one_netcon(netcon, "Port closing");
3102 	}
3103     }
3104 
3105     if (!some_to_close)
3106 	sel_run(port->runshutdown, shutdown_port_timer, port);
3107 }
3108 
3109 static void
shutdown_one_netcon(net_info_t * netcon,char * reason)3110 shutdown_one_netcon(net_info_t *netcon, char *reason)
3111 {
3112     if (netcon->closing)
3113 	return;
3114 
3115     footer_trace(netcon->port, "netcon", reason);
3116 
3117     netcon->closing = true;
3118     /* shutdown_netcon_clear() may clain the port lock, run it elsewhere. */
3119     sel_run(netcon->runshutdown, shutdown_netcon_clear, netcon);
3120 }
3121 
3122 void
got_timeout(struct selector_s * sel,sel_timer_t * timer,void * data)3123 got_timeout(struct selector_s *sel,
3124 	    sel_timer_t *timer,
3125 	    void        *data)
3126 {
3127     port_info_t *port = (port_info_t *) data;
3128     struct timeval then;
3129     unsigned char modemstate;
3130     net_info_t *netcon;
3131 
3132     LOCK(port->lock);
3133 
3134     if (port->dev_to_net_state == PORT_CLOSING) {
3135 	UNLOCK(port->lock);
3136 	return;
3137     }
3138 
3139     if (port->timeout) {
3140 	for_each_connection(port, netcon) {
3141 	    if (netcon->fd == -1 || netcon->remote_fixed)
3142 		continue;
3143 	    netcon->timeout_left--;
3144 	    if (netcon->timeout_left < 0)
3145 		shutdown_one_netcon(netcon, "timeout");
3146 	}
3147     }
3148 
3149     if (port->is_2217 &&
3150 		(port->io.f->get_modem_state(&port->io, &modemstate) != -1)) {
3151 	modemstate &= port->modemstate_mask;
3152 	if (modemstate != port->last_modemstate) {
3153 	    unsigned char data[3];
3154 	    data[0] = TN_OPT_COM_PORT;
3155 	    data[1] = 107; /* Notify modemstate */
3156 	    data[2] = modemstate;
3157 	    port->last_modemstate = modemstate;
3158 	    for_each_connection(port, netcon) {
3159 		if (netcon->fd == -1)
3160 		    continue;
3161 		telnet_send_option(&netcon->tn_data, data, 3);
3162 	    }
3163 	}
3164     }
3165 
3166     sel_get_monotonic_time(&then);
3167     then.tv_sec += 1;
3168     sel_start_timer(port->timer, &then);
3169     UNLOCK(port->lock);
3170 }
3171 
cmpstrval(const char * s,const char * prefix,unsigned int * end)3172 static int cmpstrval(const char *s, const char *prefix, unsigned int *end)
3173 {
3174     int len = strlen(prefix);
3175 
3176     if (strncmp(s, prefix, len))
3177 	return 0;
3178     *end = len;
3179     return 1;
3180 }
3181 
cmpstrint(const char * s,const char * prefix,int * val,struct absout * eout)3182 static int cmpstrint(const char *s, const char *prefix, int *val,
3183 		     struct absout *eout)
3184 {
3185     unsigned int end;
3186     char *endpos;
3187 
3188     if (!cmpstrval(s, prefix, &end))
3189 	return 0;
3190 
3191     *val = strtoul(s + end, &endpos, 10);
3192     if (endpos == s + end || *endpos != '\0') {
3193 	eout->out(eout, "Invalid number for %s: %s\n", prefix, s + end);
3194 	return -1;
3195     }
3196     return 1;
3197 }
3198 
3199 static void
port_add_one_remaddr(struct absout * eout,port_info_t * port,char * str)3200 port_add_one_remaddr(struct absout *eout, port_info_t *port, char *str)
3201 {
3202     struct port_remaddr *r, *r2;
3203     struct addrinfo *ai = NULL;
3204     bool is_dgram, is_port_set;
3205     int rv;
3206 
3207     rv = scan_network_port(str, &ai, &is_dgram, &is_port_set);
3208     if (rv) {
3209 	eout->out(eout, "Invalid remote address '%s'", str);
3210 	goto out;
3211     }
3212 
3213     if (port->dgram != is_dgram) {
3214 	eout->out(eout, "Remote address '%s' does not match the port"
3215 		  " type, one cannot be UDP while the other is UDP.", str);
3216 	goto out;
3217     }
3218 
3219     r = malloc(sizeof(*r));
3220     if (!r) {
3221 	eout->out(eout, "Out of memory allocation remote address");
3222 	goto out;
3223     }
3224 
3225     r->name = strdup(str);
3226     if (!r->name) {
3227 	eout->out(eout, "Out of memory allocation remote address string");
3228 	free(r);
3229 	goto out;
3230     }
3231 
3232     memcpy(&r->addr, ai->ai_addr, ai->ai_addrlen);
3233     r->addrlen = ai->ai_addrlen;
3234     r->is_port_set = is_port_set;
3235     r->next = NULL;
3236 
3237     r2 = port->remaddrs;
3238     if (!r2) {
3239 	port->remaddrs = r;
3240     } else {
3241 	while (r2->next)
3242 	    r2 = r2->next;
3243 	r2->next = r;
3244     }
3245 
3246  out:
3247     if (ai)
3248 	freeaddrinfo(ai);
3249 }
3250 
3251 static void
port_add_remaddr(struct absout * eout,port_info_t * port,const char * istr)3252 port_add_remaddr(struct absout *eout, port_info_t *port, const char *istr)
3253 {
3254     char *str;
3255     char *strtok_data;
3256     char *remstr;
3257 
3258     str = strdup(istr);
3259     if (!str) {
3260 	eout->out(eout, "Out of memory handling remote address '%s'", istr);
3261 	return;
3262     }
3263 
3264     remstr = strtok_r(str, ";", &strtok_data);
3265     /* Note that we ignore an empty remaddr. */
3266     while (remstr && *remstr) {
3267 	port_add_one_remaddr(eout, port, remstr);
3268 	remstr = strtok_r(NULL, ";", &strtok_data);
3269     }
3270     free(str);
3271 }
3272 
3273 static int
myconfig(void * data,struct absout * eout,const char * pos)3274 myconfig(void *data, struct absout *eout, const char *pos)
3275 {
3276     port_info_t *port = data;
3277     enum str_type stype;
3278     char *s;
3279     unsigned int len, end;
3280     int rv, val;
3281 
3282     if (strcmp(pos, "remctl") == 0) {
3283 	port->allow_2217 = 1;
3284     } else if (strcmp(pos, "-remctl") == 0) {
3285 	port->allow_2217 = 0;
3286     } else if (strcmp(pos, "kickolduser") == 0) {
3287         port->kickolduser_mode = 1;
3288     } else if (strcmp(pos, "-kickolduser") == 0) {
3289         port->kickolduser_mode = 0;
3290     } else if (strcmp(pos, "hexdump") == 0 ||
3291 	       strcmp(pos, "-hexdump") == 0) {
3292 	port->trace_read.hexdump = (*pos != '-');
3293 	port->trace_write.hexdump = (*pos != '-');
3294 	port->trace_both.hexdump = (*pos != '-');
3295     } else if (strcmp(pos, "timestamp") == 0 ||
3296 	       strcmp(pos, "-timestamp") == 0) {
3297 	port->trace_read.timestamp = (*pos != '-');
3298 	port->trace_write.timestamp = (*pos != '-');
3299 	port->trace_both.timestamp = (*pos != '-');
3300     } else if (strcmp(pos, "tr-hexdump") == 0 ||
3301 	       strcmp(pos, "-tr-hexdump") == 0) {
3302 	port->trace_read.hexdump = (*pos != '-');
3303     } else if (strcmp(pos, "tr-timestamp") == 0 ||
3304 	       strcmp(pos, "-tr-timestamp") == 0) {
3305 	port->trace_read.timestamp = (*pos != '-');
3306     } else if (strcmp(pos, "tw-hexdump") == 0 ||
3307 	       strcmp(pos, "-tw-hexdump") == 0) {
3308 	port->trace_write.hexdump = (*pos != '-');
3309     } else if (strcmp(pos, "tw-timestamp") == 0 ||
3310 	       strcmp(pos, "-tw-timestamp") == 0) {
3311 	port->trace_write.timestamp = (*pos != '-');
3312     } else if (strcmp(pos, "tb-hexdump") == 0 ||
3313 	       strcmp(pos, "-tb-hexdump") == 0) {
3314 	port->trace_both.hexdump = (*pos != '-');
3315     } else if (strcmp(pos, "tb-timestamp") == 0 ||
3316 	       strcmp(pos, "-tb-timestamp") == 0) {
3317 	port->trace_both.timestamp = (*pos != '-');
3318     } else if (cmpstrval(pos, "tr=", &end)) {
3319 	/* trace read, data from the port to the socket */
3320 	port->trace_read.filename = find_tracefile(pos + end);
3321     } else if (cmpstrval(pos, "tw=", &end)) {
3322 	/* trace write, data from the socket to the port */
3323 	port->trace_write.filename = find_tracefile(pos + end);
3324     } else if (cmpstrval(pos, "tb=", &end)) {
3325 	/* trace both directions. */
3326 	port->trace_both.filename = find_tracefile(pos + end);
3327     } else if (cmpstrval(pos, "led-rx=", &end)) {
3328 	/* LED for UART RX traffic */
3329 	port->led_rx = find_led(pos + end);
3330     } else if (cmpstrval(pos, "led-tx=", &end)) {
3331 	/* LED for UART TX traffic */
3332 	port->led_tx = find_led(pos + end);
3333 #if HAVE_DECL_TIOCSRS485
3334     } else if (cmpstrval(pos, "rs485=", &end)) {
3335 	/* get RS485 configuration. */
3336 	port->rs485conf = find_rs485conf(pos + end);
3337 #endif
3338     } else if (strcmp(pos, "telnet_brk_on_sync") == 0) {
3339 	port->telnet_brk_on_sync = 1;
3340     } else if (strcmp(pos, "-telnet_brk_on_sync") == 0) {
3341 	port->telnet_brk_on_sync = 0;
3342     } else if (strcmp(pos, "chardelay") == 0) {
3343 	port->enable_chardelay = true;
3344     } else if (strcmp(pos, "-chardelay") == 0) {
3345 	port->enable_chardelay = false;
3346     } else if ((rv = cmpstrint(pos, "chardelay-scale=", &val, eout))) {
3347 	if (rv == -1)
3348 	    return -1;
3349 	port->chardelay_scale = val;
3350     } else if ((rv = cmpstrint(pos, "chardelay-min=", &val, eout))) {
3351 	if (rv == -1)
3352 	    return -1;
3353 	port->chardelay_min = val;
3354     } else if ((rv = cmpstrint(pos, "chardelay-max=", &val, eout))) {
3355 	if (rv == -1)
3356 	    return -1;
3357 	port->chardelay_max = val;
3358     } else if ((rv = cmpstrint(pos, "dev-to-net-bufsize=", &val, eout))) {
3359 	if (rv == -1)
3360 	    return -1;
3361 	port->dev_to_net_bufsize = val;
3362     } else if ((rv = cmpstrint(pos, "net-to-dev-bufsize=", &val, eout))) {
3363 	if (rv == -1)
3364 	    return -1;
3365 	port->net_to_dev_bufsize = val;
3366     } else if ((rv = cmpstrint(pos, "dev-to-tcp-bufsize=", &val, eout))) {
3367 	/* deprecated */
3368 	if (rv == -1)
3369 	    return -1;
3370 	port->dev_to_net_bufsize = val;
3371     } else if ((rv = cmpstrint(pos, "tcp-to-dev-bufsize=", &val, eout))) {
3372 	/* deprecated */
3373 	if (rv == -1)
3374 	    return -1;
3375 	port->net_to_dev_bufsize = val;
3376     } else if ((rv = cmpstrint(pos, "max-connections=", &val, eout))) {
3377 	if (rv == -1)
3378 	    return -1;
3379 	if (val < 1)
3380 	    val = 1;
3381 	port->max_connections = val;
3382     } else if (cmpstrval(pos, "remaddr=", &end)) {
3383 	port_add_remaddr(eout, port, pos + end);
3384 	port->remaddr_set = true;
3385     } else if ((s = find_str(pos, &stype, &len))) {
3386 	/* It's a startup banner, signature or open/close string, it's
3387 	   already set. */
3388 	switch (stype) {
3389 	case BANNER: port->bannerstr = s; break;
3390 	case SIGNATURE: port->signaturestr = s; break;
3391 	case OPENSTR: port->openstr = s; break;
3392 	case CLOSESTR: port->closestr = s; break;
3393 	case CLOSEON: port->closeon = s; port->closeon_len = len; break;
3394 	default: free(s); goto unknown;
3395 	}
3396     } else {
3397     unknown:
3398 	eout->out(eout, "Unknown config item: %s", pos);
3399 	return -1;
3400     }
3401 
3402     return 0;
3403 }
3404 
3405 /* Create a port based on a set of parameters passed in. */
3406 int
portconfig(struct absout * eout,char * portnum,char * state,char * timeout,char * devname,char * devcfg,int config_num)3407 portconfig(struct absout *eout,
3408 	   char *portnum,
3409 	   char *state,
3410 	   char *timeout,
3411 	   char *devname,
3412 	   char *devcfg,
3413 	   int  config_num)
3414 {
3415     port_info_t *new_port, *curr, *prev;
3416     net_info_t *netcon;
3417     enum str_type str_type;
3418     bool is_port_set;
3419 
3420     new_port = malloc(sizeof(port_info_t));
3421     if (new_port == NULL) {
3422 	eout->out(eout, "Could not allocate a port data structure");
3423 	return -1;
3424     }
3425     memset(new_port, 0, sizeof(*new_port));
3426 
3427     INIT_LOCK(new_port->lock);
3428 
3429     new_port->accept_waiter = alloc_waiter();
3430     if (!new_port->accept_waiter) {
3431 	eout->out(eout, "Could not allocate accept waiter data");
3432 	goto errout;
3433     }
3434 
3435     if (sel_alloc_timer(ser2net_sel,
3436 			got_timeout, new_port,
3437 			&new_port->timer))
3438     {
3439 	eout->out(eout, "Could not allocate timer data");
3440 	goto errout;
3441     }
3442 
3443     if (sel_alloc_timer(ser2net_sel,
3444 			send_timeout, new_port,
3445 			&new_port->send_timer))
3446     {
3447 	eout->out(eout, "Could not allocate timer data");
3448 	goto errout;
3449     }
3450 
3451     if (sel_alloc_runner(ser2net_sel, &new_port->runshutdown)) {
3452 	goto errout;
3453     }
3454 
3455     new_port->io.devname = find_str(devname, &str_type, NULL);
3456     if (new_port->io.devname) {
3457 	if (str_type != DEVNAME) {
3458 	    free(new_port->io.devname);
3459 	    new_port->io.devname = NULL;
3460 	} else {
3461 	    new_port->orig_devname = strdup(devname);
3462 	    if (!new_port->orig_devname) {
3463 		eout->out(eout, "unable to allocate original device name");
3464 		goto errout;
3465 	    }
3466 	}
3467     }
3468     if (!new_port->io.devname)
3469 	new_port->io.devname = strdup(devname);
3470     if (!new_port->io.devname) {
3471 	eout->out(eout, "unable to allocate device name");
3472 	goto errout;
3473     }
3474 
3475     /* Errors from here on out must goto errout. */
3476     init_port_data(new_port);
3477 
3478     if (!new_port->portname) {
3479 	new_port->portname = strdup(portnum);
3480 	if (!new_port->portname)
3481 	    goto errout;
3482     }
3483 
3484     if (strisallzero(new_port->portname)) {
3485 	new_port->is_stdio = 1;
3486     } else if (scan_network_port(new_port->portname, &new_port->ai,
3487 				 &new_port->dgram, &is_port_set)) {
3488 	eout->out(eout, "port number was invalid");
3489 	goto errout;
3490     } else if (!is_port_set) {
3491 	eout->out(eout, "port number was zero");
3492 	goto errout;
3493     }
3494 
3495     if (new_port->dgram)
3496 	new_port->netread = udp_port_read;
3497     else
3498 	new_port->netread = tcp_port_read;
3499 
3500     if (strcmp(state, "raw") == 0) {
3501 	new_port->enabled = PORT_RAW;
3502     } else if (strcmp(state, "rawlp") == 0) {
3503 	new_port->enabled = PORT_RAWLP;
3504 	new_port->io.read_disabled = 1;
3505     } else if (strcmp(state, "telnet") == 0) {
3506 	new_port->enabled = PORT_TELNET;
3507     } else if (strcmp(state, "off") == 0) {
3508 	new_port->enabled = PORT_DISABLED;
3509     } else {
3510 	eout->out(eout, "state was invalid");
3511 	goto errout;
3512     }
3513 
3514     new_port->timeout = scan_int(timeout);
3515     if (new_port->timeout == -1) {
3516 	eout->out(eout, "timeout was invalid");
3517 	goto errout;
3518     }
3519 
3520     new_port->io.user_data = new_port;
3521 
3522     if (strncmp(new_port->io.devname, "sol.", 4) == 0) {
3523 	if (solcfg_init(&new_port->io, eout, devcfg, myconfig,
3524 			new_port) == -1) {
3525 	    eout->out(eout, "device configuration invalid");
3526 	    goto errout;
3527 	}
3528     } else {
3529 	if (devcfg_init(&new_port->io, eout, devcfg, myconfig,
3530 			new_port) == -1) {
3531 	    eout->out(eout, "device configuration invalid");
3532 	    goto errout;
3533 	}
3534     }
3535 
3536     /*
3537      * Don't handle the remaddr default until here, we don't want to
3538      * mess with it if the user has set it, because the user may set
3539      * it to an empty string.
3540      */
3541     if (!new_port->remaddr_set) {
3542 	char *remaddr = find_default_str("remaddr");
3543 	if (!remaddr) {
3544 	    eout->out(eout, "Out of memory processing default remote address");
3545 	} else {
3546 	    port_add_remaddr(eout, new_port, remaddr);
3547 	    free(remaddr);
3548 	}
3549     }
3550 
3551     new_port->netcons = malloc(sizeof(*(new_port->netcons)) *
3552 			       new_port->max_connections);
3553     if (new_port->netcons == NULL) {
3554 	eout->out(eout, "Could not allocate a port data structure");
3555 	goto errout;
3556     }
3557     memset(new_port->netcons, 0,
3558 	   sizeof(*(new_port->netcons)) * new_port->max_connections);
3559     for_each_connection(new_port, netcon) {
3560 	if (sel_alloc_runner(ser2net_sel, &netcon->runshutdown)) {
3561 	    eout->out(eout, "Could not allocate a netcon shutdown handler");
3562 	    goto errout;
3563 	}
3564 
3565 	netcon->port = new_port;
3566 	netcon->fd = -1;
3567 	netcon->new_fd = -1;
3568 	netcon->raddr = ((struct sockaddr *) &netcon->remote);
3569 	if (new_port->dgram) {
3570 	    netcon->udpraddr = netcon->raddr;
3571 	    netcon->new_buf = malloc(new_port->net_to_dev_bufsize);
3572 	    if (!netcon->new_buf) {
3573 		eout->out(eout, "Could not allocate a temp buf");
3574 		goto errout;
3575 	    }
3576 	}
3577     }
3578 
3579     new_port->config_num = config_num;
3580 
3581     /* See if the port already exists, and reconfigure it if so. */
3582     prev = NULL;
3583     LOCK(ports_lock);
3584     curr = ports;
3585     while (curr != NULL) {
3586 	if (strcmp(curr->portname, new_port->portname) == 0) {
3587 	    /* We are reconfiguring this port. */
3588 	    LOCK(curr->lock);
3589 	    if (curr->dev_to_net_state == PORT_UNCONNECTED) {
3590 		/* Port is disconnected, switch it now. */
3591 		LOCK(new_port->lock);
3592 		switchout_port(eout, new_port, curr, prev); /* releases locks */
3593 	    } else {
3594 		/* Mark it to be replaced later. */
3595 		if (curr->new_config != NULL)
3596 		    free_port(curr->new_config);
3597 		curr->config_num = config_num;
3598 		curr->new_config = new_port;
3599 		if (curr->dgram)
3600 		    shutdown_port(curr, "UDP reconfig"); /* releases lock */
3601 		UNLOCK(curr->lock);
3602 	    }
3603 	    goto out;
3604 	} else {
3605 	    prev = curr;
3606 	    curr = curr->next;
3607 	}
3608     }
3609 
3610     /* If we get here, the port is brand new, so don't do anything that
3611        would affect a port replacement here. */
3612 
3613     if (new_port->enabled != PORT_DISABLED) {
3614 	int rv;
3615 
3616 	LOCK(new_port->lock);
3617 	rv = startup_port(eout, new_port, false);
3618 	UNLOCK(new_port->lock);
3619 	if (rv == -1)
3620 	    goto errout_unlock;
3621     }
3622 
3623     /* Tack it on to the end of the list of ports. */
3624     new_port->next = NULL;
3625     if (ports == NULL) {
3626 	ports = new_port;
3627     } else {
3628 	curr = ports;
3629 	while (curr->next != NULL) {
3630 	    curr = curr->next;
3631 	}
3632 	curr->next = new_port;
3633     }
3634  out:
3635     UNLOCK(ports_lock);
3636 
3637     return 0;
3638 
3639 errout_unlock:
3640     UNLOCK(ports_lock);
3641 errout:
3642     free_port(new_port);
3643     return -1;
3644 }
3645 
3646 void
clear_old_port_config(int curr_config)3647 clear_old_port_config(int curr_config)
3648 {
3649     port_info_t *curr, *prev;
3650 
3651     prev = NULL;
3652     curr = ports;
3653     LOCK(ports_lock);
3654     while (curr != NULL) {
3655 	if (curr->config_num != curr_config) {
3656 	    /* The port was removed, remove it. */
3657 	    LOCK(curr->lock);
3658 	    if (curr->dev_to_net_state == PORT_UNCONNECTED) {
3659 		/* releases lock */
3660 		change_port_state(NULL, curr, PORT_DISABLED, false);
3661 		if (prev == NULL) {
3662 		    ports = curr->next;
3663 		    free_port(curr);
3664 		    curr = ports;
3665 		} else {
3666 		    prev->next = curr->next;
3667 		    free_port(curr);
3668 		    curr = prev->next;
3669 		}
3670 	    } else {
3671 		curr->config_num = -1;
3672 		/* releases lock */
3673 		change_port_state(NULL, curr, PORT_DISABLED, false);
3674 		prev = curr;
3675 		curr = curr->next;
3676 		if (curr->dgram) {
3677 		    /*
3678 		     * UDP sockets have to shut down immediately as they
3679 		     * don't have a separate accept and data socket.
3680 		     */
3681 		    LOCK(curr->lock);
3682 		    shutdown_port(curr, "UDP delete");
3683 		    UNLOCK(curr->lock);
3684 		}
3685 	    }
3686 	} else {
3687 	    prev = curr;
3688 	    curr = curr->next;
3689 	}
3690     }
3691     UNLOCK(ports_lock);
3692 }
3693 
3694 #define REMOTEADDR_COLUMN_WIDTH \
3695     (INET6_ADDRSTRLEN - 1 /* terminating NUL */ + 1 /* comma */ + 5 /* strlen("65535") */)
3696 
3697 /* Print information about a port to the control port given in cntlr. */
3698 static void
showshortport(struct controller_info * cntlr,port_info_t * port)3699 showshortport(struct controller_info *cntlr, port_info_t *port)
3700 {
3701     char buffer[NI_MAXHOST], portbuff[NI_MAXSERV];
3702     int  count;
3703     int  need_space = 0;
3704     int  err;
3705     struct absout out = { .out = cntrl_absout, .data = cntlr };
3706     net_info_t *netcon = NULL;
3707     unsigned int bytes_recv = 0, bytes_sent = 0;
3708 
3709     controller_outputf(cntlr, "%-22s ", port->portname);
3710     if (port->config_num == -1)
3711 	controller_outputf(cntlr, "%-6s ", "DEL");
3712     else
3713 	controller_outputf(cntlr, "%-6s ", enabled_str[port->enabled]);
3714     controller_outputf(cntlr, "%7d ", port->timeout);
3715 
3716     netcon = first_live_net_con(port);
3717     if (!netcon)
3718 	netcon = &(port->netcons[0]);
3719 
3720     if (port->net_to_dev_state != PORT_UNCONNECTED) {
3721 	err = getnameinfo(netcon->raddr, netcon->raddrlen,
3722 			  buffer, sizeof(buffer),
3723 			  portbuff, sizeof(portbuff),
3724 			  NI_NUMERICHOST | NI_NUMERICSERV);
3725 	if (err) {
3726 	    snprintf(buffer, sizeof(buffer), "*err*,%s", gai_strerror(err));
3727 	    /* gai_strerror could return an elongated string which could break
3728 	       our pretty formatted output below, so truncate the string nicely */
3729 	    if (strlen(buffer) > REMOTEADDR_COLUMN_WIDTH)
3730 		strcpy(&buffer[REMOTEADDR_COLUMN_WIDTH - 3], "...");
3731 	    count = controller_outputf(cntlr, "%s", buffer);
3732 	} else {
3733 	    count = controller_outputf(cntlr, "%s,%s", buffer, portbuff);
3734 	}
3735     } else {
3736 	count = controller_outputf(cntlr, "unconnected");
3737     }
3738 
3739     while (count < REMOTEADDR_COLUMN_WIDTH + 1) {
3740 	controller_outs(cntlr, " ");
3741 	count++;
3742     }
3743 
3744     bytes_recv = netcon->bytes_received;
3745     bytes_sent = netcon->bytes_sent;
3746 
3747     controller_outputf(cntlr, "%-22s ", port->io.devname);
3748     controller_outputf(cntlr, "%-14s ", state_str[port->net_to_dev_state]);
3749     controller_outputf(cntlr, "%-14s ", state_str[port->dev_to_net_state]);
3750     controller_outputf(cntlr, "%9d ", bytes_recv);
3751     controller_outputf(cntlr, "%9d ", bytes_sent);
3752     controller_outputf(cntlr, "%9d ", port->dev_bytes_received);
3753     controller_outputf(cntlr, "%9d ", port->dev_bytes_sent);
3754 
3755     if (port->enabled != PORT_RAWLP) {
3756 	port->io.f->show_devcfg(&port->io, &out);
3757 	need_space = 1;
3758     }
3759 
3760     if (port->net_to_dev_state != PORT_UNCONNECTED) {
3761 	if (need_space) {
3762 	    controller_outs(cntlr, " ");
3763 	}
3764 
3765 	port->io.f->show_devcontrol(&port->io, &out);
3766     }
3767     controller_outs(cntlr, "\r\n");
3768 
3769 }
3770 
3771 /* Print information about a port to the control port given in cntlr. */
3772 static void
showport(struct controller_info * cntlr,port_info_t * port)3773 showport(struct controller_info *cntlr, port_info_t *port)
3774 {
3775     char buffer[NI_MAXHOST], portbuff[NI_MAXSERV];
3776     struct absout out = { .out = cntrl_absout, .data = cntlr };
3777     int err;
3778     net_info_t *netcon;
3779 
3780     controller_outputf(cntlr, "TCP Port %s\r\n", port->portname);
3781     controller_outputf(cntlr, "  enable state: %s\r\n",
3782 		       enabled_str[port->enabled]);
3783     controller_outputf(cntlr, "  timeout: %d\r\n", port->timeout);
3784 
3785     for_each_connection(port, netcon) {
3786 	if (port->net_to_dev_state != PORT_UNCONNECTED) {
3787 	    err = getnameinfo(netcon->raddr, netcon->raddrlen,
3788 			      buffer, sizeof(buffer),
3789 			      portbuff, sizeof(portbuff),
3790 			      NI_NUMERICHOST | NI_NUMERICSERV);
3791 	    if (err) {
3792 		snprintf(buffer, sizeof(buffer), "*err*,%s", gai_strerror(err));
3793 		controller_outputf(cntlr, "  connected to: %s\r\n", buffer);
3794 	    } else {
3795 		controller_outputf(cntlr, "  connected to: %s,%s\r\n",
3796 				   buffer, portbuff);
3797 	    }
3798 	    controller_outputf(cntlr, "    bytes read from TCP: %d\r\n",
3799 			       netcon->bytes_received);
3800 	    controller_outputf(cntlr, "    bytes written to TCP: %d\r\n",
3801 			       netcon->bytes_sent);
3802 	} else {
3803 	    controller_outputf(cntlr, "  unconnected\r\n");
3804 	}
3805     }
3806 
3807     if (port->orig_devname)
3808 	controller_outputf(cntlr, "  device: %s (%s)\r\n", port->io.devname,
3809 			   port->orig_devname);
3810     else
3811 	controller_outputf(cntlr, "  device: %s\r\n", port->io.devname);
3812 
3813     controller_outputf(cntlr, "  device config: ");
3814     if (port->enabled == PORT_RAWLP) {
3815 	controller_outputf(cntlr, "none\r\n");
3816     } else {
3817 	port->io.f->show_devcfg(&port->io, &out);
3818 	controller_outputf(cntlr, "\r\n");
3819     }
3820 
3821     controller_outputf(cntlr, "  device controls: ");
3822     if (port->net_to_dev_state == PORT_UNCONNECTED) {
3823 	controller_outputf(cntlr, "not currently connected\r\n");
3824     } else {
3825 	port->io.f->show_devcontrol(&port->io, &out);
3826 	controller_outputf(cntlr, "\r\n");
3827     }
3828 
3829     controller_outputf(cntlr, "  tcp to device state: %s\r\n",
3830 		      state_str[port->net_to_dev_state]);
3831 
3832     controller_outputf(cntlr, "  device to tcp state: %s\r\n",
3833 		      state_str[port->dev_to_net_state]);
3834 
3835     controller_outputf(cntlr, "  bytes read from device: %d\r\n",
3836 		      port->dev_bytes_received);
3837 
3838     controller_outputf(cntlr, "  bytes written to device: %d\r\n",
3839 		      port->dev_bytes_sent);
3840 
3841     if (port->config_num == -1) {
3842 	controller_outputf(cntlr, "  Port will be deleted when current"
3843 			   " session closes.\r\n");
3844     } else if (port->new_config != NULL) {
3845 	controller_outputf(cntlr, "  Port will be reconfigured when current"
3846 			   " session closes.\r\n");
3847     }
3848 }
3849 
3850 /*
3851  * Find a port data structure given a port number.  Returns with port->lock
3852  * held, if it returns a non-NULL port.
3853  */
3854 static port_info_t *
find_port_by_num(char * portstr,bool allow_deleted)3855 find_port_by_num(char *portstr, bool allow_deleted)
3856 {
3857     port_info_t *port;
3858 
3859     LOCK(ports_lock);
3860     port = ports;
3861     while (port != NULL) {
3862 	if (strcmp(portstr, port->portname) == 0) {
3863 	    LOCK(port->lock);
3864 	    UNLOCK(ports_lock);
3865 	    if (port->config_num == -1 && !allow_deleted) {
3866 		UNLOCK(port->lock);
3867 		return NULL;
3868 	    }
3869 	    return port;
3870 	}
3871 	port = port->next;
3872     }
3873 
3874     UNLOCK(ports_lock);
3875     return NULL;
3876 }
3877 
3878 /* Handle a showport command from the control port. */
3879 void
showports(struct controller_info * cntlr,char * portspec)3880 showports(struct controller_info *cntlr, char *portspec)
3881 {
3882     port_info_t *port;
3883 
3884     if (portspec == NULL) {
3885 	LOCK(ports_lock);
3886 	/* Dump everything. */
3887 	port = ports;
3888 	while (port != NULL) {
3889 	    LOCK(port->lock);
3890 	    showport(cntlr, port);
3891 	    UNLOCK(port->lock);
3892 	    port = port->next;
3893 	}
3894 	UNLOCK(ports_lock);
3895     } else {
3896 	port = find_port_by_num(portspec, true);
3897 	if (port == NULL) {
3898 	    controller_outputf(cntlr, "Invalid port number: %s\r\n", portspec);
3899 	} else {
3900 	    showport(cntlr, port);
3901 	    UNLOCK(port->lock);
3902 	}
3903     }
3904 }
3905 
3906 /* Handle a showport command from the control port. */
3907 void
showshortports(struct controller_info * cntlr,char * portspec)3908 showshortports(struct controller_info *cntlr, char *portspec)
3909 {
3910     port_info_t *port;
3911 
3912     controller_outputf(cntlr,
3913 	    "%-22s %-6s %7s %-*s %-22s %-14s %-14s %9s %9s %9s %9s %s\r\n",
3914 	    "Port name",
3915 	    "Type",
3916 	    "Timeout",
3917 	    REMOTEADDR_COLUMN_WIDTH,
3918 	    "Remote address",
3919 	    "Device",
3920 	    "TCP to device",
3921 	    "Device to TCP",
3922 	    "TCP in",
3923 	    "TCP out",
3924 	    "Dev in",
3925 	    "Dev out",
3926 	    "State");
3927     if (portspec == NULL) {
3928 	LOCK(ports_lock);
3929 	/* Dump everything. */
3930 	port = ports;
3931 	while (port != NULL) {
3932 	    LOCK(port->lock);
3933 	    showshortport(cntlr, port);
3934 	    UNLOCK(port->lock);
3935 	    port = port->next;
3936 	}
3937 	UNLOCK(ports_lock);
3938     } else {
3939 	port = find_port_by_num(portspec, true);
3940 	if (port == NULL) {
3941 	    controller_outputf(cntlr, "Invalid port number: %s\r\n", portspec);
3942 	} else {
3943 	    showshortport(cntlr, port);
3944 	    UNLOCK(port->lock);
3945 	}
3946     }
3947 }
3948 
3949 /* Set the timeout on a port.  The port number and timeout are passed
3950    in as strings, this code will convert them, return any errors, and
3951    perform the operation. */
3952 void
setporttimeout(struct controller_info * cntlr,char * portspec,char * timeout)3953 setporttimeout(struct controller_info *cntlr, char *portspec, char *timeout)
3954 {
3955     port_info_t *port;
3956     net_info_t *netcon;
3957 
3958     port = find_port_by_num(portspec, true);
3959     if (port == NULL) {
3960 	controller_outputf(cntlr, "Invalid port number: %s\r\n", portspec);
3961     } else {
3962 	int timeout_num = scan_int(timeout);
3963 
3964 	if (timeout_num == -1) {
3965 	    controller_outputf(cntlr, "Invalid timeout: %s\r\n", timeout);
3966 	} else {
3967 	    port->timeout = timeout_num;
3968 
3969 	    for_each_connection(port, netcon) {
3970 		if (netcon->fd != -1)
3971 		    reset_timer(netcon);
3972 	    }
3973 	}
3974 	UNLOCK(port->lock);
3975     }
3976 }
3977 
3978 /* Configure a port.  The port number and configuration are passed in
3979    as strings, this code will get the port and then call the code to
3980    configure the device. */
3981 void
setportdevcfg(struct controller_info * cntlr,char * portspec,char * devcfg)3982 setportdevcfg(struct controller_info *cntlr, char *portspec, char *devcfg)
3983 {
3984     port_info_t *port;
3985     struct absout out = { .out = cntrl_abserrout, .data = cntlr };
3986 
3987     port = find_port_by_num(portspec, false);
3988     if (port == NULL) {
3989 	controller_outputf(cntlr, "Invalid port number: %s\r\n", portspec);
3990     } else {
3991 	if (port->io.f->reconfig(&port->io, &out, devcfg, myconfig, port) == -1)
3992 	{
3993 	    controller_outputf(cntlr, "Invalid device config\r\n");
3994 	}
3995 	UNLOCK(port->lock);
3996     }
3997 }
3998 
3999 /* Modify the controls of a port.  The port number and configuration
4000    are passed in as strings, this code will get the port and then call
4001    the code to control the device. */
4002 void
setportcontrol(struct controller_info * cntlr,char * portspec,char * controls)4003 setportcontrol(struct controller_info *cntlr, char *portspec, char *controls)
4004 {
4005     port_info_t *port;
4006 
4007     port = find_port_by_num(portspec, false);
4008     if (port == NULL) {
4009 	controller_outputf(cntlr, "Invalid port number: %s\r\n", portspec);
4010 	goto out;
4011     } else if (port->net_to_dev_state == PORT_UNCONNECTED) {
4012 	controller_outputf(cntlr, "Port is not currently connected: %s\r\n",
4013 			   portspec);
4014     } else {
4015 	if (port->io.f->set_devcontrol(&port->io, controls) == -1) {
4016 	    controller_outputf(cntlr, "Invalid device controls\r\n");
4017 	}
4018     }
4019     UNLOCK(port->lock);
4020  out:
4021     return;
4022 }
4023 
4024 /* Set the enable state of a port. */
4025 void
setportenable(struct controller_info * cntlr,char * portspec,char * enable)4026 setportenable(struct controller_info *cntlr, char *portspec, char *enable)
4027 {
4028     port_info_t *port;
4029     int         new_enable;
4030     struct absout eout = { .out = cntrl_abserrout, .data = cntlr };
4031 
4032     port = find_port_by_num(portspec, false);
4033     if (port == NULL) {
4034 	controller_outputf(cntlr, "Invalid port number: %s\r\n", portspec);
4035 	goto out;
4036     }
4037 
4038     if (strcmp(enable, "off") == 0) {
4039 	new_enable = PORT_DISABLED;
4040     } else if (strcmp(enable, "raw") == 0) {
4041 	new_enable = PORT_RAW;
4042     } else if (strcmp(enable, "rawlp") == 0) {
4043 	new_enable = PORT_RAWLP;
4044     } else if (strcmp(enable, "telnet") == 0) {
4045 	new_enable = PORT_TELNET;
4046     } else {
4047 	controller_outputf(cntlr, "Invalid enable: %s\r\n", enable);
4048 	goto out_unlock;
4049     }
4050 
4051     change_port_state(&eout, port, new_enable, false); /* releases lock */
4052  out:
4053     return;
4054 
4055  out_unlock:
4056     UNLOCK(port->lock);
4057 }
4058 
4059 #if HAVE_DECL_TIOCSRS485
get_rs485_conf(void * data)4060 struct serial_rs485 *get_rs485_conf(void *data)
4061 {
4062     port_info_t *port = data;
4063 
4064     return port->rs485conf;
4065 }
4066 #endif
4067 
4068 /* Start data monitoring on the given port, type may be either "tcp" or
4069    "term" and only one direction may be monitored.  This return NULL if
4070    the monitor fails.  The monitor output will go to "fd". */
4071 void *
data_monitor_start(struct controller_info * cntlr,char * type,char * portspec)4072 data_monitor_start(struct controller_info *cntlr,
4073 		   char                   *type,
4074 		   char                   *portspec)
4075 {
4076     port_info_t *port;
4077 
4078     port = find_port_by_num(portspec, true);
4079     if (port == NULL) {
4080 	char *err = "Invalid port number: ";
4081 	controller_outs(cntlr, err);
4082 	controller_outs(cntlr, portspec);
4083 	controller_outs(cntlr, "\r\n");
4084 	goto out;
4085     }
4086 
4087     if ((port->net_monitor != NULL) || (port->dev_monitor != NULL)) {
4088 	char *err = "Port is already being monitored";
4089 	controller_outs(cntlr, err);
4090 	controller_outs(cntlr, "\r\n");
4091 	goto out_unlock;
4092     }
4093 
4094     if (strcmp(type, "tcp") == 0) {
4095 	port->net_monitor = cntlr;
4096     } else if (strcmp(type, "term") == 0) {
4097 	port->dev_monitor = cntlr;
4098     } else {
4099 	char *err = "invalid monitor type: ";
4100 	controller_outs(cntlr, err);
4101 	controller_outs(cntlr, type);
4102 	controller_outs(cntlr, "\r\n");
4103 	UNLOCK(port->lock);
4104 	port = NULL;
4105 	goto out;
4106     }
4107  out_unlock:
4108     UNLOCK(port->lock);
4109  out:
4110     return port;
4111 }
4112 
4113 /* Stop monitoring the given id. */
4114 void
data_monitor_stop(struct controller_info * cntlr,void * monitor_id)4115 data_monitor_stop(struct controller_info *cntlr,
4116 		  void                   *monitor_id)
4117 {
4118     port_info_t *port = (port_info_t *) monitor_id;
4119     port_info_t *curr;
4120 
4121     LOCK(ports_lock);
4122     curr = ports;
4123     while (curr) {
4124 	if (curr == port) {
4125 	    LOCK(port->lock);
4126 	    port->net_monitor = NULL;
4127 	    port->dev_monitor = NULL;
4128 	    UNLOCK(port->lock);
4129 	    break;
4130 	}
4131 	curr = curr->next;
4132     }
4133     UNLOCK(ports_lock);
4134 }
4135 
4136 void
disconnect_port(struct controller_info * cntlr,char * portspec)4137 disconnect_port(struct controller_info *cntlr,
4138 		char *portspec)
4139 {
4140     port_info_t *port;
4141 
4142     port = find_port_by_num(portspec, true);
4143     if (port == NULL) {
4144 	char *err = "Invalid port number: ";
4145 	controller_outs(cntlr, err);
4146 	controller_outs(cntlr, portspec);
4147 	controller_outs(cntlr, "\r\n");
4148 	goto out;
4149     } else if (port->net_to_dev_state == PORT_UNCONNECTED) {
4150 	char *err = "Port not connected: ";
4151 	controller_outs(cntlr, err);
4152 	controller_outs(cntlr, portspec);
4153 	controller_outs(cntlr, "\r\n");
4154 	goto out_unlock;
4155     }
4156 
4157     shutdown_port(port, "disconnect");
4158  out_unlock:
4159     UNLOCK(port->lock);
4160  out:
4161     return;
4162 }
4163 
4164 static int
com_port_will(void * cb_data)4165 com_port_will(void *cb_data)
4166 {
4167     net_info_t *netcon = cb_data;
4168     port_info_t *port = netcon->port;
4169     unsigned char data[3];
4170 
4171     if (! port->allow_2217)
4172 	return 0;
4173 
4174     /* The remote end turned on RFC2217 handling. */
4175     port->is_2217 = 1;
4176     port->linestate_mask = 0;
4177     port->modemstate_mask = 255;
4178     port->last_modemstate = 0;
4179 
4180     /* send a modemstate notify */
4181     data[0] = TN_OPT_COM_PORT;
4182     data[1] = 107; /* Notify modemstate */
4183     data[2] = 0;
4184     if (port->io.f->get_modem_state(&port->io, data + 2) != -1) {
4185 	port->last_modemstate = data[2];
4186     }
4187     telnet_send_option(&netcon->tn_data, data, 3);
4188     return 1;
4189 }
4190 
4191 static void
com_port_handler(void * cb_data,unsigned char * option,int len)4192 com_port_handler(void *cb_data, unsigned char *option, int len)
4193 {
4194     net_info_t *netcon = cb_data;
4195     port_info_t *port = netcon->port;
4196     unsigned char outopt[MAX_TELNET_CMD_XMIT_BUF];
4197     int val;
4198     unsigned char ucval;
4199     int cisco_ios_baud_rates = 0;
4200 
4201     if (len < 2)
4202 	return;
4203 
4204     switch (option[1]) {
4205     case 0: /* SIGNATURE? */
4206     {
4207 	/* truncate signature, if it exceeds buffer size */
4208 	char *sig = port->signaturestr;
4209 	int sign_len;
4210 
4211 	if (!sig)
4212 	    /* If not set, use a default. */
4213 	    sig = rfc2217_signature;
4214 
4215 	sign_len = strlen(sig);
4216 	if (sign_len > (MAX_TELNET_CMD_XMIT_BUF - 2))
4217 	    sign_len = MAX_TELNET_CMD_XMIT_BUF - 2;
4218 
4219 	outopt[0] = 44;
4220 	outopt[1] = 100;
4221 	strncpy((char *) outopt + 2, sig, sign_len);
4222 	telnet_send_option(&netcon->tn_data, outopt, 2 + sign_len);
4223 	break;
4224     }
4225 
4226     case 1: /* SET-BAUDRATE */
4227 	if (len == 3) {
4228 	    cisco_ios_baud_rates = 1;
4229 	    val = option[2];
4230 	} else {
4231 	    if (len < 6)
4232 		return;
4233 	    /* Basically the same as:
4234 	     *  val = ntohl(*((uint32_t *) (option + 2)));
4235 	     * but handled unaligned cases */
4236 	    val = option[2] << 24;
4237 	    val |= option[3] << 16;
4238 	    val |= option[4] << 8;
4239 	    val |= option[5];
4240 	}
4241 
4242 	port->io.f->baud_rate(&port->io, &val, cisco_ios_baud_rates,
4243 			      &port->bps);
4244 	recalc_port_chardelay(port);
4245 	outopt[0] = 44;
4246 	outopt[1] = 101;
4247 	if (cisco_ios_baud_rates) {
4248 	    outopt[2] = val;
4249 	    telnet_send_option(&netcon->tn_data, outopt, 3);
4250 	} else {
4251 	    /* Basically the same as:
4252 	     * *((uint32_t *) (outopt + 2)) = htonl(val);
4253 	     * but handles unaligned cases */
4254 	    outopt[2] = val >> 24;
4255 	    outopt[3] = val >> 16;
4256 	    outopt[4] = val >> 8;
4257 	    outopt[5] = val;
4258 	    telnet_send_option(&netcon->tn_data, outopt, 6);
4259 	}
4260 	break;
4261 
4262     case 2: /* SET-DATASIZE */
4263 	if (len < 3)
4264 	    return;
4265 
4266 	ucval = option[2];
4267 	port->io.f->data_size(&port->io, &ucval, &port->bpc);
4268 	recalc_port_chardelay(port);
4269 	outopt[0] = 44;
4270 	outopt[1] = 102;
4271 	outopt[2] = ucval;
4272 	telnet_send_option(&netcon->tn_data, outopt, 3);
4273 	break;
4274 
4275     case 3: /* SET-PARITY */
4276 	if (len < 3)
4277 	    return;
4278 
4279 	ucval = option[2];
4280 	port->io.f->parity(&port->io, &ucval, &port->bpc);
4281 	recalc_port_chardelay(port);
4282 	outopt[0] = 44;
4283 	outopt[1] = 103;
4284 	outopt[2] = ucval;
4285 	telnet_send_option(&netcon->tn_data, outopt, 3);
4286 	break;
4287 
4288     case 4: /* SET-STOPSIZE */
4289 	if (len < 3)
4290 	    return;
4291 
4292 	ucval = option[2];
4293 	port->io.f->stop_size(&port->io, &ucval, &port->bpc);
4294 	recalc_port_chardelay(port);
4295 	outopt[0] = 44;
4296 	outopt[1] = 104;
4297 	outopt[2] = ucval;
4298 	telnet_send_option(&netcon->tn_data, outopt, 3);
4299 	break;
4300 
4301     case 5: /* SET-CONTROL */
4302 	if (len < 3)
4303 	    return;
4304 
4305 	ucval = option[2];
4306 	port->io.f->control(&port->io, &ucval);
4307 	outopt[0] = 44;
4308 	outopt[1] = 105;
4309 	outopt[2] = ucval;
4310 	telnet_send_option(&netcon->tn_data, outopt, 3);
4311 	break;
4312 
4313     case 8: /* FLOWCONTROL-SUSPEND */
4314 	port->io.f->flow_control(&port->io, 1);
4315 	outopt[0] = 44;
4316 	outopt[1] = 108;
4317 	telnet_send_option(&netcon->tn_data, outopt, 2);
4318 	break;
4319 
4320     case 9: /* FLOWCONTROL-RESUME */
4321 	port->io.f->flow_control(&port->io, 0);
4322 	outopt[0] = 44;
4323 	outopt[1] = 109;
4324 	telnet_send_option(&netcon->tn_data, outopt, 2);
4325 	break;
4326 
4327     case 10: /* SET-LINESTATE-MASK */
4328 	if (len < 3)
4329 	    return;
4330 	port->linestate_mask = option[2];
4331 	outopt[0] = 44;
4332 	outopt[1] = 110;
4333 	outopt[2] = port->linestate_mask;
4334 	telnet_send_option(&netcon->tn_data, outopt, 3);
4335 	break;
4336 
4337     case 11: /* SET-MODEMSTATE-MASK */
4338 	if (len < 3)
4339 	    return;
4340 	port->modemstate_mask = option[2];
4341 	outopt[0] = 44;
4342 	outopt[1] = 111;
4343 	outopt[2] = port->modemstate_mask;
4344 	telnet_send_option(&netcon->tn_data, outopt, 3);
4345 	break;
4346 
4347     case 12: /* PURGE_DATA */
4348 	if (len < 3)
4349 	    return;
4350 	val = option[2];
4351 	port->io.f->flush(&port->io, &val);
4352 	outopt[0] = 44;
4353 	outopt[1] = 112;
4354 	outopt[2] = val;
4355 	telnet_send_option(&netcon->tn_data, outopt, 3);
4356 	break;
4357 
4358     case 6: /* NOTIFY-LINESTATE */
4359     case 7: /* NOTIFY-MODEMSTATE */
4360     default:
4361 	break;
4362     }
4363 }
4364 
4365 void
shutdown_ports(void)4366 shutdown_ports(void)
4367 {
4368     port_info_t *port = ports, *next;
4369 
4370     /* No need for a lock here, nothing can reconfigure the port list at
4371        this point. */
4372     while (port != NULL) {
4373 	port->config_num = -1;
4374 	next = port->next;
4375 	LOCK(port->lock);
4376 	change_port_state(NULL, port, PORT_DISABLED, false);
4377 	LOCK(port->lock);
4378 	shutdown_port(port, "program shutdown");
4379 	UNLOCK(port->lock);
4380 	port = next;
4381     }
4382 }
4383 
4384 int
check_ports_shutdown(void)4385 check_ports_shutdown(void)
4386 {
4387     return ports == NULL;
4388 }
4389