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