1 /* 2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 * James Woodcock 8 */ 9 10 11 #include <config.h> 12 #include "pcap-int.h" 13 14 #include <OS.h> 15 16 #include <sys/socket.h> 17 #include <sys/sockio.h> 18 #include <sys/utsname.h> 19 20 #include <net/if.h> 21 #include <net/if_dl.h> 22 #include <net/if_types.h> 23 #include <net/if_media.h> 24 25 #include <errno.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <unistd.h> 30 #include <stdint.h> 31 32 33 // IFT_TUN was renamed to IFT_TUNNEL in the master branch after R1/beta4 (the 34 // integer value didn't change). Even though IFT_TUN is a no-op in versions 35 // that define it, for the time being it is desirable to support compiling 36 // libpcap on versions with the old macro and using it on later versions that 37 // support tunnel interfaces. 38 #ifndef IFT_TUNNEL 39 #define IFT_TUNNEL IFT_TUN 40 #endif 41 42 /* 43 * Private data for capturing on Haiku sockets. 44 */ 45 struct pcap_haiku { 46 struct pcap_stat stat; 47 int aux_socket; 48 struct ifreq ifreq; 49 // The original state of the promiscuous mode at the activation time, 50 // if the capture should be run in promiscuous mode. 51 int orig_promisc; 52 }; 53 54 55 static int 56 pcap_read_haiku(pcap_t* handle, int maxPackets _U_, pcap_handler callback, 57 u_char* userdata) 58 { 59 // Receive a single packet 60 61 u_char* buffer = (u_char*)handle->buffer; 62 ssize_t bytesReceived; 63 do { 64 if (handle->break_loop) { 65 handle->break_loop = 0; 66 return PCAP_ERROR_BREAK; 67 } 68 bytesReceived = recvfrom(handle->fd, buffer, handle->bufsize, MSG_TRUNC, 69 NULL, NULL); 70 } while (bytesReceived < 0 && errno == B_INTERRUPTED); 71 72 // The kernel does not implement timestamping of network packets, so 73 // doing it ASAP in userland is the best that can be done. 74 bigtime_t ts = real_time_clock_usecs(); 75 76 if (bytesReceived < 0) { 77 if (errno == B_WOULD_BLOCK) { 78 // there is no packet for us 79 return 0; 80 } 81 82 pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, 83 errno, "recvfrom"); 84 return PCAP_ERROR; 85 } 86 87 struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv; 88 // BPF is 32-bit, which is more than sufficient for any realistic 89 // packet size. 90 if (bytesReceived > UINT32_MAX) 91 goto drop; 92 // At this point, if the recvfrom() call populated its struct sockaddr 93 // and socklen_t arguments, it would be the right time to drop packets 94 // that have .sa_family not valid for the current DLT. But in the 95 // current master branch (hrev57588) this would erroneously drop some 96 // valid packets: recvfrom(), at least for tap mode tunnels, sets the 97 // address length to 0 for all incoming packets and sets .sa_len and 98 // .sa_family to 0 for packets that are broadcast or multicast. So it 99 // cannot be done yet, if there is a good reason to do it in the first 100 // place. 101 handlep->stat.ps_recv++; 102 103 bpf_u_int32 wireLength = (bpf_u_int32)bytesReceived; 104 // As long as the buffer is large enough, the captured length is equal 105 // to the wire length, but let's get the lengths right anyway in case 106 // packets grow bigger or the buffer grows smaller in future and the 107 // MSG_TRUNC effect kicks in. 108 bpf_u_int32 captureLength = 109 wireLength <= handle->bufsize ? wireLength : handle->bufsize; 110 111 // run the packet filter 112 if (handle->fcode.bf_insns) { 113 // NB: pcapint_filter() takes the wire length and the captured 114 // length, not the snapshot length of the pcap_t handle. 115 if (pcapint_filter(handle->fcode.bf_insns, buffer, wireLength, 116 captureLength) == 0) 117 goto drop; 118 } 119 120 // fill in pcap_header 121 struct pcap_pkthdr header; 122 header.caplen = captureLength <= (bpf_u_int32)handle->snapshot ? 123 captureLength : 124 (bpf_u_int32)handle->snapshot; 125 header.len = wireLength; 126 header.ts.tv_usec = ts % 1000000; 127 header.ts.tv_sec = ts / 1000000; 128 129 /* Call the user supplied callback function */ 130 callback(userdata, &header, buffer); 131 return 1; 132 drop: 133 handlep->stat.ps_drop++; 134 return 0; 135 } 136 137 138 static int 139 dgram_socket(const int af, char *errbuf) 140 { 141 int ret = socket(af, SOCK_DGRAM, 0); 142 if (ret < 0) { 143 pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno, 144 "socket"); 145 return PCAP_ERROR; 146 } 147 return ret; 148 } 149 150 151 static int 152 ioctl_ifreq(const int fd, const unsigned long op, const char *name, 153 struct ifreq *ifreq, char *errbuf) 154 { 155 if (ioctl(fd, op, ifreq, sizeof(struct ifreq)) < 0) { 156 pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno, 157 "%s", name); 158 return PCAP_ERROR; 159 } 160 return 0; 161 } 162 163 164 static int 165 get_promisc(pcap_t *handle) 166 { 167 struct pcap_haiku *handlep = (struct pcap_haiku *)handle->priv; 168 // SIOCGIFFLAGS would work fine for AF_LINK too. 169 if (ioctl_ifreq(handlep->aux_socket, SIOCGIFFLAGS, "SIOCGIFFLAGS", 170 &handlep->ifreq, handle->errbuf) < 0) 171 return PCAP_ERROR; 172 return (handlep->ifreq.ifr_flags & IFF_PROMISC) != 0; 173 } 174 175 176 static int 177 set_promisc(pcap_t *handle, const int enable) 178 { 179 struct pcap_haiku *handlep = (struct pcap_haiku *)handle->priv; 180 if (enable) 181 handlep->ifreq.ifr_flags |= IFF_PROMISC; 182 else 183 handlep->ifreq.ifr_flags &= ~IFF_PROMISC; 184 // SIOCSIFFLAGS works for AF_INET, but not for AF_LINK. 185 return ioctl_ifreq(handlep->aux_socket, SIOCSIFFLAGS, "SIOCSIFFLAGS", 186 &handlep->ifreq, handle->errbuf); 187 } 188 189 190 static void 191 pcap_cleanup_haiku(pcap_t *handle) 192 { 193 struct pcap_haiku *handlep = (struct pcap_haiku *)handle->priv; 194 if (handlep->aux_socket >= 0) { 195 // Closing the sockets has no effect on IFF_PROMISC, hence the 196 // need to restore the original state on one hand and the 197 // possibility of clash with other processes managing the same 198 // interface flag. Unset promiscuous mode iff the activation 199 // function had set it and it is still set now. 200 if (handle->opt.promisc && ! handlep->orig_promisc && 201 get_promisc(handle)) 202 (void)set_promisc(handle, 0); 203 close(handlep->aux_socket); 204 handlep->aux_socket = -1; 205 } 206 pcapint_cleanup_live_common(handle); 207 } 208 209 210 static int 211 pcap_inject_haiku(pcap_t *handle, const void *buffer _U_, int size _U_) 212 { 213 // Haiku currently (hrev57588) does not support sending raw packets. 214 // https://dev.haiku-os.org/ticket/18810 215 strlcpy(handle->errbuf, "Sending packets isn't supported yet", 216 PCAP_ERRBUF_SIZE); 217 return PCAP_ERROR; 218 } 219 220 221 static int 222 pcap_stats_haiku(pcap_t *handle, struct pcap_stat *stats) 223 { 224 struct pcap_haiku* handlep = (struct pcap_haiku*)handle->priv; 225 *stats = handlep->stat; 226 // Now ps_recv and ps_drop are accurate, but ps_ifdrop still equals to 227 // the snapshot value from the activation time. 228 if (ioctl_ifreq(handlep->aux_socket, SIOCGIFSTATS, "SIOCGIFSTATS", 229 &handlep->ifreq, handle->errbuf) < 0) 230 return PCAP_ERROR; 231 // The result is subject to wrapping around the 32-bit integer space, 232 // but that cannot be significantly improved as long as it has to fit 233 // into a 32-bit member of pcap_stats. 234 stats->ps_ifdrop = handlep->ifreq.ifr_stats.receive.dropped - stats->ps_ifdrop; 235 return 0; 236 } 237 238 239 static int 240 pcap_activate_haiku(pcap_t *handle) 241 { 242 struct pcap_haiku *handlep = (struct pcap_haiku *)handle->priv; 243 int ret = PCAP_ERROR; 244 245 // we need a socket to talk to the networking stack 246 if ((handlep->aux_socket = dgram_socket(AF_INET, handle->errbuf)) < 0) 247 goto error; 248 249 // pcap_stats_haiku() will need a baseline for ps_ifdrop. 250 // At the time of this writing SIOCGIFSTATS returns EINVAL for AF_LINK 251 // sockets. 252 if (ioctl_ifreq(handlep->aux_socket, SIOCGIFSTATS, "SIOCGIFSTATS", 253 &handlep->ifreq, handle->errbuf) < 0) { 254 // Detect a non-existent network interface at least at the 255 // first ioctl() use. 256 if (errno == EINVAL) 257 ret = PCAP_ERROR_NO_SUCH_DEVICE; 258 goto error; 259 } 260 handlep->stat.ps_ifdrop = handlep->ifreq.ifr_stats.receive.dropped; 261 262 // get link level interface for this interface 263 if ((handle->fd = dgram_socket(AF_LINK, handle->errbuf)) < 0) 264 goto error; 265 266 // Derive a DLT from the interface type. 267 // At the time of this writing SIOCGIFTYPE cannot be used for this 268 // purpose: it returns EINVAL for AF_LINK sockets and sets ifr_type to 269 // 0 for AF_INET sockets. Use the same method as Haiku ifconfig does 270 // (SIOCGIFADDR and AF_LINK). 271 if (ioctl_ifreq(handle->fd, SIOCGIFADDR, "SIOCGIFADDR", 272 &handlep->ifreq, handle->errbuf) < 0) 273 goto error; 274 struct sockaddr_dl *sdl = (struct sockaddr_dl *)&handlep->ifreq.ifr_addr; 275 if (sdl->sdl_family != AF_LINK) { 276 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 277 "Got AF %d instead of AF_LINK for interface \"%s\".", 278 sdl->sdl_family, handle->opt.device); 279 goto error; 280 } 281 switch (sdl->sdl_type) { 282 case IFT_ETHER: 283 // Ethernet on all versions, also tap (L2) mode tunnels on 284 // versions after R1/beta4. 285 handle->linktype = DLT_EN10MB; 286 break; 287 case IFT_TUNNEL: 288 // Unused on R1/beta4 and earlier versions, tun (L3) mode 289 // tunnels on later versions. 290 case IFT_LOOP: 291 // The loopback interface on all versions. 292 // Both IFT_TUNNEL and IFT_LOOP prepended a dummy Ethernet 293 // header until hrev57585: https://dev.haiku-os.org/ticket/18801 294 handle->linktype = DLT_RAW; 295 break; 296 default: 297 snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, 298 "Unknown interface type 0x%0x for interface \"%s\".", 299 sdl->sdl_type, handle->opt.device); 300 goto error; 301 } 302 303 // start monitoring 304 if (ioctl_ifreq(handle->fd, SIOCSPACKETCAP, "SIOCSPACKETCAP", 305 &handlep->ifreq, handle->errbuf) < 0) 306 goto error; 307 308 handle->selectable_fd = handle->fd; 309 handle->read_op = pcap_read_haiku; 310 handle->setfilter_op = pcapint_install_bpf_program; /* no kernel filtering */ 311 handle->inject_op = pcap_inject_haiku; 312 handle->stats_op = pcap_stats_haiku; 313 handle->cleanup_op = pcap_cleanup_haiku; 314 315 // use default hooks where possible 316 handle->getnonblock_op = pcapint_getnonblock_fd; 317 handle->setnonblock_op = pcapint_setnonblock_fd; 318 319 /* 320 * Turn a negative snapshot value (invalid), a snapshot value of 321 * 0 (unspecified), or a value bigger than the normal maximum 322 * value, into the maximum allowed value. 323 * 324 * If some application really *needs* a bigger snapshot 325 * length, we should just increase MAXIMUM_SNAPLEN. 326 */ 327 if (handle->snapshot <= 0 || handle->snapshot > MAXIMUM_SNAPLEN) 328 handle->snapshot = MAXIMUM_SNAPLEN; 329 330 // Although it would be trivial to size the buffer at the kernel end of 331 // the capture socket using setsockopt() and SO_RCVBUF, there seems to 332 // be no point in doing so: setting the size low silently drops some 333 // packets in the kernel, setting it high does not result in a visible 334 // improvement. Let's leave this buffer as it is until it is clear why 335 // it would need resizing. Meanwhile pcap_set_buffer_size() will have 336 // no effect on Haiku. 337 338 // It would be wrong to size the buffer at the libpcap end of the 339 // capture socket to the interface MTU, which limits only outgoing 340 // packets and only at layer 3. For example, an Ethernet interface 341 // with ifconfig/ioctl() MTU set to 1500 ordinarily sends layer 2 342 // packets as large as 1514 bytes and receives layer 2 packets as large 343 // as the NIC and the driver happen to accept (e.g. 9018 bytes for 344 // ipro1000). This way, valid packets larger than the MTU can occur in 345 // a capture and will arrive truncated to pcap_read_haiku() if the 346 // buffer is not large enough. So let's keep it large enough for most 347 // if not all practical use cases, then pcap_read_haiku() can handle 348 // the unlikely truncation as and if necessary. 349 handle->bufsize = 65536; 350 351 // allocate buffer for monitoring the device 352 handle->buffer = (u_char*)malloc(handle->bufsize); 353 if (handle->buffer == NULL) { 354 pcapint_fmt_errmsg_for_errno(handle->errbuf, PCAP_ERRBUF_SIZE, 355 errno, "buffer malloc"); 356 goto error; 357 } 358 359 if (handle->opt.promisc) { 360 // Set promiscuous mode iff required, in any case remember the 361 // original state. 362 if ((handlep->orig_promisc = get_promisc(handle)) < 0) 363 goto error; 364 if (! handlep->orig_promisc && set_promisc(handle, 1) < 0) 365 return PCAP_WARNING_PROMISC_NOTSUP; 366 } 367 return 0; 368 error: 369 pcap_cleanup_haiku(handle); 370 return ret; 371 } 372 373 374 static int 375 validate_ifname(const char *device, char *errbuf) 376 { 377 if (strlen(device) >= IF_NAMESIZE) { 378 snprintf(errbuf, PCAP_ERRBUF_SIZE, 379 "Interface name \"%s\" is too long.", device); 380 return PCAP_ERROR; 381 } 382 return 0; 383 } 384 385 386 // #pragma mark - pcap API 387 388 389 static int 390 can_be_bound(const char *name) 391 { 392 if (strcmp(name, "loop") != 0) 393 return 1; 394 395 // In Haiku versions before hrev57010 the loopback interface allows to 396 // start a capture, but the capture never receives any packets. 397 // 398 // Since compiling libpcap on one Haiku version and using the binary on 399 // another seems to be commonplace, comparing B_HAIKU_VERSION at the 400 // compile time would not always work as intended. Let's at least 401 // remove unsuitable well-known 64-bit versions (with or without 402 // updates) from the problem space at run time. 403 const char *badversions[] = { 404 "hrev56578", // R1/beta4 405 "hrev55182", // R1/beta3 406 "hrev54154", // R1/beta2 407 "hrev52295", // R1/beta1 408 "hrev44702", // R1/alpha4 409 NULL 410 }; 411 struct utsname uts; 412 (void)uname(&uts); 413 for (const char **s = badversions; *s; s++) 414 if (! strncmp(uts.version, *s, strlen(*s))) 415 return 0; 416 return 1; 417 } 418 419 420 pcap_t * 421 pcapint_create_interface(const char *device, char *errorBuffer) 422 { 423 if (validate_ifname(device, errorBuffer) < 0) 424 return NULL; 425 if (! can_be_bound(device)) { 426 snprintf(errorBuffer, PCAP_ERRBUF_SIZE, 427 "Interface \"%s\" does not support capturing traffic.", device); 428 return NULL; 429 } 430 431 pcap_t* handle = PCAP_CREATE_COMMON(errorBuffer, struct pcap_haiku); 432 if (handle == NULL) 433 return NULL; 434 handle->activate_op = pcap_activate_haiku; 435 436 struct pcap_haiku *handlep = (struct pcap_haiku *)handle->priv; 437 handlep->aux_socket = -1; 438 strcpy(handlep->ifreq.ifr_name, device); 439 440 return handle; 441 } 442 443 444 static int 445 get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) 446 { 447 if (validate_ifname(name, errbuf) < 0) 448 return PCAP_ERROR; 449 450 if (*flags & PCAP_IF_LOOPBACK || 451 ! strncmp(name, "tun", strlen("tun")) || 452 ! strncmp(name, "tap", strlen("tap"))) { 453 /* 454 * Loopback devices aren't wireless, and "connected"/ 455 * "disconnected" doesn't apply to them. 456 * 457 * Neither does it to tunnel interfaces. A tun mode tunnel 458 * can be identified by the IFT_TUNNEL value, but tap mode 459 * tunnels and Ethernet interfaces both use IFT_ETHER, so let's 460 * use the interface name prefix until there is a better 461 * solution. 462 */ 463 *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE; 464 return (0); 465 } 466 467 int fd = dgram_socket(AF_LINK, errbuf); 468 if (fd < 0) 469 return PCAP_ERROR; 470 struct ifreq ifreq; 471 strcpy(ifreq.ifr_name, name); 472 if (ioctl_ifreq(fd, SIOCGIFFLAGS, "SIOCGIFFLAGS", &ifreq, errbuf) < 0) { 473 close(fd); 474 return PCAP_ERROR; 475 } 476 *flags |= (ifreq.ifr_flags & IFF_LINK) ? 477 PCAP_IF_CONNECTION_STATUS_CONNECTED : 478 PCAP_IF_CONNECTION_STATUS_DISCONNECTED; 479 if (ioctl_ifreq(fd, SIOCGIFMEDIA, "SIOCGIFMEDIA", &ifreq, errbuf) < 0) { 480 close(fd); 481 return PCAP_ERROR; 482 } 483 if (IFM_TYPE(ifreq.ifr_media) == IFM_IEEE80211) 484 *flags |= PCAP_IF_WIRELESS; 485 close(fd); 486 487 return (0); 488 } 489 490 int 491 pcapint_platform_finddevs(pcap_if_list_t* _allDevices, char* errorBuffer) 492 { 493 return pcapint_findalldevs_interfaces(_allDevices, errorBuffer, can_be_bound, 494 get_if_flags); 495 } 496 497 /* 498 * Libpcap version string. 499 */ 500 const char * 501 pcap_lib_version(void) 502 { 503 return (PCAP_VERSION_STRING); 504 } 505