1 /* $NetBSD: ether_bpf.c,v 1.10 2008/12/14 18:46:33 christos Exp $ */
5 * Matthias Drochner. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "sanamespace.h"
36 #include <sys/ioctl.h>
37 #include <sys/queue.h>
38 #include <sys/socket.h>
41 #include <net/if_dl.h>
42 #include <netinet/in.h>
49 #include <netif/netif_small.h>
50 #include <netif/etherdrv.h>
52 #define BPFDEV "/dev/bpf0"
57 * Allows to use any configured interface with
58 * standalone network code. Provides the interface used
59 * by i386/stand/lib/netif/netif_small.c.
64 static struct nlist nl
[] = {
76 char errbuf
[_POSIX2_LINE_MAX
];
77 struct ifnet_head ifh
;
79 struct ifaddr
*ifap
= 0;
80 struct sockaddr_dl
*sdlp
;
83 bpf
= open(BPFDEV
, O_RDWR
, 0);
85 warn("open %s", BPFDEV
);
90 res
= ioctl(bpf
, BIOCSBLEN
, &val
);
92 warn("ioctl BIOCSBLEN");
97 res
= ioctl(bpf
, BIOCIMMEDIATE
, &val
);
99 warn("ioctl BIOCIMMEDIATE");
104 res
= ioctl(bpf
, FIONBIO
, &val
);
106 warn("ioctl FIONBIO");
110 memcpy(ifr
.ifr_name
, BPF_IFNAME
, IFNAMSIZ
);
111 res
= ioctl(bpf
, BIOCSETIF
, &ifr
);
113 warn("ioctl BIOCSETIF %s", BPF_IFNAME
);
117 kvm
= kvm_openfiles(0, 0, 0, O_RDONLY
, errbuf
);
122 if (kvm_nlist(kvm
, nl
) < 0) {
123 warnx("nlist failed (%s)", kvm_geterr(kvm
));
128 kvm_read(kvm
, nl
[0].n_value
, &ifh
, sizeof(struct ifnet_head
));
129 ifp
= TAILQ_FIRST(&ifh
);
132 kvm_read(kvm
, (u_long
)ifp
, &ifnet
, sizeof(struct ifnet
));
133 if (!strcmp(ifnet
.if_xname
, BPF_IFNAME
)) {
134 ifap
= IFADDR_FIRST(&ifnet
);
137 ifp
= IFNET_NEXT(&ifnet
);
140 warnx("interface not found");
145 #define _offsetof(t, m) ((int)((void *)&((t *)0)->m))
146 sdllen
= _offsetof(struct sockaddr_dl
,
147 sdl_data
[0]) + strlen(BPF_IFNAME
) + 6;
148 sdlp
= malloc(sdllen
);
151 struct ifaddr ifaddr
;
152 kvm_read(kvm
, (u_long
)ifap
, &ifaddr
, sizeof(struct ifaddr
));
153 kvm_read(kvm
, (u_long
)ifaddr
.ifa_addr
, sdlp
, sdllen
);
154 if (sdlp
->sdl_family
== AF_LINK
) {
155 memcpy(ha
, CLLADDR(sdlp
), 6);
158 ifap
= IFADDR_NEXT(&ifaddr
);
163 warnx("interface hw addr not found");
178 EtherSend(char *pkt
, int len
)
181 if (write(bpf
, pkt
, len
) != len
) {
194 EtherReceive(char *pkt
, int maxlen
)
198 res
= read(bpf
, &rbuf
, MAXPKT
);
202 fprintf(stderr
, "got packet, len=%d\n", rbuf
.h
.bh_caplen
);
203 if (rbuf
.h
.bh_caplen
< rbuf
.h
.bh_datalen
)
204 printf("(truncated)\n");
205 for (i
= 0; i
< 20; i
++)
206 fprintf(stderr
, "%02x ", rbuf
.buf
[rbuf
.h
.bh_hdrlen
+ i
]);
207 fprintf(stderr
, "\n");
209 if (rbuf
.h
.bh_caplen
> maxlen
)
211 memcpy(pkt
, &rbuf
.buf
[rbuf
.h
.bh_hdrlen
], rbuf
.h
.bh_caplen
);
212 return rbuf
.h
.bh_caplen
;