1 /* $OpenBSD: bpf.c,v 1.56 2017/07/07 15:14:47 krw Exp $ */ 2 3 /* BPF socket interface code, originally contributed by Archie Cobbs. */ 4 5 /* 6 * Copyright (c) 1995, 1996, 1998, 1999 7 * The Internet Software Consortium. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of The Internet Software Consortium nor the names 19 * of its contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND 23 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 30 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 33 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * This software has been written for the Internet Software Consortium 37 * by Ted Lemon <mellon@fugue.com> in cooperation with Vixie 38 * Enterprises. To learn more about the Internet Software Consortium, 39 * see ``http://www.vix.com/isc''. To learn more about Vixie 40 * Enterprises, see ``http://www.vix.com''. 41 */ 42 43 #include <sys/ioctl.h> 44 #include <sys/queue.h> 45 #include <sys/socket.h> 46 #include <sys/types.h> 47 48 #include <net/bpf.h> 49 #include <net/if.h> 50 51 #include <netinet/in.h> 52 #include <netinet/ip.h> 53 #include <netinet/udp.h> 54 #include <netinet/if_ether.h> 55 56 #include <errno.h> 57 #include <fcntl.h> 58 #include <signal.h> 59 #include <stdio.h> 60 #include <stdlib.h> 61 #include <string.h> 62 #include <unistd.h> 63 64 #include "dhcp.h" 65 #include "dhcpd.h" 66 #include "log.h" 67 68 void if_register_bpf(struct interface_info *ifi); 69 70 /* 71 * Called by get_interface_list for each interface that's discovered. 72 * Opens a packet filter for each interface and adds it to the select 73 * mask. 74 */ 75 void 76 if_register_bpf(struct interface_info *ifi) 77 { 78 struct ifreq ifr; 79 int sock; 80 81 if ((sock = open("/dev/bpf", O_RDWR | O_CLOEXEC)) == -1) 82 fatal("Can't open bpf"); 83 84 /* Set the BPF device to point at this interface. */ 85 strlcpy(ifr.ifr_name, ifi->name, IFNAMSIZ); 86 if (ioctl(sock, BIOCSETIF, &ifr) < 0) 87 fatal("Can't attach interface %s to /dev/bpf", ifi->name); 88 89 ifi->bfdesc = sock; 90 } 91 92 void 93 if_register_send(struct interface_info *ifi) 94 { 95 int sock, on = 1; 96 97 /* 98 * Use raw socket for unicast send. 99 */ 100 if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP)) == -1) 101 fatal("socket(SOCK_RAW)"); 102 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &on, 103 sizeof(on)) == -1) 104 fatal("setsockopt(IP_HDRINCL)"); 105 if (setsockopt(sock, IPPROTO_IP, SO_RTABLE, &ifi->rdomain, 106 sizeof(ifi->rdomain)) == -1) 107 fatal("setsockopt(SO_RTABLE)"); 108 109 ifi->ufdesc = sock; 110 } 111 112 /* 113 * Packet filter program. 114 * 115 * XXX: Changes to the filter program may require changes to the 116 * constant offsets used in if_register_receive to patch the BPF program! 117 */ 118 struct bpf_insn dhcp_bpf_filter[] = { 119 /* Make sure this is an IP packet. */ 120 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12), 121 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8), 122 123 /* Make sure it's a UDP packet. */ 124 BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23), 125 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6), 126 127 /* Make sure this isn't a fragment. */ 128 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20), 129 BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0), 130 131 /* Get the IP header length. */ 132 BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14), 133 134 /* Make sure it's to the right port. */ 135 BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16), 136 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), /* patch */ 137 138 /* If we passed all the tests, ask for the whole packet. */ 139 BPF_STMT(BPF_RET+BPF_K, (u_int)-1), 140 141 /* Otherwise, drop it. */ 142 BPF_STMT(BPF_RET+BPF_K, 0), 143 }; 144 145 int dhcp_bpf_filter_len = sizeof(dhcp_bpf_filter) / sizeof(struct bpf_insn); 146 147 /* 148 * Packet write filter program: 149 * 'ip and udp and src port bootps and dst port (bootps or bootpc)' 150 */ 151 struct bpf_insn dhcp_bpf_wfilter[] = { 152 BPF_STMT(BPF_LD + BPF_B + BPF_IND, 14), 153 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, (IPVERSION << 4) + 5, 0, 12), 154 155 /* Make sure this is an IP packet. */ 156 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 12), 157 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 10), 158 159 /* Make sure it's a UDP packet. */ 160 BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 23), 161 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 8), 162 163 /* Make sure this isn't a fragment. */ 164 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20), 165 BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 6, 0), /* patched */ 166 167 /* Get the IP header length. */ 168 BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 14), 169 170 /* Make sure it's from the right port. */ 171 BPF_STMT(BPF_LD + BPF_H + BPF_IND, 14), 172 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 68, 0, 3), 173 174 /* Make sure it is to the right ports. */ 175 BPF_STMT(BPF_LD + BPF_H + BPF_IND, 16), 176 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1), 177 178 /* If we passed all the tests, ask for the whole packet. */ 179 BPF_STMT(BPF_RET+BPF_K, (u_int)-1), 180 181 /* Otherwise, drop it. */ 182 BPF_STMT(BPF_RET+BPF_K, 0), 183 }; 184 185 int dhcp_bpf_wfilter_len = sizeof(dhcp_bpf_wfilter) / sizeof(struct bpf_insn); 186 187 void 188 if_register_receive(struct interface_info *ifi) 189 { 190 struct bpf_version v; 191 struct bpf_program p; 192 int flag = 1, sz; 193 194 /* Open a BPF device and hang it on this interface. */ 195 if_register_bpf(ifi); 196 197 /* Make sure the BPF version is in range. */ 198 if (ioctl(ifi->bfdesc, BIOCVERSION, &v) < 0) 199 fatal("Can't get BPF version"); 200 201 if (v.bv_major != BPF_MAJOR_VERSION || 202 v.bv_minor < BPF_MINOR_VERSION) 203 fatalx("Kernel BPF version out of range - recompile " 204 "dhclient!"); 205 206 /* 207 * Set immediate mode so that reads return as soon as a packet 208 * comes in, rather than waiting for the input buffer to fill 209 * with packets. 210 */ 211 if (ioctl(ifi->bfdesc, BIOCIMMEDIATE, &flag) < 0) 212 fatal("Can't set immediate mode on bpf device"); 213 214 if (ioctl(ifi->bfdesc, BIOCSFILDROP, &flag) < 0) 215 fatal("Can't set filter-drop mode on bpf device"); 216 217 /* Get the required BPF buffer length from the kernel. */ 218 if (ioctl(ifi->bfdesc, BIOCGBLEN, &sz) < 0) 219 fatal("Can't get bpf buffer length"); 220 ifi->rbuf_max = sz; 221 ifi->rbuf = malloc(ifi->rbuf_max); 222 if (!ifi->rbuf) 223 fatalx("Can't allocate %lu bytes for bpf input buffer.", 224 (unsigned long)ifi->rbuf_max); 225 ifi->rbuf_offset = 0; 226 ifi->rbuf_len = 0; 227 228 /* Set up the bpf filter program structure. */ 229 p.bf_len = dhcp_bpf_filter_len; 230 p.bf_insns = dhcp_bpf_filter; 231 232 /* Patch the server port into the BPF program. 233 * 234 * XXX: changes to filter program may require changes to the 235 * insn number(s) used below! 236 */ 237 dhcp_bpf_filter[8].k = LOCAL_PORT; 238 239 if (ioctl(ifi->bfdesc, BIOCSETF, &p) < 0) 240 fatal("Can't install packet filter program"); 241 242 /* Set up the bpf write filter program structure. */ 243 p.bf_len = dhcp_bpf_wfilter_len; 244 p.bf_insns = dhcp_bpf_wfilter; 245 246 if (dhcp_bpf_wfilter[7].k == 0x1fff) 247 dhcp_bpf_wfilter[7].k = htons(IP_MF|IP_OFFMASK); 248 249 if (ioctl(ifi->bfdesc, BIOCSETWF, &p) < 0) 250 fatal("Can't install write filter program"); 251 252 if (ioctl(ifi->bfdesc, BIOCLOCK, NULL) < 0) 253 fatalx("Cannot lock bpf"); 254 } 255 256 ssize_t 257 send_packet(struct interface_info *ifi, struct in_addr from, struct in_addr to) 258 { 259 struct sockaddr_in dest; 260 struct ether_header eh; 261 struct ip ip; 262 struct udphdr udp; 263 struct iovec iov[4]; 264 struct msghdr msg; 265 struct dhcp_packet *packet = &ifi->sent_packet; 266 ssize_t result; 267 int iovcnt = 0, len = ifi->sent_packet_length; 268 269 memset(&dest, 0, sizeof(dest)); 270 dest.sin_family = AF_INET; 271 dest.sin_port = htons(REMOTE_PORT); 272 dest.sin_addr.s_addr = to.s_addr; 273 274 if (to.s_addr == INADDR_BROADCAST) { 275 assemble_eh_header(ifi->hw_address, &eh); 276 iov[0].iov_base = &eh; 277 iov[0].iov_len = sizeof(eh); 278 iovcnt++; 279 } 280 281 ip.ip_v = 4; 282 ip.ip_hl = 5; 283 ip.ip_tos = IPTOS_LOWDELAY; 284 ip.ip_len = htons(sizeof(ip) + sizeof(udp) + len); 285 ip.ip_id = 0; 286 ip.ip_off = 0; 287 ip.ip_ttl = 128; 288 ip.ip_p = IPPROTO_UDP; 289 ip.ip_sum = 0; 290 ip.ip_src.s_addr = from.s_addr; 291 ip.ip_dst.s_addr = to.s_addr; 292 ip.ip_sum = wrapsum(checksum((unsigned char *)&ip, sizeof(ip), 0)); 293 iov[iovcnt].iov_base = &ip; 294 iov[iovcnt].iov_len = sizeof(ip); 295 iovcnt++; 296 297 udp.uh_sport = htons(LOCAL_PORT); 298 udp.uh_dport = htons(REMOTE_PORT); 299 udp.uh_ulen = htons(sizeof(udp) + len); 300 udp.uh_sum = 0; 301 udp.uh_sum = wrapsum(checksum((unsigned char *)&udp, sizeof(udp), 302 checksum((unsigned char *)packet, len, 303 checksum((unsigned char *)&ip.ip_src, 304 2 * sizeof(ip.ip_src), 305 IPPROTO_UDP + (u_int32_t)ntohs(udp.uh_ulen))))); 306 iov[iovcnt].iov_base = &udp; 307 iov[iovcnt].iov_len = sizeof(udp); 308 iovcnt++; 309 310 iov[iovcnt].iov_base = packet; 311 iov[iovcnt].iov_len = len; 312 iovcnt++; 313 314 if (to.s_addr == INADDR_BROADCAST) { 315 result = writev(ifi->bfdesc, iov, iovcnt); 316 } else { 317 memset(&msg, 0, sizeof(msg)); 318 msg.msg_name = (struct sockaddr *)&dest; 319 msg.msg_namelen = sizeof(dest); 320 msg.msg_iov = iov; 321 msg.msg_iovlen = iovcnt; 322 result = sendmsg(ifi->ufdesc, &msg, 0); 323 } 324 325 if (result == -1) 326 log_warn("send_packet"); 327 return (result); 328 } 329 330 ssize_t 331 receive_packet(struct interface_info *ifi, struct sockaddr_in *from, 332 struct ether_addr *hfrom) 333 { 334 struct dhcp_packet *packet = &ifi->recv_packet; 335 int length = 0, offset = 0; 336 struct bpf_hdr hdr; 337 338 /* 339 * All this complexity is because BPF doesn't guarantee that 340 * only one packet will be returned at a time. We're getting 341 * what we deserve, though - this is a terrible abuse of the BPF 342 * interface. Sigh. 343 */ 344 345 /* Process packets until we get one we can return or until we've 346 * done a read and gotten nothing we can return. 347 */ 348 do { 349 /* If the buffer is empty, fill it. */ 350 if (ifi->rbuf_offset >= ifi->rbuf_len) { 351 length = read(ifi->bfdesc, ifi->rbuf, ifi->rbuf_max); 352 if (length <= 0) 353 return (length); 354 ifi->rbuf_offset = 0; 355 ifi->rbuf_len = length; 356 } 357 358 /* 359 * If there isn't room for a whole bpf header, something 360 * went wrong, but we'll ignore it and hope it goes 361 * away. XXX 362 */ 363 if (ifi->rbuf_len - ifi->rbuf_offset < sizeof(hdr)) { 364 ifi->rbuf_offset = ifi->rbuf_len; 365 continue; 366 } 367 368 /* Copy out a bpf header. */ 369 memcpy(&hdr, &ifi->rbuf[ifi->rbuf_offset], sizeof(hdr)); 370 371 /* 372 * If the bpf header plus data doesn't fit in what's 373 * left of the buffer, stick head in sand yet again. 374 */ 375 if (ifi->rbuf_offset + hdr.bh_hdrlen + hdr.bh_caplen > 376 ifi->rbuf_len) { 377 ifi->rbuf_offset = ifi->rbuf_len; 378 continue; 379 } 380 381 /* 382 * If the captured data wasn't the whole packet, or if 383 * the packet won't fit in the input buffer, all we can 384 * do is drop it. 385 */ 386 if (hdr.bh_caplen != hdr.bh_datalen) { 387 ifi->rbuf_offset = BPF_WORDALIGN( 388 ifi->rbuf_offset + hdr.bh_hdrlen + 389 hdr.bh_caplen); 390 continue; 391 } 392 393 /* Skip over the BPF header. */ 394 ifi->rbuf_offset += hdr.bh_hdrlen; 395 396 /* Decode the physical header. */ 397 offset = decode_hw_header(ifi->rbuf + ifi->rbuf_offset, 398 hdr.bh_caplen, hfrom); 399 400 /* 401 * If a physical layer checksum failed (dunno of any 402 * physical layer that supports this, but WTH), skip 403 * this packet. 404 */ 405 if (offset < 0) { 406 ifi->rbuf_offset = BPF_WORDALIGN( 407 ifi->rbuf_offset + hdr.bh_caplen); 408 continue; 409 } 410 ifi->rbuf_offset += offset; 411 hdr.bh_caplen -= offset; 412 413 /* Decode the IP and UDP headers. */ 414 offset = decode_udp_ip_header(ifi->rbuf + ifi->rbuf_offset, 415 hdr.bh_caplen, from); 416 417 /* If the IP or UDP checksum was bad, skip the packet. */ 418 if (offset < 0) { 419 ifi->rbuf_offset = BPF_WORDALIGN( 420 ifi->rbuf_offset + hdr.bh_caplen); 421 continue; 422 } 423 ifi->rbuf_offset += offset; 424 hdr.bh_caplen -= offset; 425 426 /* 427 * If there's not enough room to stash the packet data, 428 * we have to skip it (this shouldn't happen in real 429 * life, though). 430 */ 431 if (hdr.bh_caplen > sizeof(*packet)) { 432 ifi->rbuf_offset = BPF_WORDALIGN( 433 ifi->rbuf_offset + hdr.bh_caplen); 434 continue; 435 } 436 437 /* Copy out the data in the packet. */ 438 memset(packet, DHO_END, sizeof(*packet)); 439 memcpy(packet, ifi->rbuf + ifi->rbuf_offset, hdr.bh_caplen); 440 ifi->rbuf_offset = BPF_WORDALIGN(ifi->rbuf_offset + 441 hdr.bh_caplen); 442 return (hdr.bh_caplen); 443 } while (!length); 444 return (0); 445 } 446