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#ifndef lint 22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ = 23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "@(#) $Header: /tcpdump/master/libpcap/pcap-nit.c,v 1.57.2.1 2005/05/03 18:54:37 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/types.h> 31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/time.h> 32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/timeb.h> 33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/file.h> 34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/ioctl.h> 35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h> 36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h> 38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/nit.h> 39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h> 41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in_systm.h> 42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/ip.h> 43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/if_ether.h> 44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/ip_var.h> 45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/udp.h> 46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/udp_var.h> 47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/tcp.h> 48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/tcpip.h> 49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <ctype.h> 51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <errno.h> 52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdio.h> 53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h" 55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H 57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h" 58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The chunk size for NIT. This is the amount of buffering 62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * done for read calls. 63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define CHUNKSIZE (2*1024) 65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The total buffer space used by NIT. 68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define BUFSPACE (4*CHUNKSIZE) 70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Forwards */ 72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int nit_setflags(int, int, int, char *); 73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_stats_nit(pcap_t *p, struct pcap_stat *ps) 76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_recv" counts packets handed to the filter, not packets 80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that passed the filter. As filtering is done in userland, 81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this does not include packets dropped because we ran out 82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of buffer space. 83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "ps_drop" presumably counts packets dropped by the socket 85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * because of flow control requirements or resource exhaustion; 86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it doesn't count packets dropped by the interface driver. 87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * As filtering is done in userland, it counts packets regardless 88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of whether they would've passed the filter. 89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These statistics don't include packets not yet read from the 91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * kernel by libpcap or packets not yet read from libpcap by the 92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * application. 93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *ps = p->md.stat; 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_nit(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int cc, n; 102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct bpf_insn *fcode = p->fcode.bf_insns; 103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register u_char *bp, *cp, *ep; 104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct nit_hdr *nh; 105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int caplen; 106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = p->cc; 108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc == 0) { 109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cc = read(p->fd, (char *)p->buffer, p->bufsize); 110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (cc < 0) { 111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == EWOULDBLOCK) 112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, sizeof(p->errbuf), "pcap_read: %s", 114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = p->buffer; 118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp = p->bp; 120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Loop through each packet. The increment expression 123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * rounds up to the next int boundary past the end of 124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the previous packet. 125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = 0; 127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ep = bp + cc; 128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (bp < ep) { 129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Has "pcap_breakloop()" been called? 131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If so, return immediately - if we haven't read any 132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * packets, clear the flag and return -2 to indicate 133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that we were told to break out of the loop, otherwise 134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * leave the flag set, so that the *next* call will break 135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * out of the loop without having read any packets, and 136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * return the number of packets we've processed so far. 137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->break_loop) { 139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n == 0) { 140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->break_loop = 0; 141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-2); 142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = ep - bp; 144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bp = bp; 145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nh = (struct nit_hdr *)bp; 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project cp = bp + sizeof(*nh); 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project switch (nh->nh_state) { 153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case NIT_CATCH: 155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case NIT_NOMBUF: 158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case NIT_NOCLUSTER: 159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case NIT_NOSPACE: 160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->md.stat.ps_drop = nh->nh_dropped; 161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project case NIT_SEQNO: 164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project default: 167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, sizeof(p->errbuf), 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bad nit state %d", nh->nh_state); 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ++p->md.stat.ps_recv; 172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bp += ((sizeof(struct nit_hdr) + nh->nh_datalen + 173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sizeof(int) - 1) & ~(sizeof(int) - 1)); 174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project caplen = nh->nh_wirelen; 176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (caplen > p->snapshot) 177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project caplen = p->snapshot; 178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bpf_filter(fcode, cp, nh->nh_wirelen, caplen)) { 179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct pcap_pkthdr h; 180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.ts = nh->nh_timestamp; 181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.len = nh->nh_wirelen; 182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project h.caplen = caplen; 183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (*callback)(user, &h, cp); 184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (++n >= cnt && cnt >= 0) { 185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = ep - bp; 186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bp = bp; 187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->cc = 0; 192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (n); 193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_inject_nit(pcap_t *p, const void *buf, size_t size) 197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct sockaddr sa; 199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ret; 200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&sa, 0, sizeof(sa)); 202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncpy(sa.sa_data, device, sizeof(sa.sa_data)); 203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = sendto(p->fd, buf, size, 0, &sa, sizeof(sa)); 204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret == -1) { 205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s", 206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnit_setflags(int fd, int promisc, int to_ms, char *ebuf) 214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct nit_ioc nioc; 216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(&nioc, 0, sizeof(nioc)); 218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_bufspace = BUFSPACE; 219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_chunksize = CHUNKSIZE; 220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_typetomatch = NT_ALLTYPES; 221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_snaplen = p->snapshot; 222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_bufalign = sizeof(int); 223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_bufoffset = 0; 224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (to_ms != 0) { 226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_flags |= NF_TIMEOUT; 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_timeout.tv_sec = to_ms / 1000; 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_timeout.tv_usec = (to_ms * 1000) % 1000000; 229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (promisc) 231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nioc.nioc_flags |= NF_PROMISC; 232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCSNIT, &nioc) < 0) { 234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, "SIOCSNIT: %s", 235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_close_nit(pcap_t *p) 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_close_common(p); 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->device != NULL) 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p->device); 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_t * 250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_open_live(const char *device, int snaplen, int promisc, int to_ms, 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *ebuf) 252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int fd; 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct sockaddr_nit snit; 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register pcap_t *p; 256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = (pcap_t *)malloc(sizeof(*p)); 258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p == NULL) { 259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (snaplen < 96) 264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NIT requires a snapshot length of at least 96. 266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snaplen = 96; 268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(p, 0, sizeof(*p)); 270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->fd = fd = socket(AF_NIT, SOCK_RAW, NITPROTO_RAW); 271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd < 0) { 272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, 273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "socket: %s", pcap_strerror(errno)); 274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snit.snit_family = AF_NIT; 277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)strncpy(snit.snit_ifname, device, NITIFSIZ); 278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (bind(fd, (struct sockaddr *)&snit, sizeof(snit))) { 280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project snprintf(ebuf, PCAP_ERRBUF_SIZE, 281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "bind: %s: %s", snit.snit_ifname, pcap_strerror(errno)); 282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->snapshot = snaplen; 285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project nit_setflags(p->fd, promisc, to_ms, ebuf); 286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NIT supports only ethernets. 289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->linktype = DLT_EN10MB; 291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->bufsize = BUFSPACE; 293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->buffer = (u_char *)malloc(p->bufsize); 294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->buffer == NULL) { 295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We need the device name in order to send packets. 301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->device = strdup(device); 303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->device == NULL) { 304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strlcpy(ebuf, pcap_strerror(errno), PCAP_ERRBUF_SIZE); 305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p->buffer); 306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project goto bad; 307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "p->fd" is a socket, so "select()" should work on it. 311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->selectable_fd = p->fd; 313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is (presumably) a real Ethernet capture; give it a 316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that an application can let you choose it, in case you're 318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * capturing DOCSIS traffic that a Cisco Cable Modem 319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Termination System is putting out onto an Ethernet (it 320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't put an Ethernet header onto the wire, it puts raw 321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DOCSIS frames out on the wire inside the low-level 322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Ethernet framing). 323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If that fails, just leave the list empty. 327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p->dlt_list != NULL) { 329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[0] = DLT_EN10MB; 330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_list[1] = DLT_DOCSIS; 331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->dlt_count = 2; 332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->read_op = pcap_read_nit; 335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->inject_op = pcap_inject_nit; 336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setfilter_op = install_bpf_program; /* no kernel filtering */ 337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setdirection_op = NULL; /* Not implemented. */ 338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->set_datalink_op = NULL; /* can't change data link type */ 339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->getnonblock_op = pcap_getnonblock_fd; 340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->setnonblock_op = pcap_setnonblock_fd; 341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->stats_op = pcap_stats_nit; 342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p->close_op = pcap_close_nit; 343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (p); 345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project bad: 346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd >= 0) 347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project close(fd); 348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(p); 349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (NULL); 350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 357