1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1993, 1994, 1995, 1996, 1997 3478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The Regents of the University of California. All rights reserved. 4478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 5478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Redistribution and use in source and binary forms, with or without 6478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * modification, are permitted provided that: (1) source code distributions 7478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * retain the above copyright notice and this paragraph in its entirety, (2) 8478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * distributions including binary code include the above copyright notice and 9478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this paragraph in its entirety in the documentation or other materials 10478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * provided with the distribution, and (3) all advertising materials mentioning 11478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * features or use of this software display the following acknowledgement: 12478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ``This product includes software developed by the University of California, 13478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the University nor the names of its contributors may be used to endorse 15478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or promote products derived from this software without specific prior 16478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * written permission. 17478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 21478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef lint 22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ = 23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.54.2.1 2005/05/03 18:54:38 guy Exp $ (LBL)"; 24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H 27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h" 28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/param.h> 31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/file.h> 32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/ioctl.h> 33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h> 34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/time.h> 35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/raw.h> 37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h> 38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h> 40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in_systm.h> 41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/ip.h> 42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/if_ether.h> 43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/ip_var.h> 44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/udp.h> 45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/udp_var.h> 46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/tcp.h> 47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/tcpip.h> 48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <errno.h> 50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdio.h> 51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h> 52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h> 53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <unistd.h> 54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h" 56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H 58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h" 59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_snoop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int cc; 65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct snoopheader *sh; 66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_int datalen; 67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_int caplen; 68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_char *cp; 69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectagain: 71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Has "pcap_breakloop()" been called? 73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->break_loop) { 75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Yes - clear the flag that indicates that it 77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * has, and return -2 to indicate that we were 78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * told to break out of the loop. 79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->break_loop = 0; 81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-2); 82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = read(p->fd, (char *)p->buffer, p->bufsize); 84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc < 0) { 85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* Don't choke when we get ptraced */ 86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (errno) { 87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case EINTR: 89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto again; 90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case EWOULDBLOCK: 92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); /* XXX */ 93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, sizeof(p->errbuf), 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "read: %s", pcap_strerror(errno)); 96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sh = (struct snoopheader *)p->buffer; 99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project datalen = sh->snoop_packetlen; 100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - Sigh, snoop_packetlen is a 16 bit quantity. If we 103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * got a short length, but read a full sized snoop pakcet, 104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * assume we overflowed and add back the 64K... 105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc == (p->snapshot + sizeof(struct snoopheader)) && 107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (datalen < p->snapshot)) 108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project datalen += (64 * 1024); 109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project caplen = (datalen < p->snapshot) ? datalen : p->snapshot; 111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp = (u_char *)(sh + 1) + p->offset; /* XXX */ 112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX unfortunately snoop loopback isn't exactly like 115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * BSD's. The address family is encoded in the first 2 116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * bytes rather than the first 4 bytes! Luckily the last 117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * two snoop loopback bytes are zeroed. 118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->linktype == DLT_NULL && *((short *)(cp + 2)) == 0) { 120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int *uip = (u_int *)cp; 121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *uip >>= 16; 122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->fcode.bf_insns == NULL || 125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) { 126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct pcap_pkthdr h; 127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ++p->md.stat.ps_recv; 128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.ts.tv_sec = sh->snoop_timestamp.tv_sec; 129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.ts.tv_usec = sh->snoop_timestamp.tv_usec; 130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.len = datalen; 131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.caplen = caplen; 132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (*callback)(user, &h, cp); 133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (1); 134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_inject_snoop(pcap_t *p, const void *buf, size_t size) 140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ret; 142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - libnet overwrites the source address with what I 145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * presume is the interface's address; is that required? 146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = write(p->fd, buf, size); 148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret == -1) { 149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_stats_snoop(pcap_t *p, struct pcap_stat *ps) 158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct rawstats *rs; 160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct rawstats rawstats; 161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project rs = &rawstats; 163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(rs, 0, sizeof(*rs)); 164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) { 165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, sizeof(p->errbuf), 166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "SIOCRAWSTATS: %s", pcap_strerror(errno)); 167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ifdrops" are those dropped by the network interface 172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * due to resource shortages or hardware errors. 173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "sbdrops" are those dropped due to socket buffer limits. 175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * As filter is done in userland, "sbdrops" counts packets 177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * regardless of whether they would've passed the filter. 178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - does this count *all* Snoop or Drain sockets, 180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * rather than just this socket? If not, why does it have 181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * both Snoop and Drain statistics? 182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->md.stat.ps_drop = 184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops + 185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops; 186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_recv" counts only packets that passed the filter. 189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * As filtering is done in userland, this does not include 190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets dropped because we ran out of buffer space. 191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *ps = p->md.stat; 193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* XXX can't disable promiscuous */ 197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_t * 198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_open_live(const char *device, int snaplen, int promisc, int to_ms, 199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *ebuf) 200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int fd; 202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct sockaddr_raw sr; 203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct snoopfilter sf; 204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project u_int v; 205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ll_hdrlen; 206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int snooplen; 207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_t *p; 208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct ifreq ifr; 209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = (pcap_t *)malloc(sizeof(*p)); 211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p == NULL) { 212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(p, 0, sizeof(*p)); 217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP); 218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd < 0) { 219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s", 220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fd = fd; 224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&sr, 0, sizeof(sr)); 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sr.sr_family = AF_RAW; 226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname)); 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) { 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s", 229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&sf, 0, sizeof(sf)); 233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) { 234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s", 235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = 64 * 1024; 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v)); 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX hack - map device name to link layer type 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */ 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit, 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project O2 10/100 */ 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */ 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("eg", device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */ 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */ 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */ 250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */ 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */ 252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("fa", device, 2) == 0 || 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("qaa", device, 3) == 0 || 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("cip", device, 3) == 0 || 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("el", device, 2) == 0) { 256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_EN10MB; 257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->offset = RAW_HDRPAD(sizeof(struct ether_header)); 258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ll_hdrlen = sizeof(struct ether_header); 259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is (presumably) a real Ethernet capture; give it a 261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that an application can let you choose it, in case you're 263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capturing DOCSIS traffic that a Cisco Cable Modem 264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Termination System is putting out onto an Ethernet (it 265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't put an Ethernet header onto the wire, it puts raw 266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DOCSIS frames out on the wire inside the low-level 267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet framing). 268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - are there any sorts of "fake Ethernet" that have 270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet link-layer headers but that *shouldn't offer 271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DLT_DOCSIS as a Cisco CMTS won't put traffic onto it 272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or get traffic bridged onto it? "el" is for ATM LANE 273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet devices, so that might be the case for them; 274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the same applies for "qaa" classical IP devices. If 275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "fa" devices are for FORE SPANS, that'd apply to them 276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as well; what are "cip" devices - some other ATM 277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Classical IP devices? 278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If that fails, just leave the list empty. 282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->dlt_list != NULL) { 284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[0] = DLT_EN10MB; 285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[1] = DLT_DOCSIS; 286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_count = 2; 287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else if (strncmp("ipg", device, 3) == 0 || 289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */ 290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncmp("xpi", device, 3) == 0) { 291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_FDDI; 292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->offset = 3; /* XXX yeah? */ 293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ll_hdrlen = 13; 294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else if (strncmp("ppp", device, 3) == 0) { 295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_RAW; 296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */ 297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else if (strncmp("qfa", device, 3) == 0) { 298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_IP_OVER_FC; 299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ll_hdrlen = 24; 300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else if (strncmp("pl", device, 2) == 0) { 301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_RAW; 302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ll_hdrlen = 0; /* Cray UNICOS/mp pseudo link */ 303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else if (strncmp("lo", device, 2) == 0) { 304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_NULL; 305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ll_hdrlen = 4; 306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, 308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "snoop: unknown physical layer type"); 309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef SIOCGIFMTU 312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - IRIX appears to give you an error if you try to set the 314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capture length to be greater than the MTU, so let's try to get 315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the MTU first and, if that succeeds, trim the snap length 316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to be no greater than the MTU. 317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) { 320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s", 321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OK, we got it. 326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - some versions of IRIX 6.5 define "ifr_mtu" and have an 328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ifru_metric" member of the "ifr_ifru" union in an "ifreq" 329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * structure, others don't. 330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * I've no idea what's going on, so, if "ifr_mtu" isn't defined, 332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we define it as "ifr_metric", as using that field appears to 333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * work on the versions that lack "ifr_mtu" (and, on those that 334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * don't lack it, "ifru_metric" and "ifru_mtu" are both "int" 335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * members of the "ifr_ifru" union, which suggests that they 336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * may be interchangeable in this case). 337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef ifr_mtu 339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define ifr_mtu ifr_metric 340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (snaplen > ifr.ifr_mtu + ll_hdrlen) 342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snaplen = ifr.ifr_mtu + ll_hdrlen; 343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The argument to SIOCSNOOPLEN is the number of link-layer 347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * payload bytes to capture - it doesn't count link-layer 348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * header bytes. 349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snooplen = snaplen - ll_hdrlen; 351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (snooplen < 0) 352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snooplen = 0; 353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) { 354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s", 355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->snapshot = snaplen; 359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project v = 1; 360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCSNOOPING, &v) < 0) { 361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s", 362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bufsize = 4096; /* XXX */ 367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->buffer = (u_char *)malloc(p->bufsize); 368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->buffer == NULL) { 369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "p->fd" is a socket, so "select()" should work on it. 376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->selectable_fd = p->fd; 378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->read_op = pcap_read_snoop; 380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->inject_op = pcap_inject_snoop; 381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setfilter_op = install_bpf_program; /* no kernel filtering */ 382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setdirection_op = NULL; /* Not implemented. */ 383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->set_datalink_op = NULL; /* can't change data link type */ 384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->getnonblock_op = pcap_getnonblock_fd; 385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setnonblock_op = pcap_setnonblock_fd; 386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->stats_op = pcap_stats_snoop; 387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->close_op = pcap_close_common; 388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (p); 390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bad: 391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)close(fd); 392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get rid of any link-layer type list we allocated. 394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->dlt_list != NULL) 396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p->dlt_list); 397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p); 398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 406