1 /* 2 * Copyright (c) 1993, 1994, 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 #include <config.h> 23 24 #include <sys/param.h> 25 #include <sys/file.h> 26 #include <sys/ioctl.h> 27 #include <sys/socket.h> 28 #include <sys/time.h> 29 30 #include <net/raw.h> 31 #include <net/if.h> 32 33 #include <netinet/in.h> 34 #include <netinet/in_systm.h> 35 #include <netinet/ip.h> 36 #include <netinet/if_ether.h> 37 #include <netinet/ip_var.h> 38 #include <netinet/udp.h> 39 #include <netinet/udp_var.h> 40 #include <netinet/tcp.h> 41 #include <netinet/tcpip.h> 42 43 #include <errno.h> 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <string.h> 47 #include <unistd.h> 48 49 #include "pcap-int.h" 50 51 #ifdef HAVE_OS_PROTO_H 52 #include "os-proto.h" 53 #endif 54 55 /* 56 * Private data for capturing on snoop devices. 57 */ 58 struct pcap_snoop { 59 struct pcap_stat stat; 60 }; 61 62 static int 63 pcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 64 { 65 struct pcap_snoop *psn = p->priv; 66 int cc; 67 register struct snoopheader *sh; 68 register u_int datalen; 69 register u_int caplen; 70 register u_char *cp; 71 72 again: 73 /* 74 * Has "pcap_breakloop()" been called? 75 */ 76 if (p->break_loop) { 77 /* 78 * Yes - clear the flag that indicates that it 79 * has, and return -2 to indicate that we were 80 * told to break out of the loop. 81 */ 82 p->break_loop = 0; 83 return (-2); 84 } 85 cc = read(p->fd, (char *)p->buffer, p->bufsize); 86 if (cc < 0) { 87 /* Don't choke when we get ptraced */ 88 switch (errno) { 89 90 case EINTR: 91 goto again; 92 93 case EWOULDBLOCK: 94 return (0); /* XXX */ 95 } 96 pcapint_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 97 errno, "read"); 98 return (-1); 99 } 100 sh = (struct snoopheader *)p->buffer; 101 datalen = sh->snoop_packetlen; 102 103 /* 104 * XXX - Sigh, snoop_packetlen is a 16 bit quantity. If we 105 * got a short length, but read a full sized snoop packet, 106 * assume we overflowed and add back the 64K... 107 */ 108 if (cc == (p->snapshot + sizeof(struct snoopheader)) && 109 (datalen < p->snapshot)) 110 datalen += (64 * 1024); 111 112 caplen = (datalen < p->snapshot) ? datalen : p->snapshot; 113 cp = (u_char *)(sh + 1) + p->offset; /* XXX */ 114 115 /* 116 * XXX unfortunately snoop loopback isn't exactly like 117 * BSD's. The address family is encoded in the first 2 118 * bytes rather than the first 4 bytes! Luckily the last 119 * two snoop loopback bytes are zeroed. 120 */ 121 if (p->linktype == DLT_NULL && *((short *)(cp + 2)) == 0) { 122 u_int *uip = (u_int *)cp; 123 *uip >>= 16; 124 } 125 126 if (p->fcode.bf_insns == NULL || 127 pcapint_filter(p->fcode.bf_insns, cp, datalen, caplen)) { 128 struct pcap_pkthdr h; 129 ++psn->stat.ps_recv; 130 h.ts.tv_sec = sh->snoop_timestamp.tv_sec; 131 h.ts.tv_usec = sh->snoop_timestamp.tv_usec; 132 h.len = datalen; 133 h.caplen = caplen; 134 (*callback)(user, &h, cp); 135 return (1); 136 } 137 return (0); 138 } 139 140 static int 141 pcap_inject_snoop(pcap_t *p, const void *buf, int size) 142 { 143 int ret; 144 145 /* 146 * XXX - libnet overwrites the source address with what I 147 * presume is the interface's address; is that required? 148 */ 149 ret = write(p->fd, buf, size); 150 if (ret == -1) { 151 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 152 errno, "send"); 153 return (-1); 154 } 155 return (ret); 156 } 157 158 static int 159 pcap_stats_snoop(pcap_t *p, struct pcap_stat *ps) 160 { 161 struct pcap_snoop *psn = p->priv; 162 register struct rawstats *rs; 163 struct rawstats rawstats; 164 165 rs = &rawstats; 166 memset(rs, 0, sizeof(*rs)); 167 if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) { 168 pcapint_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 169 errno, "SIOCRAWSTATS"); 170 return (-1); 171 } 172 173 /* 174 * "ifdrops" are those dropped by the network interface 175 * due to resource shortages or hardware errors. 176 * 177 * "sbdrops" are those dropped due to socket buffer limits. 178 * 179 * As filter is done in userland, "sbdrops" counts packets 180 * regardless of whether they would've passed the filter. 181 * 182 * XXX - does this count *all* Snoop or Drain sockets, 183 * rather than just this socket? If not, why does it have 184 * both Snoop and Drain statistics? 185 */ 186 psn->stat.ps_drop = 187 rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops + 188 rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops; 189 190 /* 191 * "ps_recv" counts only packets that passed the filter. 192 * As filtering is done in userland, this does not include 193 * packets dropped because we ran out of buffer space. 194 */ 195 *ps = psn->stat; 196 return (0); 197 } 198 199 /* XXX can't disable promiscuous */ 200 static int 201 pcap_activate_snoop(pcap_t *p) 202 { 203 int fd; 204 struct sockaddr_raw sr; 205 struct snoopfilter sf; 206 u_int v; 207 int ll_hdrlen; 208 int snooplen; 209 struct ifreq ifr; 210 211 fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP); 212 if (fd < 0) { 213 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 214 errno, "snoop socket"); 215 goto bad; 216 } 217 p->fd = fd; 218 memset(&sr, 0, sizeof(sr)); 219 sr.sr_family = AF_RAW; 220 (void)strncpy(sr.sr_ifname, p->opt.device, sizeof(sr.sr_ifname)); 221 if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) { 222 /* 223 * XXX - there's probably a particular bind error that 224 * means "there's no such device" and a particular bind 225 * error that means "that device doesn't support snoop"; 226 * they might be the same error, if they both end up 227 * meaning "snoop doesn't know about that device". 228 */ 229 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 230 errno, "snoop bind"); 231 goto bad; 232 } 233 memset(&sf, 0, sizeof(sf)); 234 if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) { 235 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 236 errno, "SIOCADDSNOOP"); 237 goto bad; 238 } 239 if (p->opt.buffer_size != 0) 240 v = p->opt.buffer_size; 241 else 242 v = 64 * 1024; /* default to 64K buffer size */ 243 (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v)); 244 /* 245 * XXX hack - map device name to link layer type 246 */ 247 if (strncmp("et", p->opt.device, 2) == 0 || /* Challenge 10 Mbit */ 248 strncmp("ec", p->opt.device, 2) == 0 || /* Indigo/Indy 10 Mbit, 249 O2 10/100 */ 250 strncmp("ef", p->opt.device, 2) == 0 || /* O200/2000 10/100 Mbit */ 251 strncmp("eg", p->opt.device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */ 252 strncmp("gfe", p->opt.device, 3) == 0 || /* GIO 100 Mbit */ 253 strncmp("fxp", p->opt.device, 3) == 0 || /* Challenge VME Enet */ 254 strncmp("ep", p->opt.device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */ 255 strncmp("vfe", p->opt.device, 3) == 0 || /* Challenge VME 100Mbit */ 256 strncmp("fa", p->opt.device, 2) == 0 || 257 strncmp("qaa", p->opt.device, 3) == 0 || 258 strncmp("cip", p->opt.device, 3) == 0 || 259 strncmp("el", p->opt.device, 2) == 0) { 260 p->linktype = DLT_EN10MB; 261 p->offset = RAW_HDRPAD(sizeof(struct ether_header)); 262 ll_hdrlen = sizeof(struct ether_header); 263 /* 264 * This is (presumably) a real Ethernet capture; give it a 265 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 266 * that an application can let you choose it, in case you're 267 * capturing DOCSIS traffic that a Cisco Cable Modem 268 * Termination System is putting out onto an Ethernet (it 269 * doesn't put an Ethernet header onto the wire, it puts raw 270 * DOCSIS frames out on the wire inside the low-level 271 * Ethernet framing). 272 * 273 * XXX - are there any sorts of "fake Ethernet" that have 274 * Ethernet link-layer headers but that *shouldn't offer 275 * DLT_DOCSIS as a Cisco CMTS won't put traffic onto it 276 * or get traffic bridged onto it? "el" is for ATM LANE 277 * Ethernet devices, so that might be the case for them; 278 * the same applies for "qaa" classical IP devices. If 279 * "fa" devices are for FORE SPANS, that'd apply to them 280 * as well; what are "cip" devices - some other ATM 281 * Classical IP devices? 282 */ 283 p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 284 if (p->dlt_list == NULL) { 285 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 286 errno, "malloc"); 287 goto bad; 288 } 289 p->dlt_list[0] = DLT_EN10MB; 290 p->dlt_list[1] = DLT_DOCSIS; 291 p->dlt_count = 2; 292 } else if (strncmp("ipg", p->opt.device, 3) == 0 || 293 strncmp("rns", p->opt.device, 3) == 0 || /* O2/200/2000 FDDI */ 294 strncmp("xpi", p->opt.device, 3) == 0) { 295 p->linktype = DLT_FDDI; 296 p->offset = 3; /* XXX yeah? */ 297 ll_hdrlen = 13; 298 } else if (strncmp("ppp", p->opt.device, 3) == 0) { 299 p->linktype = DLT_RAW; 300 ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */ 301 } else if (strncmp("qfa", p->opt.device, 3) == 0) { 302 p->linktype = DLT_IP_OVER_FC; 303 ll_hdrlen = 24; 304 } else if (strncmp("pl", p->opt.device, 2) == 0) { 305 p->linktype = DLT_RAW; 306 ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */ 307 } else if (strncmp("lo", p->opt.device, 2) == 0) { 308 p->linktype = DLT_NULL; 309 ll_hdrlen = 4; 310 } else { 311 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 312 "snoop: unknown physical layer type"); 313 goto bad; 314 } 315 316 if (p->opt.rfmon) { 317 /* 318 * No monitor mode on Irix (no Wi-Fi devices on 319 * hardware supported by Irix). 320 */ 321 return (PCAP_ERROR_RFMON_NOTSUP); 322 } 323 324 /* 325 * Turn a negative snapshot value (invalid), a snapshot value of 326 * 0 (unspecified), or a value bigger than the normal maximum 327 * value, into the maximum allowed value. 328 * 329 * If some application really *needs* a bigger snapshot 330 * length, we should just increase MAXIMUM_SNAPLEN. 331 */ 332 if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) 333 p->snapshot = MAXIMUM_SNAPLEN; 334 335 #ifdef SIOCGIFMTU 336 /* 337 * XXX - IRIX appears to give you an error if you try to set the 338 * capture length to be greater than the MTU, so let's try to get 339 * the MTU first and, if that succeeds, trim the snap length 340 * to be no greater than the MTU. 341 */ 342 (void)strncpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name)); 343 if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) { 344 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 345 errno, "SIOCGIFMTU"); 346 goto bad; 347 } 348 /* 349 * OK, we got it. 350 * 351 * XXX - some versions of IRIX 6.5 define "ifr_mtu" and have an 352 * "ifru_metric" member of the "ifr_ifru" union in an "ifreq" 353 * structure, others don't. 354 * 355 * I've no idea what's going on, so, if "ifr_mtu" isn't defined, 356 * we define it as "ifr_metric", as using that field appears to 357 * work on the versions that lack "ifr_mtu" (and, on those that 358 * don't lack it, "ifru_metric" and "ifru_mtu" are both "int" 359 * members of the "ifr_ifru" union, which suggests that they 360 * may be interchangeable in this case). 361 */ 362 #ifndef ifr_mtu 363 #define ifr_mtu ifr_metric 364 #endif 365 if (p->snapshot > ifr.ifr_mtu + ll_hdrlen) 366 p->snapshot = ifr.ifr_mtu + ll_hdrlen; 367 #endif 368 369 /* 370 * The argument to SIOCSNOOPLEN is the number of link-layer 371 * payload bytes to capture - it doesn't count link-layer 372 * header bytes. 373 */ 374 snooplen = p->snapshot - ll_hdrlen; 375 if (snooplen < 0) 376 snooplen = 0; 377 if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) { 378 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 379 errno, "SIOCSNOOPLEN"); 380 goto bad; 381 } 382 v = 1; 383 if (ioctl(fd, SIOCSNOOPING, &v) < 0) { 384 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 385 errno, "SIOCSNOOPING"); 386 goto bad; 387 } 388 389 p->bufsize = 4096; /* XXX */ 390 p->buffer = malloc(p->bufsize); 391 if (p->buffer == NULL) { 392 pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 393 errno, "malloc"); 394 goto bad; 395 } 396 397 /* 398 * "p->fd" is a socket, so "select()" should work on it. 399 */ 400 p->selectable_fd = p->fd; 401 402 p->read_op = pcap_read_snoop; 403 p->inject_op = pcap_inject_snoop; 404 p->setfilter_op = pcapint_install_bpf_program; /* no kernel filtering */ 405 p->setdirection_op = NULL; /* Not implemented. */ 406 p->set_datalink_op = NULL; /* can't change data link type */ 407 p->getnonblock_op = pcapint_getnonblock_fd; 408 p->setnonblock_op = pcapint_setnonblock_fd; 409 p->stats_op = pcap_stats_snoop; 410 411 return (0); 412 bad: 413 pcapint_cleanup_live_common(p); 414 return (PCAP_ERROR); 415 } 416 417 pcap_t * 418 pcapint_create_interface(const char *device _U_, char *ebuf) 419 { 420 pcap_t *p; 421 422 p = PCAP_CREATE_COMMON(ebuf, struct pcap_snoop); 423 if (p == NULL) 424 return (NULL); 425 426 p->activate_op = pcap_activate_snoop; 427 return (p); 428 } 429 430 /* 431 * XXX - there's probably a particular bind error that means "that device 432 * doesn't support snoop"; if so, we should try a bind and use that. 433 */ 434 static int 435 can_be_bound(const char *name _U_) 436 { 437 return (1); 438 } 439 440 static int 441 get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_) 442 { 443 /* 444 * Nothing we can do. 445 * XXX - is there a way to find out whether an adapter has 446 * something plugged into it? 447 */ 448 return (0); 449 } 450 451 int 452 pcapint_platform_finddevs(pcap_if_list_t *devlistp, char *errbuf) 453 { 454 return (pcapint_findalldevs_interfaces(devlistp, errbuf, can_be_bound, 455 get_if_flags)); 456 } 457 458 /* 459 * Libpcap version string. 460 */ 461 const char * 462 pcap_lib_version(void) 463 { 464 return (PCAP_VERSION_STRING); 465 } 466