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#include "bpf.h"
65
66#ifndef __GNUC__
67#define inline
68#else
69#define inline __inline
70#endif
71
72#include <sys/param.h>
73#include <sys/systm.h>
74#include <sys/conf.h>
75#include <sys/malloc.h>
76#include <sys/mbuf.h>
77#include <sys/time.h>
78#include <sys/proc.h>
79#include <sys/signalvar.h>
80#include <sys/filio.h>
81#include <sys/sockio.h>
82#include <sys/ttycom.h>
83#include <sys/filedesc.h>
84#include <sys/uio_internal.h>
85
86#if defined(sparc) && BSD < 199103
87#include <sys/stream.h>
88#endif
89#include <sys/poll.h>
90
91#include <sys/socket.h>
92#include <sys/vnode.h>
93
94#include <net/if.h>
95#include <net/bpf.h>
96#include <net/bpfdesc.h>
97
98#include <netinet/in.h>
99#include <netinet/if_ether.h>
100#include <sys/kernel.h>
101#include <sys/sysctl.h>
102#include <net/firewire.h>
103
104#include <machine/spl.h>
105#include <miscfs/devfs/devfs.h>
106#include <net/dlil.h>
107
108#include <kern/locks.h>
109
110extern int tvtohz(struct timeval *);
111
112#if NBPFILTER > 0
113
114
115
116
117#if BSD < 199103
118extern bcopy();
119static caddr_t bpf_alloc();
120#include <net/bpf_compat.h>
121#define BPF_BUFSIZE (MCLBYTES-8)
122#define UIOMOVE(cp, len, code, uio) uiomove(cp, len, code, uio)
123#else
124#define BPF_BUFSIZE 4096
125#define UIOMOVE(cp, len, code, uio) uiomove(cp, len, uio)
126#endif
127
128
129#define PRINET 26
130
131
132
133
134static unsigned int bpf_bufsize = BPF_BUFSIZE;
135SYSCTL_INT(_debug, OID_AUTO, bpf_bufsize, CTLFLAG_RW,
136 &bpf_bufsize, 0, "");
137static unsigned int bpf_maxbufsize = BPF_MAXBUFSIZE;
138SYSCTL_INT(_debug, OID_AUTO, bpf_maxbufsize, CTLFLAG_RW,
139 &bpf_maxbufsize, 0, "");
140static unsigned int bpf_maxdevices = 256;
141SYSCTL_UINT(_debug, OID_AUTO, bpf_maxdevices, CTLFLAG_RW,
142 &bpf_maxdevices, 0, "");
143
144
145
146
147
148static struct bpf_if *bpf_iflist;
149#ifdef __APPLE__
150
151
152
153
154
155
156
157
158
159
160static struct bpf_d **bpf_dtab = NULL;
161static unsigned int bpf_dtab_size = 0;
162static unsigned int nbpfilter = 0;
163
164static lck_mtx_t *bpf_mlock;
165static lck_grp_t *bpf_mlock_grp;
166static lck_grp_attr_t *bpf_mlock_grp_attr;
167static lck_attr_t *bpf_mlock_attr;
168
169
170
171
172
173
174#endif
175
176static int bpf_allocbufs(struct bpf_d *);
177static void bpf_attachd(struct bpf_d *d, struct bpf_if *bp);
178static void bpf_detachd(struct bpf_d *d);
179static void bpf_freed(struct bpf_d *);
180static void bpf_mcopy(const void *, void *, size_t);
181static int bpf_movein(struct uio *, int,
182 struct mbuf **, struct sockaddr *, int *);
183static int bpf_setif(struct bpf_d *, struct ifreq *);
184static void bpf_wakeup(struct bpf_d *);
185static void catchpacket(struct bpf_d *, u_char *, u_int,
186 u_int, void (*)(const void *, void *, size_t));
187static void reset_d(struct bpf_d *);
188static int bpf_setf(struct bpf_d *, struct user_bpf_program *);
189
190
191
192static int bpf_devsw_installed;
193
194void bpf_init(void *unused);
195int bpf_tap_callback(struct ifnet *ifp, struct mbuf *m);
196
197
198
199
200
201 d_open_t bpfopen;
202 d_close_t bpfclose;
203 d_read_t bpfread;
204 d_write_t bpfwrite;
205 ioctl_fcn_t bpfioctl;
206 select_fcn_t bpfpoll;
207
208
209
210#define CDEV_MAJOR 23
211static struct cdevsw bpf_cdevsw = {
212 bpfopen,
213 bpfclose,
214 bpfread,
215 bpfwrite,
216 bpfioctl,
217 eno_stop,
218 eno_reset,
219 NULL,
220 bpfpoll,
221 eno_mmap,
222 eno_strat,
223 eno_getc,
224 eno_putc,
225 0
226};
227
228#define SOCKADDR_HDR_LEN offsetof(struct sockaddr, sa_data)
229
230static int
231bpf_movein(struct uio *uio, int linktype, struct mbuf **mp, struct sockaddr *sockp, int *datlen)
232{
233 struct mbuf *m;
234 int error;
235 int len;
236 int hlen;
237
238 if (sockp) {
239
240
241
242
243
244
245
246
247
248 switch (linktype) {
249
250 case DLT_SLIP:
251 sockp->sa_family = AF_INET;
252 hlen = 0;
253 break;
254
255 case DLT_EN10MB:
256 sockp->sa_family = AF_UNSPEC;
257
258 hlen = sizeof(struct ether_header);
259 break;
260
261 case DLT_FDDI:
262 #if defined(__FreeBSD__) || defined(__bsdi__)
263 sockp->sa_family = AF_IMPLINK;
264 hlen = 0;
265 #else
266 sockp->sa_family = AF_UNSPEC;
267
268 hlen = 24;
269 #endif
270 break;
271
272 case DLT_RAW:
273 case DLT_NULL:
274 sockp->sa_family = AF_UNSPEC;
275 hlen = 0;
276 break;
277
278 #ifdef __FreeBSD__
279 case DLT_ATM_RFC1483:
280
281
282
283
284
285 sockp->sa_family = AF_UNSPEC;
286 hlen = 12;
287 break;
288 #endif
289 case DLT_PPP:
290 sockp->sa_family = AF_UNSPEC;
291 hlen = 4;
292 break;
293
294 case DLT_APPLE_IP_OVER_IEEE1394:
295 sockp->sa_family = AF_UNSPEC;
296 hlen = sizeof(struct firewire_header);
297 break;
298
299 default:
300 return (EIO);
301 }
302 if ((hlen + SOCKADDR_HDR_LEN) > sockp->sa_len) {
303 return (EIO);
304 }
305 }
306 else {
307 hlen = 0;
308 }
309
310
311 len = uio_resid(uio);
312 *datlen = len - hlen;
313 if ((unsigned)len > MCLBYTES)
314 return (EIO);
315
316 MGETHDR(m, M_WAIT, MT_DATA);
317 if (m == 0)
318 return (ENOBUFS);
319 if ((unsigned)len > MHLEN) {
320#if BSD >= 199103
321 MCLGET(m, M_WAIT);
322 if ((m->m_flags & M_EXT) == 0) {
323#else
324 MCLGET(m);
325 if (m->m_len != MCLBYTES) {
326#endif
327 error = ENOBUFS;
328 goto bad;
329 }
330 }
331 m->m_pkthdr.len = m->m_len = len;
332 m->m_pkthdr.rcvif = NULL;
333 *mp = m;
334
335
336
337 if (hlen != 0) {
338 m->m_pkthdr.len -= hlen;
339 m->m_len -= hlen;
340#if BSD >= 199103
341 m->m_data += hlen;
342#else
343 m->m_off += hlen;
344#endif
345 error = UIOMOVE((caddr_t)sockp->sa_data, hlen, UIO_WRITE, uio);
346 if (error)
347 goto bad;
348 }
349 error = UIOMOVE(mtod(m, caddr_t), len - hlen, UIO_WRITE, uio);
350 if (!error)
351 return (0);
352 bad:
353 m_freem(m);
354 return (error);
355}
356
357#ifdef __APPLE__
358
359int bpf_tap_callback(struct ifnet *ifp, struct mbuf *m)
360{
361
362
363
364
365
366
367 if (ifp->if_bpf)
368 bpf_mtap(ifp, m);
369 return 0;
370}
371
372
373
374
375
376static void
377bpf_make_dev_t(int maj)
378{
379 static int bpf_growing = 0;
380 unsigned int cur_size = nbpfilter, i;
381
382 if (nbpfilter >= bpf_maxdevices)
383 return;
384
385 while (bpf_growing) {
386
387 (void)tsleep((caddr_t)&bpf_growing, PZERO, "bpf_growing", 0);
388 }
389 if (nbpfilter > cur_size) {
390
391 return;
392 }
393 bpf_growing = 1;
394
395
396 if (nbpfilter == bpf_dtab_size) {
397 int new_dtab_size;
398 struct bpf_d **new_dtab = NULL;
399 struct bpf_d **old_dtab = NULL;
400
401 new_dtab_size = bpf_dtab_size + NBPFILTER;
402 new_dtab = (struct bpf_d **)_MALLOC(sizeof(struct bpf_d *) * new_dtab_size, M_DEVBUF, M_WAIT);
403 if (new_dtab == 0) {
404 printf("bpf_make_dev_t: malloc bpf_dtab failed\n");
405 goto done;
406 }
407 if (bpf_dtab) {
408 bcopy(bpf_dtab, new_dtab,
409 sizeof(struct bpf_d *) * bpf_dtab_size);
410 }
411 bzero(new_dtab + bpf_dtab_size,
412 sizeof(struct bpf_d *) * NBPFILTER);
413 old_dtab = bpf_dtab;
414 bpf_dtab = new_dtab;
415 bpf_dtab_size = new_dtab_size;
416 if (old_dtab != NULL)
417 _FREE(old_dtab, M_DEVBUF);
418 }
419 i = nbpfilter++;
420 (void) devfs_make_node(makedev(maj, i),
421 DEVFS_CHAR, UID_ROOT, GID_WHEEL, 0600,
422 "bpf%d", i);
423done:
424 bpf_growing = 0;
425 wakeup((caddr_t)&bpf_growing);
426}
427
428#endif
429
430
431
432
433
434static void
435bpf_attachd(struct bpf_d *d, struct bpf_if *bp)
436{
437
438
439
440
441
442 d->bd_bif = bp;
443 d->bd_next = bp->bif_dlist;
444 bp->bif_dlist = d;
445
446 bp->bif_ifp->if_bpf = bp;
447
448#ifdef __APPLE__
449 dlil_set_bpf_tap(bp->bif_ifp, BPF_TAP_INPUT_OUTPUT, bpf_tap_callback);
450#endif
451}
452
453
454
455
456static void
457bpf_detachd(struct bpf_d *d)
458{
459 struct bpf_d **p;
460 struct bpf_if *bp;
461#ifdef __APPLE__
462 struct ifnet *ifp;
463
464 ifp = d->bd_bif->bif_ifp;
465
466#endif
467
468 bp = d->bd_bif;
469
470
471
472
473 if (d->bd_promisc) {
474 d->bd_promisc = 0;
475 if (ifnet_set_promiscuous(bp->bif_ifp, 0))
476
477
478
479
480
481
482 printf("bpf: ifnet_set_promiscuous failed");
483 }
484
485 p = &bp->bif_dlist;
486 while (*p != d) {
487 p = &(*p)->bd_next;
488 if (*p == 0)
489 panic("bpf_detachd: descriptor not in list");
490 }
491 *p = (*p)->bd_next;
492 if (bp->bif_dlist == 0) {
493
494
495
496 if (ifp->if_set_bpf_tap)
497 (*ifp->if_set_bpf_tap)(ifp, BPF_TAP_DISABLE, 0);
498 d->bd_bif->bif_ifp->if_bpf = 0;
499 }
500 d->bd_bif = 0;
501}
502
503
504
505
506
507
508
509 int
510bpfopen(dev_t dev, __unused int flags, __unused int fmt, __unused struct proc *p)
511{
512 register struct bpf_d *d;
513
514 if ((unsigned int) minor(dev) >= nbpfilter)
515 return (ENXIO);
516
517
518
519
520
521
522
523
524
525
526 if ((unsigned int) minor(dev) == (nbpfilter - 1))
527 bpf_make_dev_t(major(dev));
528
529
530
531
532
533
534
535
536
537 if (bpf_dtab[minor(dev)] == 0)
538 bpf_dtab[minor(dev)] = (void *)1;
539 else
540 return (EBUSY);
541
542 d = (struct bpf_d *)_MALLOC(sizeof(struct bpf_d), M_DEVBUF, M_WAIT);
543 if (d == NULL) {
544
545 printf("bpfopen: malloc bpf_d failed\n");
546 bpf_dtab[minor(dev)] = 0;
547 return ENOMEM;
548 }
549 bzero(d, sizeof(struct bpf_d));
550
551
552
553
554
555
556
557 d->bd_bufsize = bpf_bufsize;
558 d->bd_sig = SIGIO;
559 d->bd_seesent = 1;
560 bpf_dtab[minor(dev)] = d;
561
562 return (0);
563}
564
565
566
567
568
569
570 int
571bpfclose(dev_t dev, __unused int flags, __unused int fmt, __unused struct proc *p)
572{
573 register struct bpf_d *d;
574
575 d = bpf_dtab[minor(dev)];
576 if (d == 0 || d == (void *)1)
577 return (ENXIO);
578
579 bpf_dtab[minor(dev)] = (void *)1;
580
581
582 lck_mtx_lock(bpf_mlock);
583
584 if (d->bd_bif)
585 bpf_detachd(d);
586 selthreadclear(&d->bd_sel);
587 bpf_freed(d);
588
589 lck_mtx_unlock(bpf_mlock);
590
591
592 bpf_dtab[minor(dev)] = 0;
593 _FREE(d, M_DEVBUF);
594
595 return (0);
596}
597
598
599#define BPF_SLEEP bpf_sleep
600
601static int
602bpf_sleep(struct bpf_d *d, int pri, const char *wmesg, int timo)
603{
604 register int st;
605
606 lck_mtx_unlock(bpf_mlock);
607
608 st = tsleep((caddr_t)d, pri, wmesg, timo);
609
610 lck_mtx_lock(bpf_mlock);
611
612 return st;
613}
614
615
616
617
618
619
620#define ROTATE_BUFFERS(d) \
621 (d)->bd_hbuf = (d)->bd_sbuf; \
622 (d)->bd_hlen = (d)->bd_slen; \
623 (d)->bd_sbuf = (d)->bd_fbuf; \
624 (d)->bd_slen = 0; \
625 (d)->bd_fbuf = 0;
626
627
628
629 int
630bpfread(dev_t dev, struct uio *uio, int ioflag)
631{
632 register struct bpf_d *d;
633 int error;
634 int s;
635
636 d = bpf_dtab[minor(dev)];
637 if (d == 0 || d == (void *)1)
638 return (ENXIO);
639
640 lck_mtx_lock(bpf_mlock);
641
642
643
644
645
646
647
648 if (uio->uio_resid != d->bd_bufsize) {
649 lck_mtx_unlock(bpf_mlock);
650 return (EINVAL);
651 }
652
653 s = splimp();
654
655
656
657
658
659 while (d->bd_hbuf == 0) {
660 if (d->bd_immediate && d->bd_slen != 0) {
661
662
663
664
665
666 ROTATE_BUFFERS(d);
667 break;
668 }
669
670
671
672
673
674
675
676 if (d->bd_bif == NULL) {
677 splx(s);
678 lck_mtx_unlock(bpf_mlock);
679 return (ENXIO);
680 }
681
682 if (ioflag & IO_NDELAY)
683 error = EWOULDBLOCK;
684 else
685 error = BPF_SLEEP(d, PRINET|PCATCH, "bpf",
686 d->bd_rtout);
687 if (error == EINTR || error == ERESTART) {
688 splx(s);
689 lck_mtx_unlock(bpf_mlock);
690 return (error);
691 }
692 if (error == EWOULDBLOCK) {
693
694
695
696
697
698 if (d->bd_hbuf)
699
700
701
702
703
704 break;
705
706 if (d->bd_slen == 0) {
707 splx(s);
708 lck_mtx_unlock(bpf_mlock);
709 return (0);
710 }
711 ROTATE_BUFFERS(d);
712 break;
713 }
714 }
715
716
717
718 splx(s);
719
720
721
722
723
724
725 error = UIOMOVE(d->bd_hbuf, d->bd_hlen, UIO_READ, uio);
726
727 s = splimp();
728 d->bd_fbuf = d->bd_hbuf;
729 d->bd_hbuf = 0;
730 d->bd_hlen = 0;
731 splx(s);
732 lck_mtx_unlock(bpf_mlock);
733 return (error);
734}
735
736
737
738
739
740static void
741bpf_wakeup(struct bpf_d *d)
742{
743 wakeup((caddr_t)d);
744 if (d->bd_async && d->bd_sig && d->bd_sigio)
745 pgsigio(d->bd_sigio, d->bd_sig, 0);
746
747#if BSD >= 199103
748 selwakeup(&d->bd_sel);
749#ifndef __APPLE__
750
751 d->bd_sel.si_pid = 0;
752#endif
753#else
754 if (d->bd_selproc) {
755 selwakeup(d->bd_selproc, (int)d->bd_selcoll);
756 d->bd_selcoll = 0;
757 d->bd_selproc = 0;
758 }
759#endif
760}
761
762
763#define MAX_DATALINK_HDR_LEN (sizeof(struct firewire_header))
764
765 int
766bpfwrite(dev_t dev, struct uio *uio, __unused int ioflag)
767{
768 register struct bpf_d *d;
769 struct ifnet *ifp;
770 struct mbuf *m;
771 int error;
772 char dst_buf[SOCKADDR_HDR_LEN + MAX_DATALINK_HDR_LEN];
773 int datlen;
774
775 d = bpf_dtab[minor(dev)];
776 if (d == 0 || d == (void *)1)
777 return (ENXIO);
778
779 lck_mtx_lock(bpf_mlock);
780
781 if (d->bd_bif == 0) {
782 lck_mtx_unlock(bpf_mlock);
783 return (ENXIO);
784 }
785
786 ifp = d->bd_bif->bif_ifp;
787
788 if (uio->uio_resid == 0) {
789 lck_mtx_unlock(bpf_mlock);
790 return (0);
791 }
792 ((struct sockaddr *)dst_buf)->sa_len = sizeof(dst_buf);
793 error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, &m,
794 d->bd_hdrcmplt ? 0 : (struct sockaddr *)dst_buf, &datlen);
795 if (error) {
796 lck_mtx_unlock(bpf_mlock);
797 return (error);
798 }
799
800 if ((unsigned)datlen > ifp->if_mtu) {
801 lck_mtx_unlock(bpf_mlock);
802 return (EMSGSIZE);
803 }
804
805 lck_mtx_unlock(bpf_mlock);
806
807 if (d->bd_hdrcmplt) {
808 error = dlil_output(ifp, 0, m, NULL, NULL, 1);
809 }
810 else {
811 error = dlil_output(ifp, PF_INET, m, NULL, (struct sockaddr *)dst_buf, 0);
812 }
813
814
815
816
817 return (error);
818}
819
820
821
822
823
824static void
825reset_d(struct bpf_d *d)
826{
827 if (d->bd_hbuf) {
828
829 d->bd_fbuf = d->bd_hbuf;
830 d->bd_hbuf = 0;
831 }
832 d->bd_slen = 0;
833 d->bd_hlen = 0;
834 d->bd_rcount = 0;
835 d->bd_dcount = 0;
836}
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859int
860bpfioctl(dev_t dev, u_long cmd, caddr_t addr, __unused int flags, struct proc *p)
861{
862 register struct bpf_d *d;
863 int s, error = 0;
864
865 d = bpf_dtab[minor(dev)];
866 if (d == 0 || d == (void *)1)
867 return (ENXIO);
868
869 lck_mtx_lock(bpf_mlock);
870
871 switch (cmd) {
872
873 default:
874 error = EINVAL;
875 break;
876
877
878
879
880 case FIONREAD:
881 {
882 int n;
883
884 s = splimp();
885 n = d->bd_slen;
886 if (d->bd_hbuf)
887 n += d->bd_hlen;
888 splx(s);
889
890 *(int *)addr = n;
891 break;
892 }
893
894 case SIOCGIFADDR:
895 {
896 struct ifnet *ifp;
897
898 if (d->bd_bif == 0)
899 error = EINVAL;
900 else {
901 ifp = d->bd_bif->bif_ifp;
902 error = dlil_ioctl(0, ifp, cmd, addr);
903 }
904 break;
905 }
906
907
908
909
910 case BIOCGBLEN:
911 *(u_int *)addr = d->bd_bufsize;
912 break;
913
914
915
916
917 case BIOCSBLEN:
918#if BSD < 199103
919 error = EINVAL;
920#else
921 if (d->bd_bif != 0)
922 error = EINVAL;
923 else {
924 register u_int size = *(u_int *)addr;
925
926 if (size > bpf_maxbufsize)
927 *(u_int *)addr = size = bpf_maxbufsize;
928 else if (size < BPF_MINBUFSIZE)
929 *(u_int *)addr = size = BPF_MINBUFSIZE;
930 d->bd_bufsize = size;
931 }
932#endif
933 break;
934
935
936
937
938 case BIOCSETF:
939 if (proc_is64bit(p)) {
940 error = bpf_setf(d, (struct user_bpf_program *)addr);
941 }
942 else {
943 struct bpf_program * tmpp;
944 struct user_bpf_program tmp;
945
946 tmpp = (struct bpf_program *)addr;
947 tmp.bf_len = tmpp->bf_len;
948 tmp.bf_insns = CAST_USER_ADDR_T(tmpp->bf_insns);
949 error = bpf_setf(d, &tmp);
950 }
951 break;
952
953
954
955
956 case BIOCFLUSH:
957 s = splimp();
958 reset_d(d);
959 splx(s);
960 break;
961
962
963
964
965 case BIOCPROMISC:
966 if (d->bd_bif == 0) {
967
968
969
970 error = EINVAL;
971 break;
972 }
973 s = splimp();
974 if (d->bd_promisc == 0) {
975 error = ifnet_set_promiscuous(d->bd_bif->bif_ifp, 1);
976 if (error == 0)
977 d->bd_promisc = 1;
978 }
979 splx(s);
980 break;
981
982
983
984
985 case BIOCGDLT:
986 if (d->bd_bif == 0)
987 error = EINVAL;
988 else
989 *(u_int *)addr = d->bd_bif->bif_dlt;
990 break;
991
992
993
994
995 case BIOCGETIF:
996 if (d->bd_bif == 0)
997 error = EINVAL;
998 else {
999 struct ifnet *const ifp = d->bd_bif->bif_ifp;
1000 struct ifreq *const ifr = (struct ifreq *)addr;
1001
1002 snprintf(ifr->ifr_name, sizeof(ifr->ifr_name),
1003 "%s%d", ifp->if_name, ifp->if_unit);
1004 }
1005 break;
1006
1007
1008
1009
1010 case BIOCSETIF:
1011 error = bpf_setif(d, (struct ifreq *)addr);
1012 break;
1013
1014
1015
1016
1017 case BIOCSRTIMEOUT:
1018 {
1019 struct timeval *tv = (struct timeval *)addr;
1020
1021
1022
1023
1024
1025 if ((error = itimerfix(tv)) == 0)
1026 d->bd_rtout = tvtohz(tv) - 1;
1027 break;
1028 }
1029
1030
1031
1032
1033 case BIOCGRTIMEOUT:
1034 {
1035 struct timeval *tv = (struct timeval *)addr;
1036
1037 tv->tv_sec = d->bd_rtout / hz;
1038 tv->tv_usec = (d->bd_rtout % hz) * tick;
1039 break;
1040 }
1041
1042
1043
1044
1045 case BIOCGSTATS:
1046 {
1047 struct bpf_stat *bs = (struct bpf_stat *)addr;
1048
1049 bs->bs_recv = d->bd_rcount;
1050 bs->bs_drop = d->bd_dcount;
1051 break;
1052 }
1053
1054
1055
1056
1057 case BIOCIMMEDIATE:
1058 d->bd_immediate = *(u_int *)addr;
1059 break;
1060
1061 case BIOCVERSION:
1062 {
1063 struct bpf_version *bv = (struct bpf_version *)addr;
1064
1065 bv->bv_major = BPF_MAJOR_VERSION;
1066 bv->bv_minor = BPF_MINOR_VERSION;
1067 break;
1068 }
1069
1070
1071
1072
1073 case BIOCGHDRCMPLT:
1074 *(u_int *)addr = d->bd_hdrcmplt;
1075 break;
1076
1077
1078
1079
1080 case BIOCSHDRCMPLT:
1081 d->bd_hdrcmplt = *(u_int *)addr ? 1 : 0;
1082 break;
1083
1084
1085
1086
1087 case BIOCGSEESENT:
1088 *(u_int *)addr = d->bd_seesent;
1089 break;
1090
1091
1092
1093
1094 case BIOCSSEESENT:
1095 d->bd_seesent = *(u_int *)addr;
1096 break;
1097
1098 case FIONBIO:
1099 break;
1100
1101 case FIOASYNC:
1102 d->bd_async = *(int *)addr;
1103 break;
1104#ifndef __APPLE__
1105 case FIOSETOWN:
1106 error = fsetown(*(int *)addr, &d->bd_sigio);
1107 break;
1108
1109 case FIOGETOWN:
1110 *(int *)addr = fgetown(d->bd_sigio);
1111 break;
1112
1113
1114 case TIOCSPGRP:
1115 error = fsetown(-(*(int *)addr), &d->bd_sigio);
1116 break;
1117
1118
1119 case TIOCGPGRP:
1120 *(int *)addr = -fgetown(d->bd_sigio);
1121 break;
1122#endif
1123 case BIOCSRSIG:
1124 {
1125 u_int sig;
1126
1127 sig = *(u_int *)addr;
1128
1129 if (sig >= NSIG)
1130 error = EINVAL;
1131 else
1132 d->bd_sig = sig;
1133 break;
1134 }
1135 case BIOCGRSIG:
1136 *(u_int *)addr = d->bd_sig;
1137 break;
1138 }
1139
1140 lck_mtx_unlock(bpf_mlock);
1141
1142 return (error);
1143}
1144
1145
1146
1147
1148
1149static int
1150bpf_setf(struct bpf_d *d, struct user_bpf_program *fp)
1151{
1152 struct bpf_insn *fcode, *old;
1153 u_int flen, size;
1154 int s;
1155
1156 old = d->bd_filter;
1157 if (fp->bf_insns == USER_ADDR_NULL) {
1158 if (fp->bf_len != 0)
1159 return (EINVAL);
1160 s = splimp();
1161 d->bd_filter = 0;
1162 reset_d(d);
1163 splx(s);
1164 if (old != 0)
1165 FREE((caddr_t)old, M_DEVBUF);
1166 return (0);
1167 }
1168 flen = fp->bf_len;
1169 if (flen > BPF_MAXINSNS)
1170 return (EINVAL);
1171
1172 size = flen * sizeof(struct bpf_insn);
1173 fcode = (struct bpf_insn *) _MALLOC(size, M_DEVBUF, M_WAIT);
1174#ifdef __APPLE__
1175 if (fcode == NULL)
1176 return (ENOBUFS);
1177#endif
1178 if (copyin(fp->bf_insns, (caddr_t)fcode, size) == 0 &&
1179 bpf_validate(fcode, (int)flen)) {
1180 s = splimp();
1181 d->bd_filter = fcode;
1182 reset_d(d);
1183 splx(s);
1184 if (old != 0)
1185 FREE((caddr_t)old, M_DEVBUF);
1186
1187 return (0);
1188 }
1189 FREE((caddr_t)fcode, M_DEVBUF);
1190 return (EINVAL);
1191}
1192
1193
1194
1195
1196
1197
1198static int
1199bpf_setif(struct bpf_d *d, struct ifreq *ifr)
1200{
1201 struct bpf_if *bp;
1202 int s, error;
1203 struct ifnet *theywant;
1204
1205 theywant = ifunit(ifr->ifr_name);
1206 if (theywant == 0)
1207 return ENXIO;
1208
1209
1210
1211
1212 for (bp = bpf_iflist; bp != 0; bp = bp->bif_next) {
1213 struct ifnet *ifp = bp->bif_ifp;
1214
1215 if (ifp == 0 || ifp != theywant)
1216 continue;
1217
1218
1219
1220
1221
1222
1223
1224 if ((ifp->if_flags & IFF_UP) == 0)
1225 return (ENETDOWN);
1226
1227 if (d->bd_sbuf == 0) {
1228 error = bpf_allocbufs(d);
1229 if (error != 0)
1230 return (error);
1231 }
1232 s = splimp();
1233 if (bp != d->bd_bif) {
1234 if (d->bd_bif)
1235
1236
1237
1238 bpf_detachd(d);
1239
1240 bpf_attachd(d, bp);
1241 }
1242 reset_d(d);
1243 splx(s);
1244 return (0);
1245 }
1246
1247 return (ENXIO);
1248}
1249
1250
1251
1252
1253
1254
1255
1256int
1257bpfpoll(dev_t dev, int events, void * wql, struct proc *p)
1258{
1259 register struct bpf_d *d;
1260 register int s;
1261 int revents = 0;
1262
1263 d = bpf_dtab[minor(dev)];
1264 if (d == 0 || d == (void *)1)
1265 return (ENXIO);
1266
1267 lck_mtx_lock(bpf_mlock);
1268
1269
1270
1271
1272 if (d->bd_bif == NULL) {
1273 lck_mtx_unlock(bpf_mlock);
1274 return (ENXIO);
1275 }
1276
1277 s = splimp();
1278 if (events & (POLLIN | POLLRDNORM)) {
1279 if (d->bd_hlen != 0 || (d->bd_immediate && d->bd_slen != 0))
1280 revents |= events & (POLLIN | POLLRDNORM);
1281 else
1282 selrecord(p, &d->bd_sel, wql);
1283 }
1284 splx(s);
1285
1286 lck_mtx_unlock(bpf_mlock);
1287 return (revents);
1288}
1289
1290
1291
1292
1293
1294
1295
1296void
1297bpf_tap(struct ifnet *ifp, u_char *pkt, u_int pktlen)
1298{
1299 struct bpf_if *bp;
1300 register struct bpf_d *d;
1301 register u_int slen;
1302
1303
1304
1305
1306
1307 lck_mtx_lock(bpf_mlock);
1308
1309 bp = ifp->if_bpf;
1310#ifdef __APPLE__
1311 if (bp) {
1312#endif
1313 for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
1314 ++d->bd_rcount;
1315 slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
1316 if (slen != 0)
1317 catchpacket(d, pkt, pktlen, slen, bcopy);
1318 }
1319#ifdef __APPLE__
1320 }
1321 lck_mtx_unlock(bpf_mlock);
1322#endif
1323}
1324
1325
1326
1327
1328
1329static void
1330bpf_mcopy(const void *src_arg, void *dst_arg, size_t len)
1331{
1332 const struct mbuf *m;
1333 u_int count;
1334 u_char *dst;
1335
1336 m = src_arg;
1337 dst = dst_arg;
1338 while (len > 0) {
1339 if (m == 0)
1340 panic("bpf_mcopy");
1341 count = min(m->m_len, len);
1342 bcopy(mtod(m, const void *), dst, count);
1343 m = m->m_next;
1344 dst += count;
1345 len -= count;
1346 }
1347}
1348
1349
1350
1351
1352void
1353bpf_mtap(struct ifnet *ifp, struct mbuf *m)
1354{
1355 struct bpf_if *bp;
1356 struct bpf_d *d;
1357 u_int pktlen, slen;
1358 struct mbuf *m0;
1359
1360 lck_mtx_lock(bpf_mlock);
1361
1362 bp = ifp->if_bpf;
1363 if (bp) {
1364 pktlen = 0;
1365 for (m0 = m; m0 != 0; m0 = m0->m_next)
1366 pktlen += m0->m_len;
1367
1368 for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
1369 if (!d->bd_seesent && (m->m_pkthdr.rcvif == NULL))
1370 continue;
1371 ++d->bd_rcount;
1372 slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
1373 if (slen != 0)
1374 catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
1375 }
1376 }
1377
1378 lck_mtx_unlock(bpf_mlock);
1379}
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389static void
1390catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
1391 void (*cpfn)(const void *, void *, size_t))
1392{
1393 register struct bpf_hdr *hp;
1394 register int totlen, curlen;
1395 register int hdrlen = d->bd_bif->bif_hdrlen;
1396
1397
1398
1399
1400
1401
1402 totlen = hdrlen + min(snaplen, pktlen);
1403 if (totlen > d->bd_bufsize)
1404 totlen = d->bd_bufsize;
1405
1406
1407
1408
1409 curlen = BPF_WORDALIGN(d->bd_slen);
1410 if (curlen + totlen > d->bd_bufsize) {
1411
1412
1413
1414
1415
1416 if (d->bd_fbuf == 0) {
1417
1418
1419
1420
1421 ++d->bd_dcount;
1422 return;
1423 }
1424 ROTATE_BUFFERS(d);
1425 bpf_wakeup(d);
1426 curlen = 0;
1427 }
1428 else if (d->bd_immediate)
1429
1430
1431
1432
1433 bpf_wakeup(d);
1434
1435
1436
1437
1438 hp = (struct bpf_hdr *)(d->bd_sbuf + curlen);
1439#if BSD >= 199103
1440 microtime(&hp->bh_tstamp);
1441#elif defined(sun)
1442 uniqtime(&hp->bh_tstamp);
1443#else
1444 hp->bh_tstamp = time;
1445#endif
1446 hp->bh_datalen = pktlen;
1447 hp->bh_hdrlen = hdrlen;
1448
1449
1450
1451 (*cpfn)(pkt, (u_char *)hp + hdrlen, (hp->bh_caplen = totlen - hdrlen));
1452 d->bd_slen = curlen + totlen;
1453}
1454
1455
1456
1457
1458static int
1459bpf_allocbufs(struct bpf_d *d)
1460{
1461 d->bd_fbuf = (caddr_t) _MALLOC(d->bd_bufsize, M_DEVBUF, M_WAIT);
1462 if (d->bd_fbuf == 0)
1463 return (ENOBUFS);
1464
1465 d->bd_sbuf = (caddr_t) _MALLOC(d->bd_bufsize, M_DEVBUF, M_WAIT);
1466 if (d->bd_sbuf == 0) {
1467 FREE(d->bd_fbuf, M_DEVBUF);
1468 return (ENOBUFS);
1469 }
1470 d->bd_slen = 0;
1471 d->bd_hlen = 0;
1472 return (0);
1473}
1474
1475
1476
1477
1478
1479static void
1480bpf_freed(struct bpf_d *d)
1481{
1482
1483
1484
1485
1486
1487 if (d->bd_sbuf != 0) {
1488 FREE(d->bd_sbuf, M_DEVBUF);
1489 if (d->bd_hbuf != 0)
1490 FREE(d->bd_hbuf, M_DEVBUF);
1491 if (d->bd_fbuf != 0)
1492 FREE(d->bd_fbuf, M_DEVBUF);
1493 }
1494 if (d->bd_filter)
1495 FREE((caddr_t)d->bd_filter, M_DEVBUF);
1496}
1497
1498
1499
1500
1501
1502
1503void
1504bpfattach(struct ifnet *ifp, u_int dlt, u_int hdrlen)
1505{
1506 struct bpf_if *bp;
1507 bp = (struct bpf_if *) _MALLOC(sizeof(*bp), M_DEVBUF, M_WAIT);
1508 if (bp == 0)
1509 panic("bpfattach");
1510
1511 lck_mtx_lock(bpf_mlock);
1512
1513 bp->bif_dlist = 0;
1514 bp->bif_ifp = ifp;
1515 bp->bif_dlt = dlt;
1516
1517 bp->bif_next = bpf_iflist;
1518 bpf_iflist = bp;
1519
1520 bp->bif_ifp->if_bpf = 0;
1521
1522
1523
1524
1525
1526
1527
1528 bp->bif_hdrlen = BPF_WORDALIGN(hdrlen + SIZEOF_BPF_HDR) - hdrlen;
1529
1530
1531 ifp_reference(ifp);
1532
1533 lck_mtx_unlock(bpf_mlock);
1534
1535#ifndef __APPLE__
1536 if (bootverbose)
1537 printf("bpf: %s%d attached\n", ifp->if_name, ifp->if_unit);
1538#endif
1539}
1540
1541
1542
1543
1544
1545
1546
1547void
1548bpfdetach(struct ifnet *ifp)
1549{
1550 struct bpf_if *bp, *bp_prev;
1551 struct bpf_d *d;
1552 int s;
1553
1554 s = splimp();
1555
1556 lck_mtx_lock(bpf_mlock);
1557
1558
1559 bp_prev = NULL;
1560 for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
1561 if (ifp == bp->bif_ifp)
1562 break;
1563 bp_prev = bp;
1564 }
1565
1566#ifdef __APPLE__
1567
1568 if (bp == NULL) {
1569 return;
1570 }
1571#endif
1572
1573
1574 if (bp->bif_ifp == NULL) {
1575 splx(s);
1576#ifndef __APPLE__
1577 printf("bpfdetach: %s%d was not attached\n", ifp->if_name,
1578 ifp->if_unit);
1579#endif
1580 return;
1581 }
1582
1583 while ((d = bp->bif_dlist) != NULL) {
1584 bpf_detachd(d);
1585 bpf_wakeup(d);
1586 }
1587
1588 if (bp_prev) {
1589 bp_prev->bif_next = bp->bif_next;
1590 } else {
1591 bpf_iflist = bp->bif_next;
1592 }
1593
1594 ifp_release(ifp);
1595
1596 lck_mtx_unlock(bpf_mlock);
1597
1598 FREE(bp, M_DEVBUF);
1599
1600 splx(s);
1601}
1602
1603void
1604bpf_init(__unused void *unused)
1605{
1606#ifdef __APPLE__
1607 int i;
1608 int maj;
1609
1610 if (bpf_devsw_installed == 0) {
1611 bpf_devsw_installed = 1;
1612
1613 bpf_mlock_grp_attr = lck_grp_attr_alloc_init();
1614 lck_grp_attr_setdefault(bpf_mlock_grp_attr);
1615
1616 bpf_mlock_grp = lck_grp_alloc_init("bpf", bpf_mlock_grp_attr);
1617
1618 bpf_mlock_attr = lck_attr_alloc_init();
1619 lck_attr_setdefault(bpf_mlock_attr);
1620
1621 bpf_mlock = lck_mtx_alloc_init(bpf_mlock_grp, bpf_mlock_attr);
1622
1623 if (bpf_mlock == 0) {
1624 printf("bpf_init: failed to allocate bpf_mlock\n");
1625 bpf_devsw_installed = 0;
1626 return;
1627 }
1628
1629 maj = cdevsw_add(CDEV_MAJOR, &bpf_cdevsw);
1630 if (maj == -1) {
1631 if (bpf_mlock)
1632 lck_mtx_free(bpf_mlock, bpf_mlock_grp);
1633 if (bpf_mlock_attr)
1634 lck_attr_free(bpf_mlock_attr);
1635 if (bpf_mlock_grp)
1636 lck_grp_free(bpf_mlock_grp);
1637 if (bpf_mlock_grp_attr)
1638 lck_grp_attr_free(bpf_mlock_grp_attr);
1639
1640 bpf_mlock = 0;
1641 bpf_mlock_attr = 0;
1642 bpf_mlock_grp = 0;
1643 bpf_mlock_grp_attr = 0;
1644 bpf_devsw_installed = 0;
1645 printf("bpf_init: failed to allocate a major number!\n");
1646 return;
1647 }
1648
1649 for (i = 0 ; i < NBPFILTER; i++)
1650 bpf_make_dev_t(maj);
1651 }
1652#else
1653 cdevsw_add(&bpf_cdevsw);
1654#endif
1655}
1656
1657#ifndef __APPLE__
1658SYSINIT(bpfdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,bpf_drvinit,NULL)
1659#endif
1660
1661#else
1662#ifndef __APPLE__
1663
1664
1665
1666
1667
1668
1669
1670void
1671bpf_tap(ifp, pkt, pktlen)
1672 struct ifnet *ifp;
1673 register u_char *pkt;
1674 register u_int pktlen;
1675{
1676}
1677
1678void
1679bpf_mtap(ifp, m)
1680 struct ifnet *ifp;
1681 struct mbuf *m;
1682{
1683}
1684
1685void
1686bpfattach(ifp, dlt, hdrlen)
1687 struct ifnet *ifp;
1688 u_int dlt, hdrlen;
1689{
1690}
1691
1692void
1693bpfdetach(ifp)
1694 struct ifnet *ifp;
1695{
1696}
1697
1698u_int
1699bpf_filter(pc, p, wirelen, buflen)
1700 register const struct bpf_insn *pc;
1701 register u_char *p;
1702 u_int wirelen;
1703 register u_int buflen;
1704{
1705 return -1;
1706}
1707#endif
1708#endif
1709