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