1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996 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 * Modifications made to accommodate the new SunOS4.0 NIT facility by 22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Micky Liu, micky@cunixc.cc.columbia.edu, Columbia University in May, 1989. 23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This module now handles the STREAMS based NIT. 24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef lint 27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ = 28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "@(#) $Header: /tcpdump/master/libpcap/pcap-snit.c,v 1.72.2.1 2005/05/03 18:54:38 guy Exp $ (LBL)"; 29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H 32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h" 33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/types.h> 36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/time.h> 37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/timeb.h> 38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/dir.h> 39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/fcntlcom.h> 40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/file.h> 41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/ioctl.h> 42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h> 43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/stropts.h> 44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h> 46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/nit.h> 47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/nit_if.h> 48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/nit_pf.h> 49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/nit_buf.h> 50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h> 52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in_systm.h> 53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/ip.h> 54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/if_ether.h> 55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/ip_var.h> 56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/udp.h> 57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/udp_var.h> 58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/tcp.h> 59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/tcpip.h> 60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <ctype.h> 62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <errno.h> 63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdio.h> 64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h> 65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <unistd.h> 66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h" 68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H 70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h" 71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The chunk size for NIT. This is the amount of buffering 75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * done for read calls. 76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define CHUNKSIZE (2*1024) 78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The total buffer space used by NIT. 81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define BUFSPACE (4*CHUNKSIZE) 83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Forwards */ 85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int nit_setflags(int, int, int, char *); 86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_stats_snit(pcap_t *p, struct pcap_stat *ps) 89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_recv" counts packets handed to the filter, not packets 93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that passed the filter. As filtering is done in userland, 94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this does not include packets dropped because we ran out 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of buffer space. 96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_drop" counts packets dropped inside the "/dev/nit" 98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * device because of flow control requirements or resource 99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * exhaustion; it doesn't count packets dropped by the 100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * interface driver, or packets dropped upstream. As filtering 101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is done in userland, it counts packets regardless of whether 102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * they would've passed the filter. 103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These statistics don't include packets not yet read from the 105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * kernel by libpcap or packets not yet read from libpcap by the 106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * application. 107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *ps = p->md.stat; 109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_snit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int cc, n; 116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct bpf_insn *fcode = p->fcode.bf_insns; 117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_char *bp, *cp, *ep; 118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct nit_bufhdr *hdrp; 119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct nit_iftime *ntp; 120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct nit_iflen *nlp; 121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct nit_ifdrops *ndp; 122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int caplen; 123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = p->cc; 125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc == 0) { 126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = read(p->fd, (char *)p->buffer, p->bufsize); 127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc < 0) { 128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == EWOULDBLOCK) 129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", 131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = p->buffer; 135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = p->bp; 137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * loop through each snapshot in the chunk 140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = 0; 142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ep = bp + cc; 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (bp < ep) { 144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Has "pcap_breakloop()" been called? 146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If so, return immediately - if we haven't read any 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets, clear the flag and return -2 to indicate 148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that we were told to break out of the loop, otherwise 149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * leave the flag set, so that the *next* call will break 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * out of the loop without having read any packets, and 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * return the number of packets we've processed so far. 152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->break_loop) { 154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n == 0) { 155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->break_loop = 0; 156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-2); 157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bp = bp; 159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = ep - bp; 160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ++p->md.stat.ps_recv; 165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp = bp; 166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* get past NIT buffer */ 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project hdrp = (struct nit_bufhdr *)cp; 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp += sizeof(*hdrp); 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* get past NIT timer */ 172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ntp = (struct nit_iftime *)cp; 173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp += sizeof(*ntp); 174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ndp = (struct nit_ifdrops *)cp; 176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->md.stat.ps_drop = ndp->nh_drops; 177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp += sizeof *ndp; 178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* get past packet len */ 180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nlp = (struct nit_iflen *)cp; 181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp += sizeof(*nlp); 182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* next snapshot */ 184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp += hdrp->nhb_totlen; 185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project caplen = nlp->nh_pktlen; 187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (caplen > p->snapshot) 188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project caplen = p->snapshot; 189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) { 191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct pcap_pkthdr h; 192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.ts = ntp->nh_timestamp; 193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.len = nlp->nh_pktlen; 194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.caplen = caplen; 195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (*callback)(user, &h, cp); 196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (++n >= cnt && cnt >= 0) { 197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = ep - bp; 198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bp = bp; 199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = 0; 204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_inject_snit(pcap_t *p, const void *buf, size_t size) 209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct strbuf ctl, data; 211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - can we just do 214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = write(pd->f, buf, size); 216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ctl.len = sizeof(*sa); /* XXX - what was this? */ 218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ctl.buf = (char *)sa; 219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project data.buf = buf; 220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project data.len = size; 221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = putmsg(p->fd, &ctl, &data); 222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret == -1) { 223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnit_setflags(int fd, int promisc, int to_ms, char *ebuf) 232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bpf_u_int32 flags; 234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct strioctl si; 235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct timeval timeout; 236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_timout = INFTIM; 238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (to_ms != 0) { 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project timeout.tv_sec = to_ms / 1000; 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project timeout.tv_usec = (to_ms * 1000) % 1000000; 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_cmd = NIOCSTIME; 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_len = sizeof(timeout); 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_dp = (char *)&timeout; 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, I_STR, (char *)&si) < 0) { 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSTIME: %s", 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project flags = NI_TIMESTAMP | NI_LEN | NI_DROPS; 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (promisc) 252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project flags |= NI_PROMISC; 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_cmd = NIOCSFLAGS; 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_len = sizeof(flags); 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_dp = (char *)&flags; 256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, I_STR, (char *)&si) < 0) { 257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSFLAGS: %s", 258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_t * 265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_open_live(const char *device, int snaplen, int promisc, int to_ms, 266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *ebuf) 267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct strioctl si; /* struct for ioctl() */ 269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct ifreq ifr; /* interface request struct */ 270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int chunksize = CHUNKSIZE; 271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int fd; 272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project static char dev[] = "/dev/nit"; 273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register pcap_t *p; 274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = (pcap_t *)malloc(sizeof(*p)); 276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p == NULL) { 277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (snaplen < 96) 282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NIT requires a snapshot length of at least 96. 284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snaplen = 96; 286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(p, 0, sizeof(*p)); 288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Initially try a read/write open (to allow the inject 290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * method to work). If that fails due to permission 291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * issues, fall back to read-only. This allows a 292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * non-root user to be granted specific access to pcap 293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capabilities via file permissions. 294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - we should have an API that has a flag that 296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * controls whether to open read-only or read-write, 297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so that denial of permission to send (or inability 298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to send, if sending packets isn't supported on 299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the device in question) can be indicated at open 300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * time. 301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fd = fd = open(dev, O_RDWR); 303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd < 0 && errno == EACCES) 304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fd = fd = open(dev, O_RDONLY); 305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd < 0) { 306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s", dev, 307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* arrange to get discrete messages from the STREAM and use NIT_BUF */ 312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, I_SRDOPT, (char *)RMSGD) < 0) { 313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "I_SRDOPT: %s", 314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, I_PUSH, "nbuf") < 0) { 318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "push nbuf: %s", 319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* set the chunksize */ 323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_cmd = NIOCSCHUNK; 324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_timout = INFTIM; 325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_len = sizeof(chunksize); 326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_dp = (char *)&chunksize; 327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, I_STR, (char *)&si) < 0) { 328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSCHUNK: %s", 329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* request the interface */ 334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; 336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_cmd = NIOCBIND; 337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_len = sizeof(ifr); 338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_dp = (char *)𝔦 339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, I_STR, (char *)&si) < 0) { 340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCBIND: %s: %s", 341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifr.ifr_name, pcap_strerror(errno)); 342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* set the snapshot length */ 346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_cmd = NIOCSSNAP; 347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_len = sizeof(snaplen); 348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project si.ic_dp = (char *)&snaplen; 349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, I_STR, (char *)&si) < 0) { 350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "NIOCSSNAP: %s", 351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->snapshot = snaplen; 355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (nit_setflags(p->fd, promisc, to_ms, ebuf) < 0) 356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)ioctl(fd, I_FLUSH, (char *)FLUSHR); 359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NIT supports only ethernets. 361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_EN10MB; 363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bufsize = BUFSPACE; 365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->buffer = (u_char *)malloc(p->bufsize); 366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->buffer == NULL) { 367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "p->fd" is an FD for a STREAMS device, so "select()" and 373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "poll()" should work on it. 374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->selectable_fd = p->fd; 376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is (presumably) a real Ethernet capture; give it a 379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that an application can let you choose it, in case you're 381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capturing DOCSIS traffic that a Cisco Cable Modem 382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Termination System is putting out onto an Ethernet (it 383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't put an Ethernet header onto the wire, it puts raw 384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DOCSIS frames out on the wire inside the low-level 385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet framing). 386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If that fails, just leave the list empty. 390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->dlt_list != NULL) { 392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[0] = DLT_EN10MB; 393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[1] = DLT_DOCSIS; 394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_count = 2; 395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->read_op = pcap_read_snit; 398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->inject_op = pcap_inject_snit; 399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setfilter_op = install_bpf_program; /* no kernel filtering */ 400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setdirection_op = NULL; /* Not implemented. */ 401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->set_datalink_op = NULL; /* can't change data link type */ 402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->getnonblock_op = pcap_getnonblock_fd; 403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setnonblock_op = pcap_setnonblock_fd; 404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->stats_op = pcap_stats_snit; 405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->close_op = pcap_close_common; 406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (p); 408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bad: 409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd >= 0) 410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project close(fd); 411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p); 412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 420