1/* $NetBSD: if_strip.c,v 1.95 2010/04/05 07:22:24 joerg Exp $ */ 2/* from: NetBSD: if_sl.c,v 1.38 1996/02/13 22:00:23 christos Exp $ */ 3 4/* 5 * Copyright 1996 The Board of Trustees of The Leland Stanford 6 * Junior University. All Rights Reserved. 7 * 8 * Permission to use, copy, modify, and distribute this 9 * software and its documentation for any purpose and without 10 * fee is hereby granted, provided that the above copyright 11 * notice appear in all copies. Stanford University 12 * makes no representations about the suitability of this 13 * software for any purpose. It is provided "as is" without 14 * express or implied warranty. 15 * 16 * 17 * This driver was contributed by Jonathan Stone. 18 * 19 * Starmode Radio IP interface (STRIP) for Metricom wireless radio. 20 * This STRIP driver assumes address resolution of IP addresses to 21 * Metricom MAC addresses is done via local link-level routes. 22 * The link-level addresses are entered as an 8-digit packed BCD number. 23 * To add a route for a radio at IP address 10.1.2.3, with radio 24 * address '1234-5678', reachable via interface strip0, use the command 25 * 26 * route add -host 10.1.2.3 -link strip0:12:34:56:78 27 */ 28 29 30/* 31 * Copyright (c) 1987, 1989, 1992, 1993 32 * The Regents of the University of California. All rights reserved. 33 * 34 * Redistribution and use in source and binary forms, with or without 35 * modification, are permitted provided that the following conditions 36 * are met: 37 * 1. Redistributions of source code must retain the above copyright 38 * notice, this list of conditions and the following disclaimer. 39 * 2. Redistributions in binary form must reproduce the above copyright 40 * notice, this list of conditions and the following disclaimer in the 41 * documentation and/or other materials provided with the distribution. 42 * 3. Neither the name of the University nor the names of its contributors 43 * may be used to endorse or promote products derived from this software 44 * without specific prior written permission. 45 * 46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 56 * SUCH DAMAGE. 57 * 58 * @(#)if_sl.c 8.6 (Berkeley) 2/1/94 59 */ 60 61/* 62 * Derived from: Serial Line interface written by Rick Adams (rick@seismo.gov) 63 * 64 * Rick Adams 65 * Center for Seismic Studies 66 * 1300 N 17th Street, Suite 1450 67 * Arlington, Virginia 22209 68 * (703)276-7900 69 * rick@seismo.ARPA 70 * seismo!rick 71 * 72 * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris). 73 * N.B.: this belongs in netinet, not net, the way it stands now. 74 * Should have a link-layer type designation, but wouldn't be 75 * backwards-compatible. 76 * 77 * Converted to 4.3BSD Beta by Chris Torek. 78 * Other changes made at Berkeley, based in part on code by Kirk Smith. 79 * W. Jolitz added slip abort. 80 * 81 * Hacked almost beyond recognition by Van Jacobson (van@helios.ee.lbl.gov). 82 * Added priority queuing for "interactive" traffic; hooks for TCP 83 * header compression; ICMP filtering (at 2400 baud, some cretin 84 * pinging you can use up all your bandwidth). Made low clist behavior 85 * more robust and slightly less likely to hang serial line. 86 * Sped up a bunch of things. 87 */ 88 89#include <sys/cdefs.h> 90__KERNEL_RCSID(0, "$NetBSD: if_strip.c,v 1.95 2010/04/05 07:22:24 joerg Exp $"); 91 92#include "opt_inet.h" 93 94#include <sys/param.h> 95#include <sys/proc.h> 96#include <sys/mbuf.h> 97#include <sys/buf.h> 98#include <sys/dkstat.h> 99#include <sys/socket.h> 100#include <sys/ioctl.h> 101#include <sys/file.h> 102#include <sys/conf.h> 103#include <sys/tty.h> 104#include <sys/kernel.h> 105#if __NetBSD__ 106#include <sys/systm.h> 107#include <sys/callout.h> 108#include <sys/kauth.h> 109#endif 110#include <sys/syslog.h> 111#include <sys/cpu.h> 112#include <sys/intr.h> 113#include <sys/socketvar.h> 114 115#include <net/if.h> 116#include <net/if_dl.h> 117#include <net/if_types.h> 118#include <net/netisr.h> 119#include <net/route.h> 120 121#ifdef INET 122#include <netinet/in.h> 123#include <netinet/in_systm.h> 124#include <netinet/in_var.h> 125#include <netinet/ip.h> 126#endif 127 128#include <net/slcompress.h> 129#include <net/if_stripvar.h> 130#include <net/slip.h> 131 132#ifdef __NetBSD__ /* XXX -- jrs */ 133typedef u_char ttychar_t; 134#else 135typedef char ttychar_t; 136#endif 137 138#include <sys/time.h> 139#include <net/bpf.h> 140 141/* 142 * SLMAX is a hard limit on input packet size. To simplify the code 143 * and improve performance, we require that packets fit in an mbuf 144 * cluster, and if we get a compressed packet, there's enough extra 145 * room to expand the header into a max length tcp/ip header (128 146 * bytes). So, SLMAX can be at most 147 * MCLBYTES - 128 148 * 149 * SLMTU is a hard limit on output packet size. To insure good 150 * interactive response, SLMTU wants to be the smallest size that 151 * amortizes the header cost. Remember that even with 152 * type-of-service queuing, we have to wait for any in-progress 153 * packet to finish. I.e., we wait, on the average, 1/2 * mtu / 154 * cps, where cps is the line speed in characters per second. 155 * E.g., 533ms wait for a 1024 byte MTU on a 9600 baud line. The 156 * average compressed header size is 6-8 bytes so any MTU > 90 157 * bytes will give us 90% of the line bandwidth. A 100ms wait is 158 * tolerable (500ms is not), so want an MTU around 296. (Since TCP 159 * will send 256 byte segments (to allow for 40 byte headers), the 160 * typical packet size on the wire will be around 260 bytes). In 161 * 4.3tahoe+ systems, we can set an MTU in a route so we do that & 162 * leave the interface MTU relatively high (so we don't IP fragment 163 * when acting as a gateway to someone using a stupid MTU). 164 * 165 * Similar considerations apply to SLIP_HIWAT: It's the amount of 166 * data that will be queued 'downstream' of us (i.e., in clists 167 * waiting to be picked up by the tty output interrupt). If we 168 * queue a lot of data downstream, it's immune to our t.o.s. queuing. 169 * E.g., if SLIP_HIWAT is 1024, the interactive traffic in mixed 170 * telnet/ftp will see a 1 sec wait, independent of the mtu (the 171 * wait is dependent on the ftp window size but that's typically 172 * 1k - 4k). So, we want SLIP_HIWAT just big enough to amortize 173 * the cost (in idle time on the wire) of the tty driver running 174 * off the end of its clists & having to call back slstart for a 175 * new packet. For a tty interface with any buffering at all, this 176 * cost will be zero. Even with a totally brain dead interface (like 177 * the one on a typical workstation), the cost will be <= 1 character 178 * time. So, setting SLIP_HIWAT to ~100 guarantees that we'll lose 179 * at most 1% while maintaining good interactive response. 180 */ 181#define BUFOFFSET (128+sizeof(struct ifnet **)+SLIP_HDRLEN) 182#define SLMAX (MCLBYTES - BUFOFFSET) 183#define SLBUFSIZE (SLMAX + BUFOFFSET) 184#define SLMTU 1100 /* XXX -- appromaximated. 1024 may be safer. */ 185 186#define STRIP_MTU_ONWIRE (SLMTU + 20 + STRIP_HDRLEN) /* (2*SLMTU+2 in sl.c */ 187 188 189#define SLIP_HIWAT roundup(50, TTROUND) 190 191/* This is a NetBSD-1.0 or later kernel. */ 192#define CCOUNT(q) ((q)->c_cc) 193 194 195#ifndef __NetBSD__ /* XXX - cgd */ 196#define CLISTRESERVE 1024 /* Can't let clists get too low */ 197#endif /* !__NetBSD__ */ 198 199/* 200 * SLIP ABORT ESCAPE MECHANISM: 201 * (inspired by HAYES modem escape arrangement) 202 * 1sec escape 1sec escape 1sec escape { 1sec escape 1sec escape } 203 * within window time signals a "soft" exit from slip mode by remote end 204 * if the IFF_DEBUG flag is on. 205 */ 206#define ABT_ESC '\033' /* can't be t_intr - distant host must know it*/ 207#define ABT_IDLE 1 /* in seconds - idle before an escape */ 208#define ABT_COUNT 3 /* count of escapes for abort */ 209#define ABT_WINDOW (ABT_COUNT*2+2) /* in seconds - time to count */ 210 211static int strip_clone_create(struct if_clone *, int); 212static int strip_clone_destroy(struct ifnet *); 213 214static LIST_HEAD(, strip_softc) strip_softc_list; 215 216struct if_clone strip_cloner = 217 IF_CLONE_INITIALIZER("strip", strip_clone_create, strip_clone_destroy); 218 219#define STRIP_FRAME_END 0x0D /* carriage return */ 220 221static void stripintr(void *); 222 223static int stripinit(struct strip_softc *); 224static struct mbuf *strip_btom(struct strip_softc *, int); 225 226/* 227 * STRIP header: '*' + modem address (dddd-dddd) + '*' + mactype ('SIP0') 228 * A Metricom packet looks like this: *<address>*<key><payload><CR> 229 * eg. *0000-1164*SIP0<payload><CR> 230 * 231 */ 232 233#define STRIP_ENCAP_SIZE(X) ((36) + (X)*65/64 + 2) 234#define STRIP_HDRLEN 15 235#define STRIP_MAC_ADDR_LEN 9 236 237/* 238 * Star mode packet header. 239 * (may be used for encapsulations other than STRIP.) 240 */ 241#define STARMODE_ADDR_LEN 11 242struct st_header { 243 u_char starmode_addr[STARMODE_ADDR_LEN]; 244 u_char starmode_type[4]; 245}; 246 247/* 248 * Forward declarations for Metricom-specific functions. 249 * Ideally, these would be in a library and shared across 250 * different STRIP implementations: *BSD, Linux, etc. 251 * 252 */ 253static u_char* UnStuffData(u_char *src, u_char *end, u_char 254 *dest, u_long dest_length); 255 256static u_char* StuffData(u_char *src, u_long length, u_char *dest, 257 u_char **code_ptr_ptr); 258 259static void RecvErr(const char *msg, struct strip_softc *sc); 260static void RecvErr_Message(struct strip_softc *strip_info, 261 u_char *sendername, const u_char *msg); 262void strip_resetradio(struct strip_softc *sc, struct tty *tp); 263void strip_proberadio(struct strip_softc *sc, struct tty *tp); 264void strip_watchdog(struct ifnet *ifp); 265void strip_sendbody(struct strip_softc *sc, struct mbuf *m); 266int strip_newpacket(struct strip_softc *sc, u_char *ptr, u_char *end); 267void strip_send(struct strip_softc *sc, struct mbuf *m0); 268 269void strip_timeout(void *x); 270 271#ifdef DEBUG 272#define DPRINTF(x) printf x 273#else 274#define DPRINTF(x) 275#endif 276 277 278 279/* 280 * Radio reset macros. 281 * The Metricom radios are not particularly well-designed for 282 * use in packet mode (starmode). There's no easy way to tell 283 * when the radio is in starmode. Worse, when the radios are reset 284 * or power-cycled, they come back up in Hayes AT-emulation mode, 285 * and there's no good way for this driver to tell. 286 * We deal with this by peridically tickling the radio 287 * with an invalid starmode command. If the radio doesn't 288 * respond with an error, the driver knows to reset the radio. 289 */ 290 291/* Radio-reset finite state machine (if_watchdog) callback rate, in seconds */ 292#define STRIP_WATCHDOG_INTERVAL 5 293 294/* Period between intrusive radio probes, in seconds */ 295#define ST_PROBE_INTERVAL 10 296 297/* Grace period for radio to answer probe, in seconds */ 298#define ST_PROBERESPONSE_INTERVAL 2 299 300/* Be less agressive about repeated resetting. */ 301#define STRIP_RESET_INTERVAL 5 302 303/* 304 * We received a response from the radio that indicates it's in 305 * star mode. Clear any pending probe or reset timer. 306 * Don't probe radio again for standard polling interval. 307 */ 308#define CLEAR_RESET_TIMER(sc) \ 309 do {\ 310 (sc)->sc_state = ST_ALIVE; \ 311 (sc)->sc_statetimo = time_second + ST_PROBE_INTERVAL; \ 312} while (/*CONSTCOND*/ 0) 313 314/* 315 * we received a response from the radio that indicates it's crashed 316 * out of starmode into Hayse mode. Reset it ASAP. 317 */ 318#define FORCE_RESET(sc) \ 319 do {\ 320 (sc)->sc_statetimo = time_second - 1; \ 321 (sc)->sc_state = ST_DEAD; \ 322 /*(sc)->sc_if.if_timer = 0;*/ \ 323 } while (/*CONSTCOND*/ 0) 324 325#define RADIO_PROBE_TIMEOUT(sc) \ 326 ((sc)-> sc_statetimo > time_second) 327 328static int stripclose(struct tty *, int); 329static int stripinput(int, struct tty *); 330static int stripioctl(struct ifnet *, u_long, void *); 331static int stripopen(dev_t, struct tty *); 332static int stripoutput(struct ifnet *, 333 struct mbuf *, const struct sockaddr *, struct rtentry *); 334static int stripstart(struct tty *); 335static int striptioctl(struct tty *, u_long, void *, int, struct lwp *); 336 337static struct linesw strip_disc = { 338 .l_name = "strip", 339 .l_open = stripopen, 340 .l_close = stripclose, 341 .l_read = ttyerrio, 342 .l_write = ttyerrio, 343 .l_ioctl = striptioctl, 344 .l_rint = stripinput, 345 .l_start = stripstart, 346 .l_modem = nullmodem, 347 .l_poll = ttyerrpoll 348}; 349 350void 351stripattach(void) 352{ 353 if (ttyldisc_attach(&strip_disc) != 0) 354 panic("stripattach"); 355 LIST_INIT(&strip_softc_list); 356 if_clone_attach(&strip_cloner); 357} 358 359static int 360strip_clone_create(struct if_clone *ifc, int unit) 361{ 362 struct strip_softc *sc; 363 364 sc = malloc(sizeof(*sc), M_DEVBUF, M_WAIT|M_ZERO); 365 sc->sc_unit = unit; 366 if_initname(&sc->sc_if, ifc->ifc_name, unit); 367 callout_init(&sc->sc_timo_ch, 0); 368 sc->sc_if.if_softc = sc; 369 sc->sc_if.if_mtu = SLMTU; 370 sc->sc_if.if_flags = 0; 371 sc->sc_if.if_type = IFT_OTHER; 372#if 0 373 sc->sc_if.if_flags |= SC_AUTOCOMP /* | IFF_POINTOPOINT | IFF_MULTICAST*/; 374#endif 375 sc->sc_if.if_type = IFT_SLIP; 376 sc->sc_if.if_ioctl = stripioctl; 377 sc->sc_if.if_output = stripoutput; 378 sc->sc_if.if_dlt = DLT_SLIP; 379 sc->sc_fastq.ifq_maxlen = 32; 380 IFQ_SET_READY(&sc->sc_if.if_snd); 381 382 sc->sc_if.if_watchdog = strip_watchdog; 383 if_attach(&sc->sc_if); 384 if_alloc_sadl(&sc->sc_if); 385 bpf_attach(&sc->sc_if, DLT_SLIP, SLIP_HDRLEN); 386 LIST_INSERT_HEAD(&strip_softc_list, sc, sc_iflist); 387 return 0; 388} 389 390static int 391strip_clone_destroy(struct ifnet *ifp) 392{ 393 struct strip_softc *sc = (struct strip_softc *)ifp->if_softc; 394 395 if (sc->sc_ttyp != NULL) 396 return EBUSY; /* Not removing it */ 397 398 LIST_REMOVE(sc, sc_iflist); 399 400 bpf_detach(ifp); 401 if_detach(ifp); 402 403 free(sc, M_DEVBUF); 404 return 0; 405} 406 407static int 408stripinit(struct strip_softc *sc) 409{ 410 u_char *p; 411 412 if (sc->sc_mbuf == NULL) { 413 sc->sc_mbuf = m_get(M_WAIT, MT_DATA); 414 m_clget(sc->sc_mbuf, M_WAIT); 415 } 416 sc->sc_ep = (u_char *) sc->sc_mbuf->m_ext.ext_buf + 417 sc->sc_mbuf->m_ext.ext_size; 418 sc->sc_mp = sc->sc_pktstart = (u_char *) sc->sc_mbuf->m_ext.ext_buf + 419 BUFOFFSET; 420 421 /* Get contiguous buffer in which to de-bytestuff/rll-decode input */ 422 if (sc->sc_rxbuf == NULL) { 423 p = (u_char *)malloc(MCLBYTES, M_DEVBUF, M_WAITOK); 424 if (p) 425 sc->sc_rxbuf = p + SLBUFSIZE - SLMAX; 426 else { 427 printf("%s: can't allocate input buffer\n", 428 sc->sc_if.if_xname); 429 sc->sc_if.if_flags &= ~IFF_UP; 430 return (0); 431 } 432 } 433 434 /* Get contiguous buffer in which to bytestuff/rll-encode output */ 435 if (sc->sc_txbuf == NULL) { 436 p = (u_char *)malloc(MCLBYTES, M_DEVBUF, M_WAITOK); 437 if (p) 438 sc->sc_txbuf = (u_char *)p + SLBUFSIZE - SLMAX; 439 else { 440 printf("%s: can't allocate buffer\n", 441 sc->sc_if.if_xname); 442 443 sc->sc_if.if_flags &= ~IFF_UP; 444 return (0); 445 } 446 } 447 448#ifdef INET 449 sl_compress_init(&sc->sc_comp); 450#endif 451 452 /* Initialize radio probe/reset state machine */ 453 sc->sc_state = ST_DEAD; /* assumet the worst. */ 454 sc->sc_statetimo = time_second; /* do reset immediately */ 455 456 return (1); 457} 458 459/* 460 * Line specific open routine. 461 * Attach the given tty to the first available sl unit. 462 */ 463/* ARGSUSED */ 464int 465stripopen(dev_t dev, struct tty *tp) 466{ 467 struct lwp *l = curlwp; /* XXX */ 468 struct strip_softc *sc; 469 int error; 470 471 error = kauth_authorize_network(l->l_cred, 472 KAUTH_NETWORK_INTERFACE_STRIP, 473 KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD, NULL, NULL, NULL); 474 if (error) 475 return (error); 476 477 if (tp->t_linesw == &strip_disc) 478 return (0); 479 480 LIST_FOREACH(sc, &strip_softc_list, sc_iflist) { 481 if (sc->sc_ttyp == NULL) { 482 sc->sc_si = softint_establish(SOFTINT_NET, 483 stripintr, sc); 484 if (stripinit(sc) == 0) { 485 softint_disestablish(sc->sc_si); 486 return (ENOBUFS); 487 } 488 mutex_spin_enter(&tty_lock); 489 tp->t_sc = (void *)sc; 490 sc->sc_ttyp = tp; 491 sc->sc_if.if_baudrate = tp->t_ospeed; 492 ttyflush(tp, FREAD | FWRITE); 493 /* 494 * Make sure tty output queue is large enough 495 * to hold a full-sized packet (including frame 496 * end, and a possible extra frame end). 497 * A full-sized of 65/64) *SLMTU bytes (because 498 * of escapes and clever RLL bytestuffing), 499 * plus frame header, and add two on for frame ends. 500 */ 501 if (tp->t_outq.c_cn < STRIP_MTU_ONWIRE) { 502 sc->sc_oldbufsize = tp->t_outq.c_cn; 503 sc->sc_oldbufquot = tp->t_outq.c_cq != 0; 504 505 mutex_spin_exit(&tty_lock); 506 clfree(&tp->t_outq); 507 error = clalloc(&tp->t_outq, 3*SLMTU, 0); 508 if (error) { 509 softint_disestablish(sc->sc_si); 510 /* 511 * clalloc() might return -1 which 512 * is no good, so we need to return 513 * something else. 514 */ 515 return (ENOMEM); 516 } 517 mutex_spin_enter(&tty_lock); 518 } else 519 sc->sc_oldbufsize = sc->sc_oldbufquot = 0; 520 strip_resetradio(sc, tp); 521 mutex_spin_exit(&tty_lock); 522 523 /* 524 * Start the watchdog timer to get the radio 525 * "probe-for-death"/reset machine going. 526 */ 527 sc->sc_if.if_timer = STRIP_WATCHDOG_INTERVAL; 528 529 return (0); 530 } 531 } 532 return (ENXIO); 533} 534 535/* 536 * Line specific close routine. 537 * Detach the tty from the strip unit. 538 */ 539static int 540stripclose(struct tty *tp, int flag) 541{ 542 struct strip_softc *sc; 543 int s; 544 545 ttywflush(tp); 546 sc = tp->t_sc; 547 548 if (sc != NULL) { 549 softint_disestablish(sc->sc_si); 550 s = splnet(); 551 /* 552 * Cancel watchdog timer, which stops the "probe-for-death"/ 553 * reset machine. 554 */ 555 sc->sc_if.if_timer = 0; 556 if_down(&sc->sc_if); 557 IF_PURGE(&sc->sc_fastq); 558 splx(s); 559 560 s = spltty(); 561 ttyldisc_release(tp->t_linesw); 562 tp->t_linesw = ttyldisc_default(); 563 tp->t_state = 0; 564 565 sc->sc_ttyp = NULL; 566 tp->t_sc = NULL; 567 568 m_freem(sc->sc_mbuf); 569 sc->sc_mbuf = NULL; 570 sc->sc_ep = sc->sc_mp = sc->sc_pktstart = NULL; 571 IF_PURGE(&sc->sc_inq); 572 573 /* XXX */ 574 free((void *)(sc->sc_rxbuf - SLBUFSIZE + SLMAX), M_DEVBUF); 575 sc->sc_rxbuf = NULL; 576 577 /* XXX */ 578 free((void *)(sc->sc_txbuf - SLBUFSIZE + SLMAX), M_DEVBUF); 579 sc->sc_txbuf = NULL; 580 581 if (sc->sc_flags & SC_TIMEOUT) { 582 callout_stop(&sc->sc_timo_ch); 583 sc->sc_flags &= ~SC_TIMEOUT; 584 } 585 586 /* 587 * If necessary, install a new outq buffer of the 588 * appropriate size. 589 */ 590 if (sc->sc_oldbufsize != 0) { 591 clfree(&tp->t_outq); 592 clalloc(&tp->t_outq, sc->sc_oldbufsize, 593 sc->sc_oldbufquot); 594 } 595 splx(s); 596 } 597 598 return (0); 599} 600 601/* 602 * Line specific (tty) ioctl routine. 603 * Provide a way to get the sl unit number. 604 */ 605/* ARGSUSED */ 606int 607striptioctl(struct tty *tp, u_long cmd, void *data, int flag, 608 struct lwp *l) 609{ 610 struct strip_softc *sc = (struct strip_softc *)tp->t_sc; 611 612 switch (cmd) { 613 case SLIOCGUNIT: 614 *(int *)data = sc->sc_unit; 615 break; 616 617 default: 618 return (EPASSTHROUGH); 619 } 620 return (0); 621} 622 623/* 624 * Take an mbuf chain containing a STRIP packet (no link-level header), 625 * byte-stuff (escape) it, and enqueue it on the tty send queue. 626 */ 627void 628strip_sendbody(struct strip_softc *sc, struct mbuf *m) 629{ 630 struct tty *tp = sc->sc_ttyp; 631 u_char *dp = sc->sc_txbuf; 632 struct mbuf *m2; 633 int len; 634 u_char *rllstate_ptr = NULL; 635 636 while (m) { 637 if (m->m_len != 0) { 638 /* 639 * Byte-stuff/run-length encode this mbuf's data 640 * into the output buffer. 641 * XXX Note that chained calls to stuffdata() 642 * require that the stuffed data be left in the 643 * output buffer until the entire packet is encoded. 644 */ 645 dp = StuffData(mtod(m, u_char *), m->m_len, dp, 646 &rllstate_ptr); 647 } 648 MFREE(m, m2); 649 m = m2; 650 } 651 652 /* 653 * Put the entire stuffed packet into the tty output queue. 654 */ 655 len = dp - sc->sc_txbuf; 656 if (b_to_q((ttychar_t *)sc->sc_txbuf, len, &tp->t_outq)) { 657 if (sc->sc_if.if_flags & IFF_DEBUG) 658 addlog("%s: tty output overflow\n", 659 sc->sc_if.if_xname); 660 return; 661 } 662 sc->sc_if.if_obytes += len; 663} 664 665/* 666 * Send a STRIP packet. Must be called at spltty(). 667 */ 668void 669strip_send(struct strip_softc *sc, struct mbuf *m0) 670{ 671 struct tty *tp = sc->sc_ttyp; 672 struct st_header *hdr; 673 674 /* 675 * Send starmode header (unstuffed). 676 */ 677 hdr = mtod(m0, struct st_header *); 678 if (b_to_q((ttychar_t *)hdr, STRIP_HDRLEN, &tp->t_outq)) { 679 if (sc->sc_if.if_flags & IFF_DEBUG) 680 addlog("%s: outq overflow writing header\n", 681 sc->sc_if.if_xname); 682 m_freem(m0); 683 return; 684 } 685 686 m_adj(m0, sizeof(struct st_header)); 687 688 /* Byte-stuff and run-length encode the remainder of the packet. */ 689 strip_sendbody(sc, m0); 690 691 if (putc(STRIP_FRAME_END, &tp->t_outq)) { 692 /* 693 * Not enough room. Remove a char to make room 694 * and end the packet normally. 695 * If you get many collisions (more than one or two 696 * a day) you probably do not have enough clists 697 * and you should increase "nclist" in param.c. 698 */ 699 (void) unputc(&tp->t_outq); 700 (void) putc(STRIP_FRAME_END, &tp->t_outq); 701 sc->sc_if.if_collisions++; 702 } else { 703 ++sc->sc_if.if_obytes; 704 sc->sc_if.if_opackets++; 705 } 706 707 /* 708 * If a radio probe is due now, append it to this packet rather 709 * than waiting until the watchdog routine next runs. 710 */ 711 if (time_second >= sc->sc_statetimo && sc->sc_state == ST_ALIVE) 712 strip_proberadio(sc, tp); 713} 714 715/* 716 * Queue a packet. Start transmission if not active. 717 * Compression happens in stripintr(); if we do it here, IP TOS 718 * will cause us to not compress "background" packets, because 719 * ordering gets trashed. It can be done for all packets in stripintr(). 720 */ 721int 722stripoutput(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 723 struct rtentry *rt) 724{ 725 struct strip_softc *sc = ifp->if_softc; 726 struct ip *ip; 727 struct st_header *shp; 728 const u_char *dldst; /* link-level next-hop */ 729 struct ifqueue *ifq; 730 int s, error; 731 u_char dl_addrbuf[STARMODE_ADDR_LEN+1]; 732 ALTQ_DECL(struct altq_pktattr pktattr;) 733 734 /* 735 * Verify tty line is up and alive. 736 */ 737 if (sc->sc_ttyp == NULL) { 738 m_freem(m); 739 return (ENETDOWN); /* sort of */ 740 } 741 if ((sc->sc_ttyp->t_state & TS_CARR_ON) == 0 && 742 (sc->sc_ttyp->t_cflag & CLOCAL) == 0) { 743 m_freem(m); 744 return (EHOSTUNREACH); 745 } 746 747#ifdef DEBUG 748 if (rt) { 749 printf("stripout, rt: dst af%d gw af%d", 750 rt_getkey(rt)->sa_family, rt->rt_gateway->sa_family); 751 if (rt_getkey(rt)->sa_family == AF_INET) 752 printf(" dst %x", 753 satocsin(rt_getkey(rt))->sin_addr.s_addr); 754 printf("\n"); 755 } 756#endif 757 switch (dst->sa_family) { 758 case AF_INET: 759 if (rt != NULL && rt->rt_gwroute != NULL) 760 rt = rt->rt_gwroute; 761 762 /* assume rt is never NULL */ 763 if (rt == NULL || rt->rt_gateway->sa_family != AF_LINK 764 || satocsdl(rt->rt_gateway)->sdl_alen != ifp->if_addrlen) { 765 DPRINTF(("strip: could not arp starmode addr %x\n", 766 satocsin(dst)->sin_addr.s_addr)); 767 m_freem(m); 768 return (EHOSTUNREACH); 769 } 770 dldst = CLLADDR(satocsdl(rt->rt_gateway)); 771 break; 772 773 case AF_LINK: 774 dldst = CLLADDR(satocsdl(dst)); 775 break; 776 777 default: 778 /* 779 * `Cannot happen' (see stripioctl). Someday we will extend 780 * the line protocol to support other address families. 781 */ 782 printf("%s: af %d not supported\n", sc->sc_if.if_xname, 783 dst->sa_family); 784 m_freem(m); 785 sc->sc_if.if_noproto++; 786 return (EAFNOSUPPORT); 787 } 788 789 ip = mtod(m, struct ip *); 790#ifdef INET 791 if (sc->sc_if.if_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) { 792 m_freem(m); 793 return (ENETRESET); /* XXX ? */ 794 } 795 if ((ip->ip_tos & IPTOS_LOWDELAY) != 0 796#ifdef ALTQ 797 && ALTQ_IS_ENABLED(&ifp->if_snd) == 0 798#endif 799 ) 800 ifq = &sc->sc_fastq; 801 else 802#endif 803 ifq = NULL; 804 805 /* 806 * Add local net header. If no space in first mbuf, 807 * add another. 808 */ 809 M_PREPEND(m, sizeof(struct st_header), M_DONTWAIT); 810 if (m == 0) { 811 DPRINTF(("strip: could not prepend starmode header\n")); 812 return (ENOBUFS); 813 } 814 815 /* 816 * Unpack BCD route entry into an ASCII starmode address. 817 */ 818 dl_addrbuf[0] = '*'; 819 820 dl_addrbuf[1] = ((dldst[0] >> 4) & 0x0f) + '0'; 821 dl_addrbuf[2] = ((dldst[0] ) & 0x0f) + '0'; 822 823 dl_addrbuf[3] = ((dldst[1] >> 4) & 0x0f) + '0'; 824 dl_addrbuf[4] = ((dldst[1] ) & 0x0f) + '0'; 825 826 dl_addrbuf[5] = '-'; 827 828 dl_addrbuf[6] = ((dldst[2] >> 4) & 0x0f) + '0'; 829 dl_addrbuf[7] = ((dldst[2] ) & 0x0f) + '0'; 830 831 dl_addrbuf[8] = ((dldst[3] >> 4) & 0x0f) + '0'; 832 dl_addrbuf[9] = ((dldst[3] ) & 0x0f) + '0'; 833 834 dl_addrbuf[10] = '*'; 835 dl_addrbuf[11] = 0; 836 dldst = dl_addrbuf; 837 838 shp = mtod(m, struct st_header *); 839 memcpy(&shp->starmode_type, "SIP0", sizeof(shp->starmode_type)); 840 841 memcpy(shp->starmode_addr, dldst, sizeof(shp->starmode_addr)); 842 843 s = spltty(); 844 if (sc->sc_oqlen && sc->sc_ttyp->t_outq.c_cc == sc->sc_oqlen) { 845 struct bintime bt; 846 847 /* if output's been stalled for too long, and restart */ 848 getbinuptime(&bt); 849 bintime_sub(&bt, &sc->sc_lastpacket); 850 if (bt.sec > 0) { 851 DPRINTF(("stripoutput: stalled, resetting\n")); 852 sc->sc_otimeout++; 853 stripstart(sc->sc_ttyp); 854 } 855 } 856 splx(s); 857 858 s = splnet(); 859 if ((error = ifq_enqueue2(ifp, ifq, m ALTQ_COMMA 860 ALTQ_DECL(&pktattr))) != 0) { 861 splx(s); 862 return error; 863 } 864 getbinuptime(&sc->sc_lastpacket); 865 splx(s); 866 867 s = spltty(); 868 stripstart(sc->sc_ttyp); 869 splx(s); 870 871 return (0); 872} 873 874 875/* 876 * Start output on interface. Get another datagram 877 * to send from the interface queue and map it to 878 * the interface before starting output. 879 * 880 */ 881int 882stripstart(struct tty *tp) 883{ 884 struct strip_softc *sc = tp->t_sc; 885 886 /* 887 * If there is more in the output queue, just send it now. 888 * We are being called in lieu of ttstart and must do what 889 * it would. 890 */ 891 if (tp->t_outq.c_cc != 0) { 892 (*tp->t_oproc)(tp); 893 if (tp->t_outq.c_cc > SLIP_HIWAT) 894 return (0); 895 } 896 897 /* 898 * This happens briefly when the line shuts down. 899 */ 900 if (sc == NULL) 901 return (0); 902 softint_schedule(sc->sc_si); 903 return (0); 904} 905 906/* 907 * Copy data buffer to mbuf chain; add ifnet pointer. 908 */ 909static struct mbuf * 910strip_btom(struct strip_softc *sc, int len) 911{ 912 struct mbuf *m; 913 914 /* 915 * Allocate a new input buffer and swap. 916 */ 917 m = sc->sc_mbuf; 918 MGETHDR(sc->sc_mbuf, M_DONTWAIT, MT_DATA); 919 if (sc->sc_mbuf == NULL) { 920 sc->sc_mbuf = m; 921 return (NULL); 922 } 923 MCLGET(sc->sc_mbuf, M_DONTWAIT); 924 if ((sc->sc_mbuf->m_flags & M_EXT) == 0) { 925 m_freem(sc->sc_mbuf); 926 sc->sc_mbuf = m; 927 return (NULL); 928 } 929 sc->sc_ep = (u_char *) sc->sc_mbuf->m_ext.ext_buf + 930 sc->sc_mbuf->m_ext.ext_size; 931 932 m->m_data = sc->sc_pktstart; 933 934 m->m_pkthdr.len = m->m_len = len; 935 m->m_pkthdr.rcvif = &sc->sc_if; 936 return (m); 937} 938 939/* 940 * tty interface receiver interrupt. 941 * 942 * Called with a single char from the tty receiver interrupt; put 943 * the char into the buffer containing a partial packet. If the 944 * char is a packet delimiter, decapsulate the packet, wrap it in 945 * an mbuf, and put it on the protocol input queue. 946*/ 947int 948stripinput(int c, struct tty *tp) 949{ 950 struct strip_softc *sc; 951 struct mbuf *m; 952 int len; 953 954 tk_nin++; 955 sc = (struct strip_softc *)tp->t_sc; 956 if (sc == NULL) 957 return (0); 958 if (c & TTY_ERRORMASK || ((tp->t_state & TS_CARR_ON) == 0 && 959 (tp->t_cflag & CLOCAL) == 0)) { 960 sc->sc_flags |= SC_ERROR; 961 DPRINTF(("strip: input, error %x\n", c)); /* XXX */ 962 return (0); 963 } 964 c &= TTY_CHARMASK; 965 966 ++sc->sc_if.if_ibytes; 967 968 /* 969 * Accumulate characters until we see a frame terminator (\r). 970 */ 971 switch (c) { 972 973 case '\n': 974 /* 975 * Error message strings from the modem are terminated with 976 * \r\n. This driver interprets the \r as a packet terminator. 977 * If the first character in a packet is a \n, drop it. 978 * (it can never be the first char of a vaild frame). 979 */ 980 if (sc->sc_mp - sc->sc_pktstart == 0) 981 break; 982 983 /* Fall through to */ 984 985 default: 986 if (sc->sc_mp < sc->sc_ep) { 987 *sc->sc_mp++ = c; 988 } else { 989 sc->sc_flags |= SC_ERROR; 990 goto error; 991 } 992 return (0); 993 994 case STRIP_FRAME_END: 995 break; 996 } 997 998 999 /* 1000 * We only reach here if we see a CR delimiting a packet. 1001 */ 1002 1003 1004 len = sc->sc_mp - sc->sc_pktstart; 1005 1006#ifdef XDEBUG 1007 if (len < 15 || sc->sc_flags & SC_ERROR) 1008 printf("stripinput: end of pkt, len %d, err %d\n", 1009 len, sc->sc_flags & SC_ERROR); /*XXX*/ 1010#endif 1011 if(sc->sc_flags & SC_ERROR) { 1012 sc->sc_flags &= ~SC_ERROR; 1013 addlog("%s: sc error flag set. terminating packet\n", 1014 sc->sc_if.if_xname); 1015 goto newpack; 1016 } 1017 1018 /* 1019 * We have a frame. 1020 * Process an IP packet, ARP packet, AppleTalk packet, 1021 * AT command resposne, or Starmode error. 1022 */ 1023 len = strip_newpacket(sc, sc->sc_pktstart, sc->sc_mp); 1024 if (len <= 1) 1025 /* less than min length packet - ignore */ 1026 goto newpack; 1027 1028 m = strip_btom(sc, len); 1029 if (m == NULL) 1030 goto error; 1031 1032 IF_ENQUEUE(&sc->sc_inq, m); 1033 softint_schedule(sc->sc_si); 1034 goto newpack; 1035 1036error: 1037 sc->sc_if.if_ierrors++; 1038 1039newpack: 1040 sc->sc_mp = sc->sc_pktstart = (u_char *) sc->sc_mbuf->m_ext.ext_buf + 1041 BUFOFFSET; 1042 1043 return (0); 1044} 1045 1046static void 1047stripintr(void *arg) 1048{ 1049 struct strip_softc *sc = arg; 1050 struct tty *tp = sc->sc_ttyp; 1051 struct mbuf *m; 1052 int s, len; 1053 u_char *pktstart; 1054#ifdef INET 1055 u_char c; 1056#endif 1057 u_char chdr[CHDR_LEN]; 1058 1059 KASSERT(tp != NULL); 1060 1061 /* 1062 * Output processing loop. 1063 */ 1064 mutex_enter(softnet_lock); 1065 for (;;) { 1066#ifdef INET 1067 struct ip *ip; 1068#endif 1069 struct mbuf *bpf_m; 1070 1071 /* 1072 * Do not remove the packet from the queue if it 1073 * doesn't look like it will fit into the current 1074 * serial output queue (STRIP_MTU_ONWIRE, or 1075 * Starmode header + 20 bytes + 4 bytes in case we 1076 * have to probe the radio). 1077 */ 1078 s = spltty(); 1079 if (tp->t_outq.c_cn - tp->t_outq.c_cc < 1080 STRIP_MTU_ONWIRE + 4) { 1081 splx(s); 1082 break; 1083 } 1084 splx(s); 1085 1086 /* 1087 * Get a packet and send it to the radio. 1088 */ 1089 s = splnet(); 1090 IF_DEQUEUE(&sc->sc_fastq, m); 1091 if (m) 1092 sc->sc_if.if_omcasts++; /* XXX */ 1093 else 1094 IFQ_DEQUEUE(&sc->sc_if.if_snd, m); 1095 splx(s); 1096 1097 if (m == NULL) 1098 break; 1099 1100 /* 1101 * We do the header compression here rather than in 1102 * stripoutput() because the packets will be out of 1103 * order if we are using TOS queueing, and the 1104 * connection ID compression will get munged when 1105 * this happens. 1106 */ 1107 if (sc->sc_if.if_bpf) { 1108 /* 1109 * We need to save the TCP/IP header before 1110 * it's compressed. To avoid complicated 1111 * code, we just make a deep copy of the 1112 * entire packet (since this is a serial 1113 * line, packets should be short and/or the 1114 * copy should be negligible cost compared 1115 * to the packet transmission time). 1116 */ 1117 bpf_m = m_dup(m, 0, M_COPYALL, M_DONTWAIT); 1118 } else 1119 bpf_m = NULL; 1120#ifdef INET 1121 if ((ip = mtod(m, struct ip *))->ip_p == IPPROTO_TCP) { 1122 if (sc->sc_if.if_flags & SC_COMPRESS) 1123 *mtod(m, u_char *) |= 1124 sl_compress_tcp(m, ip, 1125 &sc->sc_comp, 1); 1126 } 1127#endif 1128 if (bpf_m != NULL) 1129 bpf_mtap_sl_out(&sc->sc_if, mtod(m, u_char *), bpf_m); 1130 getbinuptime(&sc->sc_lastpacket); 1131 1132 s = spltty(); 1133 strip_send(sc, m); 1134 1135 /* 1136 * We now have characters in the output queue, 1137 * kick the serial port. 1138 */ 1139 if (tp->t_outq.c_cc != 0) 1140 (*tp->t_oproc)(tp); 1141 splx(s); 1142 } 1143 1144 /* 1145 * Input processing loop. 1146 */ 1147 for (;;) { 1148 s = spltty(); 1149 IF_DEQUEUE(&sc->sc_inq, m); 1150 splx(s); 1151 if (m == NULL) 1152 break; 1153 pktstart = mtod(m, u_char *); 1154 len = m->m_pkthdr.len; 1155 if (sc->sc_if.if_bpf) { 1156 /* 1157 * Save the compressed header, so we 1158 * can tack it on later. Note that we 1159 * will end up copying garbage in come 1160 * cases but this is okay. We remember 1161 * where the buffer started so we can 1162 * compute the new header length. 1163 */ 1164 memcpy(chdr, pktstart, CHDR_LEN); 1165 } 1166#ifdef INET 1167 if ((c = (*pktstart & 0xf0)) != (IPVERSION << 4)) { 1168 if (c & 0x80) 1169 c = TYPE_COMPRESSED_TCP; 1170 else if (c == TYPE_UNCOMPRESSED_TCP) 1171 *pktstart &= 0x4f; /* XXX */ 1172 /* 1173 * We've got something that's not an IP 1174 * packet. If compression is enabled, 1175 * try to decompress it. Otherwise, if 1176 * `auto-enable' compression is on and 1177 * it's a reasonable packet, decompress 1178 * it and then enable compression. 1179 * Otherwise, drop it. 1180 */ 1181 if (sc->sc_if.if_flags & SC_COMPRESS) { 1182 len = sl_uncompress_tcp(&pktstart, len, 1183 (u_int)c, &sc->sc_comp); 1184 if (len <= 0) { 1185 m_freem(m); 1186 continue; 1187 } 1188 } else if ((sc->sc_if.if_flags & SC_AUTOCOMP) && 1189 c == TYPE_UNCOMPRESSED_TCP && len >= 40) { 1190 len = sl_uncompress_tcp(&pktstart, len, 1191 (u_int)c, &sc->sc_comp); 1192 if (len <= 0) { 1193 m_freem(m); 1194 continue; 1195 } 1196 sc->sc_if.if_flags |= SC_COMPRESS; 1197 } else { 1198 m_freem(m); 1199 continue; 1200 } 1201 } 1202#endif 1203 m->m_data = (void *) pktstart; 1204 m->m_pkthdr.len = m->m_len = len; 1205 if (sc->sc_if.if_bpf) { 1206 bpf_mtap_sl_in(&sc->sc_if, chdr, &m); 1207 if (m == NULL) 1208 continue; 1209 } 1210 /* 1211 * If the packet will fit into a single 1212 * header mbuf, copy it into one, to save 1213 * memory. 1214 */ 1215 if (m->m_pkthdr.len < MHLEN) { 1216 struct mbuf *n; 1217 int pktlen; 1218 1219 MGETHDR(n, M_DONTWAIT, MT_DATA); 1220 pktlen = m->m_pkthdr.len; 1221 M_MOVE_PKTHDR(n, m); 1222 memcpy(mtod(n, void *), mtod(m, void *), pktlen); 1223 n->m_len = m->m_len; 1224 m_freem(m); 1225 m = n; 1226 } 1227 1228 sc->sc_if.if_ipackets++; 1229 getbinuptime(&sc->sc_lastpacket); 1230 1231#ifdef INET 1232 s = splnet(); 1233 if (IF_QFULL(&ipintrq)) { 1234 IF_DROP(&ipintrq); 1235 sc->sc_if.if_ierrors++; 1236 sc->sc_if.if_iqdrops++; 1237 m_freem(m); 1238 } else { 1239 IF_ENQUEUE(&ipintrq, m); 1240 schednetisr(NETISR_IP); 1241 } 1242 splx(s); 1243#endif 1244 } 1245 mutex_exit(softnet_lock); 1246} 1247 1248/* 1249 * Process an ioctl request. 1250 */ 1251int 1252stripioctl(struct ifnet *ifp, u_long cmd, void *data) 1253{ 1254 struct ifaddr *ifa = (struct ifaddr *)data; 1255 struct ifreq *ifr; 1256 int s, error = 0; 1257 1258 s = splnet(); 1259 1260 switch (cmd) { 1261 1262 case SIOCINITIFADDR: 1263 if (ifa->ifa_addr->sa_family == AF_INET) 1264 ifp->if_flags |= IFF_UP; 1265 else 1266 error = EAFNOSUPPORT; 1267 break; 1268 1269 case SIOCSIFDSTADDR: 1270 if (ifa->ifa_addr->sa_family != AF_INET) 1271 error = EAFNOSUPPORT; 1272 break; 1273 1274 case SIOCADDMULTI: 1275 case SIOCDELMULTI: 1276 ifr = (struct ifreq *)data; 1277 if (ifr == 0) { 1278 error = EAFNOSUPPORT; /* XXX */ 1279 break; 1280 } 1281 switch (ifreq_getaddr(cmd, ifr)->sa_family) { 1282 1283#ifdef INET 1284 case AF_INET: 1285 break; 1286#endif 1287 1288 default: 1289 error = EAFNOSUPPORT; 1290 break; 1291 } 1292 break; 1293 1294 default: 1295 error = ifioctl_common(ifp, cmd, data); 1296 } 1297 splx(s); 1298 return (error); 1299} 1300 1301 1302/* 1303 * Strip subroutines 1304 */ 1305 1306/* 1307 * Set a radio into starmode. 1308 * Must be called at spltty(). 1309 */ 1310void 1311strip_resetradio(struct strip_softc *sc, struct tty *tp) 1312{ 1313#if 0 1314 static ttychar_t InitString[] = 1315 "\r\n\r\n\r\nat\r\n\r\n\r\nate0dt**starmode\r\n**\r\n"; 1316#else 1317 static ttychar_t InitString[] = 1318 "\r\rat\r\r\rate0q1dt**starmode\r**\r"; 1319#endif 1320 int i; 1321 1322 /* 1323 * XXX Perhaps flush tty output queue? 1324 */ 1325 1326 if ((i = b_to_q(InitString, sizeof(InitString) - 1, &tp->t_outq))) { 1327 printf("resetradio: %d chars didn't fit in tty queue\n", i); 1328 return; 1329 } 1330 sc->sc_if.if_obytes += sizeof(InitString) - 1; 1331 1332 /* 1333 * Assume the radio is still dead, so we can detect repeated 1334 * resets (perhaps the radio is disconnected, powered off, or 1335 * is so badlyhung it needs powercycling. 1336 */ 1337 sc->sc_state = ST_DEAD; 1338 getbinuptime(&sc->sc_lastpacket); 1339 sc->sc_statetimo = time_second + STRIP_RESET_INTERVAL; 1340 1341 /* 1342 * XXX Does calling the tty output routine now help resets? 1343 */ 1344 (*sc->sc_ttyp->t_oproc)(tp); 1345} 1346 1347 1348/* 1349 * Send an invalid starmode packet to the radio, to induce an error message 1350 * indicating the radio is in starmode. 1351 * Update the state machine to indicate a response is expected. 1352 * Either the radio answers, which will be caught by the parser, 1353 * or the watchdog will start resetting. 1354 * 1355 * NOTE: drops chars directly on the tty output queue. 1356 * should be caled at spl >= spltty. 1357 */ 1358void 1359strip_proberadio(struct strip_softc *sc, struct tty *tp) 1360{ 1361 1362 int overflow; 1363 const char *strip_probestr = "**"; 1364 1365 if (sc->sc_if.if_flags & IFF_DEBUG) 1366 addlog("%s: attempting to probe radio\n", sc->sc_if.if_xname); 1367 1368 overflow = b_to_q((const ttychar_t *)strip_probestr, 2, &tp->t_outq); 1369 if (overflow == 0) { 1370 if (sc->sc_if.if_flags & IFF_DEBUG) 1371 addlog("%s:: sent probe to radio\n", 1372 sc->sc_if.if_xname); 1373 /* Go to probe-sent state, set timeout accordingly. */ 1374 sc->sc_state = ST_PROBE_SENT; 1375 sc->sc_statetimo = time_second + ST_PROBERESPONSE_INTERVAL; 1376 } else { 1377 addlog("%s: incomplete probe, tty queue %d bytes overfull\n", 1378 sc->sc_if.if_xname, overflow); 1379 } 1380} 1381 1382 1383#ifdef DEBUG 1384static const char *strip_statenames[] = { 1385 "Alive", 1386 "Probe sent, awaiting answer", 1387 "Probe not answered, resetting" 1388}; 1389#endif 1390 1391 1392/* 1393 * Timeout routine -- try to start more output. 1394 * Will be needed to make strip work on ptys. 1395 */ 1396void 1397strip_timeout(void *x) 1398{ 1399 struct strip_softc *sc = (struct strip_softc *) x; 1400 struct tty *tp = sc->sc_ttyp; 1401 int s; 1402 1403 s = spltty(); 1404 sc->sc_flags &= ~SC_TIMEOUT; 1405 stripstart(tp); 1406 splx(s); 1407} 1408 1409 1410/* 1411 * Strip watchdog routine. 1412 * The radio hardware is balky. When sent long packets or bursts of small 1413 * packets, the radios crash and reboots into Hayes-emulation mode. 1414 * The transmit-side machinery, the error parser, and strip_watchdog() 1415 * implement a simple finite state machine. 1416 * 1417 * We attempt to send a probe to the radio every ST_PROBE seconds. There 1418 * is no direct way to tell if the radio is in starmode, so we send it a 1419 * malformed starmode packet -- a frame with no destination address -- 1420 * and expect to an "name missing" error response from the radio within 1421 * 1 second. If we hear such a response, we assume the radio is alive 1422 * for the next ST_PROBE seconds. 1423 * If we don't hear a starmode-error response from the radio, we reset it. 1424 * 1425 * Probes, and parsing of error responses, are normally done inside the send 1426 * and receive side respectively. This watchdog routine examines the 1427 * state-machine variables. If there are no packets to send to the radio 1428 * during an entire probe interval, strip_output will not be called, 1429 * so we send a probe on its behalf. 1430 */ 1431void 1432strip_watchdog(struct ifnet *ifp) 1433{ 1434 struct strip_softc *sc = ifp->if_softc; 1435 struct tty *tp = sc->sc_ttyp; 1436 1437 /* 1438 * Just punt if the line has been closed. 1439 */ 1440 if (tp == NULL) 1441 return; 1442 1443#ifdef DEBUG 1444 if (ifp->if_flags & IFF_DEBUG) 1445 addlog("\n%s: in watchdog, state %s timeout %lld\n", 1446 ifp->if_xname, 1447 ((unsigned) sc->sc_state < 3) ? 1448 strip_statenames[sc->sc_state] : "<<illegal state>>", 1449 (long long)(sc->sc_statetimo - time_second)); 1450#endif 1451 1452 /* 1453 * If time in this state hasn't yet expired, return. 1454 */ 1455 if ((ifp->if_flags & IFF_UP) == 0 || sc->sc_statetimo > time_second) { 1456 goto done; 1457 } 1458 1459 /* 1460 * The time in the current state has expired. 1461 * Take appropriate action and advance FSA to the next state. 1462 */ 1463 switch (sc->sc_state) { 1464 case ST_ALIVE: 1465 /* 1466 * A probe is due but we haven't piggybacked one on a packet. 1467 * Send a probe now. 1468 */ 1469 strip_proberadio(sc, sc->sc_ttyp); 1470 (*tp->t_oproc)(tp); 1471 break; 1472 1473 case ST_PROBE_SENT: 1474 /* 1475 * Probe sent but no response within timeout. Reset. 1476 */ 1477 addlog("%s: no answer to probe, resetting radio\n", 1478 ifp->if_xname); 1479 strip_resetradio(sc, sc->sc_ttyp); 1480 ifp->if_oerrors++; 1481 break; 1482 1483 case ST_DEAD: 1484 /* 1485 * The radio has been sent a reset but didn't respond. 1486 * XXX warn user to remove AC adaptor and battery, 1487 * wait 5 secs, and replace. 1488 */ 1489 addlog("%s: radio reset but not responding, Trying again\n", 1490 ifp->if_xname); 1491 strip_resetradio(sc, sc->sc_ttyp); 1492 ifp->if_oerrors++; 1493 break; 1494 1495 default: 1496 /* Cannot happen. To be safe, do a reset. */ 1497 addlog("%s: %s %d, resetting\n", 1498 sc->sc_if.if_xname, 1499 "radio-reset finite-state machine in invalid state", 1500 sc->sc_state); 1501 strip_resetradio(sc, sc->sc_ttyp); 1502 sc->sc_state = ST_DEAD; 1503 break; 1504 } 1505 1506 done: 1507 ifp->if_timer = STRIP_WATCHDOG_INTERVAL; 1508 return; 1509} 1510 1511 1512/* 1513 * The following bytestuffing and run-length encoding/decoding 1514 * functions are taken, with permission from Stuart Cheshire, 1515 * from the MosquitonNet strip driver for Linux. 1516 * XXX Linux style left intact, to ease folding in updates from 1517 * the Mosquitonet group. 1518 */ 1519 1520 1521/* 1522 * Process a received packet. 1523 */ 1524int 1525strip_newpacket(struct strip_softc *sc, u_char *ptr, u_char *end) 1526{ 1527 int len = ptr - end; 1528 u_char *name, *name_end; 1529 u_int packetlen; 1530 1531 /* Ignore empty lines */ 1532 if (len == 0) return 0; 1533 1534 /* Catch 'OK' responses which show radio has fallen out of starmode */ 1535 if (len >= 2 && ptr[0] == 'O' && ptr[1] == 'K') { 1536 printf("%s: Radio is back in AT command mode: will reset\n", 1537 sc->sc_if.if_xname); 1538 FORCE_RESET(sc); /* Do reset ASAP */ 1539 return 0; 1540 } 1541 1542 /* Check for start of address marker, and then skip over it */ 1543 if (*ptr != '*') { 1544 /* Catch other error messages */ 1545 if (ptr[0] == 'E' && ptr[1] == 'R' && ptr[2] == 'R' && ptr[3] == '_') 1546 RecvErr_Message(sc, NULL, ptr+4); 1547 /* XXX what should the message above be? */ 1548 else { 1549 RecvErr("No initial *", sc); 1550 addlog("(len = %d)\n", len); 1551 } 1552 return 0; 1553 } 1554 1555 /* skip the '*' */ 1556 ptr++; 1557 1558 /* Skip the return address */ 1559 name = ptr; 1560 while (ptr < end && *ptr != '*') 1561 ptr++; 1562 1563 /* Check for end of address marker, and skip over it */ 1564 if (ptr == end) { 1565 RecvErr("No second *", sc); 1566 return 0; 1567 } 1568 name_end = ptr++; 1569 1570 /* Check for SRIP key, and skip over it */ 1571 if (ptr[0] != 'S' || ptr[1] != 'I' || ptr[2] != 'P' || ptr[3] != '0') { 1572 if (ptr[0] == 'E' && ptr[1] == 'R' && ptr[2] == 'R' && 1573 ptr[3] == '_') { 1574 *name_end = 0; 1575 RecvErr_Message(sc, name, ptr+4); 1576 } 1577 else RecvErr("No SRIP key", sc); 1578 return 0; 1579 } 1580 ptr += 4; 1581 1582 /* Decode start of the IP packet header */ 1583 ptr = UnStuffData(ptr, end, sc->sc_rxbuf, 4); 1584 if (ptr == 0) { 1585 RecvErr("Runt packet (hdr)", sc); 1586 return 0; 1587 } 1588 1589 /* 1590 * The STRIP bytestuff/RLL encoding has no explicit length 1591 * of the decoded packet. Decode start of IP header, get the 1592 * IP header length and decode that many bytes in total. 1593 */ 1594 packetlen = ((uint16_t)sc->sc_rxbuf[2] << 8) | sc->sc_rxbuf[3]; 1595 1596#ifdef DIAGNOSTIC 1597#if 0 1598 printf("Packet %02x.%02x.%02x.%02x\n", 1599 sc->sc_rxbuf[0], sc->sc_rxbuf[1], 1600 sc->sc_rxbuf[2], sc->sc_rxbuf[3]); 1601 printf("Got %d byte packet\n", packetlen); 1602#endif 1603#endif 1604 1605 /* Decode remainder of the IP packer */ 1606 ptr = UnStuffData(ptr, end, sc->sc_rxbuf+4, packetlen-4); 1607 if (ptr == 0) { 1608 RecvErr("Short packet", sc); 1609 return 0; 1610 } 1611 1612 /* XXX redundant copy */ 1613 memcpy(sc->sc_pktstart, sc->sc_rxbuf, packetlen ); 1614 return (packetlen); 1615} 1616 1617 1618/* 1619 * Stuffing scheme: 1620 * 00 Unused (reserved character) 1621 * 01-3F Run of 2-64 different characters 1622 * 40-7F Run of 1-64 different characters plus a single zero at the end 1623 * 80-BF Run of 1-64 of the same character 1624 * C0-FF Run of 1-64 zeroes (ASCII 0) 1625*/ 1626typedef enum 1627{ 1628 Stuff_Diff = 0x00, 1629 Stuff_DiffZero = 0x40, 1630 Stuff_Same = 0x80, 1631 Stuff_Zero = 0xC0, 1632 Stuff_NoCode = 0xFF, /* Special code, meaning no code selected */ 1633 1634 Stuff_CodeMask = 0xC0, 1635 Stuff_CountMask = 0x3F, 1636 Stuff_MaxCount = 0x3F, 1637 Stuff_Magic = 0x0D /* The value we are eliminating */ 1638} StuffingCode; 1639 1640/* 1641 * StuffData encodes the data starting at "src" for "length" bytes. 1642 * It writes it to the buffer pointed to by "dest" (which must be at least 1643 * as long as 1 + 65/64 of the input length). The output may be up to 1.6% 1644 * larger than the input for pathological input, but will usually be smaller. 1645 * StuffData returns the new value of the dest pointer as its result. 1646 * 1647 * "code_ptr_ptr" points to a "u_char *" which is used to hold 1648 * encoding state between calls, allowing an encoded packet to be 1649 * incrementally built up from small parts. 1650 * On the first call, the "u_char *" pointed to should be initialized 1651 * to NULL; between subsequent calls the calling routine should leave 1652 * the value alone and simply pass it back unchanged so that the 1653 * encoder can recover its current state. 1654 */ 1655 1656#define StuffData_FinishBlock(X) \ 1657 (*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode) 1658 1659static u_char* 1660StuffData(u_char *src, u_long length, u_char *dest, u_char **code_ptr_ptr) 1661{ 1662 u_char *end = src + length; 1663 u_char *code_ptr = *code_ptr_ptr; 1664 u_char code = Stuff_NoCode, count = 0; 1665 1666 if (!length) return (dest); 1667 1668 if (code_ptr) { /* Recover state from last call, if applicable */ 1669 code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask; 1670 count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask; 1671 } 1672 1673 while (src < end) { 1674 switch (code) { 1675 /* 1676 * Stuff_NoCode: If no current code, select one 1677 */ 1678 case Stuff_NoCode: 1679 code_ptr = dest++; /* Record where we're going to put this code */ 1680 count = 0; /* Reset the count (zero means one instance) */ 1681 /* Tentatively start a new block */ 1682 if (*src == 0) { 1683 code = Stuff_Zero; 1684 src++; 1685 } else { 1686 code = Stuff_Same; 1687 *dest++ = *src++ ^ Stuff_Magic; 1688 } 1689 /* Note: We optimistically assume run of same -- which will be */ 1690 /* fixed later in Stuff_Same if it turns out not to be true. */ 1691 break; 1692 1693 /* 1694 * Stuff_Zero: We already have at least one zero encoded 1695 */ 1696 case Stuff_Zero: 1697 1698 /* If another zero, count it, else finish this code block */ 1699 if (*src == 0) { 1700 count++; 1701 src++; 1702 } else 1703 StuffData_FinishBlock(Stuff_Zero + count); 1704 break; 1705 1706 /* 1707 * Stuff_Same: We already have at least one byte encoded 1708 */ 1709 case Stuff_Same: 1710 /* If another one the same, count it */ 1711 if ((*src ^ Stuff_Magic) == code_ptr[1]) { 1712 count++; 1713 src++; 1714 break; 1715 } 1716 /* else, this byte does not match this block. */ 1717 /* If we already have two or more bytes encoded, finish this code block */ 1718 if (count) { 1719 StuffData_FinishBlock(Stuff_Same + count); 1720 break; 1721 } 1722 /* else, we only have one so far, so switch to Stuff_Diff code */ 1723 code = Stuff_Diff; /* and fall through to Stuff_Diff case below */ 1724 1725 case Stuff_Diff: /* Stuff_Diff: We have at least two *different* bytes encoded */ 1726 /* If this is a zero, must encode a Stuff_DiffZero, and begin a new block */ 1727 if (*src == 0) 1728 StuffData_FinishBlock(Stuff_DiffZero + count); 1729 /* else, if we have three in a row, it is worth starting a Stuff_Same block */ 1730 else if ((*src ^ Stuff_Magic) == dest[-1] && dest[-1] == dest[-2]) 1731 { 1732 code += count-2; 1733 if (code == Stuff_Diff) 1734 code = Stuff_Same; 1735 StuffData_FinishBlock(code); 1736 code_ptr = dest-2; 1737 /* dest[-1] already holds the correct value */ 1738 count = 2; /* 2 means three bytes encoded */ 1739 code = Stuff_Same; 1740 } 1741 /* else, another different byte, so add it to the block */ 1742 else { 1743 *dest++ = *src ^ Stuff_Magic; 1744 count++; 1745 } 1746 src++; /* Consume the byte */ 1747 break; 1748 } 1749 1750 if (count == Stuff_MaxCount) 1751 StuffData_FinishBlock(code + count); 1752 } 1753 if (code == Stuff_NoCode) 1754 *code_ptr_ptr = NULL; 1755 else { 1756 *code_ptr_ptr = code_ptr; 1757 StuffData_FinishBlock(code + count); 1758 } 1759 1760 return (dest); 1761} 1762 1763 1764 1765/* 1766 * UnStuffData decodes the data at "src", up to (but not including) 1767 * "end". It writes the decoded data into the buffer pointed to by 1768 * "dst", up to a maximum of "dst_length", and returns the new 1769 * value of "src" so that a follow-on call can read more data, 1770 * continuing from where the first left off. 1771 * 1772 * There are three types of results: 1773 * 1. The source data runs out before extracting "dst_length" bytes: 1774 * UnStuffData returns NULL to indicate failure. 1775 * 2. The source data produces exactly "dst_length" bytes: 1776 * UnStuffData returns new_src = end to indicate that all bytes 1777 * were consumed. 1778 * 3. "dst_length" bytes are extracted, with more 1779 * remaining. UnStuffData returns new_src < end to indicate that 1780 * there are more bytes to be read. 1781 * 1782 * Note: The decoding may be dstructive, in that it may alter the 1783 * source data in the process of decoding it (this is necessary to 1784 * allow a follow-on call to resume correctly). 1785 */ 1786 1787static u_char* 1788UnStuffData(u_char *src, u_char *end, u_char *dst, u_long dst_length) 1789{ 1790 u_char *dst_end = dst + dst_length; 1791 1792 /* Sanity check */ 1793 if (!src || !end || !dst || !dst_length) 1794 return (NULL); 1795 1796 while (src < end && dst < dst_end) 1797 { 1798 int count = (*src ^ Stuff_Magic) & Stuff_CountMask; 1799 switch ((*src ^ Stuff_Magic) & Stuff_CodeMask) 1800 { 1801 case Stuff_Diff: 1802 if (src+1+count >= end) 1803 return (NULL); 1804 do 1805 { 1806 *dst++ = *++src ^ Stuff_Magic; 1807 } 1808 while(--count >= 0 && dst < dst_end); 1809 if (count < 0) 1810 src += 1; 1811 else 1812 if (count == 0) 1813 *src = Stuff_Same ^ Stuff_Magic; 1814 else 1815 *src = (Stuff_Diff + count) ^ Stuff_Magic; 1816 break; 1817 case Stuff_DiffZero: 1818 if (src+1+count >= end) 1819 return (NULL); 1820 do 1821 { 1822 *dst++ = *++src ^ Stuff_Magic; 1823 } 1824 while(--count >= 0 && dst < dst_end); 1825 if (count < 0) 1826 *src = Stuff_Zero ^ Stuff_Magic; 1827 else 1828 *src = (Stuff_DiffZero + count) ^ Stuff_Magic; 1829 break; 1830 case Stuff_Same: 1831 if (src+1 >= end) 1832 return (NULL); 1833 do 1834 { 1835 *dst++ = src[1] ^ Stuff_Magic; 1836 } 1837 while(--count >= 0 && dst < dst_end); 1838 if (count < 0) 1839 src += 2; 1840 else 1841 *src = (Stuff_Same + count) ^ Stuff_Magic; 1842 break; 1843 case Stuff_Zero: 1844 do 1845 { 1846 *dst++ = 0; 1847 } 1848 while(--count >= 0 && dst < dst_end); 1849 if (count < 0) 1850 src += 1; 1851 else 1852 *src = (Stuff_Zero + count) ^ Stuff_Magic; 1853 break; 1854 } 1855 } 1856 1857 if (dst < dst_end) 1858 return (NULL); 1859 else 1860 return (src); 1861} 1862 1863 1864 1865/* 1866 * Log an error mesesage (for a packet received with errors?) 1867 * from the STRIP driver. 1868 */ 1869static void 1870RecvErr(const char *msg, struct strip_softc *sc) 1871{ 1872#define MAX_RecErr 80 1873 u_char *ptr = sc->sc_pktstart; 1874 u_char *end = sc->sc_mp; 1875 u_char pkt_text[MAX_RecErr], *p = pkt_text; 1876 *p++ = '\"'; 1877 while (ptr < end && p < &pkt_text[MAX_RecErr-4]) { 1878 if (*ptr == '\\') { 1879 *p++ = '\\'; 1880 *p++ = '\\'; 1881 } else if (*ptr >= 32 && *ptr <= 126) 1882 *p++ = *ptr; 1883 else { 1884 snprintf(p, sizeof(pkt_text) - (p - pkt_text), 1885 "\\%02x", *ptr); 1886 p += 3; 1887 } 1888 ptr++; 1889 } 1890 1891 if (ptr == end) *p++ = '\"'; 1892 *p++ = 0; 1893 addlog("%s: %13s : %s\n", sc->sc_if.if_xname, msg, pkt_text); 1894 1895 sc->sc_if.if_ierrors++; 1896} 1897 1898 1899/* 1900 * Parse an error message from the radio. 1901 */ 1902static void 1903RecvErr_Message(struct strip_softc *strip_info, u_char *sendername, 1904 const u_char *msg) 1905{ 1906 static const char ERR_001[] = "001"; /* Not in StarMode! */ 1907 static const char ERR_002[] = "002"; /* Remap handle */ 1908 static const char ERR_003[] = "003"; /* Can't resolve name */ 1909 static const char ERR_004[] = "004"; /* Name too small or missing */ 1910 static const char ERR_005[] = "005"; /* Bad count specification */ 1911 static const char ERR_006[] = "006"; /* Header too big */ 1912 static const char ERR_007[] = "007"; /* Body too big */ 1913 static const char ERR_008[] = "008"; /* Bad character in name */ 1914 static const char ERR_009[] = "009"; /* No count or line terminator */ 1915 1916 char * if_name; 1917 1918 if_name = strip_info->sc_if.if_xname; 1919 1920 if (!strncmp(msg, ERR_001, sizeof(ERR_001)-1)) 1921 { 1922 RecvErr("radio error message:", strip_info); 1923 addlog("%s: Radio %s is not in StarMode\n", 1924 if_name, sendername); 1925 } 1926 else if (!strncmp(msg, ERR_002, sizeof(ERR_002)-1)) 1927 { 1928 RecvErr("radio error message:", strip_info); 1929#ifdef notyet /*Kernel doesn't have scanf!*/ 1930 int handle; 1931 u_char newname[64]; 1932 sscanf(msg, "ERR_002 Remap handle &%d to name %s", &handle, newname); 1933 addlog("%s: Radio name %s is handle %d\n", 1934 if_name, newname, handle); 1935#endif 1936 } 1937 else if (!strncmp(msg, ERR_003, sizeof(ERR_003)-1)) 1938 { 1939 RecvErr("radio error message:", strip_info); 1940 addlog("%s: Destination radio name is unknown\n", if_name); 1941 } 1942 else if (!strncmp(msg, ERR_004, sizeof(ERR_004)-1)) { 1943 /* 1944 * The radio reports it got a badly-framed starmode packet 1945 * from us; so it must me in starmode. 1946 */ 1947 if (strip_info->sc_if.if_flags & IFF_DEBUG) 1948 addlog("%s: radio responded to probe\n", if_name); 1949 if (strip_info->sc_state == ST_DEAD) { 1950 /* A successful reset... */ 1951 addlog("%s: Radio back in starmode\n", if_name); 1952 } 1953 CLEAR_RESET_TIMER(strip_info); 1954 } 1955 else if (!strncmp(msg, ERR_005, sizeof(ERR_005)-1)) 1956 RecvErr("radio error message:", strip_info); 1957 else if (!strncmp(msg, ERR_006, sizeof(ERR_006)-1)) 1958 RecvErr("radio error message:", strip_info); 1959 else if (!strncmp(msg, ERR_007, sizeof(ERR_007)-1)) 1960 { 1961 /* 1962 * Note: This error knocks the radio back into 1963 * command mode. 1964 */ 1965 RecvErr("radio error message:", strip_info); 1966 printf("%s: Error! Packet size too big for radio.", 1967 if_name); 1968 FORCE_RESET(strip_info); 1969 } 1970 else if (!strncmp(msg, ERR_008, sizeof(ERR_008)-1)) 1971 { 1972 RecvErr("radio error message:", strip_info); 1973 printf("%s: Radio name contains illegal character\n", 1974 if_name); 1975 } 1976 else if (!strncmp(msg, ERR_009, sizeof(ERR_009)-1)) 1977 RecvErr("radio error message:", strip_info); 1978 else { 1979 addlog("failed to parse ]%3s[\n", msg); 1980 RecvErr("unparsed radio error message:", strip_info); 1981 } 1982} 1983