33 #define WIRESHARK_IMPORT_FORMAT 1 41 #include <sys/types.h> 47 #include <sys/ioctl.h> 48 #include <sys/socket.h> 49 #include <netinet/in.h> 50 #include <arpa/inet.h> 59 extern int slip_config_verbose;
60 extern int slip_config_flowcontrol;
61 extern const char *slip_config_siodev;
62 extern const char *slip_config_host;
63 extern const char *slip_config_port;
64 extern uint16_t slip_config_basedelay;
65 extern speed_t slip_config_b_rate;
67 #ifdef SLIP_DEV_CONF_SEND_DELAY 68 #define SEND_DELAY SLIP_DEV_CONF_SEND_DELAY 73 int devopen(
const char *dev,
int flags);
79 long slip_received = 0;
83 #define PROGRESS(s) do { } while(0) 87 #define SLIP_ESC_END 0334 88 #define SLIP_ESC_ESC 0335 92 get_in_addr(
struct sockaddr *sa)
94 if(sa->sa_family == AF_INET) {
95 return &(((
struct sockaddr_in *)sa)->sin_addr);
97 return &(((
struct sockaddr_in6 *)sa)->sin6_addr);
101 connect_to_server(
const char *host,
const char *port)
104 struct addrinfo hints, *servinfo, *p;
105 char s[INET6_ADDRSTRLEN];
108 memset(&hints, 0,
sizeof hints);
109 hints.ai_family = AF_UNSPEC;
110 hints.ai_socktype = SOCK_STREAM;
112 if((rv = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
113 err(1,
"getaddrinfo: %s", gai_strerror(rv));
118 for(p = servinfo; p != NULL; p = p->ai_next) {
119 if((fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
120 perror(
"client: socket");
124 if(connect(fd, p->ai_addr, p->ai_addrlen) == -1) {
126 perror(
"client: connect");
133 err(1,
"can't connect to ``%s:%s''", host, port);
137 fcntl(fd, F_SETFL, O_NONBLOCK);
139 inet_ntop(p->ai_family, get_in_addr((
struct sockaddr *)p->ai_addr),
143 freeaddrinfo(servinfo);
148 is_sensible_string(
const unsigned char *s,
int len)
151 for(i = 1; i < len; i++) {
152 if(s[i] == 0 || s[i] ==
'\r' || s[i] ==
'\n' || s[i] ==
'\t') {
154 }
else if(s[i] <
' ' ||
'~' < s[i]) {
162 slip_packet_input(
unsigned char *data,
int len)
165 if(slip_config_verbose > 0) {
166 printf(
"Packet input over SLIP: %d\n", len);
168 NETSTACK_MAC.
input();
176 serial_input(FILE *inslip)
178 static unsigned char inbuf[2048];
179 static int inbufptr = 0;
184 ret = fread(&c, 1, 1, inslip);
185 if(ret == -1 || ret == 0) {
186 err(1,
"serial_input: read");
192 if(inbufptr >=
sizeof(inbuf)) {
193 fprintf(stderr,
"*** dropping large %d byte packet\n", inbufptr);
196 ret = fread(&c, 1, 1, inslip);
201 err(1,
"serial_input: read");
211 if(inbuf[0] ==
'!') {
212 command_context = CMD_CONTEXT_RADIO;
213 cmd_input(inbuf, inbufptr);
214 }
else if(inbuf[0] ==
'?') {
215 #define DEBUG_LINE_MARKER '\r' 216 }
else if(inbuf[0] == DEBUG_LINE_MARKER) {
217 fwrite(inbuf + 1, inbufptr - 1, 1, stdout);
218 }
else if(is_sensible_string(inbuf, inbufptr)) {
219 if(slip_config_verbose == 1) {
220 fwrite(inbuf, inbufptr, 1, stdout);
223 if(slip_config_verbose > 2) {
224 printf(
"Packet from SLIP of length %d - write TUN\n", inbufptr);
225 if(slip_config_verbose > 4) {
226 #if WIRESHARK_IMPORT_FORMAT 228 for(i = 0; i < inbufptr; i++) {
229 printf(
" %02x", inbuf[i]);
233 for(i = 0; i < inbufptr; i++) {
234 printf(
"%02x", inbuf[i]);
246 slip_packet_input(inbuf, inbufptr);
253 if(fread(&c, 1, 1, inslip) != 1) {
256 ungetc(SLIP_ESC, inslip);
270 inbuf[inbufptr++] = c;
274 if(slip_config_verbose == 4) {
275 if(c == 0 || c ==
'\r' || c ==
'\n' || c ==
'\t' || (c >=
' ' && c <=
'~')) {
276 fwrite(&c, 1, 1, stdout);
278 }
else if(slip_config_verbose >= 2) {
279 if(c ==
'\n' && is_sensible_string(inbuf, inbufptr)) {
280 fwrite(inbuf, inbufptr, 1, stdout);
289 unsigned char slip_buf[2048];
290 int slip_end, slip_begin, slip_packet_end, slip_packet_count;
291 static struct timer send_delay_timer;
293 static clock_time_t send_delay = SEND_DELAY;
298 if(slip_end >=
sizeof(slip_buf)) {
299 err(1,
"slip_send overflow");
301 slip_buf[slip_end] = c;
307 if(slip_packet_end == 0) {
308 slip_packet_end = slip_end;
316 return slip_packet_end == 0;
320 slip_flushbuf(
int fd)
328 n = write(fd, slip_buf + slip_begin, slip_packet_end - slip_begin);
330 if(n == -1 && errno != EAGAIN) {
331 err(1,
"slip_flushbuf write failed");
336 if(slip_begin == slip_packet_end) {
338 if(slip_end > slip_packet_end) {
339 memmove(slip_buf, slip_buf + slip_packet_end,
340 slip_end - slip_packet_end);
342 slip_end -= slip_packet_end;
343 slip_begin = slip_packet_end = 0;
346 for(n = 1; n < slip_end; n++) {
347 if(slip_buf[n] == SLIP_END) {
348 slip_packet_end = n + 1;
354 timer_set(&send_delay_timer, send_delay);
362 write_to_serial(
int outfd,
const uint8_t *inbuf,
int len)
364 const uint8_t *p = inbuf;
367 if(slip_config_verbose > 2) {
369 printf(
"Packet from WPCAP of length %d - write SLIP\n", len);
371 printf(
"Packet from TUN of length %d - write SLIP\n", len);
373 if(slip_config_verbose > 4) {
374 #if WIRESHARK_IMPORT_FORMAT 376 for(i = 0; i < len; i++) {
377 printf(
" %02x", p[i]);
381 for(i = 0; i < len; i++) {
382 printf(
"%02x", p[i]);
400 for(i = 0; i < len; i++) {
421 write_to_slip(
const uint8_t *buf,
int len)
424 write_to_serial(slipfd, buf, len);
432 speed_t speed = slip_config_b_rate;
435 if(tcflush(fd, TCIOFLUSH) == -1) {
439 if(tcgetattr(fd, &tty) == -1) {
448 if(slip_config_flowcontrol) {
449 tty.c_cflag |= CRTSCTS;
451 tty.c_cflag &= ~CRTSCTS;
453 tty.c_cflag &= ~HUPCL;
454 tty.c_cflag &= ~CLOCAL;
456 cfsetispeed(&tty, speed);
457 cfsetospeed(&tty, speed);
459 if(tcsetattr(fd, TCSAFLUSH, &tty) == -1) {
467 tty.c_cflag |= CLOCAL;
468 if(tcsetattr(fd, TCSAFLUSH, &tty) == -1) {
473 if(ioctl(fd, TIOCMBIS, &i) == -1) {
481 if(tcflush(fd, TCIOFLUSH) == -1) {
487 set_fd(fd_set *rset, fd_set *wset)
490 if(!slip_empty() && (send_delay == 0 ||
timer_expired(&send_delay_timer))) {
491 FD_SET(slipfd, wset);
494 FD_SET(slipfd, rset);
499 handle_fd(fd_set *rset, fd_set *wset)
501 if(FD_ISSET(slipfd, rset)) {
502 serial_input(inslip);
505 if(FD_ISSET(slipfd, wset)) {
506 slip_flushbuf(slipfd);
510 static const struct select_callback slip_callback = { set_fd, handle_fd };
515 setvbuf(stdout, NULL, _IOLBF, 0);
517 if(slip_config_host != NULL) {
518 if(slip_config_port == NULL) {
519 slip_config_port =
"60001";
521 slipfd = connect_to_server(slip_config_host, slip_config_port);
523 err(1,
"can't connect to ``%s:%s''", slip_config_host, slip_config_port);
525 }
else if(slip_config_siodev != NULL) {
526 if(strcmp(slip_config_siodev,
"null") == 0) {
530 slipfd = devopen(slip_config_siodev, O_RDWR | O_NONBLOCK);
532 err(1,
"can't open siodev ``/dev/%s''", slip_config_siodev);
535 static const char *siodevs[] = {
536 "ttyUSB0",
"cuaU0",
"ucom0" 539 for(i = 0; i < 3; i++) {
540 slip_config_siodev = siodevs[i];
541 slipfd = devopen(slip_config_siodev, O_RDWR | O_NONBLOCK);
547 err(1,
"can't open siodev");
551 select_set_callback(slipfd, &slip_callback);
553 if(slip_config_host != NULL) {
554 fprintf(stderr,
"********SLIP opened to ``%s:%s''\n", slip_config_host,
557 fprintf(stderr,
"********SLIP started on ``/dev/%s''\n", slip_config_siodev);
563 inslip = fdopen(slipfd,
"r");
565 err(1,
"slip_init: fdopen");
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
void(* input)(void)
Callback for getting notified of incoming packet.
int timer_expired(struct timer *t)
Check if a timer has expired.
int packetbuf_copyfrom(const void *from, uint16_t len)
Copy from external data into the packetbuf.
Sets up some commands for the border router
Header file for the Packet buffer (packetbuf) management
Include file for the Contiki low-layer network stack (NETSTACK)