#include <sys/param.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <net/raw.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "pcap-int.h"
Include dependency graph for pcap-snoop.c:
Go to the source code of this file.
Functions | |
int | pcap_read (pcap_t *p, int cnt, pcap_handler callback, u_char *user) |
int | pcap_stats (pcap_t *p, struct pcap_stat *ps) |
pcap_t * | pcap_open_live (char *device, int snaplen, int promisc, int to_ms, char *ebuf) |
int | pcap_setfilter (pcap_t *p, struct bpf_program *fp) |
Variables | |
const char | rcsid [] |
|
Definition at line 147 of file pcap-snoop.c. References bind(), BIOCGBLEN, BIOCGDLT, BIOCIMMEDIATE, BIOCPROMISC, BIOCSBLEN, BIOCSETIF, BIOCSRTIMEOUT, BIOCVERSION, BPF_MAJOR_VERSION, BPF_MINOR_VERSION, bpf_open(), pcap::buffer, pcap::bufsize, bpf_version::bv_major, bpf_version::bv_minor, close(), DLT_CHDLC, DLT_EN10MB, DLT_FDDI, DLT_FRELAY, DLT_IEEE802, DLT_NULL, DLT_PPP, DLT_PPP_BSDOS, DLT_RAW, DLT_SLIP, DLT_SLIP_BSDOS, errno, pcap::fd, ioctl(), pcap::linktype, malloc(), pcap::offset, p, PCAP_ERRBUF_SIZE, pcap_strerror(), pcap_t, setsockopt(), snaplen, pcap::snapshot, snprintf(), and socket(). Referenced by add_or_find_if(), and PktInterfaceSrc::PktInterfaceSrc().
00148 { 00149 int fd; 00150 struct sockaddr_raw sr; 00151 struct snoopfilter sf; 00152 u_int v; 00153 int ll_hdrlen; 00154 int snooplen; 00155 pcap_t *p; 00156 struct ifreq ifr; 00157 00158 p = (pcap_t *)malloc(sizeof(*p)); 00159 if (p == NULL) { 00160 snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 00161 pcap_strerror(errno)); 00162 return (NULL); 00163 } 00164 memset(p, 0, sizeof(*p)); 00165 fd = socket(PF_RAW, SOCK_RAW, RAWPROTO_SNOOP); 00166 if (fd < 0) { 00167 snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop socket: %s", 00168 pcap_strerror(errno)); 00169 goto bad; 00170 } 00171 p->fd = fd; 00172 memset(&sr, 0, sizeof(sr)); 00173 sr.sr_family = AF_RAW; 00174 (void)strncpy(sr.sr_ifname, device, sizeof(sr.sr_ifname)); 00175 if (bind(fd, (struct sockaddr *)&sr, sizeof(sr))) { 00176 snprintf(ebuf, PCAP_ERRBUF_SIZE, "snoop bind: %s", 00177 pcap_strerror(errno)); 00178 goto bad; 00179 } 00180 memset(&sf, 0, sizeof(sf)); 00181 if (ioctl(fd, SIOCADDSNOOP, &sf) < 0) { 00182 snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCADDSNOOP: %s", 00183 pcap_strerror(errno)); 00184 goto bad; 00185 } 00186 v = 64 * 1024; 00187 (void)setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&v, sizeof(v)); 00188 /* 00189 * XXX hack - map device name to link layer type 00190 */ 00191 if (strncmp("et", device, 2) == 0 || /* Challenge 10 Mbit */ 00192 strncmp("ec", device, 2) == 0 || /* Indigo/Indy 10 Mbit, 00193 O2 10/100 */ 00194 strncmp("ef", device, 2) == 0 || /* O200/2000 10/100 Mbit */ 00195 strncmp("eg", device, 2) == 0 || /* Octane/O2xxx/O3xxx Gigabit */ 00196 strncmp("gfe", device, 3) == 0 || /* GIO 100 Mbit */ 00197 strncmp("fxp", device, 3) == 0 || /* Challenge VME Enet */ 00198 strncmp("ep", device, 2) == 0 || /* Challenge 8x10 Mbit EPLEX */ 00199 strncmp("vfe", device, 3) == 0 || /* Challenge VME 100Mbit */ 00200 strncmp("fa", device, 2) == 0 || 00201 strncmp("qaa", device, 3) == 0 || 00202 strncmp("cip", device, 3) == 0 || 00203 strncmp("el", device, 2) == 0) { 00204 p->linktype = DLT_EN10MB; 00205 p->offset = RAW_HDRPAD(sizeof(struct ether_header)); 00206 ll_hdrlen = sizeof(struct ether_header); 00207 } else if (strncmp("ipg", device, 3) == 0 || 00208 strncmp("rns", device, 3) == 0 || /* O2/200/2000 FDDI */ 00209 strncmp("xpi", device, 3) == 0) { 00210 p->linktype = DLT_FDDI; 00211 p->offset = 3; /* XXX yeah? */ 00212 ll_hdrlen = 13; 00213 } else if (strncmp("ppp", device, 3) == 0) { 00214 p->linktype = DLT_RAW; 00215 ll_hdrlen = 0; /* DLT_RAW meaning "no PPP header, just the IP packet"? */ 00216 } else if (strncmp("lo", device, 2) == 0) { 00217 p->linktype = DLT_NULL; 00218 ll_hdrlen = 4; /* is this just like BSD's loopback device? */ 00219 } else { 00220 snprintf(ebuf, PCAP_ERRBUF_SIZE, 00221 "snoop: unknown physical layer type"); 00222 goto bad; 00223 } 00224 #ifdef SIOCGIFMTU 00225 /* 00226 * XXX - IRIX appears to give you an error if you try to set the 00227 * capture length to be greater than the MTU, so let's try to get 00228 * the MTU first and, if that succeeds, trim the snap length 00229 * to be no greater than the MTU. 00230 */ 00231 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 00232 if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) { 00233 snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCGIFMTU: %s", 00234 pcap_strerror(errno)); 00235 goto bad; 00236 } 00237 /* 00238 * OK, we got it. 00239 * 00240 * XXX - some versions of IRIX 6.5 define "ifr_mtu" and have an 00241 * "ifru_metric" member of the "ifr_ifru" union in an "ifreq" 00242 * structure, others don't. 00243 * 00244 * I've no idea what's going on, so, if "ifr_mtu" isn't defined, 00245 * we define it as "ifr_metric", as using that field appears to 00246 * work on the versions that lack "ifr_mtu" (and, on those that 00247 * don't lack it, "ifru_metric" and "ifru_mtu" are both "int" 00248 * members of the "ifr_ifru" union, which suggests that they 00249 * may be interchangeable in this case). 00250 */ 00251 #ifndef ifr_mtu 00252 #define ifr_mtu ifr_metric 00253 #endif 00254 if (snaplen > ifr.ifr_mtu + ll_hdrlen) 00255 snaplen = ifr.ifr_mtu + ll_hdrlen; 00256 #endif 00257 00258 /* 00259 * The argument to SIOCSNOOPLEN is the number of link-layer 00260 * payload bytes to capture - it doesn't count link-layer 00261 * header bytes. 00262 */ 00263 snooplen = snaplen - ll_hdrlen; 00264 if (snooplen < 0) 00265 snooplen = 0; 00266 if (ioctl(fd, SIOCSNOOPLEN, &snooplen) < 0) { 00267 snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPLEN: %s", 00268 pcap_strerror(errno)); 00269 goto bad; 00270 } 00271 p->snapshot = snaplen; 00272 v = 1; 00273 if (ioctl(fd, SIOCSNOOPING, &v) < 0) { 00274 snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNOOPING: %s", 00275 pcap_strerror(errno)); 00276 goto bad; 00277 } 00278 00279 p->bufsize = 4096; /* XXX */ 00280 p->buffer = (u_char *)malloc(p->bufsize); 00281 if (p->buffer == NULL) { 00282 snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", 00283 pcap_strerror(errno)); 00284 goto bad; 00285 } 00286 00287 return (p); 00288 bad: 00289 (void)close(fd); 00290 free(p); 00291 return (NULL); 00292 } |
|
Definition at line 62 of file pcap-snoop.c. References bpf_program::bf_insns, bhp, pcap::bp, bpf_filter(), BPF_WORDALIGN, pcap::buffer, pcap::bufsize, pcap_pkthdr::caplen, pcap::cc, ep, pcap::errbuf, errno, pcap::fcode, pcap::fd, pcap_pkthdr::len, lseek(), pcap::md, pcap::offset, p, PCAP_ERRBUF_SIZE, pcap_handler, pcap_strerror(), pcap_t, pcap_stat::ps_recv, read(), pcap::snapshot, snprintf(), pcap_md::stat, and pcap_pkthdr::ts. Referenced by pcap_dispatch(), and pcap_loop().
00063 { 00064 int cc; 00065 register struct snoopheader *sh; 00066 register int datalen; 00067 register int caplen; 00068 register u_char *cp; 00069 00070 again: 00071 cc = read(p->fd, (char *)p->buffer, p->bufsize); 00072 if (cc < 0) { 00073 /* Don't choke when we get ptraced */ 00074 switch (errno) { 00075 00076 case EINTR: 00077 goto again; 00078 00079 case EWOULDBLOCK: 00080 return (0); /* XXX */ 00081 } 00082 snprintf(p->errbuf, sizeof(p->errbuf), 00083 "read: %s", pcap_strerror(errno)); 00084 return (-1); 00085 } 00086 sh = (struct snoopheader *)p->buffer; 00087 datalen = sh->snoop_packetlen; 00088 caplen = (datalen < p->snapshot) ? datalen : p->snapshot; 00089 cp = (u_char *)(sh + 1) + p->offset; /* XXX */ 00090 00091 if (p->fcode.bf_insns == NULL || 00092 bpf_filter(p->fcode.bf_insns, cp, datalen, caplen)) { 00093 struct pcap_pkthdr h; 00094 ++p->md.stat.ps_recv; 00095 h.ts.tv_sec = sh->snoop_timestamp.tv_sec; 00096 h.ts.tv_usec = sh->snoop_timestamp.tv_usec; 00097 h.len = datalen; 00098 h.caplen = caplen; 00099 (*callback)(user, &h, cp); 00100 return (1); 00101 } 00102 return (0); 00103 } |
|
Definition at line 295 of file pcap-snoop.c. References BIOCSETF, pcap::errbuf, errno, pcap::fd, install_bpf_program(), ioctl(), no_optimize, p, PCAP_ERRBUF_SIZE, pcap_strerror(), pcap_t, pcap_sf::rfile, pcap::sf, and snprintf(). Referenced by PktSrc::SetFilter().
00296 { 00297 00298 if (install_bpf_program(p, fp) < 0) 00299 return (-1); 00300 return (0); 00301 } |
|
Definition at line 106 of file pcap-snoop.c. References BIOCGSTATS, bpf_stat::bs_drop, bpf_stat::bs_recv, pcap::errbuf, errno, pcap::fd, ioctl(), pcap::md, p, PCAP_ERRBUF_SIZE, pcap_strerror(), pcap_t, pcap_stat::ps_drop, pcap_stat::ps_recv, snprintf(), and pcap_md::stat. Referenced by PktSrc::Statistics().
00107 { 00108 register struct rawstats *rs; 00109 struct rawstats rawstats; 00110 00111 rs = &rawstats; 00112 memset(rs, 0, sizeof(*rs)); 00113 if (ioctl(p->fd, SIOCRAWSTATS, (char *)rs) < 0) { 00114 snprintf(p->errbuf, sizeof(p->errbuf), 00115 "SIOCRAWSTATS: %s", pcap_strerror(errno)); 00116 return (-1); 00117 } 00118 00119 /* 00120 * "ifdrops" are those dropped by the network interface 00121 * due to resource shortages or hardware errors. 00122 * 00123 * "sbdrops" are those dropped due to socket buffer limits. 00124 * 00125 * As filter is done in userland, "sbdrops" counts packets 00126 * regardless of whether they would've passed the filter. 00127 * 00128 * XXX - does this count *all* Snoop or Drain sockets, 00129 * rather than just this socket? If not, why does it have 00130 * both Snoop and Drain statistics? 00131 */ 00132 p->md.stat.ps_drop = 00133 rs->rs_snoop.ss_ifdrops + rs->rs_snoop.ss_sbdrops + 00134 rs->rs_drain.ds_ifdrops + rs->rs_drain.ds_sbdrops; 00135 00136 /* 00137 * "ps_recv" counts only packets that passed the filter. 00138 * As filtering is done in userland, this does not include 00139 * packets dropped because we ran out of buffer space. 00140 */ 00141 *ps = p->md.stat; 00142 return (0); 00143 } |
|
Initial value:
"@(#) $Header: /tcpdump/master/libpcap/pcap-snoop.c,v 1.33.2.3 2002/07/30 07:48:48 guy Exp $ (LBL)"
Definition at line 22 of file pcap-snoop.c. |