📄 dataxfer.c
字号:
voidsetportdevcfg(struct controller_info *cntlr, char *portspec, char *devcfg){ port_info_t *port; port = find_port_by_num(portspec); if (port == NULL) { char *err = "Invalid port number: "; controller_output(cntlr, err, strlen(err)); controller_output(cntlr, portspec, strlen(portspec)); controller_output(cntlr, "\n\r", 2); } else { if (devconfig(devcfg, &(port->termctl), &port->allow_2217, &port->banner) == -1) { char *err = "Invalid device config\n\r"; controller_output(cntlr, err, strlen(err)); } }}/* Modify the controls of a port. The port number and configuration are passed in as strings, this code will get the port and then call the code to control the device. */voidsetportcontrol(struct controller_info *cntlr, char *portspec, char *controls){ port_info_t *port; port = find_port_by_num(portspec); if (port == NULL) { char *err = "Invalid port number: "; controller_output(cntlr, err, strlen(err)); controller_output(cntlr, portspec, strlen(portspec)); controller_output(cntlr, "\n\r", 2); } else if (port->tcp_to_dev_state == PORT_UNCONNECTED) { char *err = "Port is not currently connected: "; controller_output(cntlr, err, strlen(err)); controller_output(cntlr, portspec, strlen(portspec)); controller_output(cntlr, "\n\r", 2); } else { if (setdevcontrol(controls, port->devfd) == -1) { char *err = "Invalid device controls\n\r"; controller_output(cntlr, err, strlen(err)); } }}/* Set the enable state of a port. */voidsetportenable(struct controller_info *cntlr, char *portspec, char *enable){ port_info_t *port; int new_enable; char *err; port = find_port_by_num(portspec); if (port == NULL) { err = "Invalid port number: "; controller_output(cntlr, err, strlen(err)); controller_output(cntlr, portspec, strlen(portspec)); controller_output(cntlr, "\n\r", 2); return; } if (strcmp(enable, "off") == 0) { new_enable = PORT_DISABLED; } else if (strcmp(enable, "raw") == 0) { new_enable = PORT_RAW; } else if (strcmp(enable, "rawlp") == 0) { new_enable = PORT_RAWLP; } else if (strcmp(enable, "telnet") == 0) { new_enable = PORT_TELNET; } else { err = "Invalid enable: "; controller_output(cntlr, err, strlen(err)); controller_output(cntlr, enable, strlen(enable)); controller_output(cntlr, "\n\r", 2); return; } err = change_port_state(port, new_enable); if (err != NULL) { controller_output(cntlr, err, strlen(err)); controller_output(cntlr, "\n\r", 2); }}/* Start data monitoring on the given port, type may be either "tcp" or "term" and only one direction may be monitored. This return NULL if the monitor fails. The monitor output will go to "fd". */void *data_monitor_start(struct controller_info *cntlr, char *type, char *portspec){ port_info_t *port; port = find_port_by_num(portspec); if (port == NULL) { char *err = "Invalid port number: "; controller_output(cntlr, err, strlen(err)); controller_output(cntlr, portspec, strlen(portspec)); controller_output(cntlr, "\n\r", 2); return NULL; } if ((port->tcp_monitor != NULL) || (port->dev_monitor != NULL)) { char *err = "Port is already being monitored"; controller_output(cntlr, err, strlen(err)); controller_output(cntlr, "\n\r", 2); return NULL; } if (strcmp(type, "tcp") == 0) { port->tcp_monitor = cntlr; return port; } else if (strcmp(type, "term") == 0) { port->dev_monitor = cntlr; return port; } else { char *err = "invalid monitor type: "; controller_output(cntlr, err, strlen(err)); controller_output(cntlr, type, strlen(type)); controller_output(cntlr, "\n\r", 2); return NULL; }}/* Stop monitoring the given id. */voiddata_monitor_stop(struct controller_info *cntlr, void *monitor_id){ port_info_t *port = (port_info_t *) monitor_id; port->tcp_monitor = NULL; port->dev_monitor = NULL;}voiddisconnect_port(struct controller_info *cntlr, char *portspec){ port_info_t *port; port = find_port_by_num(portspec); if (port == NULL) { char *err = "Invalid port number: "; controller_output(cntlr, err, strlen(err)); controller_output(cntlr, portspec, strlen(portspec)); controller_output(cntlr, "\n\r", 2); return; } shutdown_port(port, "disconnect");}static struct baud_rates_s { int real_rate; int val; int cisco_ios_val;} baud_rates[] ={ { 50, B50, -1 }, { 75, B75, -1 }, { 110, B110, -1 }, { 134, B134, -1 }, { 150, B150, -1 }, { 200, B200, -1 }, { 300, B300, 3 }, { 600, B600 , 4}, { 1200, B1200, 5 }, { 1800, B1800, -1 }, { 2400, B2400, 6 }, { 4800, B4800, 7 }, { 9600, B9600, 8 }, /* We don't support 14400 baud */ { 19200, B19200, 10 }, /* We don't support 28800 baud */ { 38400, B38400, 12 }, { 57600, B57600, 13 }, { 115200, B115200, 14 }, { 230400, B230400, 15 }, /* We don't support 460800 baud */};#define BAUD_RATES_LEN ((sizeof(baud_rates) / sizeof(struct baud_rates_s)))intget_baud_rate(int rate, int *val){ int i; for (i=0; i<BAUD_RATES_LEN; i++) { if (cisco_ios_baud_rates) { if (rate == baud_rates[i].cisco_ios_val) { *val = baud_rates[i].val; return 1; } } else { if (rate == baud_rates[i].real_rate) { *val = baud_rates[i].val; return 1; } } } return 0;}voidget_rate_from_baud_rate(int baud_rate, int *val){ int i; for (i=0; i<BAUD_RATES_LEN; i++) { if (baud_rate == baud_rates[i].val) { if (cisco_ios_baud_rates) { if (baud_rates[i].cisco_ios_val < 0) /* We are at a baud rate unsopported by the enumeration, just return zero. */ *val = 0; else *val = baud_rates[i].cisco_ios_val; } else { *val = baud_rates[i].real_rate; } return; } }}static intcom_port_will(void *cb_data){ port_info_t *port = cb_data; unsigned char data[3]; int val; if (! port->allow_2217) return 0; /* The remote end turned on RFC2217 handling. */ port->is_2217 = 1; port->linestate_mask = 0; port->modemstate_mask = 255; port->last_modemstate = 0; /* send a modemstate notify */ data[0] = TN_OPT_COM_PORT; data[1] = 7; /* Notify modemstate */ data[2] = 0; if (ioctl(port->devfd, TIOCMGET, &val) != -1) { if (val & TIOCM_CD) data[2] |= 0x80; if (val & TIOCM_RI) data[2] |= 0x40; if (val & TIOCM_DSR) data[2] |= 0x20; if (val & TIOCM_CTS) data[2] |= 0x10; port->last_modemstate = data[2]; } telnet_send_option(&port->tn_data, data, 3); return 1;}static voidcom_port_handler(void *cb_data, unsigned char *option, int len){ port_info_t *port = cb_data; char outopt[16]; struct termios termio; int val; if (len < 2) return; switch (option[1]) { case 0: /* SIGNATURE? */ outopt[0] = 44; outopt[1] = 0; strcpy(outopt+2, "ser2net"); telnet_send_option(&port->tn_data, outopt, 9); break; case 1: /* SET-BAUDRATE */ if (cisco_ios_baud_rates) { if (len < 3) return; val = option[2]; } else { if (len < 6) return; val = ntohl(*((uint32_t *) (option+2))); } if (tcgetattr(port->devfd, &termio) != -1) { if ((val != 0) && (get_baud_rate(val, &val))) { /* We have a valid baud rate. */ cfsetispeed(&termio, val); cfsetospeed(&termio, val); tcsetattr(port->devfd, TCSANOW, &termio); } tcgetattr(port->devfd, &termio); val = cfgetispeed(&termio); } else { val = 0; } get_rate_from_baud_rate(val, &val); outopt[0] = 44; outopt[1] = 101; if (cisco_ios_baud_rates) { outopt[2] = val; telnet_send_option(&port->tn_data, outopt, 3); } else { *((uint32_t *) (outopt+2)) = htonl(val); telnet_send_option(&port->tn_data, outopt, 6); } break; case 2: /* SET-DATASIZE */ if (len < 3) return; val = 0; if (tcgetattr(port->devfd, &termio) != -1) { if ((option[2] >= 5) && (option[2] <= 8)) { val = option[2]; termio.c_cflag &= ~CSIZE; switch (val) { case 5: termio.c_cflag |= CS5; break; case 6: termio.c_cflag |= CS6; break; case 7: termio.c_cflag |= CS7; break; case 8: termio.c_cflag |= CS8; break; } tcsetattr(port->devfd, TCSANOW, &termio); } switch (termio.c_cflag & CSIZE) { case CS5: val = 5; break; case CS6: val = 6; break; case CS7: val = 7; break; case CS8: val = 8; break; } } outopt[0] = 44; outopt[1] = 102; outopt[2] = val; telnet_send_option(&port->tn_data, outopt, 3); break; case 3: /* SET-PARITY */ if (len < 3) return; val = 0; if (tcgetattr(port->devfd, &termio) != -1) { /* We don't support MARK or SPACE parity. */ if ((option[2] >= 1) && (option[2] <= 3)) { val = option[2]; termio.c_cflag &= ~(PARENB | PARODD); switch (val) { case 1: break; /* NONE */ case 2: termio.c_cflag |= PARENB | PARODD; break; /* ODD */ case 3: termio.c_cflag |= PARENB; break; /* EVEN */ } tcsetattr(port->devfd, TCSANOW, &termio); } if (termio.c_cflag & PARENB) { if (termio.c_cflag & PARODD) val = 2; /* ODD */ else val = 3; /* EVEN */ } else val = 1; /* NONE */ } outopt[0] = 44; outopt[1] = 103; outopt[2] = val; telnet_send_option(&port->tn_data, outopt, 3); break; case 4: /* SET-STOPSIZE */ if (len < 3) return; val = 0; if (tcgetattr(port->devfd, &termio) != -1) { /* We don't support 1.5 stop bits. */ if ((option[2] == 1) || (option[2] == 3)) { val = option[2]; termio.c_cflag &= ~CSTOPB; switch (val) { case 1: break; /* 1 stop bit */ case 3: termio.c_cflag |= CSTOPB; break; /* 2 stop bits */ } tcsetattr(port->devfd, TCSANOW, &termio); } if (termio.c_cflag & CSTOPB) val = 3; /* 2 stop bits. */ else val = 1; /* 1 stop bit. */ } outopt[0] = 44; outopt[1] = 104; outopt[2] = val; telnet_send_option(&port->tn_data, outopt, 3); break; case 5: /* SET-CONTROL */ if (len < 3) return; val = 0; switch (option[2]) { case 0: case 1: case 2: case 3: /* Outbound/both flow control */ if (tcgetattr(port->devfd, &termio) != -1) { if (option[2] != 0) { val = option[2]; termio.c_iflag &= ~(IXON | IXOFF); termio.c_cflag &= ~CRTSCTS; switch (val) { case 1: break; /* NONE */ case 2: termio.c_iflag |= IXON | IXOFF; break; case 3: termio.c_cflag |= CRTSCTS; break; } tcsetattr(port->devfd, TCSANOW, &termio); } if (termio.c_cflag & CRTSCTS) val = 3; else if (termio.c_iflag & IXON) val = 2; else val = 1; } break; case 13: case 14: case 15: case 16: case 17: case 18: case 19: /* Inbound flow-control */ if (tcgetattr(port->devfd, &termio) != -1) { if (option[2] == 15) { /* We can only set XON/XOFF independently */ termio.c_iflag |= IXOFF; tcsetattr(port->devfd, TCSANOW, &termio); } if (termio.c_cflag & CRTSCTS) val = 16; else if (termio.c_iflag & IXOFF) val = 15; else val = 14; } break; /* Handle BREAK stuff. */ case 6: if (ioctl(port->devfd, TIOCCBRK) != -1) port->break_set = 0; goto read_break_val; case 5: if (ioctl(port->devfd, TIOCSBRK) != -1) port->break_set = 1; goto read_break_val; case 4: read_break_val: if (port->break_set) val = 5; else val = 6; break; /* DTR handling */ case 8: val = TIOCM_DTR; ioctl(port->devfd, TIOCMBIS, &val); goto read_dtr_val; case 9: val = TIOCM_DTR; ioctl(port->devfd, TIOCMBIC, &val); goto read_dtr_val; case 7: read_dtr_val: if (ioctl(port->devfd, TIOCMGET, &val) == -1) val = 7; else if (val & TIOCM_DTR) val = 8; else val = 9; /* RTS handling */ case 11: val = TIOCM_RTS; ioctl(port->devfd, TIOCMBIS, &val); goto read_rts_val; case 12: val = TIOCM_RTS; ioctl(port->devfd, TIOCMBIC, &val); goto read_rts_val; case 10: read_rts_val: if (ioctl(port->devfd, TIOCMGET, &val) == -1) val = 10; else if (val & TIOCM_RTS) val = 11; else val = 12; } outopt[0] = 44; outopt[1] = 105; outopt[2] = val; telnet_send_option(&port->tn_data, outopt, 3); break; case 8: /* FLOWCONTROL-SUSPEND */ tcflow(port->devfd, TCIOFF); break; case 9: /* FLOWCONTROL-RESUME */ tcflow(port->devfd, TCION); break; case 10: /* SET-LINESTATE-MASK */ if (len < 3) return; port->linestate_mask = option[2]; break; case 11: /* SET-MODEMSTATE-MASK */ if (len < 3) return; port->modemstate_mask = option[2]; break; case 12: /* PURGE_DATA */ if (len < 3) return; switch (option[2]) { case 1: val = TCIFLUSH; goto purge_found; case 2: val = TCOFLUSH; goto purge_found; case 3: val = TCIOFLUSH; goto purge_found; } break; purge_found: tcflush(port->devfd, val); break; case 6: /* NOTIFY-LINESTATE */ case 7: /* NOTIFY-MODEMSTATE */ default: break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -