This source file includes following definitions.
- stripattach
- stripinit
- stripopen
- stripclose
- striptioctl
- strip_sendbody
- strip_send
- stripoutput
- stripstart
- strip_btom
- stripinput
- stripioctl
- strip_resetradio
- strip_proberadio
- strip_timeout
- strip_watchdog
- strip_newpacket
- Stuff_Diff
- Stuff_DiffZero
- Stuff_Same
- Stuff_Zero
- Stuff_NoCode
- Stuff_CodeMask
- Stuff_CountMask
- Stuff_MaxCount
- Stuff_Magic
- StuffingCode
- StuffData
- UnStuffData
- RecvErr
- RecvErr_Message
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 #include "strip.h"
91 #if NSTRIP > 0
92
93 #include "bpfilter.h"
94
95 #include <sys/param.h>
96 #include <sys/proc.h>
97 #include <sys/mbuf.h>
98 #include <sys/dkstat.h>
99 #include <sys/socket.h>
100 #include <sys/ioctl.h>
101 #include <sys/file.h>
102 #include <sys/tty.h>
103 #include <sys/kernel.h>
104 #include <sys/conf.h>
105 #if defined(__NetBSD__) || defined(__OpenBSD__)
106 #include <sys/systm.h>
107 #endif
108 #include <sys/syslog.h>
109
110 #include <machine/cpu.h>
111
112 #include <net/if.h>
113 #include <net/if_dl.h>
114 #include <net/if_types.h>
115 #include <net/netisr.h>
116 #include <net/route.h>
117
118 #if INET
119 #include <netinet/in.h>
120 #include <netinet/in_systm.h>
121 #include <netinet/in_var.h>
122 #include <netinet/ip.h>
123 #else
124 #error Starmode Radio IP configured without configuring inet?
125 #endif
126
127 #include <net/slcompress.h>
128 #include <net/if_stripvar.h>
129 #include <net/slip.h>
130
131 #if defined(__NetBSD__) || defined(__OpenBSD__)
132 typedef u_char ttychar_t;
133 #else
134 typedef char ttychar_t;
135 #endif
136
137 #if NBPFILTER > 0
138 #include <sys/time.h>
139 #include <net/bpf.h>
140 #endif
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182 #if NBPFILTER > 0
183 #define BUFOFFSET (128+sizeof(struct ifnet **)+SLIP_HDRLEN)
184 #else
185 #define BUFOFFSET (128+sizeof(struct ifnet **))
186 #endif
187 #define SLMAX (MCLBYTES - BUFOFFSET)
188 #define SLBUFSIZE (SLMAX + BUFOFFSET)
189 #ifdef SLMTU
190 #undef SLMTU
191 #endif
192 #define SLMTU 1100
193
194 #define STRIP_MTU_ONWIRE (SLMTU + 20 + STRIP_HDRLEN)
195
196
197
198 #define SLIP_HIWAT roundup(50,CBSIZE)
199
200
201 #define CCOUNT(q) ((q)->c_cc)
202
203
204 #if !(defined(__NetBSD__) || defined(__OpenBSD__))
205 #define CLISTRESERVE 1024
206 #endif
207
208
209
210
211
212
213
214
215 #define ABT_ESC '\033'
216 #define ABT_IDLE 1
217 #define ABT_COUNT 3
218 #define ABT_WINDOW (ABT_COUNT*2+2)
219
220 struct st_softc st_softc[NSTRIP];
221
222 #define STRIP_FRAME_END 0x0D
223
224
225 static int stripinit(struct st_softc *);
226 static struct mbuf *strip_btom(struct st_softc *, int);
227
228
229
230
231
232
233
234
235 #define STRIP_ENCAP_SIZE(X) ((36) + (X)*65/64 + 2)
236 #define STRIP_HDRLEN 15
237 #define STRIP_MAC_ADDR_LEN 9
238
239
240
241
242
243 #define STARMODE_ADDR_LEN 11
244 struct st_header {
245 u_char starmode_addr[STARMODE_ADDR_LEN];
246 u_char starmode_type[4];
247 };
248
249
250
251
252
253
254
255 static u_char *UnStuffData(u_char *src, u_char *end, u_char
256 *dest, u_long dest_length);
257
258 static u_char *StuffData(u_char *src, u_long length, u_char *dest,
259 u_char **code_ptr_ptr);
260
261 static void RecvErr(char *msg, struct st_softc *sc);
262 static void RecvErr_Message(struct st_softc *strip_info,
263 u_char *sendername, u_char *msg);
264 void strip_resetradio(struct st_softc *sc, struct tty *tp);
265 void strip_proberadio(struct st_softc *sc, struct tty *tp);
266 void strip_watchdog(struct ifnet *ifp);
267 void strip_sendbody(struct st_softc *sc, struct mbuf *m);
268 int strip_newpacket(struct st_softc *sc, u_char *ptr, u_char *end);
269 struct mbuf * strip_send(struct st_softc *sc, struct mbuf *m0);
270
271 void strip_timeout(void *x);
272
273
274
275 #ifdef DEBUG
276 #define DPRINTF(x) printf x
277 #else
278 #define DPRINTF(x)
279 #endif
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296 #define STRIP_WATCHDOG_INTERVAL 5
297
298
299 #define ST_PROBE_INTERVAL 10
300
301
302 #define ST_PROBERESPONSE_INTERVAL 2
303
304
305 #define STRIP_RESET_INTERVAL 5
306
307
308
309
310
311
312 #define CLEAR_RESET_TIMER(sc) \
313 do {\
314 (sc)->sc_state = ST_ALIVE; \
315 (sc)->sc_statetimo = time_second + ST_PROBE_INTERVAL; \
316 } while (0)
317
318
319
320
321
322 #define FORCE_RESET(sc) \
323 do {\
324 (sc)->sc_statetimo = time_second - 1; \
325 (sc)->sc_state = ST_DEAD; \
326 \
327 } while (0)
328
329 #define RADIO_PROBE_TIMEOUT(sc) \
330 ((sc)-> sc_statetimo > time_second)
331
332
333
334
335
336
337 void
338 stripattach(n)
339 int n;
340 {
341 struct st_softc *sc;
342 int i = 0;
343
344 for (sc = st_softc; i < NSTRIP; sc++) {
345 timeout_set(&sc->sc_timo, strip_timeout, sc);
346 sc->sc_unit = i;
347 snprintf(sc->sc_if.if_xname, sizeof sc->sc_if.if_xname,
348 "strip%d", i++);
349 sc->sc_if.if_softc = sc;
350 sc->sc_if.if_mtu = SLMTU;
351 sc->sc_if.if_flags = 0;
352 sc->sc_if.if_type = IFT_OTHER;
353 #if 0
354 sc->sc_if.if_flags |= SC_AUTOCOMP ;
355 #endif
356 sc->sc_if.if_type = IFT_SLIP;
357 sc->sc_if.if_ioctl = stripioctl;
358 sc->sc_if.if_output = stripoutput;
359 IFQ_SET_MAXLEN(&sc->sc_if.if_snd, 50);
360 sc->sc_fastq.ifq_maxlen = 32;
361
362 sc->sc_if.if_watchdog = strip_watchdog;
363 sc->sc_if.if_timer = STRIP_WATCHDOG_INTERVAL;
364 IFQ_SET_READY(&sc->sc_if.if_snd);
365 if_attach(&sc->sc_if);
366 if_alloc_sadl(&sc->sc_if);
367 #if NBPFILTER > 0
368 bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_SLIP, SLIP_HDRLEN);
369 #endif
370 }
371 }
372
373 static int
374 stripinit(sc)
375 struct st_softc *sc;
376 {
377 caddr_t p;
378
379 if (sc->sc_ep == (u_char *) 0) {
380 MCLALLOC(p, M_WAIT);
381 if (p)
382 sc->sc_ep = (u_char *)p + SLBUFSIZE;
383 else {
384 addlog("%s: can't allocate buffer\n",
385 sc->sc_if.if_xname);
386 sc->sc_if.if_flags &= ~IFF_UP;
387 return (0);
388 }
389 }
390
391
392 if (sc->sc_rxbuf == (u_char *) 0) {
393 MCLALLOC(p, M_WAIT);
394 if (p)
395 sc->sc_rxbuf = (u_char *)p + SLBUFSIZE - SLMAX;
396 else {
397 addlog("%s: can't allocate input buffer\n",
398 sc->sc_if.if_xname);
399 sc->sc_if.if_flags &= ~IFF_UP;
400 return (0);
401 }
402 }
403
404
405 if (sc->sc_txbuf == (u_char *) 0) {
406 MCLALLOC(p, M_WAIT);
407 if (p)
408 sc->sc_txbuf = (u_char *)p + SLBUFSIZE - SLMAX;
409 else {
410 addlog("%s: can't allocate buffer\n",
411 sc->sc_if.if_xname);
412
413 sc->sc_if.if_flags &= ~IFF_UP;
414 return (0);
415 }
416 }
417
418 sc->sc_buf = sc->sc_ep - SLMAX;
419 sc->sc_mp = sc->sc_buf;
420 sl_compress_init(&sc->sc_comp);
421
422
423 sc->sc_state = ST_DEAD;
424 sc->sc_statetimo = time_second;
425
426 return (1);
427 }
428
429
430
431
432
433
434 int
435 stripopen(dev, tp)
436 dev_t dev;
437 struct tty *tp;
438 {
439 struct proc *p = curproc;
440 struct st_softc *sc;
441 int nstrip;
442 int error;
443 #if defined(__NetBSD__) || defined(__OpenBSD__)
444 int s;
445 #endif
446
447 if ((error = suser(p, 0)) != 0)
448 return (error);
449
450 if (tp->t_line == STRIPDISC)
451 return (0);
452
453 for (nstrip = NSTRIP, sc = st_softc; --nstrip >= 0; sc++)
454 if (sc->sc_ttyp == NULL) {
455 if (stripinit(sc) == 0)
456 return (ENOBUFS);
457 tp->t_sc = (caddr_t)sc;
458 sc->sc_ttyp = tp;
459 sc->sc_if.if_baudrate = tp->t_ospeed;
460 ttyflush(tp, FREAD | FWRITE);
461 #if defined(__NetBSD__) || defined(__OpenBSD__)
462
463
464
465
466
467
468
469
470 s = spltty();
471 if (tp->t_outq.c_cn < STRIP_MTU_ONWIRE) {
472 sc->sc_oldbufsize = tp->t_outq.c_cn;
473 sc->sc_oldbufquot = tp->t_outq.c_cq != 0;
474
475 clfree(&tp->t_outq);
476 error = clalloc(&tp->t_outq, 3*SLMTU, 0);
477 if (error) {
478 splx(s);
479 return (error);
480 }
481 } else
482 sc->sc_oldbufsize = sc->sc_oldbufquot = 0;
483 splx(s);
484 #endif
485 s = spltty();
486 strip_resetradio(sc, tp);
487 splx(s);
488
489 return (0);
490 }
491 return (ENXIO);
492 }
493
494
495
496
497
498 void
499 stripclose(tp)
500 struct tty *tp;
501 {
502 struct st_softc *sc;
503 int s;
504
505 ttywflush(tp);
506
507 s = spltty();
508 tp->t_line = 0;
509 sc = (struct st_softc *)tp->t_sc;
510 if (sc != NULL) {
511 if_down(&sc->sc_if);
512 sc->sc_ttyp = NULL;
513 tp->t_sc = NULL;
514 MCLFREE((caddr_t)(sc->sc_ep - SLBUFSIZE));
515 MCLFREE((caddr_t)(sc->sc_rxbuf - SLBUFSIZE + SLMAX));
516 MCLFREE((caddr_t)(sc->sc_txbuf - SLBUFSIZE + SLMAX));
517 sc->sc_ep = 0;
518 sc->sc_mp = 0;
519 sc->sc_buf = 0;
520 sc->sc_rxbuf = 0;
521 sc->sc_txbuf = 0;
522
523 if (sc->sc_flags & SC_TIMEOUT) {
524 timeout_del(&sc->sc_timo);
525 sc->sc_flags &= ~SC_TIMEOUT;
526 }
527 }
528 #if defined(__NetBSD__) || defined(__OpenBSD__)
529
530 if (sc->sc_oldbufsize != 0) {
531 clfree(&tp->t_outq);
532 clalloc(&tp->t_outq, sc->sc_oldbufsize, sc->sc_oldbufquot);
533 }
534 #endif
535 splx(s);
536 }
537
538
539
540
541
542
543 int
544 striptioctl(tp, cmd, data, flag)
545 struct tty *tp;
546 u_long cmd;
547 caddr_t data;
548 int flag;
549 {
550 struct st_softc *sc = (struct st_softc *)tp->t_sc;
551
552 switch (cmd) {
553 case SLIOCGUNIT:
554 *(int *)data = sc->sc_unit;
555 break;
556
557 default:
558 return (-1);
559 }
560 return (0);
561 }
562
563
564
565
566
567 void
568 strip_sendbody(sc, m)
569 struct st_softc *sc;
570 struct mbuf *m;
571 {
572 struct tty *tp = sc->sc_ttyp;
573 u_char *dp = sc->sc_txbuf;
574 struct mbuf *m2;
575 int len;
576 u_char *rllstate_ptr = NULL;
577
578 while (m) {
579
580
581
582
583
584
585
586
587 dp = StuffData(mtod(m, u_char *), m->m_len, dp, &rllstate_ptr);
588
589 MFREE(m, m2);
590 m = m2;
591 }
592
593
594
595
596 len = dp - sc->sc_txbuf;
597 if (b_to_q((ttychar_t *)sc->sc_txbuf,
598 len, &tp->t_outq)) {
599 if (sc->sc_if.if_flags & IFF_DEBUG)
600 addlog("%s: tty output overflow\n",
601 sc->sc_if.if_xname);
602 goto bad;
603 }
604 sc->sc_if.if_obytes += len;
605
606 return;
607
608 bad:
609 m_freem(m);
610 return;
611 }
612
613
614
615
616
617
618
619
620
621 struct mbuf *
622 strip_send(sc, m0)
623 struct st_softc *sc;
624 struct mbuf *m0;
625 {
626 struct tty *tp = sc->sc_ttyp;
627 struct st_header *hdr;
628
629
630
631
632 hdr = mtod(m0, struct st_header *);
633 if (b_to_q((ttychar_t *)hdr, STRIP_HDRLEN, &tp->t_outq)) {
634 if (sc->sc_if.if_flags & IFF_DEBUG)
635 addlog("%s: outq overflow writing header\n",
636 sc->sc_if.if_xname);
637 m_freem(m0);
638 return 0;
639 }
640
641
642 m0->m_data += sizeof(struct st_header);
643 m0->m_len -= sizeof(struct st_header);
644 if (m0->m_flags & M_PKTHDR) {
645 m0->m_pkthdr.len -= sizeof(struct st_header);
646 }
647 #ifdef DIAGNOSTIC
648 else
649 addlog("%s: strip_send: missing pkthdr, %d remains\n",
650 sc->sc_if.if_xname, m0->m_len);
651 #endif
652
653
654
655
656
657 if (m0->m_len == 0) {
658 struct mbuf *m;
659 MFREE(m0, m);
660 m0 = m;
661 }
662
663
664 strip_sendbody(sc, m0);
665
666 if (putc(STRIP_FRAME_END, &tp->t_outq)) {
667
668
669
670
671
672
673
674 (void) unputc(&tp->t_outq);
675 (void) putc(STRIP_FRAME_END, &tp->t_outq);
676 sc->sc_if.if_collisions++;
677 } else {
678 ++sc->sc_if.if_obytes;
679 sc->sc_if.if_opackets++;
680 }
681
682
683
684
685
686 if (time_second >= sc->sc_statetimo && sc->sc_state == ST_ALIVE)
687 strip_proberadio(sc, tp);
688
689 return (m0);
690 }
691
692
693
694
695
696
697
698
699
700 int
701 stripoutput(ifp, m, dst, rt)
702 struct ifnet *ifp;
703 struct mbuf *m;
704 struct sockaddr *dst;
705 struct rtentry *rt;
706 {
707 struct st_softc *sc = ifp->if_softc;
708 struct ip *ip;
709 struct ifqueue *ifq;
710 struct st_header *shp;
711 u_char *dldst;
712 int s;
713 u_char dl_addrbuf[STARMODE_ADDR_LEN+1];
714
715
716
717
718 if (sc->sc_ttyp == NULL) {
719 m_freem(m);
720 return (ENETDOWN);
721 }
722 if ((sc->sc_ttyp->t_state & TS_CARR_ON) == 0 &&
723 (sc->sc_ttyp->t_cflag & CLOCAL) == 0) {
724 m_freem(m);
725 return (EHOSTUNREACH);
726 }
727
728 #define SDL(a) ((struct sockaddr_dl *) (a))
729
730 #ifdef DEBUG
731 if (rt) {
732 printf("stripout, rt: dst af%d gw af%d",
733 rt_key(rt)->sa_family,
734 rt->rt_gateway->sa_family);
735 if (rt_key(rt)->sa_family == AF_INET)
736 printf(" dst %x",
737 ((struct sockaddr_in *)rt_key(rt))->sin_addr.s_addr);
738 printf("\n");
739 }
740 #endif
741
742 switch (dst->sa_family) {
743 case AF_INET:
744 if (rt != NULL && rt->rt_gwroute != NULL)
745 rt = rt->rt_gwroute;
746
747
748 if (rt == NULL || rt->rt_gateway->sa_family != AF_LINK
749 || SDL(rt->rt_gateway)->sdl_alen != ifp->if_addrlen) {
750 DPRINTF(("strip: could not arp starmode addr %x\n",
751 ((struct sockaddr_in *)dst)->sin_addr.s_addr));
752 m_freem(m);
753 return (EHOSTUNREACH);
754 }
755
756 dldst = LLADDR(SDL(rt->rt_gateway));
757 break;
758
759 case AF_LINK:
760
761 dldst = LLADDR(SDL(dst));
762 break;
763
764 default:
765
766
767
768
769 addlog("%s: af %d not supported\n", sc->sc_if.if_xname,
770 dst->sa_family);
771 m_freem(m);
772 sc->sc_if.if_noproto++;
773 return (EAFNOSUPPORT);
774 }
775
776 ifq = NULL;
777 ip = mtod(m, struct ip *);
778 if (sc->sc_if.if_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) {
779 m_freem(m);
780 return (ENETRESET);
781 }
782 if ((ip->ip_tos & IPTOS_LOWDELAY)
783 #ifdef ALTQ
784 && ALTQ_IS_ENABLED(&sc->sc_if.if_snd) == 0
785 #endif
786 )
787 ifq = &sc->sc_fastq;
788
789
790
791
792
793 M_PREPEND(m, sizeof(struct st_header), M_DONTWAIT);
794 if (m == 0) {
795 DPRINTF(("strip: could not prepend starmode header\n"));
796 return (ENOBUFS);
797 }
798
799
800
801
802
803
804 dl_addrbuf[0] = '*';
805
806 dl_addrbuf[1] = ((dldst[0] >> 4) & 0x0f) + '0';
807 dl_addrbuf[2] = ((dldst[0] ) & 0x0f) + '0';
808
809 dl_addrbuf[3] = ((dldst[1] >> 4) & 0x0f) + '0';
810 dl_addrbuf[4] = ((dldst[1] ) & 0x0f) + '0';
811
812 dl_addrbuf[5] = '-';
813
814 dl_addrbuf[6] = ((dldst[2] >> 4) & 0x0f) + '0';
815 dl_addrbuf[7] = ((dldst[2] ) & 0x0f) + '0';
816
817 dl_addrbuf[8] = ((dldst[3] >> 4) & 0x0f) + '0';
818 dl_addrbuf[9] = ((dldst[3] ) & 0x0f) + '0';
819
820 dl_addrbuf[10] = '*';
821 dl_addrbuf[11] = 0;
822 dldst = dl_addrbuf;
823
824 shp = mtod(m, struct st_header *);
825 bcopy((caddr_t)"SIP0", (caddr_t)shp->starmode_type,
826 sizeof(shp->starmode_type));
827
828 bcopy((caddr_t)dldst, (caddr_t)shp->starmode_addr,
829 sizeof (shp->starmode_addr));
830
831 s = spltty();
832 if (sc->sc_oqlen && sc->sc_ttyp->t_outq.c_cc == sc->sc_oqlen) {
833 struct timeval tv, tm;
834
835
836 getmicrotime(&tm);
837 timersub(&tm, &sc->sc_lastpacket, &tv);
838 if (tv.tv_sec > 0) {
839 DPRINTF(("stripoutput: stalled, resetting\n"));
840 sc->sc_otimeout++;
841 stripstart(sc->sc_ttyp);
842 }
843 }
844
845 (void) splnet();
846 if (ifq != NULL) {
847 if (IF_QFULL(ifq)) {
848 IF_DROP(ifq);
849 m_freem(m);
850 error = ENOBUFS;
851 } else {
852 IF_ENQUEUE(ifq, m);
853 error = 0;
854 }
855 } else
856 IFQ_ENQUEUE(&sc->sc_if.if_snd, m, NULL, error);
857 if (error) {
858 splx(s);
859 sc->sc_if.if_oerrors++;
860 return (error);
861 }
862
863 (void) spltty();
864 getmicrotime(&sc->sc_lastpacket);
865 if ((sc->sc_oqlen = sc->sc_ttyp->t_outq.c_cc) == 0) {
866 stripstart(sc->sc_ttyp);
867 }
868
869
870
871
872
873 stripstart(sc->sc_ttyp);
874
875 splx(s);
876 return (0);
877 }
878
879
880
881
882
883
884
885
886 void
887 stripstart(tp)
888 struct tty *tp;
889 {
890 struct st_softc *sc = (struct st_softc *)tp->t_sc;
891 struct mbuf *m;
892 struct ip *ip;
893 int s;
894 #if NBPFILTER > 0
895 u_char bpfbuf[SLMTU + SLIP_HDRLEN];
896 int len = 0;
897 #endif
898 #if !(defined(__NetBSD__) || defined(__OpenBSD__))
899 extern int cfreecount;
900 #endif
901
902
903
904
905
906
907
908
909 if (((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
910 || sc == NULL || tp != (struct tty *) sc->sc_ttyp) {
911 if (tp->t_oproc != NULL)
912 (*tp->t_oproc)(tp);
913 if (sc && (sc->sc_if.if_flags & IFF_DEBUG))
914 addlog("%s: late call to stripstart\n ",
915 sc->sc_if.if_xname);
916 }
917
918
919 if (CCOUNT(&tp->t_outq) != 0) {
920 (*tp->t_oproc)(tp);
921 }
922
923 while (CCOUNT(&tp->t_outq) < SLIP_HIWAT) {
924
925
926
927
928 if (sc == NULL) {
929 return;
930 }
931
932 #if defined(__NetBSD__) || defined(__OpenBSD__)
933
934
935
936
937
938
939
940
941
942 if (tp->t_outq.c_cn - tp->t_outq.c_cc < STRIP_MTU_ONWIRE + 4)
943 return;
944 #endif
945
946
947
948 s = splnet();
949 IF_DEQUEUE(&sc->sc_fastq, m);
950 if (m)
951 sc->sc_if.if_omcasts++;
952 else
953 IFQ_DEQUEUE(&sc->sc_if.if_snd, m);
954 splx(s);
955 if (m == NULL) {
956 return;
957 }
958
959
960
961
962
963
964 #if NBPFILTER > 0
965 if (sc->sc_bpf) {
966
967
968
969
970
971
972
973
974 struct mbuf *m1 = m;
975 u_char *cp = bpfbuf + SLIP_HDRLEN;
976
977 len = 0;
978 do {
979 int mlen = m1->m_len;
980
981 bcopy(mtod(m1, caddr_t), cp, mlen);
982 cp += mlen;
983 len += mlen;
984 } while ((m1 = m1->m_next) != NULL);
985 }
986 #endif
987 if ((ip = mtod(m, struct ip *))->ip_p == IPPROTO_TCP) {
988 if (sc->sc_if.if_flags & SC_COMPRESS)
989 *mtod(m, u_char *) |= sl_compress_tcp(m, ip,
990 &sc->sc_comp, 1);
991 }
992 #if NBPFILTER > 0
993 if (sc->sc_bpf) {
994 u_char *cp = bpfbuf + STRIP_HDRLEN;
995
996
997
998
999
1000 cp[SLX_DIR] = SLIPDIR_OUT;
1001
1002 bcopy(mtod(m, caddr_t)+STRIP_HDRLEN, &cp[SLX_CHDR], CHDR_LEN);
1003 bpf_tap(sc->sc_bpf, cp, len + SLIP_HDRLEN,
1004 BPF_DIRECTION_OUT);
1005 }
1006 #endif
1007 getmicrotime(&sc->sc_lastpacket);
1008
1009 #if !(defined(__NetBSD__) || defined(__OpenBSD__))
1010
1011
1012
1013
1014
1015 if (cfreecount < CLISTRESERVE + SLMTU) {
1016 m_freem(m);
1017 sc->sc_if.if_collisions++;
1018 continue;
1019 }
1020 #endif
1021
1022 if (strip_send(sc, m) == NULL) {
1023 DPRINTF(("stripsend: failed to send pkt\n"));
1024 }
1025 }
1026
1027
1028 #if 0
1029
1030 if ((sc->sc_flags & SC_TIMEOUT) == 0) {
1031 timeout_add(&sc->sc_timo, hz);
1032 sc->sc_flags |= SC_TIMEOUT;
1033 }
1034 #endif
1035
1036 #if 0
1037
1038
1039
1040
1041
1042 if ((sc->sc_flags & SC_TIMEOUT) == 0) {
1043 timeout_add(&sc->sc_timo, hz);
1044 sc->sc_flags |= SC_TIMEOUT;
1045 }
1046 #endif
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057 if (tp->t_oproc != NULL)
1058 (*tp->t_oproc)(tp);
1059 }
1060
1061
1062
1063
1064
1065
1066 static struct mbuf *
1067 strip_btom(sc, len)
1068 struct st_softc *sc;
1069 int len;
1070 {
1071 struct mbuf *m;
1072
1073 MGETHDR(m, M_DONTWAIT, MT_DATA);
1074 if (m == NULL)
1075 return (NULL);
1076
1077
1078
1079
1080
1081
1082
1083
1084 if (len >= MHLEN) {
1085 MCLGET(m, M_DONTWAIT);
1086 if ((m->m_flags & M_EXT) == 0) {
1087
1088
1089
1090
1091 (void) m_free(m);
1092 return (NULL);
1093 }
1094 sc->sc_ep = mtod(m, u_char *) + SLBUFSIZE;
1095 m->m_data = (caddr_t)sc->sc_buf;
1096 m->m_ext.ext_buf = (caddr_t)((long)sc->sc_buf &~ MCLOFSET);
1097 } else
1098 bcopy((caddr_t)sc->sc_buf, mtod(m, caddr_t), len);
1099
1100 m->m_len = len;
1101 m->m_pkthdr.len = len;
1102 m->m_pkthdr.rcvif = &sc->sc_if;
1103 return (m);
1104 }
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114 void
1115 stripinput(c, tp)
1116 int c;
1117 struct tty *tp;
1118 {
1119 struct st_softc *sc;
1120 struct mbuf *m;
1121 int len;
1122 int s;
1123 #if NBPFILTER > 0
1124 u_char chdr[CHDR_LEN];
1125 #endif
1126
1127 tk_nin++;
1128 sc = (struct st_softc *)tp->t_sc;
1129 if (sc == NULL)
1130 return;
1131 if (c & TTY_ERRORMASK || ((tp->t_state & TS_CARR_ON) == 0 &&
1132 (tp->t_cflag & CLOCAL) == 0)) {
1133 sc->sc_flags |= SC_ERROR;
1134 DPRINTF(("strip: input, error %x\n", c));
1135 return;
1136 }
1137 c &= TTY_CHARMASK;
1138
1139 ++sc->sc_if.if_ibytes;
1140
1141
1142
1143
1144 switch (c) {
1145
1146 case '\n':
1147
1148
1149
1150
1151
1152
1153 if (sc->sc_mp - sc->sc_buf == 0)
1154 break;
1155
1156
1157
1158 default:
1159 if (sc->sc_mp < sc->sc_ep) {
1160 *sc->sc_mp++ = c;
1161 } else {
1162 sc->sc_flags |= SC_ERROR;
1163 goto error;
1164 }
1165 return;
1166
1167 case STRIP_FRAME_END:
1168 break;
1169 }
1170
1171
1172
1173
1174
1175
1176
1177 len = sc->sc_mp - sc->sc_buf;
1178
1179 #ifdef XDEBUG
1180 if (len < 15 || sc->sc_flags & SC_ERROR)
1181 addlog("stripinput: end of pkt, len %d, err %d\n",
1182 len, sc->sc_flags & SC_ERROR);
1183 #endif
1184 if(sc->sc_flags & SC_ERROR) {
1185 sc->sc_flags &= ~SC_ERROR;
1186 addlog("%s: sc error flag set. terminating packet\n",
1187 sc->sc_if.if_xname);
1188 goto newpack;
1189 }
1190
1191
1192
1193
1194
1195
1196 len = strip_newpacket(sc, sc->sc_buf, sc->sc_mp);
1197 if (len <= 1)
1198
1199 goto newpack;
1200
1201
1202 #if NBPFILTER > 0
1203 if (sc->sc_bpf) {
1204
1205
1206
1207
1208
1209
1210
1211
1212 bcopy(sc->sc_buf, chdr, CHDR_LEN);
1213 }
1214 #endif
1215
1216 if ((c = (*sc->sc_buf & 0xf0)) != (IPVERSION << 4)) {
1217 if (c & 0x80)
1218 c = TYPE_COMPRESSED_TCP;
1219 else if (c == TYPE_UNCOMPRESSED_TCP)
1220 *sc->sc_buf &= 0x4f;
1221
1222
1223
1224
1225
1226
1227
1228 if (sc->sc_if.if_flags & SC_COMPRESS) {
1229 len = sl_uncompress_tcp(&sc->sc_buf, len,
1230 (u_int)c, &sc->sc_comp);
1231 if (len <= 0)
1232 goto error;
1233 } else if ((sc->sc_if.if_flags & SC_AUTOCOMP) &&
1234 c == TYPE_UNCOMPRESSED_TCP && len >= 40) {
1235 len = sl_uncompress_tcp(&sc->sc_buf, len,
1236 (u_int)c, &sc->sc_comp);
1237 if (len <= 0)
1238 goto error;
1239 sc->sc_if.if_flags |= SC_COMPRESS;
1240 } else
1241 goto error;
1242 }
1243
1244 #if NBPFILTER > 0
1245 if (sc->sc_bpf) {
1246
1247
1248
1249
1250
1251
1252 u_char *hp = sc->sc_buf - SLIP_HDRLEN;
1253
1254 hp[SLX_DIR] = SLIPDIR_IN;
1255 bcopy(chdr, &hp[SLX_CHDR], CHDR_LEN);
1256 bpf_tap(sc->sc_bpf, hp, len + SLIP_HDRLEN, BPF_DIRECTION_IN);
1257 }
1258 #endif
1259 m = strip_btom(sc, len);
1260 if (m == NULL) {
1261 goto error;
1262 }
1263
1264 sc->sc_if.if_ipackets++;
1265 getmicrotime(&sc->sc_lastpacket);
1266 s = splnet();
1267 if (IF_QFULL(&ipintrq)) {
1268 IF_DROP(&ipintrq);
1269 sc->sc_if.if_ierrors++;
1270 sc->sc_if.if_iqdrops++;
1271 if (!ipintrq.ifq_congestion)
1272 if_congestion(&ipintrq);
1273 m_freem(m);
1274 } else {
1275 IF_ENQUEUE(&ipintrq, m);
1276 schednetisr(NETISR_IP);
1277 }
1278 splx(s);
1279 goto newpack;
1280
1281 error:
1282 sc->sc_if.if_ierrors++;
1283
1284 newpack:
1285
1286 sc->sc_mp = sc->sc_buf = sc->sc_ep - SLMAX;
1287 }
1288
1289
1290
1291
1292 int
1293 stripioctl(ifp, cmd, data)
1294 struct ifnet *ifp;
1295 u_long cmd;
1296 caddr_t data;
1297 {
1298 struct ifaddr *ifa = (struct ifaddr *)data;
1299 struct ifreq *ifr;
1300 int s = splnet(), error = 0;
1301
1302 switch (cmd) {
1303
1304 case SIOCSIFADDR:
1305 if (ifa->ifa_addr->sa_family == AF_INET)
1306 ifp->if_flags |= IFF_UP;
1307 else
1308 error = EAFNOSUPPORT;
1309 break;
1310
1311 case SIOCSIFDSTADDR:
1312 if (ifa->ifa_addr->sa_family != AF_INET)
1313 error = EAFNOSUPPORT;
1314 break;
1315
1316 case SIOCADDMULTI:
1317 case SIOCDELMULTI:
1318 ifr = (struct ifreq *)data;
1319 if (ifr == 0) {
1320 error = EAFNOSUPPORT;
1321 break;
1322 }
1323 switch (ifr->ifr_addr.sa_family) {
1324
1325 #ifdef INET
1326 case AF_INET:
1327 break;
1328 #endif
1329
1330 default:
1331 error = EAFNOSUPPORT;
1332 break;
1333 }
1334 break;
1335
1336 default:
1337
1338 #ifdef DEBUG
1339 addlog("stripioctl: unknown request 0x%lx\n", cmd);
1340 #endif
1341 error = EINVAL;
1342 }
1343 splx(s);
1344 return (error);
1345 }
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356 void
1357 strip_resetradio(sc, tp)
1358 struct st_softc *sc;
1359 struct tty *tp;
1360 {
1361 #if 0
1362 static ttychar_t InitString[] =
1363 "\r\n\r\n\r\nat\r\n\r\n\r\nate0dt**starmode\r\n**\r\n";
1364 #else
1365 static ttychar_t InitString[] =
1366 "\r\rat\r\r\rate0q1dt**starmode\r**\r";
1367 #endif
1368 int i;
1369
1370
1371
1372
1373
1374 if (tp == NULL)
1375 return;
1376
1377 if ((i = b_to_q(InitString, sizeof(InitString) - 1, &tp->t_outq))) {
1378 addlog("resetradio: %d chars didn't fit in tty queue\n", i);
1379 return;
1380 }
1381 sc->sc_if.if_obytes += sizeof(InitString) - 1;
1382
1383
1384
1385
1386
1387
1388 sc->sc_state = ST_DEAD;
1389 getmicrotime(&sc->sc_lastpacket);
1390 sc->sc_statetimo = time_second + STRIP_RESET_INTERVAL;
1391
1392
1393
1394
1395 (*sc->sc_ttyp->t_oproc)(tp);
1396 }
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409 void
1410 strip_proberadio(sc, tp)
1411 struct st_softc *sc;
1412 struct tty *tp;
1413 {
1414
1415 int overflow;
1416 char *strip_probestr = "**";
1417
1418 if (sc->sc_if.if_flags & IFF_DEBUG)
1419 addlog("%s: attempting to probe radio\n", sc->sc_if.if_xname);
1420
1421 if (tp == NULL) {
1422 addlog("%s: no tty attached\n", sc->sc_if.if_xname);
1423 return;
1424 }
1425
1426 overflow = b_to_q((ttychar_t *)strip_probestr, 2, &tp->t_outq);
1427 if (overflow == 0) {
1428 if (sc->sc_if.if_flags & IFF_DEBUG)
1429 addlog("%s:: sent probe to radio\n",
1430 sc->sc_if.if_xname);
1431
1432 sc->sc_state = ST_PROBE_SENT;
1433 sc->sc_statetimo = time_second + ST_PROBERESPONSE_INTERVAL;
1434 } else {
1435 addlog("%s: incomplete probe, tty queue %d bytes overfull\n",
1436 sc->sc_if.if_xname, overflow);
1437 }
1438 }
1439
1440
1441 #ifdef DEBUG
1442 static char *strip_statenames[] = {
1443 "Alive",
1444 "Probe sent, awaiting answer",
1445 "Probe not answered, resetting"
1446 };
1447 #endif
1448
1449
1450
1451
1452
1453
1454 void
1455 strip_timeout(x)
1456 void *x;
1457 {
1458 struct st_softc *sc = (struct st_softc *) x;
1459 struct tty *tp = sc->sc_ttyp;
1460 int s;
1461
1462 s = spltty();
1463 sc->sc_flags &= ~SC_TIMEOUT;
1464 stripstart(tp);
1465 splx(s);
1466 }
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490 void
1491 strip_watchdog(ifp)
1492 struct ifnet *ifp;
1493 {
1494 struct st_softc *sc = ifp->if_softc;
1495 struct tty *tp = sc->sc_ttyp;
1496
1497 #ifdef DEBUG
1498 if (ifp->if_flags & IFF_DEBUG)
1499 addlog("\n%s: in watchdog, state %s timeout %ld\n",
1500 ifp->if_xname,
1501 ((unsigned) sc->sc_state < 3) ?
1502 strip_statenames[sc->sc_state] : "<<illegal state>>",
1503 sc->sc_statetimo - time_second);
1504 #endif
1505
1506
1507
1508
1509 if ((ifp->if_flags & IFF_UP) == 0 || sc->sc_statetimo > time_second) {
1510 goto done;
1511 }
1512
1513
1514
1515
1516
1517 switch (sc->sc_state) {
1518 case ST_ALIVE:
1519
1520
1521
1522
1523 if (tp == NULL)
1524 break;
1525 strip_proberadio(sc, sc->sc_ttyp);
1526 (*tp->t_oproc)(tp);
1527 break;
1528
1529 case ST_PROBE_SENT:
1530
1531
1532
1533 addlog("%s: no answer to probe, resetting radio\n",
1534 ifp->if_xname);
1535 strip_resetradio(sc, sc->sc_ttyp);
1536 ifp->if_oerrors++;
1537 break;
1538
1539 case ST_DEAD:
1540
1541
1542
1543
1544
1545 addlog("%s: radio reset but not responding, Trying again\n",
1546 ifp->if_xname);
1547 strip_resetradio(sc, sc->sc_ttyp);
1548 ifp->if_oerrors++;
1549 break;
1550
1551 default:
1552
1553 addlog("%s: %s %d, resetting\n",
1554 sc->sc_if.if_xname,
1555 "radio-reset finite-state machine in invalid state",
1556 sc->sc_state);
1557 strip_resetradio(sc, sc->sc_ttyp);
1558 sc->sc_state = ST_DEAD;
1559 break;
1560 }
1561
1562 done:
1563 ifp->if_timer = STRIP_WATCHDOG_INTERVAL;
1564 return;
1565 }
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580 int
1581 strip_newpacket(sc, ptr, end)
1582 struct st_softc *sc;
1583 u_char *ptr, *end;
1584 {
1585 int len = ptr - end;
1586 u_char *name, *name_end;
1587 u_int packetlen;
1588
1589
1590 if (len == 0) return 0;
1591
1592
1593 if (len >= 2 && ptr[0] == 'O' && ptr[1] == 'K') {
1594 addlog("%s: Radio is back in AT command mode: will reset\n",
1595 sc->sc_if.if_xname);
1596 FORCE_RESET(sc);
1597 return 0;
1598 }
1599
1600
1601 if (*ptr != '*') {
1602
1603 if (ptr[0] == 'E' && ptr[1] == 'R' && ptr[2] == 'R' && ptr[3] == '_')
1604 RecvErr_Message(sc, NULL, ptr+4);
1605
1606 else {
1607 RecvErr("No initial *", sc);
1608 addlog("(len = %d)\n", len);
1609 }
1610 return 0;
1611 }
1612
1613
1614 ptr++;
1615
1616
1617 name = ptr;
1618 while (ptr < end && *ptr != '*')
1619 ptr++;
1620
1621
1622 if (ptr == end) {
1623 RecvErr("No second *", sc);
1624 return 0;
1625 }
1626 name_end = ptr++;
1627
1628
1629 if (ptr[0] != 'S' || ptr[1] != 'I' || ptr[2] != 'P' || ptr[3] != '0') {
1630 if (ptr[0] == 'E' && ptr[1] == 'R' && ptr[2] == 'R' &&
1631 ptr[3] == '_') {
1632 *name_end = 0;
1633 RecvErr_Message(sc, name, ptr+4);
1634 }
1635 else RecvErr("No SRIP key", sc);
1636 return 0;
1637 }
1638 ptr += 4;
1639
1640
1641 ptr = UnStuffData(ptr, end, sc->sc_rxbuf, 4);
1642 if (ptr == 0) {
1643 RecvErr("Runt packet (hdr)", sc);
1644 return 0;
1645 }
1646
1647
1648
1649
1650
1651
1652 packetlen = ((u_short)sc->sc_rxbuf[2] << 8) | sc->sc_rxbuf[3];
1653
1654 #ifdef DIAGNOSTIC
1655
1656
1657
1658
1659 #endif
1660
1661
1662 ptr = UnStuffData(ptr, end, sc->sc_rxbuf+4, packetlen-4);
1663 if (ptr == 0) {
1664 RecvErr("Short packet", sc);
1665 return 0;
1666 }
1667
1668
1669 bcopy(sc->sc_rxbuf, sc->sc_buf, packetlen );
1670 return (packetlen);
1671 }
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682 typedef enum
1683 {
1684 Stuff_Diff = 0x00,
1685 Stuff_DiffZero = 0x40,
1686 Stuff_Same = 0x80,
1687 Stuff_Zero = 0xC0,
1688 Stuff_NoCode = 0xFF,
1689
1690 Stuff_CodeMask = 0xC0,
1691 Stuff_CountMask = 0x3F,
1692 Stuff_MaxCount = 0x3F,
1693 Stuff_Magic = 0x0D
1694 } StuffingCode;
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712 #define StuffData_FinishBlock(X) \
1713 (*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode)
1714
1715 static u_char *
1716 StuffData(u_char *src, u_long length, u_char *dest, u_char **code_ptr_ptr)
1717 {
1718 u_char *end = src + length;
1719 u_char *code_ptr = *code_ptr_ptr;
1720 u_char code = Stuff_NoCode, count = 0;
1721
1722 if (!length) return (dest);
1723
1724 if (code_ptr) {
1725 code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask;
1726 count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask;
1727 }
1728
1729 while (src < end) {
1730 switch (code) {
1731
1732
1733
1734 case Stuff_NoCode:
1735 code_ptr = dest++;
1736 count = 0;
1737
1738 if (*src == 0) {
1739 code = Stuff_Zero;
1740 src++;
1741 } else {
1742 code = Stuff_Same;
1743 *dest++ = *src++ ^ Stuff_Magic;
1744 }
1745
1746
1747 break;
1748
1749
1750
1751
1752 case Stuff_Zero:
1753
1754
1755 if (*src == 0) {
1756 count++;
1757 src++;
1758 } else
1759 StuffData_FinishBlock(Stuff_Zero + count);
1760 break;
1761
1762
1763
1764
1765 case Stuff_Same:
1766
1767 if ((*src ^ Stuff_Magic) == code_ptr[1]) {
1768 count++;
1769 src++;
1770 break;
1771 }
1772
1773
1774 if (count) {
1775 StuffData_FinishBlock(Stuff_Same + count);
1776 break;
1777 }
1778
1779 code = Stuff_Diff;
1780
1781 case Stuff_Diff:
1782
1783 if (*src == 0)
1784 StuffData_FinishBlock(Stuff_DiffZero + count);
1785
1786 else if ((*src ^ Stuff_Magic) == dest[-1] && dest[-1] == dest[-2])
1787 {
1788 code += count-2;
1789 if (code == Stuff_Diff)
1790 code = Stuff_Same;
1791 StuffData_FinishBlock(code);
1792 code_ptr = dest-2;
1793
1794 count = 2;
1795 code = Stuff_Same;
1796 }
1797
1798 else {
1799 *dest++ = *src ^ Stuff_Magic;
1800 count++;
1801 }
1802 src++;
1803 break;
1804 }
1805
1806 if (count == Stuff_MaxCount)
1807 StuffData_FinishBlock(code + count);
1808 }
1809 if (code == Stuff_NoCode)
1810 *code_ptr_ptr = NULL;
1811 else {
1812 *code_ptr_ptr = code_ptr;
1813 StuffData_FinishBlock(code + count);
1814 }
1815
1816 return (dest);
1817 }
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843 static u_char *
1844 UnStuffData(u_char *src, u_char *end, u_char *dst, u_long dst_length)
1845 {
1846 u_char *dst_end = dst + dst_length;
1847
1848
1849 if (!src || !end || !dst || !dst_length)
1850 return (NULL);
1851
1852 while (src < end && dst < dst_end)
1853 {
1854 int count = (*src ^ Stuff_Magic) & Stuff_CountMask;
1855 switch ((*src ^ Stuff_Magic) & Stuff_CodeMask)
1856 {
1857 case Stuff_Diff:
1858 if (src+1+count >= end)
1859 return (NULL);
1860 do
1861 {
1862 *dst++ = *++src ^ Stuff_Magic;
1863 }
1864 while(--count >= 0 && dst < dst_end);
1865 if (count < 0)
1866 src += 1;
1867 else
1868 if (count == 0)
1869 *src = Stuff_Same ^ Stuff_Magic;
1870 else
1871 *src = (Stuff_Diff + count) ^ Stuff_Magic;
1872 break;
1873 case Stuff_DiffZero:
1874 if (src+1+count >= end)
1875 return (NULL);
1876 do
1877 {
1878 *dst++ = *++src ^ Stuff_Magic;
1879 }
1880 while(--count >= 0 && dst < dst_end);
1881 if (count < 0)
1882 *src = Stuff_Zero ^ Stuff_Magic;
1883 else
1884 *src = (Stuff_DiffZero + count) ^ Stuff_Magic;
1885 break;
1886 case Stuff_Same:
1887 if (src+1 >= end)
1888 return (NULL);
1889 do
1890 {
1891 *dst++ = src[1] ^ Stuff_Magic;
1892 }
1893 while(--count >= 0 && dst < dst_end);
1894 if (count < 0)
1895 src += 2;
1896 else
1897 *src = (Stuff_Same + count) ^ Stuff_Magic;
1898 break;
1899 case Stuff_Zero:
1900 do
1901 {
1902 *dst++ = 0;
1903 }
1904 while(--count >= 0 && dst < dst_end);
1905 if (count < 0)
1906 src += 1;
1907 else
1908 *src = (Stuff_Zero + count) ^ Stuff_Magic;
1909 break;
1910 }
1911 }
1912
1913 if (dst < dst_end)
1914 return (NULL);
1915 else
1916 return (src);
1917 }
1918
1919
1920
1921
1922
1923
1924
1925 static void
1926 RecvErr(msg, sc)
1927 char *msg;
1928 struct st_softc *sc;
1929 {
1930 static const int MAX_RecErr = 80;
1931 u_char *ptr = sc->sc_buf;
1932 u_char *end = sc->sc_mp;
1933 u_char pkt_text[MAX_RecErr], *p = pkt_text;
1934 *p++ = '\"';
1935 while (ptr < end && p < &pkt_text[MAX_RecErr-4]) {
1936 if (*ptr == '\\') {
1937 *p++ = '\\';
1938 *p++ = '\\';
1939 } else if (*ptr >= 32 && *ptr <= 126)
1940 *p++ = *ptr;
1941 else {
1942 sprintf(p, "\\%02x", *ptr);
1943 p+= 3;
1944 }
1945 ptr++;
1946 }
1947
1948 if (ptr == end) *p++ = '\"';
1949 *p++ = 0;
1950 addlog("%s: %13s : %s\n", sc->sc_if.if_xname, msg, pkt_text);
1951
1952 sc->sc_if.if_ierrors++;
1953 }
1954
1955
1956
1957
1958
1959 static void
1960 RecvErr_Message(strip_info, sendername, msg)
1961 struct st_softc *strip_info;
1962 u_char *sendername;
1963 u_char *msg;
1964 {
1965 static const char ERR_001[] = "001";
1966 static const char ERR_002[] = "002";
1967 static const char ERR_003[] = "003";
1968 static const char ERR_004[] = "004";
1969 static const char ERR_005[] = "005";
1970 static const char ERR_006[] = "006";
1971 static const char ERR_007[] = "007";
1972 static const char ERR_008[] = "008";
1973 static const char ERR_009[] = "009";
1974
1975 char * if_name;
1976
1977 if_name = strip_info->sc_if.if_xname;
1978
1979 if (!strncmp(msg, ERR_001, sizeof(ERR_001)-1))
1980 {
1981 RecvErr("radio error message:", strip_info);
1982 addlog("%s: Radio %s is not in StarMode\n",
1983 if_name, sendername);
1984 }
1985 else if (!strncmp(msg, ERR_002, sizeof(ERR_002)-1))
1986 {
1987 RecvErr("radio error message:", strip_info);
1988 #ifdef notyet
1989 int handle;
1990 u_char newname[64];
1991 sscanf(msg, "ERR_002 Remap handle &%d to name %s", &handle, newname);
1992 addlog("%s: Radio name %s is handle %d\n",
1993 if_name, newname, handle);
1994 #endif
1995 }
1996 else if (!strncmp(msg, ERR_003, sizeof(ERR_003)-1))
1997 {
1998 RecvErr("radio error message:", strip_info);
1999 addlog("%s: Destination radio name is unknown\n", if_name);
2000 }
2001 else if (!strncmp(msg, ERR_004, sizeof(ERR_004)-1)) {
2002
2003
2004
2005
2006 if (strip_info->sc_if.if_flags & IFF_DEBUG)
2007 addlog("%s: radio responded to probe\n", if_name);
2008 if (strip_info->sc_state == ST_DEAD) {
2009
2010 addlog("%s: Radio back in starmode\n", if_name);
2011 }
2012 CLEAR_RESET_TIMER(strip_info);
2013 }
2014 else if (!strncmp(msg, ERR_005, sizeof(ERR_005)-1))
2015 RecvErr("radio error message:", strip_info);
2016 else if (!strncmp(msg, ERR_006, sizeof(ERR_006)-1))
2017 RecvErr("radio error message:", strip_info);
2018 else if (!strncmp(msg, ERR_007, sizeof(ERR_007)-1))
2019 {
2020
2021
2022
2023
2024 RecvErr("radio error message:", strip_info);
2025 addlog("%s: Error! Packet size too big for radio.",
2026 if_name);
2027 FORCE_RESET(strip_info);
2028 }
2029 else if (!strncmp(msg, ERR_008, sizeof(ERR_008)-1))
2030 {
2031 RecvErr("radio error message:", strip_info);
2032 addlog("%s: Radio name contains illegal character\n",
2033 if_name);
2034 }
2035 else if (!strncmp(msg, ERR_009, sizeof(ERR_009)-1))
2036 RecvErr("radio error message:", strip_info);
2037 else {
2038 addlog("failed to parse ]%3s[\n", msg);
2039 RecvErr("unparsed radio error message:", strip_info);
2040 }
2041 }
2042
2043 #endif