This source file includes following definitions.
- slattach
- sl_clone_create
- sl_clone_destroy
- slinit
- slopen
- slclose
- sltioctl
- sloutput
- slstart
- sl_btom
- slinput
- slioctl
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 #include "bpfilter.h"
64
65 #include <sys/param.h>
66 #include <sys/proc.h>
67 #include <sys/mbuf.h>
68 #include <sys/dkstat.h>
69 #include <sys/socket.h>
70 #include <sys/ioctl.h>
71 #include <sys/file.h>
72 #include <sys/tty.h>
73 #include <sys/kernel.h>
74 #include <sys/conf.h>
75 #if defined(__NetBSD__) || defined(__OpenBSD__)
76 #include <sys/systm.h>
77 #endif
78
79 #include <machine/cpu.h>
80
81 #include <net/if.h>
82 #include <net/if_types.h>
83 #include <net/netisr.h>
84 #include <net/route.h>
85
86 #if INET
87 #include <netinet/in.h>
88 #include <netinet/in_systm.h>
89 #include <netinet/in_var.h>
90 #include <netinet/ip.h>
91 #else
92 #error Huh? Slip without inet?
93 #endif
94
95 #include <net/slcompress.h>
96 #include <net/if_slvar.h>
97 #include <net/slip.h>
98
99 #if NBPFILTER > 0
100 #include <sys/time.h>
101 #include <net/bpf.h>
102 #endif
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144 #if NBPFILTER > 0
145 #define BUFOFFSET (128+sizeof(struct ifnet **)+SLIP_HDRLEN)
146 #else
147 #define BUFOFFSET (128+sizeof(struct ifnet **))
148 #endif
149 #define SLMAX (MCLBYTES - BUFOFFSET)
150 #define SLBUFSIZE (SLMAX + BUFOFFSET)
151 #ifndef SLMTU
152 #define SLMTU 296
153 #endif
154 #if (SLMTU < 3)
155 #error Huh? SLMTU way too small.
156 #endif
157 #define SLIP_HIWAT roundup(50,CBSIZE)
158 #if !(defined(__NetBSD__) || defined(__OpenBSD__))
159 #define CLISTRESERVE 1024
160 #endif
161
162
163
164
165
166
167
168
169 #define ABT_ESC '\033'
170 #define ABT_IDLE 1
171 #define ABT_COUNT 3
172 #define ABT_WINDOW (ABT_COUNT*2+2)
173
174
175 #define FRAME_END 0xc0
176 #define FRAME_ESCAPE 0xdb
177 #define TRANS_FRAME_END 0xdc
178 #define TRANS_FRAME_ESCAPE 0xdd
179
180 static int slinit(struct sl_softc *);
181 static struct mbuf *sl_btom(struct sl_softc *, int);
182
183 int sl_clone_create(struct if_clone *, int);
184 int sl_clone_destroy(struct ifnet *);
185
186 LIST_HEAD(, sl_softc) sl_softc_list;
187 struct if_clone sl_cloner =
188 IF_CLONE_INITIALIZER("sl", sl_clone_create, sl_clone_destroy);
189
190
191
192
193 void
194 slattach(n)
195 int n;
196 {
197 LIST_INIT(&sl_softc_list);
198 if_clone_attach(&sl_cloner);
199 }
200
201 int
202 sl_clone_create(ifc, unit)
203 struct if_clone *ifc;
204 int unit;
205 {
206 struct sl_softc *sc;
207 int s;
208
209 sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
210 if (!sc)
211 return (ENOMEM);
212 bzero(sc, sizeof(*sc));
213
214 sc->sc_unit = unit;
215 snprintf(sc->sc_if.if_xname, sizeof sc->sc_if.if_xname, "%s%d",
216 ifc->ifc_name, unit);
217 sc->sc_if.if_softc = sc;
218 sc->sc_if.if_mtu = SLMTU;
219 sc->sc_if.if_flags =
220 IFF_POINTOPOINT | SC_AUTOCOMP | IFF_MULTICAST;
221 sc->sc_if.if_type = IFT_SLIP;
222 sc->sc_if.if_ioctl = slioctl;
223 sc->sc_if.if_output = sloutput;
224 IFQ_SET_MAXLEN(&sc->sc_if.if_snd, 50);
225 sc->sc_fastq.ifq_maxlen = 32;
226 IFQ_SET_READY(&sc->sc_if.if_snd);
227 if_attach(&sc->sc_if);
228 if_alloc_sadl(&sc->sc_if);
229 #if NBPFILTER > 0
230 bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_SLIP, SLIP_HDRLEN);
231 #endif
232 s = splnet();
233 LIST_INSERT_HEAD(&sl_softc_list, sc, sc_list);
234 splx(s);
235
236 return (0);
237 }
238
239 int
240 sl_clone_destroy(ifp)
241 struct ifnet *ifp;
242 {
243 struct sl_softc *sc = ifp->if_softc;
244 int s;
245
246 if (sc->sc_ttyp != NULL)
247 return (EBUSY);
248
249 s = splnet();
250 LIST_REMOVE(sc, sc_list);
251 splx(s);
252
253 if_detach(ifp);
254
255 free(sc, M_DEVBUF);
256 return (0);
257 }
258
259 static int
260 slinit(sc)
261 struct sl_softc *sc;
262 {
263 if (sc->sc_ep == (u_char *) 0) {
264 MGETHDR(sc->sc_mbuf, M_WAIT, MT_DATA);
265 if (sc->sc_mbuf)
266 MCLGET(sc->sc_mbuf, M_WAIT);
267 if (sc->sc_mbuf == NULL || sc->sc_mbuf->m_ext.ext_buf == NULL) {
268 printf("sl%d: can't allocate buffer\n", sc->sc_unit);
269 sc->sc_if.if_flags &= ~IFF_UP;
270 return (0);
271 }
272 }
273 sc->sc_ep = (u_char *) sc->sc_mbuf->m_ext.ext_buf +
274 sc->sc_mbuf->m_ext.ext_size;
275 sc->sc_mp = sc->sc_pktstart = (u_char *) sc->sc_mbuf->m_ext.ext_buf +
276 BUFOFFSET;
277
278 sl_compress_init(&sc->sc_comp);
279
280 return (1);
281 }
282
283
284
285
286
287
288 int
289 slopen(dev, tp)
290 dev_t dev;
291 struct tty *tp;
292 {
293 struct proc *p = curproc;
294 struct sl_softc *sc;
295 int error, s;
296
297 if ((error = suser(p, 0)) != 0)
298 return (error);
299
300 if (tp->t_line == SLIPDISC)
301 return (0);
302
303 LIST_FOREACH(sc, &sl_softc_list, sc_list)
304 if (sc->sc_ttyp == NULL) {
305 if (slinit(sc) == 0)
306 return (ENOBUFS);
307 tp->t_sc = (caddr_t)sc;
308 sc->sc_ttyp = tp;
309 sc->sc_if.if_baudrate = tp->t_ospeed;
310 s = spltty();
311 tp->t_state |= TS_ISOPEN | TS_XCLUDE;
312 splx(s);
313 ttyflush(tp, FREAD | FWRITE);
314 #if defined(__NetBSD__) || defined(__OpenBSD__)
315
316
317
318
319
320
321
322
323 s = spltty();
324 if (tp->t_outq.c_cn < 2*SLMTU+2) {
325 sc->sc_oldbufsize = tp->t_outq.c_cn;
326 sc->sc_oldbufquot = tp->t_outq.c_cq != 0;
327
328 clfree(&tp->t_outq);
329 error = clalloc(&tp->t_outq, 3*SLMTU, 0);
330 if (error) {
331 splx(s);
332 return (error);
333 }
334 } else
335 sc->sc_oldbufsize = sc->sc_oldbufquot = 0;
336 splx(s);
337 #endif
338 return (0);
339 }
340 return (ENXIO);
341 }
342
343
344
345
346
347 void
348 slclose(tp)
349 struct tty *tp;
350 {
351 struct sl_softc *sc;
352 int s;
353
354 ttywflush(tp);
355 tp->t_line = 0;
356 sc = (struct sl_softc *)tp->t_sc;
357 if (sc != NULL) {
358 s = spltty();
359
360 if_down(&sc->sc_if);
361 sc->sc_ttyp = NULL;
362 tp->t_sc = NULL;
363
364 m_freem(sc->sc_mbuf);
365 sc->sc_mbuf = NULL;
366 sc->sc_ep = sc->sc_mp = sc->sc_pktstart = NULL;
367
368 #if defined(__NetBSD__) || defined(__OpenBSD__)
369
370 if (sc->sc_oldbufsize != 0) {
371 clfree(&tp->t_outq);
372 clalloc(&tp->t_outq, sc->sc_oldbufsize, sc->sc_oldbufquot);
373 }
374 #endif
375 splx(s);
376 }
377 }
378
379
380
381
382
383
384 int
385 sltioctl(tp, cmd, data, flag)
386 struct tty *tp;
387 u_long cmd;
388 caddr_t data;
389 int flag;
390 {
391 struct sl_softc *sc = (struct sl_softc *)tp->t_sc;
392
393 switch (cmd) {
394 case SLIOCGUNIT:
395 *(int *)data = sc->sc_unit;
396 break;
397
398 default:
399 return (-1);
400 }
401 return (0);
402 }
403
404
405
406
407
408
409
410 int
411 sloutput(ifp, m, dst, rtp)
412 struct ifnet *ifp;
413 struct mbuf *m;
414 struct sockaddr *dst;
415 struct rtentry *rtp;
416 {
417 struct sl_softc *sc = ifp->if_softc;
418 struct ip *ip;
419 int s, error;
420
421
422
423
424
425 if (dst->sa_family != AF_INET) {
426 printf("%s: af%d not supported\n", sc->sc_if.if_xname,
427 dst->sa_family);
428 m_freem(m);
429 sc->sc_if.if_noproto++;
430 return (EAFNOSUPPORT);
431 }
432
433 if (sc->sc_ttyp == NULL) {
434 m_freem(m);
435 return (ENETDOWN);
436 }
437 if ((sc->sc_ttyp->t_state & TS_CARR_ON) == 0 &&
438 (sc->sc_ttyp->t_cflag & CLOCAL) == 0) {
439 m_freem(m);
440 return (EHOSTUNREACH);
441 }
442 ip = mtod(m, struct ip *);
443 if (sc->sc_if.if_flags & SC_NOICMP && ip->ip_p == IPPROTO_ICMP) {
444 m_freem(m);
445 return (ENETRESET);
446 }
447 s = spltty();
448 if (sc->sc_oqlen && sc->sc_ttyp->t_outq.c_cc == sc->sc_oqlen) {
449 struct timeval tv, tm;
450
451 getmicrotime(&tm);
452
453 timersub(&tm, &sc->sc_lastpacket, &tv);
454 if (tv.tv_sec > 0) {
455 sc->sc_otimeout++;
456 slstart(sc->sc_ttyp);
457 }
458 }
459
460 (void) splnet();
461 IFQ_ENQUEUE(&sc->sc_if.if_snd, m, NULL, error);
462 if (error) {
463 splx(s);
464 sc->sc_if.if_oerrors++;
465 return (error);
466 }
467
468 (void) spltty();
469 getmicrotime(&sc->sc_lastpacket);
470 if ((sc->sc_oqlen = sc->sc_ttyp->t_outq.c_cc) == 0)
471 slstart(sc->sc_ttyp);
472 splx(s);
473 return (0);
474 }
475
476
477
478
479
480
481 void
482 slstart(tp)
483 struct tty *tp;
484 {
485 struct sl_softc *sc = (struct sl_softc *)tp->t_sc;
486 struct mbuf *m;
487 u_char *cp;
488 struct ip *ip;
489 int s;
490 struct mbuf *m2;
491 #if NBPFILTER > 0
492 u_char bpfbuf[SLMTU + SLIP_HDRLEN];
493 int len = 0;
494 #endif
495 #if !(defined(__NetBSD__) || defined(__OpenBSD__))
496 extern int cfreecount;
497 #endif
498
499 for (;;) {
500
501
502
503
504
505 if (tp->t_outq.c_cc != 0) {
506 (*tp->t_oproc)(tp);
507 if (tp->t_outq.c_cc > SLIP_HIWAT)
508 return;
509 }
510
511
512
513 if (sc == NULL)
514 return;
515
516 #if defined(__NetBSD__) || defined(__OpenBSD__)
517
518
519
520
521
522
523 if (tp->t_outq.c_cn - tp->t_outq.c_cc < 2*SLMTU+2)
524 return;
525 #endif
526
527
528
529
530 s = splnet();
531 IF_DEQUEUE(&sc->sc_fastq, m);
532 if (m)
533 sc->sc_if.if_omcasts++;
534 else
535 IFQ_DEQUEUE(&sc->sc_if.if_snd, m);
536 splx(s);
537 if (m == NULL)
538 return;
539
540
541
542
543
544
545
546 #if NBPFILTER > 0
547 if (sc->sc_bpf) {
548
549
550
551
552
553
554
555
556 struct mbuf *m1 = m;
557 u_char *cp = bpfbuf + SLIP_HDRLEN;
558
559 len = 0;
560 do {
561 int mlen = m1->m_len;
562
563 bcopy(mtod(m1, caddr_t), cp, mlen);
564 cp += mlen;
565 len += mlen;
566 } while ((m1 = m1->m_next) != NULL);
567 }
568 #endif
569 if ((ip = mtod(m, struct ip *))->ip_p == IPPROTO_TCP) {
570 if (sc->sc_if.if_flags & SC_COMPRESS)
571 *mtod(m, u_char *) |= sl_compress_tcp(m, ip,
572 &sc->sc_comp, 1);
573 }
574 #if NBPFILTER > 0
575 if (sc->sc_bpf) {
576
577
578
579
580
581 bpfbuf[SLX_DIR] = SLIPDIR_OUT;
582 bcopy(mtod(m, caddr_t), &bpfbuf[SLX_CHDR], CHDR_LEN);
583 bpf_tap(sc->sc_bpf, bpfbuf, len + SLIP_HDRLEN,
584 BPF_DIRECTION_OUT);
585 }
586 #endif
587 getmicrotime(&sc->sc_lastpacket);
588
589 #if !(defined(__NetBSD__) || defined(__OpenBSD__))
590
591
592
593
594
595 if (cfreecount < CLISTRESERVE + SLMTU) {
596 m_freem(m);
597 sc->sc_if.if_collisions++;
598 continue;
599 }
600 #endif
601
602
603
604
605
606 if (tp->t_outq.c_cc == 0) {
607 ++sc->sc_if.if_obytes;
608 (void) putc(FRAME_END, &tp->t_outq);
609 }
610
611 while (m) {
612 u_char *ep;
613
614 cp = mtod(m, u_char *); ep = cp + m->m_len;
615 while (cp < ep) {
616
617
618
619
620 u_char *bp = cp;
621
622 while (cp < ep) {
623 switch (*cp++) {
624 case FRAME_ESCAPE:
625 case FRAME_END:
626 --cp;
627 goto out;
628 }
629 }
630 out:
631 if (cp > bp) {
632
633
634
635
636 #if defined(__NetBSD__) || defined(__OpenBSD__)
637 if (b_to_q((u_char *)bp, cp - bp,
638 #else
639 if (b_to_q((char *)bp, cp - bp,
640 #endif
641 &tp->t_outq))
642 break;
643 sc->sc_if.if_obytes += cp - bp;
644 }
645
646
647
648
649
650 if (cp < ep) {
651 if (putc(FRAME_ESCAPE, &tp->t_outq))
652 break;
653 if (putc(*cp++ == FRAME_ESCAPE ?
654 TRANS_FRAME_ESCAPE : TRANS_FRAME_END,
655 &tp->t_outq)) {
656 (void) unputc(&tp->t_outq);
657 break;
658 }
659 sc->sc_if.if_obytes += 2;
660 }
661 }
662 MFREE(m, m2);
663 m = m2;
664 }
665
666 if (putc(FRAME_END, &tp->t_outq)) {
667
668
669
670
671
672
673
674 (void) unputc(&tp->t_outq);
675 (void) putc(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
687 static struct mbuf *
688 sl_btom(sc, len)
689 struct sl_softc *sc;
690 int len;
691 {
692 struct mbuf *m;
693
694
695
696
697 m = sc->sc_mbuf;
698 MGETHDR(sc->sc_mbuf, M_DONTWAIT, MT_DATA);
699 if (sc->sc_mbuf == NULL) {
700 sc->sc_mbuf = m;
701 return (NULL);
702 }
703 MCLGET(sc->sc_mbuf, M_DONTWAIT);
704 if ((sc->sc_mbuf->m_flags & M_EXT) == 0) {
705
706
707
708
709 m_freem(sc->sc_mbuf);
710 sc->sc_mbuf = m;
711 return (NULL);
712 }
713 sc->sc_ep = (u_char *) sc->sc_mbuf->m_ext.ext_buf +
714 sc->sc_mbuf->m_ext.ext_size;
715
716 m->m_data = sc->sc_pktstart;
717
718 m->m_len = len;
719 m->m_pkthdr.len = len;
720 m->m_pkthdr.rcvif = &sc->sc_if;
721 return (m);
722 }
723
724
725
726
727 void
728 slinput(c, tp)
729 int c;
730 struct tty *tp;
731 {
732 struct sl_softc *sc;
733 struct mbuf *m;
734 int len;
735 int s;
736 #if NBPFILTER > 0
737 u_char chdr[CHDR_LEN];
738 #endif
739
740 tk_nin++;
741 sc = (struct sl_softc *)tp->t_sc;
742 if (sc == NULL)
743 return;
744 if (c & TTY_ERRORMASK || ((tp->t_state & TS_CARR_ON) == 0 &&
745 (tp->t_cflag & CLOCAL) == 0)) {
746 sc->sc_flags |= SC_ERROR;
747 return;
748 }
749 c &= TTY_CHARMASK;
750
751 ++sc->sc_if.if_ibytes;
752
753 if (sc->sc_if.if_flags & IFF_DEBUG) {
754 if (c == ABT_ESC) {
755
756
757
758
759 if (sc->sc_abortcount &&
760 time_second >= sc->sc_starttime + ABT_WINDOW)
761 sc->sc_abortcount = 0;
762
763
764
765
766 if (time_second >= sc->sc_lasttime + ABT_IDLE) {
767 if (++sc->sc_abortcount == 1)
768 sc->sc_starttime = time_second;
769 if (sc->sc_abortcount >= ABT_COUNT) {
770 slclose(tp);
771 return;
772 }
773 }
774 } else
775 sc->sc_abortcount = 0;
776 sc->sc_lasttime = time_second;
777 }
778
779 switch (c) {
780
781 case TRANS_FRAME_ESCAPE:
782 if (sc->sc_escape)
783 c = FRAME_ESCAPE;
784 break;
785
786 case TRANS_FRAME_END:
787 if (sc->sc_escape)
788 c = FRAME_END;
789 break;
790
791 case FRAME_ESCAPE:
792 sc->sc_escape = 1;
793 return;
794
795 case FRAME_END:
796 if(sc->sc_flags & SC_ERROR) {
797 sc->sc_flags &= ~SC_ERROR;
798 goto newpack;
799 }
800 len = sc->sc_mp - sc->sc_pktstart;
801 if (len < 3)
802
803 goto newpack;
804
805 #if NBPFILTER > 0
806 if (sc->sc_bpf) {
807
808
809
810
811
812
813
814
815 bcopy(sc->sc_pktstart, chdr, CHDR_LEN);
816 }
817 #endif
818
819 if ((c = (*sc->sc_pktstart & 0xf0)) != (IPVERSION << 4)) {
820 if (c & 0x80)
821 c = TYPE_COMPRESSED_TCP;
822 else if (c == TYPE_UNCOMPRESSED_TCP)
823 *sc->sc_pktstart &= 0x4f;
824
825
826
827
828
829
830
831 if (sc->sc_if.if_flags & SC_COMPRESS) {
832 len = sl_uncompress_tcp(&sc->sc_pktstart, len,
833 (u_int)c, &sc->sc_comp);
834 if (len <= 0)
835 goto error;
836 } else if ((sc->sc_if.if_flags & SC_AUTOCOMP) &&
837 c == TYPE_UNCOMPRESSED_TCP && len >= 40) {
838 len = sl_uncompress_tcp(&sc->sc_pktstart, len,
839 (u_int)c, &sc->sc_comp);
840 if (len <= 0)
841 goto error;
842 sc->sc_if.if_flags |= SC_COMPRESS;
843 } else
844 goto error;
845 }
846
847 m = sl_btom(sc, len);
848 if (m == NULL)
849 goto error;
850
851 #if NBPFILTER > 0
852 if (sc->sc_bpf) {
853
854
855
856
857
858
859 u_char *hp;
860
861 M_PREPEND(m, SLIP_HDRLEN, M_DONTWAIT);
862 if (m == NULL)
863 goto error;
864
865 hp = mtod(m, u_char *);
866 hp[SLX_DIR] = SLIPDIR_IN;
867 memcpy(&hp[SLX_CHDR], chdr, CHDR_LEN);
868
869 s = splnet();
870 bpf_mtap(sc->sc_bpf, m, BPF_DIRECTION_IN);
871 splx(s);
872
873 m_adj(m, SLIP_HDRLEN);
874 }
875 #endif
876
877 sc->sc_if.if_ipackets++;
878 getmicrotime(&sc->sc_lastpacket);
879 s = splnet();
880 if (IF_QFULL(&ipintrq)) {
881 IF_DROP(&ipintrq);
882 sc->sc_if.if_ierrors++;
883 sc->sc_if.if_iqdrops++;
884 m_freem(m);
885 if (!ipintrq.ifq_congestion)
886 if_congestion(&ipintrq);
887 } else {
888 IF_ENQUEUE(&ipintrq, m);
889 schednetisr(NETISR_IP);
890 }
891 splx(s);
892 goto newpack;
893 }
894 if (sc->sc_mp < sc->sc_ep) {
895 *sc->sc_mp++ = c;
896 sc->sc_escape = 0;
897 return;
898 }
899
900
901 sc->sc_flags |= SC_ERROR;
902
903 error:
904 sc->sc_if.if_ierrors++;
905 newpack:
906 sc->sc_mp = sc->sc_pktstart = (u_char *) sc->sc_mbuf->m_ext.ext_buf +
907 BUFOFFSET;
908 sc->sc_escape = 0;
909 }
910
911
912
913
914 int
915 slioctl(ifp, cmd, data)
916 struct ifnet *ifp;
917 u_long cmd;
918 caddr_t data;
919 {
920 struct sl_softc *sc = ifp->if_softc;
921 struct ifaddr *ifa = (struct ifaddr *)data;
922 struct ifreq *ifr;
923 int s = splnet(), error = 0;
924 struct sl_stats *slsp;
925
926 switch (cmd) {
927
928 case SIOCSIFADDR:
929 if (ifa->ifa_addr->sa_family == AF_INET)
930 ifp->if_flags |= IFF_UP;
931 else
932 error = EAFNOSUPPORT;
933 break;
934
935 case SIOCSIFDSTADDR:
936 if (ifa->ifa_addr->sa_family != AF_INET)
937 error = EAFNOSUPPORT;
938 break;
939
940 case SIOCADDMULTI:
941 case SIOCDELMULTI:
942 ifr = (struct ifreq *)data;
943 if (ifr == 0) {
944 error = EAFNOSUPPORT;
945 break;
946 }
947 switch (ifr->ifr_addr.sa_family) {
948
949 #ifdef INET
950 case AF_INET:
951 break;
952 #endif
953
954 default:
955 error = EAFNOSUPPORT;
956 break;
957 }
958 break;
959
960 case SIOCGSLSTATS:
961 slsp = &((struct ifslstatsreq *) data)->stats;
962 bzero(slsp, sizeof(*slsp));
963
964 slsp->sl.sl_ibytes = sc->sc_if.if_ibytes;
965 slsp->sl.sl_obytes = sc->sc_if.if_obytes;
966 slsp->sl.sl_ipackets = sc->sc_if.if_ipackets;
967 slsp->sl.sl_opackets = sc->sc_if.if_opackets;
968 #ifdef INET
969 slsp->vj.vjs_packets = sc->sc_comp.sls_packets;
970 slsp->vj.vjs_compressed = sc->sc_comp.sls_compressed;
971 slsp->vj.vjs_searches = sc->sc_comp.sls_searches;
972 slsp->vj.vjs_misses = sc->sc_comp.sls_misses;
973 slsp->vj.vjs_uncompressedin = sc->sc_comp.sls_uncompressedin;
974 slsp->vj.vjs_compressedin = sc->sc_comp.sls_compressedin;
975 slsp->vj.vjs_errorin = sc->sc_comp.sls_errorin;
976 slsp->vj.vjs_tossed = sc->sc_comp.sls_tossed;
977 #endif
978 break;
979
980 default:
981 error = EINVAL;
982 }
983 splx(s);
984 return (error);
985 }