Esempio n. 1
0
void reader_libpcap_init(char *UNUSED(name))
{
    char errbuf[1024];

    int i;

    for (i = 0; i < MAX_INTERFACES && config.interface[i]; i++) {

#ifdef SNF
        pcaps[i] = pcap_open_live(config.interface[i], MOLOCH_SNAPLEN, 1, 0, errbuf);
#else
        pcaps[i] = reader_libpcap_open_live(config.interface[i], MOLOCH_SNAPLEN, 1, 0, errbuf);
#endif

        if (!pcaps[i]) {
            LOG("pcap open live failed! %s", errbuf);
            exit(1);
        }

        pcap_setnonblock(pcaps[i], FALSE, errbuf);
    }

    if (i == MAX_INTERFACES) {
        LOG("Only support up to %d interfaces", MAX_INTERFACES);
        exit(1);
    }

    moloch_reader_start         = reader_libpcap_start;
    moloch_reader_stop          = reader_libpcap_stop;
    moloch_reader_stats         = reader_libpcap_stats;
}
Esempio n. 2
0
void
pcap_ex_setnonblock(pcap_t *pcap, int nonblock, char *ebuf)
{
#ifdef HAVE_PCAP_SETNONBLOCK
	pcap_setnonblock(pcap, nonblock, ebuf);
#endif
}
Esempio n. 3
0
struct pcap_port *
pcap_open(struct pcap_port *pcap_port) {
    char errbuf[PCAP_ERRBUF_SIZE];
    struct pcap_drv *pcap_drv = pcap_port->drv;

    pcap_t *pcap = NULL;
    pcap = pcap_open_live(pcap_port->name, PCAP_SNAPLEN, true/*promisc*/, -1/*to_ms*/, errbuf);
    if (pcap == NULL) {
        logger_log(pcap_drv->logger, LOG_ERR, "Unable to open device %s: %s.", pcap_port->name, errbuf);
        return NULL;
    }

    if(pcap_setnonblock(pcap, true, errbuf) != 0) {
        logger_log(pcap_drv->logger, LOG_ERR, "Unable to set device to promisc %s: %s.", pcap_port->name, errbuf);
        return NULL;
    }

    if(pcap_setdirection(pcap, PCAP_D_IN) != 0) {
        logger_log(pcap_drv->logger, LOG_ERR, "Unable to set device direction %s: %s.", pcap_port->name, pcap_geterr(pcap));
        return NULL;
    }

    pcap_port->pcap    = pcap;
    pcap_port->fd      = pcap_fileno(pcap);

    pcap_port->watcher = malloc(sizeof(ev_io));
    pcap_port->watcher->data = pcap_port;
    ev_io_init(pcap_port->watcher, event_loop_packet_in_cb, pcap_port->fd, EV_READ);
    pcap_port_fill(pcap_port);

    return pcap_port;
}
Esempio n. 4
0
static void
add_device(orchids_t *ctx, mod_entry_t *mod, config_directive_t *dir)
{

  /*  dev: the network device to open
      capd: a packet capture descriptor
   */

  int fd;
  char* dev;
  char errbuf[PCAP_ERRBUF_SIZE]="";
  pcap_t* capd = NULL;

  dev = dir->args;
  DebugLog(DF_MOD, DS_INFO, "Add 802.11 listen device %s\n", dev);

  capd = pcap_open_live(dev, 65535, 1, 1, errbuf);

  if ( strlen(errbuf) != 0 ) {
    DebugLog(DF_MOD, DS_ERROR, "pcap_open_live error: %s\n", errbuf);
    return;
  }

  pcap_setnonblock(capd, 1, NULL);
  fd = pcap_fileno(capd);
  datalink_type = pcap_datalink(capd);

  add_input_descriptor(ctx, mod, wifi_callback, fd, capd);
}
Esempio n. 5
0
static void prvConfigureCaptureBehaviour( void )
{
    struct bpf_program xFilterCode;
    const long lMinBytesToCopy = 10L, lBlocking = 1L;
    unsigned long ulNetMask;

    /* Unblock a read as soon as anything is received. */
    pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy );

    /* Allow blocking. */
    pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer );

    /* Set up a filter so only the packets of interest are passed to the lwIP
    stack.  cErrorBuffer is used for convenience to create the string.  Don't
    confuse this with an error message. */
    sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );

    ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;

    if( pcap_compile(pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 ) {
        printf( "\r\nThe packet filter string is invalid\r\n" );
    } else {
        if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 ) {
            printf( "\r\nAn error occurred setting the packet filter.\r\n" );
        }
    }

    /* Create a task that simulates an interrupt in a real system.  This will
    block waiting for packets, then send a message to the uIP task when data
    is available. */
    xTaskCreate( prvInterruptSimulator, "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, configMAC_ISR_SIMULATOR_PRIORITY, NULL );
}
Esempio n. 6
0
int
tc_pcap_socket_in_init(pcap_t **pd, char *device, 
        int snap_len, int buf_size, char *pcap_filter)
{
    int         fd;
    char        ebuf[PCAP_ERRBUF_SIZE]; 
    struct      bpf_program fp;
    bpf_u_int32 net, netmask;      

    if (device == NULL) {
        return TC_INVALID_SOCK;
    }

    tc_log_info(LOG_NOTICE, 0, "pcap open,device:%s", device);

    *ebuf = '\0';

    if (tc_pcap_open(pd, device, snap_len, buf_size) == TC_ERR) {
        return TC_INVALID_SOCK;
    }

    if (pcap_lookupnet(device, &net, &netmask, ebuf) < 0) {
        net = 0;
        netmask = 0;
        tc_log_info(LOG_WARN, 0, "lookupnet:%s", ebuf);
        return TC_INVALID_SOCK;
    }

    if (pcap_compile(*pd, &fp, pcap_filter, 0, netmask) == -1) {
        tc_log_info(LOG_ERR, 0, "couldn't parse filter %s: %s", 
                pcap_filter, pcap_geterr(*pd));
        return TC_INVALID_SOCK;
    }

    if (pcap_setfilter(*pd, &fp) == -1) {
        tc_log_info(LOG_ERR, 0, "couldn't install filter %s: %s",
                pcap_filter, pcap_geterr(*pd));
        pcap_freecode(&fp);
        return TC_INVALID_SOCK;
    }

    pcap_freecode(&fp);

    if (pcap_get_selectable_fd(*pd) == -1) {
        tc_log_info(LOG_ERR, 0, "pcap_get_selectable_fd fails"); 
        return TC_INVALID_SOCK;
    }

    if (pcap_setnonblock(*pd, 1, ebuf) == -1) {
        tc_log_info(LOG_ERR, 0, "pcap_setnonblock failed: %s", ebuf);
        return TC_INVALID_SOCK;
    }

    fd = pcap_get_selectable_fd(*pd);

    return fd;
}
Esempio n. 7
0
int
tc_pcap_socket_in_init(pcap_t **pd, char *device, char *pcap_filter)
{
    int         fd;
    char        ebuf[PCAP_ERRBUF_SIZE]; 
    struct      bpf_program fp;
    bpf_u_int32 net, netmask;      

    if (device == NULL) {
        return TC_INVALID_SOCKET;
    }

    tc_log_info(LOG_NOTICE, 0, "pcap open,device:%s", device);

    *ebuf = '\0';
    *pd = pcap_open_live(device, PCAP_RECV_BUF_SIZE, 0, 1000, ebuf);
    if (*pd == NULL) {
        tc_log_info(LOG_ERR, 0, "pcap error:%s", ebuf);
        return TC_INVALID_SOCKET;
    } else if (*ebuf) {
        tc_log_info(LOG_WARN, 0, "pcap warn:%s", ebuf);
    }

    if (pcap_lookupnet(device, &net, &netmask, ebuf) < 0) {
        net = 0;
        netmask = 0;
        tc_log_info(LOG_WARN, 0, "lookupnet:%s", ebuf);
    }

    if (pcap_compile(*pd, &fp, pcap_filter, 0, netmask) == -1) {
        tc_log_info(LOG_ERR, 0, "couldn't parse filter %s: %s", 
                pcap_filter, pcap_geterr(*pd));
        return TC_INVALID_SOCKET;
    }

    if (pcap_setfilter(*pd, &fp) == -1) {
        tc_log_info(LOG_ERR, 0, "couldn't install filter %s: %s",
                pcap_filter, pcap_geterr(*pd));
        return TC_INVALID_SOCKET;
    }

    if (pcap_get_selectable_fd(*pd) == -1) {
        tc_log_info(LOG_ERR, 0, "pcap_get_selectable_fd fails"); 
        return TC_INVALID_SOCKET;
    }

    if (pcap_setnonblock(*pd, 1, ebuf) == -1) {
        tc_log_info(LOG_ERR, 0, "pcap_setnonblock failed: %s", ebuf);
        return TC_INVALID_SOCKET;
    }

    fd = pcap_get_selectable_fd(*pd);

    return fd;
}
Esempio n. 8
0
int main(int argc, char *argv[])
{
	char *dev, errbuf[PCAP_ERRBUF_SIZE];
	pcap_t *handle;
	int selectable_fd;

	if (argc == 2) {
		dev = argv[1];
	} else {
		dev = pcap_lookupdev(errbuf);
	}

	if (dev == NULL) {
		fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
		return (2);
	}

	handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
	if (handle == NULL) {
		fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
		return (2);
	}

	if (pcap_datalink(handle) != DLT_EN10MB) {
		fprintf(stderr, "Device %s doesn't provide Ethernet headers - "
		                "not supported\n",
		        dev);
		return (2);
	}

	if (pcap_setnonblock(handle, 1, errbuf) != 0) {
		fprintf(stderr, "Non-blocking mode failed: %s\n", errbuf);
		return (2);
	}

	selectable_fd = pcap_get_selectable_fd(handle);
	if (-1 == selectable_fd) {
		fprintf(stderr, "pcap handle not selectable.\n");
		return (2);
	}

	init_curses();
	mvprintw(0, 0, "Device: %s\n", dev);

	grab_packets(selectable_fd, handle);

	/* And close the session */
	pcap_close(handle);
	return 0;
}
Esempio n. 9
0
static PyObject * p_setnonblock (PyObject *self, PyObject *args)
{
  pcap_t * ppcap;
  int nonblock;
  char errbuf[PCAP_ERRBUF_SIZE];

  if (!PyArg_ParseTuple(args, "li", (long*)&ppcap, (int*)&nonblock)) return NULL;
  if (pcap_setnonblock(ppcap, nonblock ? 1 : 0, errbuf) == -1)
  {
    PyErr_SetString(PyExc_RuntimeError, errbuf);
    return NULL;
  }

  Py_RETURN_NONE;
}
Esempio n. 10
0
struct mif *mi_open(char *iface)
{
    struct mif *mi;
    struct priv_if *pi;
    pcap_t *pkt_in, *pkt_out;
    char errbuf[PCAP_ERRBUF_SIZE];

    /* setup mi struct */
    mi = mi_alloc(sizeof(*pi));
    if (!mi)
        return NULL;

    mi->read  = mi_read;
    mi->write = mi_write;
    mi->close = mi_close;

    // for pkt in
    pkt_in = pcap_open_live(iface, 4096, 1, 10, errbuf);
    if (pkt_in == NULL) {
        printf("Unable to open interface %s in pcap: %s\n", iface, errbuf);
        return NULL;
    }

    if (pcap_datalink(pkt_in) != DLT_IEEE802_11_RADIO) {
        printf("Device %s doesn't provide 80211 radiotap header\n", iface);
        return NULL;
    }

    if (pcap_setnonblock(pkt_in, 1, errbuf) == -1) {
        printf("Device %s doesn't set non-blocking mode\n", iface);
        return NULL;
    }

    // for pkt out
    pkt_out = pcap_open_live(iface, 4096, 1, 10, errbuf);
    if (pkt_out == NULL) {
        printf("Unable to open interface %s in pcap: %s\n", iface, errbuf);
        return NULL;
    }

    pi = mi_priv(mi);
    pi->fd_in = pkt_in;
    pi->fd_out = pkt_out;

    return mi;
}
Esempio n. 11
0
void pcap_init(void)
{
    //char *dev;
    char err_buff[PCAP_ERRBUF_SIZE];

    if (dev == NULL) {
        // 1. find the active interface for capturing data
        if ((dev = pcap_lookupdev(err_buff)) == NULL) {
            fprintf(stderr, "Couldn't find default device: %s\n", err_buff);
            exit(EXIT_FAILURE);
        }
    }

    // 2. open the interface
    bpf_u_int32 net, mask;

    if ((pcap_dest = pcap_open_live(dev, SNAP_LEN, 0, 1000, err_buff)) == NULL){
        fprintf(stderr, "Failed to open the device %s\n", dev);
        exit(EXIT_FAILURE);
    }

    if (pcap_lookupnet(dev, &net, &mask, err_buff) == -1) {
        fprintf(stderr, "Failed to get net.\n");
        exit(EXIT_FAILURE);
    }

    // 3. complie the filter
    char filter[] = "ip";
    struct bpf_program fp;
    if (pcap_compile(pcap_dest, &fp, filter, 0, net) == -1) {
        fprintf(stderr, "failed to compile the filter %s: %s\n",
                                                filter, pcap_geterr(pcap_dest));
        exit(EXIT_FAILURE);
    }

    if (pcap_setfilter(pcap_dest, &fp) == -1) {
        fprintf(stderr, "failed to set filter %s: %s\n", filter,
                                                        pcap_geterr(pcap_dest));
        exit(EXIT_FAILURE);
    }

    // 4. set the mode of pcap as non-block
    if ((pcap_setnonblock(pcap_dest, 1, err_buff)) != 0) {
        fprintf(stderr, "\e\[31m[Error]\e\[0m: %s\n", err_buff);
        exit(EXIT_FAILURE);
    }
Esempio n. 12
0
pcap_t *
reader_libpcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
{
    pcap_t *p;
    int status;

    p = pcap_create(source, errbuf);
    if (p == NULL)
        return (NULL);
    status = pcap_set_snaplen(p, snaplen);
    if (status < 0)
        goto fail;
    status = pcap_set_promisc(p, promisc);
    if (status < 0)
        goto fail;
    status = pcap_set_timeout(p, to_ms);
    if (status < 0)
        goto fail;
    status = pcap_set_buffer_size(p, config.pcapBufferSize);
    if (status < 0)
        goto fail;
    status = pcap_activate(p);
    if (status < 0)
        goto fail;
    status = pcap_setnonblock(p, TRUE, errbuf);
    if (status < 0) {
        pcap_close(p);
        return (NULL);
    }

    return (p);
fail:
    if (status == PCAP_ERROR)
        snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
            pcap_geterr(p));
    else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
        status == PCAP_ERROR_PERM_DENIED)
        snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source,
            pcap_statustostr(status), pcap_geterr(p));
    else
        snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
            pcap_statustostr(status));
    pcap_close(p);
    return (NULL);
}
Esempio n. 13
0
static PyObject *ppcap_setnonblock(ppcap *self, PyObject *args)
{
    int nonblock, retval;
    char errbuf[PCAP_ERRBUF_SIZE];

    if (!PyArg_ParseTuple(args, "i", &nonblock))
        return NULL;
    if (!ppcap_isset_handle(self->handle)) {
        PyErr_SetString(PyExc_Ppcap, "pcap handle is not created.");
        return NULL;
    }
    retval = pcap_setnonblock(self->handle, nonblock, errbuf);
    if (retval == -1) {
        PyErr_Format(PyExc_Ppcap, "%s", errbuf);
        return NULL;
    }
    Py_RETURN_NONE;
}
Esempio n. 14
0
ebbrt::RawSocket::RawSocket()
{
  char errbuf[PCAP_ERRBUF_SIZE];
  pcap_if_t* alldevs;

  int ret = pcap_findalldevs(&alldevs, errbuf);
  assert(ret != -1);

  while (alldevs != NULL) {
    if (strcmp(alldevs->name, dev) == 0) {
      break;
    }
    alldevs = alldevs->next;
  }

  assert(alldevs != NULL);

  auto addr = alldevs->addresses;
  while (addr != NULL) {
    if (addr->addr->sa_family == AF_PACKET) {
      break;
    }
    addr = addr->next;
  }
  assert(addr != NULL);

  auto packet_addr = reinterpret_cast<struct sockaddr_ll*>(addr->addr);
  std::copy(&packet_addr->sll_addr[0], &packet_addr->sll_addr[5], mac_addr_);

  pdev_ = pcap_open_live(dev, 65535, 0, 0, errbuf);
  assert(dev != NULL);

  ret = pcap_setnonblock(pdev_, 1, errbuf);
  assert(ret != -1);

  int fd = pcap_get_selectable_fd(pdev_);
  assert(fd != -1);

  uint8_t interrupt = event_manager->AllocateInterrupt([]() {
      ethernet->Receive();
    });
  event_manager->RegisterFD(fd, EPOLLIN, interrupt);
}
Esempio n. 15
0
void
pcap_event_init(client_conn_t * conn)
{
    struct bpf_program filterp;
    bpf_u_int32     maskp,
                    netp;
    char            errbuf[PCAP_ERRBUF_SIZE];

    if (pcap_lookupnet(conn->start_header.dev, &netp, &maskp, errbuf) < 0)
	goto pcap_err;

    if ((conn->descr =
	 pcap_open_live(conn->start_header.dev,
			conn->start_header.snaplen, 1, 100,
			errbuf)) == NULL)
	goto pcap_err;

    if (conn->start_header.bpf != NULL) {
	if (pcap_compile(conn->descr, &filterp,
			 conn->start_header.bpf, 0, netp) < 0)
	    goto pcap_err;

	pcap_setfilter(conn->descr, &filterp);
    }

    if (pcap_setnonblock(conn->descr, 1, errbuf) < 0)
	goto pcap_err;

    if ((conn->pcap_fd = pcap_get_selectable_fd(conn->descr)) <= 0)
	goto pcap_err;

    event_set(&conn->pcap_event, conn->pcap_fd,
	      EV_READ | EV_PERSIST, (void *) pcap_driver, (void *) conn);
    event_add(&conn->pcap_event, 0);
    return;

  pcap_err:
    LOG("pcap err %s\n", errbuf);
    free_client_conn(conn);
    return;
}
Esempio n. 16
0
/**
 * Open pcap device
 *
 */
static int hijack_open ( const char *interface, struct hijack *hijack ) {
    char errbuf[PCAP_ERRBUF_SIZE];

    /* Open interface via pcap */
    errbuf[0] = '\0';
    hijack->pcap = pcap_open_live ( interface, SNAPLEN, 1, 0, errbuf );
    if ( ! hijack->pcap ) {
        logmsg ( LOG_ERR, "Failed to open %s: %s\n",
                 interface, errbuf );
        goto err;
    }
    if ( errbuf[0] )
        logmsg ( LOG_WARNING, "Warning: %s\n", errbuf );

    /* Set capture interface to non-blocking mode */
    if ( pcap_setnonblock ( hijack->pcap, 1, errbuf ) < 0 ) {
        logmsg ( LOG_ERR, "Could not make %s non-blocking: %s\n",
                 interface, errbuf );
        goto err;
    }

    /* Get file descriptor for select() */
    hijack->fd = pcap_get_selectable_fd ( hijack->pcap );
    if ( hijack->fd < 0 ) {
        logmsg ( LOG_ERR, "Cannot get selectable file descriptor "
                 "for %s\n", interface );
        goto err;
    }

    /* Get link layer type */
    hijack->datalink = pcap_datalink ( hijack->pcap );

    return 0;

err:
    if ( hijack->pcap )
        pcap_close ( hijack->pcap );
    return -1;
}
Esempio n. 17
0
static void listener_handler(u_char* u, const struct pcap_pkthdr * ph, const u_char* buf) {
	char errbuf[PCAP_ERRBUF_SIZE];

	dprintf(2,"listener handler invoked dumping=%d\n",dumping);

	if (dumping) {
		dprintf(2,"last round\n");
		keep_going = 0;
	} else {
		if (pcap_setfilter(listener, &stop_filter) < 0) {
			panic(23,"could not apply stop filter to listener: %s\n",pcap_geterr(listener));
		}

		dprintf(2,"apply stop filter to listener\n");

		if (pcap_setnonblock(listener, 1, errbuf) < 0) {
			panic(24,"could not set listener in non blocking mode: %s\n",errbuf);
		}

		dprintf(2,"listener -> non_blocking\n");
		dumping = 1;
	}
}
Esempio n. 18
0
ether_device *
create_ether_device( const char *name, const size_t max_send_queue, const size_t max_recv_queue ) {
    assert( name != NULL );
    assert( strlen( name ) > 0 );
    assert( max_send_queue > 0 );
    assert( max_recv_queue > 0 );

    int nfd = socket( PF_INET, SOCK_DGRAM, 0 );
    if ( nfd < 0 ) {
        char error_string[ ERROR_STRING_SIZE ];
        error( "Failed to open a socket ( ret = %d, errno = %s [%d] ).",
               nfd, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno );
        return NULL;
    }

    struct ifreq ifr;
    memset( &ifr, 0, sizeof( ifr ) );
    strncpy( ifr.ifr_name, name, IFNAMSIZ );
    ifr.ifr_name[ IFNAMSIZ - 1 ] = '\0';
    int ret = ioctl( nfd, SIOCGIFINDEX, &ifr );
    if ( ret == -1 ) {
        char error_string[ ERROR_STRING_SIZE ];
        error( "Failed to retrieve an interface index of %s ( ret = %d, errno = %s [%d] ).",
               name, ret, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno );
        close( nfd );
        return NULL;
    }
    int ifindex = ifr.ifr_ifindex;

    ret = ioctl( nfd, SIOCGIFMTU, &ifr );
    if ( ret == -1 ) {
        char error_string[ ERROR_STRING_SIZE ];
        error( "Failed to retrieve MTU of %s ( ret = %d, errno = %s [%d] ).",
               name, ret, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno );
        close( nfd );
        return NULL;
    }
    int mtu = ifr.ifr_mtu;

    ret = ioctl( nfd, SIOCGIFHWADDR, &ifr );
    if ( ret == -1 ) {
        char error_string[ ERROR_STRING_SIZE ];
        error( "Failed to retrieve hardware address of %s ( ret = %d, error = %s [%d] ).",
               name, ret, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno );
        close( nfd );
        return NULL;
    }

    close( nfd );

    size_t device_mtu = ( size_t ) mtu + MAX_L2_HEADER_LENGTH;
#ifdef WITH_PCAP
    char errbuf[ PCAP_ERRBUF_SIZE ];
    pcap_t *handle = pcap_open_live( name, ( int ) device_mtu, 1, 100, errbuf );
    if( handle == NULL ) {
        error( "Failed to open %s ( %s ).", name, errbuf );
        return NULL;
    }
    if ( pcap_setnonblock( handle, 1, errbuf ) == -1 ) {
        warn( "Failed to setnonblock %s ( %s ).", name, errbuf );
    }
    int fd = pcap_get_selectable_fd( handle );
#else // WITH_PCAP
    int fd = socket( PF_PACKET, SOCK_RAW, htons( ETH_P_ALL ) );
    if ( fd < 0 ) {
        char error_string[ ERROR_STRING_SIZE ];
        error( "Failed to open a socket ( ret = %d, errno = %s [%d] ).",
               fd, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno );
        return NULL;
    }

    struct sockaddr_ll sll;
    memset( &sll, 0, sizeof( sll ) );
    sll.sll_family = AF_PACKET;
    sll.sll_protocol = htons( ETH_P_ALL );
    sll.sll_ifindex = ifindex;
    ret = bind( fd, ( struct sockaddr * ) &sll, sizeof( sll ) );
    if ( ret < 0 ) {
        char error_string[ ERROR_STRING_SIZE ];
        error( "Failed to bind ( fd = %d, ret = %d, errno = %s [%d] ).",
               fd, ret, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno );
        close( fd );
        return NULL;
    }

    int val = TPACKET_V2;
    ret = setsockopt( fd, SOL_PACKET, PACKET_VERSION, &val, sizeof( val ) );
    if ( ret < 0 ) {
        char error_string[ ERROR_STRING_SIZE ];
        error( "Failed to set PACKET_VERSION to %d ( fd = %d, ret = %d, errno = %s [%d] ).",
               val, fd, ret, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno );
        close( fd );
        return NULL;
    }

    val = 1;
    ret = setsockopt( fd, SOL_PACKET, PACKET_AUXDATA, &val, sizeof( val ) );
    if ( ret < 0 ) {
        char error_string[ ERROR_STRING_SIZE ];
        error( "Failed to set PACKET_AUXDATA to %d ( fd = %d, ret = %d, errno = %s [%d] ).",
               val, fd, ret, safe_strerror_r( errno, error_string, sizeof( error_string ) ), errno );
        close( fd );
        return NULL;
    }

    while ( 1 ) {
        char buf;
        ssize_t length = recv( fd, &buf, 1, MSG_DONTWAIT );
        if ( length <= 0 ) {
            break;
        }
    }
#endif // WITH_PCAP

    ether_device *device = xmalloc( sizeof( ether_device ) );
    memset( device, 0, sizeof( ether_device ) );
    strncpy( device->name, name, IFNAMSIZ );
    device->name[ IFNAMSIZ - 1 ] = '\0';
#if WITH_PCAP
    device->pcap = handle;
#endif
    device->fd = fd;
    device->ifindex = ifindex;
    memcpy( device->hw_addr, ifr.ifr_hwaddr.sa_data, ETH_ADDRLEN );
    device->status.can_retrieve_link_status = true;
    device->status.can_retrieve_pause = true;
    device->mtu = device_mtu;
    device->recv_buffer = alloc_buffer_with_length( device->mtu );
    device->send_queue = create_packet_buffers( ( unsigned int ) max_send_queue, device->mtu );
    device->recv_queue = create_packet_buffers( ( unsigned int ) max_recv_queue, device->mtu );

    short int flags = get_device_flags( device->name );
    device->original_flags = flags;

    set_fd_handler_safe( fd, receive_frame, device, flush_send_queue, device );
    set_readable_safe( fd, true );

    enable_promiscuous( device );
    up_ether_device( device );
    update_device_status( device );

    time_now( &device->created_at );

    return device;
}
static int l2_packet_init_libpcap(struct l2_packet_data *l2,
				  unsigned short protocol)
{
	bpf_u_int32 pcap_maskp, pcap_netp;
	char pcap_filter[200], pcap_err[PCAP_ERRBUF_SIZE];
	struct bpf_program pcap_fp;

#ifdef CONFIG_WINPCAP
	char ifname[128];
	os_snprintf(ifname, sizeof(ifname), "\\Device\\NPF_%s", l2->ifname);
	pcap_lookupnet(ifname, &pcap_netp, &pcap_maskp, pcap_err);
	l2->pcap = pcap_open_live(ifname, 2500, 0, 10, pcap_err);
	if (l2->pcap == NULL) {
		fprintf(stderr, "pcap_open_live: %s\n", pcap_err);
		fprintf(stderr, "ifname='%s'\n", ifname);
		return -1;
	}
	if (pcap_setnonblock(l2->pcap, 1, pcap_err) < 0)
		fprintf(stderr, "pcap_setnonblock: %s\n",
			pcap_geterr(l2->pcap));
#else /* CONFIG_WINPCAP */
	pcap_lookupnet(l2->ifname, &pcap_netp, &pcap_maskp, pcap_err);
	l2->pcap = pcap_open_live(l2->ifname, 2500, 0, 10, pcap_err);
	if (l2->pcap == NULL) {
		fprintf(stderr, "pcap_open_live: %s\n", pcap_err);
		fprintf(stderr, "ifname='%s'\n", l2->ifname);
		return -1;
	}
	if (pcap_datalink(l2->pcap) != DLT_EN10MB &&
	    pcap_set_datalink(l2->pcap, DLT_EN10MB) < 0) {
		fprintf(stderr, "pcap_set_datalinke(DLT_EN10MB): %s\n",
			pcap_geterr(l2->pcap));
		return -1;
	}
#endif /* CONFIG_WINPCAP */
	os_snprintf(pcap_filter, sizeof(pcap_filter),
		    "not ether src " MACSTR " and "
		    "( ether dst " MACSTR " or ether dst " MACSTR " ) and "
		    "ether proto 0x%x",
		    MAC2STR(l2->own_addr), /* do not receive own packets */
		    MAC2STR(l2->own_addr), MAC2STR(pae_group_addr),
		    protocol);
	if (pcap_compile(l2->pcap, &pcap_fp, pcap_filter, 1, pcap_netp) < 0) {
		fprintf(stderr, "pcap_compile: %s\n", pcap_geterr(l2->pcap));
		return -1;
	}

	if (pcap_setfilter(l2->pcap, &pcap_fp) < 0) {
		fprintf(stderr, "pcap_setfilter: %s\n", pcap_geterr(l2->pcap));
		return -1;
	}

	pcap_freecode(&pcap_fp);
#ifdef BIOCIMMEDIATE
	/*
	 * When libpcap uses BPF we must enable "immediate mode" to
	 * receive frames right away; otherwise the system may
	 * buffer them for us.
	 */
	{
		unsigned int on = 1;
		if (ioctl(pcap_fileno(l2->pcap), BIOCIMMEDIATE, &on) < 0) {
			fprintf(stderr, "%s: cannot enable immediate mode on "
				"interface %s: %s\n",
				__func__, l2->ifname, strerror(errno));
			/* XXX should we fail? */
		}
	}
#endif /* BIOCIMMEDIATE */

#ifdef CONFIG_WINPCAP
	eloop_register_timeout(0, 100000, l2_packet_receive_timeout,
			       l2, l2->pcap);
#else /* CONFIG_WINPCAP */
	eloop_register_read_sock(pcap_get_selectable_fd(l2->pcap),
				 l2_packet_receive, l2, l2->pcap);
#endif /* CONFIG_WINPCAP */

	return 0;
}
Esempio n. 20
0
/* Convert new nsiod to pcap descriptor. Other parameters have the same meaning
 * as for pcap_open_live in pcap(3).
 *   device   : pcap-style device name
 *   snaplen  : size of packet to be copied to hanler
 *   promisc  : whether to open device in promiscuous mode
 *   bpf_fmt   : berkeley filter
 * return value: NULL if everything was okay, or error string if error occurred. */
char* nsock_pcap_open(nsock_pool nsp, nsock_iod nsiod, const char *pcap_device, int snaplen,
                      int promisc, const char *bpf_fmt, ...) {
  msiod *nsi = (msiod *)nsiod;
  mspool *ms = (mspool *)nsp;
  mspcap *mp = (mspcap *)nsi->pcap;
  static char errorbuf[128];
  char err0r[PCAP_ERRBUF_SIZE];
  /* packet filter string */
  char bpf[4096];
  va_list ap;
  int failed, datalink;
  char *e;

  gettimeofday(&nsock_tod, NULL);

#ifdef PCAP_CAN_DO_SELECT

#if PCAP_BSD_SELECT_HACK
  /* MacOsX reports error if to_ms is too big (like INT_MAX) with error
   *  FAILED. Reported error: BIOCSRTIMEOUT: Invalid argument
   *  INT_MAX/6 (=357913941) seems to be working... */
  int to_ms = 357913941;
#else
  int to_ms = 200;
#endif /* PCAP_BSD_SELECT_HACK */

#else
  int to_ms = 1;
#endif

  if (mp)
    return "nsock-pcap: this nsi already has pcap device opened";

  mp = (mspcap *)safe_zalloc(sizeof(mspcap));
  nsi->pcap = (void *)mp;

  va_start(ap, bpf_fmt);
  if (Vsnprintf(bpf, sizeof(bpf), bpf_fmt, ap) >= (int)sizeof(bpf)) {
    va_end(ap);
    return "nsock-pcap: nsock_pcap_open called with too-large bpf filter arg";
  }
  va_end(ap);

  if (ms->tracelevel > 0)
      nsock_trace(ms,
                  "PCAP requested on device '%s' with berkeley filter '%s' (promisc=%i snaplen=%i to_ms=%i) (IOD #%li)",
                  pcap_device,bpf, promisc, snaplen, to_ms, nsi->id);

  failed = 0;
  do {
    mp->pt = pcap_open_live((char* )pcap_device, snaplen, promisc, to_ms, err0r);
    if (mp->pt)  /* okay, opened!*/
      break;

    /* sorry, something failed*/
    if (++failed >= 3) {
      mp->pcap_device = strdup(pcap_device);
      fprintf(stderr,
              "Call to pcap_open_live(%s, %d, %d, %d) failed three times. Reported error: %s\n"
              "There are several possible reasons for this, depending on your operating system:\n"
              "LINUX: If you are getting Socket type not supported, try modprobe af_packet or recompile your kernel with PACKET enabled.\n"
              "*BSD:  If you are getting device not configured, you need to recompile your kernel with Berkeley Packet Filter support.  If you are getting No such file or directory, try creating the device (eg cd /dev; MAKEDEV <device>; or use mknod).\n"
              "*WINDOWS:  Nmap only supports ethernet interfaces on Windows for most operations because Microsoft disabled raw sockets as of Windows XP SP2.  Depending on the reason for this error, it is possible that the --unprivileged command-line argument will help.\n"
              "SOLARIS:  If you are trying to scan localhost and getting '/dev/lo0: No such file or directory', complain to Sun.  I don't think Solaris can support advanced localhost scans.  You can probably use \"-PN -sT localhost\" though.\n\n",
        pcap_device, snaplen, promisc, to_ms, err0r);
      return "nsock-pcap: can't open pcap! Are you root?";
    }

    fprintf(stderr,
            "pcap_open_live(%s, %d, %d, %d) FAILED. Reported error: %s. Will wait %d seconds then retry.\n",
            pcap_device, snaplen, promisc, to_ms, err0r, 4*failed);
    sleep(4* failed);
  } while (1);

  e = nsock_pcap_set_filter(mp->pt, pcap_device, bpf);
  if (e)
    return e;

#ifdef WIN32
  /* We want any responses back ASAP */
  pcap_setmintocopy(mp->pt, 1);
#endif

  mp->l3_offset = nsock_pcap_get_l3_offset(mp->pt, &datalink);
  mp->snaplen = snaplen;
  mp->datalink = datalink;
  mp->pcap_device = strdup(pcap_device);
#ifdef PCAP_CAN_DO_SELECT
  mp->pcap_desc = pcap_get_selectable_fd(mp->pt);
#else
  mp->pcap_desc = -1;
#endif
  mp->readsd_count = 0;

  /* Without setting this ioctl, some systems (BSDs, though it depends on the
   * release) will buffer packets in non-blocking mode and only return them in a
   * bunch when the buffer is full. Setting the ioctl makes each one be
   * delivered immediately. This is how Linux works by default. See the comments
   * surrounding the setting of BIOCIMMEDIATE in libpcap/pcap-bpf.c. */
#ifdef BIOCIMMEDIATE
  if (mp->pcap_desc != -1) {
    int immediate = 1;

    if (ioctl(mp->pcap_desc, BIOCIMMEDIATE, &immediate) < 0)
      fatal("Cannot set BIOCIMMEDIATE on pcap descriptor");
  }
#endif

  /* Set device non-blocking */
  if (pcap_setnonblock(mp->pt, 1, err0r) < 0) {
    /* I can't do select() on pcap! blocking + no_select is fatal */
    if(mp->pcap_desc < 0){
      Snprintf(errorbuf, sizeof(errorbuf),
               "nsock-pcap: Failed to set pcap descriptor on device %s to nonblocking state: %s",
               pcap_device, err0r);
      return errorbuf;
    }

    /* When we use bsd hack we also need to set non-blocking */
#ifdef PCAP_BSD_SELECT_HACK
    Snprintf(errorbuf, sizeof(errorbuf),
             "nsock-pcap: Failed to set pcap descriptor on device %s to nonblocking state: %s",
             pcap_device, err0r);
    return errorbuf;
#endif

    /* in other case, we can accept blocking pcap */
    fprintf(stderr, "Failed to set pcap descriptor on device %s to nonblocking state: %s",
            pcap_device, err0r);
  }

  if (ms->tracelevel > 0)
      nsock_trace(ms, "PCAP created successfully on device '%s' (pcap_desc=%i bsd_hack=%i to_valid=%i l3_offset=%i) (IOD #%li)",
      pcap_device,
      mp->pcap_desc,
#if PCAP_BSD_SELECT_HACK
      1,
#else
      0,
#endif
#if PCAP_RECV_TIMEVAL_VALID
      1,
#else
      0,
#endif
      mp->l3_offset,
      nsi->id);

  return NULL;
}
Esempio n. 21
0
int main (int argc, char *argv[]) {
    char           *dev = NULL;
    char		errbuf    [ERRBUF_SIZE];	/* Error string */
    struct bpf_program fp;	/* The compiled filter */
    char		filter_exp[] = "ether proto 0x88d9"; //"port 80";	/* The filter expression */
    bpf_u_int32	mask;	/* Our netmask */
    bpf_u_int32	net;	/* Our IP */
    struct pcap_pkthdr header;
    const u_char   *packet;
    int c,i;
    libnet_t       *l;
    libnet_ptag_t   eth_ptag = 0;
    u_char buf[0x100];
    struct itimerspec tspec;

    memset(&tspec, 0, sizeof(tspec));
    tspec.it_value.tv_sec = 3;

    while ((c = getopt(argc, argv, "t:i:hvu")) != EOF) {
        switch (c) {
        case 'i': // interface
            dev = optarg;
            break;
        case 't': // timeout
            i = atoi(optarg);
            if( i>0 ) {
#ifndef __linux__
                if( i > PCAP_PERIOD ) i-=PCAP_PERIOD-10; // try to be more precise
#endif
                tspec.it_value.tv_sec = i/1000;
                tspec.it_value.tv_nsec = (i%1000)*1000000;
            }
            break;
        case 'v': // verbosity
            verbose++;
            break;
        case 'u': // unicode support
            unicode = 1;
            break;
        case 'h': // show usage
            usage(argv[0]);
            exit(EXIT_SUCCESS);
        default:
            exit(EXIT_FAILURE);
        }
    }
    argc -= optind;
    argv += optind;

    if( argc > 1 ) {
        usage(argv[0]);
        exit(EXIT_FAILURE);
    }
    if( argc == 1 ) {
        if( strlen(argv[0]) != 17 ) {
            fprintf(stderr, "Invalid MAC-address: '%s'\n", argv[0]);
            exit(EXIT_FAILURE);
        }
        mac_to_find = argv[0];
    }

    setlinebuf(stdout);

    if(!dev) dev = pcap_lookupdev(errbuf);
    if (dev == NULL) {
        fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
        return (2);
    }

    printf("interface %s\n",dev);

    l = libnet_init(LIBNET_LINK, dev, errbuf);
    if (l == NULL) {
        fprintf(stderr, "libnet_init() failed: %s", errbuf);
        exit(EXIT_FAILURE);
    }

    /* Find the properties for the device */
    if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
        fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
        net = 0;
        mask = 0;
    }

    struct ether_addr *ha = NULL;
    if ((ha = (struct ether_addr *) libnet_get_hwaddr(l)) == NULL) {
        fprintf(stderr, "%s", libnet_geterror(l));
        exit(EXIT_FAILURE);
    }

    // LLTP magic packet
    char* payload = "\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00";
    char* hwdst   = "\xff\xff\xff\xff\xff\xff";

    memcpy(buf,payload,18);
    memcpy(buf+10, ha, 6);

    gettimeofday(&start_time, NULL);
    memcpy(buf+16, &start_time.tv_sec, 2); // emulate sequence number

    eth_ptag = libnet_build_ethernet(
                   hwdst, /* ethernet destination */
                   ha->ether_addr_octet,
                   /* ethernet source */
                   0x88d9,        /* protocol type */
                   buf,       /* payload */
                   18,    /* payload size */
                   l,     /* libnet handle */
                   0);    /* libnet id */
    if (eth_ptag == -1) {
        fprintf(stderr, "Can't build ethernet header: %s\n", libnet_geterror(l));
        libnet_destroy(l);
        exit(EXIT_FAILURE);
    }
    /*
     * Write it to the wire.
     */
    c = libnet_write(l);

    if (c == -1) {
        fprintf(stderr, "Write error: %s\n", libnet_geterror(l));
        libnet_destroy(l);
        exit(EXIT_FAILURE);
    }

    /* Open the session in promiscuous mode */
    pcap_handle = pcap_open_live(dev, BUFSIZ, 1, PCAP_PERIOD, errbuf);
    if (pcap_handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        libnet_destroy(l);
        return (2);
    }
    /* Compile and apply the filter */
    if (pcap_compile(pcap_handle, &fp, filter_exp, 0, net) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(pcap_handle));
        libnet_destroy(l);
        return (2);
    }
    if (pcap_setfilter(pcap_handle, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(pcap_handle));
        libnet_destroy(l);
        return (2);
    }

    signal(SIGALRM, on_alarm);

    gettimeofday(&start_time, NULL);

    timer_create(CLOCK_MONOTONIC, NULL, &timer_id);
    timer_settime(timer_id, 0, &tspec, NULL);

    // don't know why, but pcap_dispatch does not return control to main after
    // timeout expires. so, we use nonblocking pcap on linux.
#ifdef __linux__
    pcap_setnonblock(pcap_handle, 1, errbuf);
#endif

    while( !do_stop ) {
        pcap_dispatch(pcap_handle, -1, got_packet, NULL);
#ifdef __linux__
        usleep(1000);
#endif
    }

    pcap_close(pcap_handle);

    i = tv_diff2msec(NULL);

    printf("found %d hosts in %d.%d seconds", nhosts, i/1000, i%1000);

    if( mac_to_find && !mac_found ) {
        printf(", but '%s' is not found.\n", mac_to_find);
    } else {
        puts("");
    }

    return (0);
}
Esempio n. 22
0
/**
 *  Set up pcap listener for the given interfaces and protocols.
 *  @return a properly configured pcap_t* object for listening for the given protocols - NULL on error
 *  @see pcap_protocols
 */
pcap_t*
create_pcap_listener(const char * dev		///<[in] Device name to listen on
                     ,		     gboolean blocking		///<[in] TRUE if this is a blocking connection
                     ,		     unsigned listenmask	///<[in] Bit mask of protocols to listen for
                     ///< (see @ref pcap_protocols "list of valid bits")
                     ,		     struct bpf_program*prog)	///<[out] Compiled PCAP program
{
    pcap_t*			pcdescr = NULL;
    bpf_u_int32		maskp = 0;
    bpf_u_int32		netp = 0;
    char			errbuf[PCAP_ERRBUF_SIZE];
    char *			expr = NULL;
    int			filterlen = 1;
    unsigned		j;
    int			cnt=0;
    int			rc;
    const char ORWORD [] = " or ";
    gboolean		need_promisc = FALSE;

    BINDDEBUG(pcap_t);
//	setbuf(stdout, NULL);
    setvbuf(stdout, NULL, _IONBF, 0);
    errbuf[0] = '\0';

    // Search the list of valid bits so we can construct the libpcap filter
    // for the given set of protocols on the fly...
    // On this pass we just compute the amount of memory we'll need...
    for (j = 0, cnt = 0; j < DIMOF(filterinfo); ++j) {
        if (listenmask & filterinfo[j].filterbit) {
            ++cnt;
            if (cnt > 1) {
                filterlen += sizeof(ORWORD);
            }
            filterlen += strlen(filterinfo[j].filter);
        }
    }

    if (filterlen < 2) {
        g_warning("Constructed filter is too short - invalid mask argument.");
        return NULL;
    }
    if (NULL == (expr = malloc(filterlen))) {
        g_error("Out of memory!");
        return NULL;
    }
    // Same song, different verse...
    // This time around, we construct the filter
    expr[0] = '\0';
    for (j = 0, cnt = 0; j < DIMOF(filterinfo); ++j) {
        if (listenmask & filterinfo[j].filterbit) {
            ++cnt;
            if (cnt > 1) {
                g_strlcat(expr, ORWORD, filterlen);
            }
            g_strlcat(expr, filterinfo[j].filter, filterlen);
        }
    }
    if (pcap_lookupnet(dev, &netp, &maskp, errbuf) != 0) {
        // This is not a problem for non-IPv4 protocols...
        // It just looks up the ipv4 address - which we mostly don't care about.
        g_info("%s.%d: pcap_lookupnet(\"%s\") failed: [%s]"
               ,	__FUNCTION__, __LINE__, dev, errbuf);
    }

    if (NULL == (pcdescr = pcap_create(dev, errbuf))) {
        g_warning("pcap_create failed: [%s]", errbuf);
        goto oopsie;
    }
    //pcap_set_promisc(pcdescr, FALSE);
    for (j = 0; j < DIMOF(filterinfo); ++j) {
        if (listenmask & filterinfo[j].filterbit) {
            const char * addrstring = filterinfo[j].mcastaddr;
            if (addrstring && !_enable_mcast_address(addrstring, dev, TRUE)) {
                need_promisc = TRUE;
            }
        }
    }
    pcap_set_promisc(pcdescr, need_promisc);
#ifdef HAVE_PCAP_SET_RFMON
    pcap_set_rfmon(pcdescr, FALSE);
#endif
    pcap_setdirection(pcdescr, PCAP_D_IN);
    // Weird bug - returns -3 and doesn't show an error message...
    // And pcap_getnonblock also returns -3... Neither should happen AFAIK...
    errbuf[0] = '\0';
    if ((rc = pcap_setnonblock(pcdescr, !blocking, errbuf)) < 0 && errbuf[0] != '\0') {
        g_warning("pcap_setnonblock(%d) failed: [%s] [rc=%d]", !blocking, errbuf, rc);
        g_warning("Have no idea why this happens - current blocking state is: %d."
                  ,	pcap_getnonblock(pcdescr, errbuf));
    }
    pcap_set_snaplen(pcdescr, 1500);
    /// @todo deal with pcap_set_timeout() call here.
    if (blocking) {
        pcap_set_timeout(pcdescr, 240*1000);
    } else {
        pcap_set_timeout(pcdescr, 1);
    }
    //pcap_set_buffer_size(pcdescr, 1500);

    if (pcap_activate(pcdescr) != 0) {
        g_warning("pcap_activate failed: [%s]", pcap_geterr(pcdescr));
        goto oopsie;
    }
    if (pcap_compile(pcdescr, prog, expr, FALSE, maskp) < 0) {
        g_warning("pcap_compile of [%s] failed: [%s]", expr, pcap_geterr(pcdescr));
        goto oopsie;
    }
    if (pcap_setfilter(pcdescr, prog) < 0) {
        g_warning("pcap_setfilter on [%s] failed: [%s]", expr, pcap_geterr(pcdescr));
        goto oopsie;
    }
    DEBUGMSG1("Compile of [%s] worked!", expr);
    free(expr);
    expr = NULL;
    return(pcdescr);

oopsie:	// Some kind of failure - free things up and return NULL

    g_warning("%s.%d: Could not set up PCAP on %s"
              ,	__FUNCTION__, __LINE__, dev);
    if (expr) {
        free(expr);
        expr = NULL;
    }
    if (pcdescr) {
        close_pcap_listener(pcdescr, dev, listenmask);
        pcdescr = NULL;
    }
    return NULL;
}
Esempio n. 23
0
static void probe_host(const char *host)
{
	struct sockaddr_in sin;
	char pcap_errbuf[PCAP_ERRBUF_SIZE];
	struct pcap_pkthdr pkthdr;
	const uint8_t *data;
	struct bpf_program fp;
	pcap_t *ph;
	int fd;

	ph = pcap_create(iface, pcap_errbuf);
	if (ph == NULL) {
		perror("pcap_create");
		goto err1;
	}

	if (pcap_setnonblock(ph, 1, pcap_errbuf) == -1) {
		perror("pcap_setnonblock");
		goto err2;
	}

	if (pcap_setfilter(ph, &fp) == -1) {
		pcap_perror(ph, "pcap_setfilter");
		goto err2;
	}

	if (pcap_activate(ph) != 0) {
		pcap_perror(ph, "pcap_activate");
		goto err2;
	}

	if (pcap_compile(ph, &fp, "src host 127.0.0.1 and tcp and src port 80",
			 1, PCAP_NETMASK_UNKNOWN) == -1) {
		pcap_perror(ph, "pcap_compile");
		goto err2;
	}

	fd = socket(AF_INET, SOCK_STREAM, 0);
	if (fd < 0) {
		perror("socket");
		goto err3;
	}

	memset(&sin, 0, sizeof(sin));
	sin.sin_family		= AF_INET;
	sin.sin_port		= htons(port);
	sin.sin_addr.s_addr	= inet_addr(host);

	if (connect(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		perror("connect");
		goto err4;
	}

	for (;;) {
		data = pcap_next(ph, &pkthdr);
		if (data == NULL)
			break;
		if (parse_packet(host, data))
			break;
	}

	close(fd);

err4:
	close(fd);
err3:
	pcap_freecode(&fp);
err2:
	pcap_close(ph);
err1:
	return;
}
Esempio n. 24
0
int beginCapture() {
  char* dev, errbuf[PCAP_ERRBUF_SIZE];
  pcap_if_t *alldevsp, *devsp;
  //TODO(willscott): Remove IPv4 Limitation
  bpf_u_int32 mask;
  bpf_u_int32 net;

  struct bpf_program fp;
  char filter_exp[] = "icmp[0:1] == 0x0b or (dst port 8080 and dst host %s)";
  char filterbuf[256];

  // Find Device. Gets the first valid device.
  if (pcap_findalldevs(&alldevsp, errbuf)) {
    printf("Couldn't find Devices: %s \n", errbuf);
    exit(1);
  }
  devsp = alldevsp;
  dev = NULL;
  while (devsp != NULL) {
    // flags = !loopback
    char* addr = NULL;
    if (devsp->addresses != NULL && (devsp->flags & 1) != 1) {
      struct pcap_addr* addrs = devsp->addresses;
      while (addrs != NULL) {
        if (addrs->addr->sa_family == AF_INET) {
          addr = inet_ntoa(((struct sockaddr_in*)addrs->addr)->sin_addr);
          break;
        }
        addrs = addrs->next;
      }
      if (addr != NULL) {
        sprintf(filterbuf, filter_exp,addr);
        printf("%s\n", filterbuf);
        dev = devsp->name;
        break;
      }
    } else {
      devsp = devsp->next;
    }
  }
  if (dev == NULL) {
    printf("No valid device found!\n");
    exit(1);
  }
  printf("Using Dev %s\n", dev);

  // Initialize Log.
  logfile = fopen("log.txt", "a");
  if (logfile == NULL) {
    printf("Couldn't open log file.\n");
    exit(1);
  }

  // Get Local IP.
  if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
    printf("Couldn't get netmask for device %s: %s\n", dev, errbuf);
    exit(1);
  }

  // Open Device.
  handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
  if (handle == NULL) {
    printf("Couldn't open device %s: %s\n", dev, errbuf);
    exit(1);
  }

  // free list
  pcap_freealldevs(alldevsp);

  // Set the filter.
  if (pcap_compile(handle, &fp, filterbuf, 0, net) == -1) {
    printf("Invalid Filter: %s\n", filter_exp);
    exit(1);
  }
  if (pcap_setfilter(handle, &fp) == -1) {
    printf("Filter couldn't be installed: %s\n", pcap_geterr(handle));
    exit(1);
  }

  if (pcap_setnonblock(handle, 1, errbuf) == -1) {
    printf("Nonblocking mode failed: %s\n", errbuf);
    exit(1);
  }

  // Initialize Sending.
  initSender();

  return pcap_get_selectable_fd(handle);
};
Esempio n. 25
0
int
main(int argc, char **argv)
{
	register int op;
	register char *cp, *cmdbuf, *device;
	long longarg;
	char *p;
	int timeout = 1000;
	int immediate = 0;
	int nonblock = 0;
	bpf_u_int32 localnet, netmask;
	struct bpf_program fcode;
	char ebuf[PCAP_ERRBUF_SIZE];
	int status;
	int packet_count;

	device = NULL;
	if ((cp = strrchr(argv[0], '/')) != NULL)
		program_name = cp + 1;
	else
		program_name = argv[0];

	opterr = 0;
	while ((op = getopt(argc, argv, "i:mnt:")) != -1) {
		switch (op) {

		case 'i':
			device = optarg;
			break;

		case 'm':
			immediate = 1;
			break;

		case 'n':
			nonblock = 1;
			break;

		case 't':
			longarg = strtol(optarg, &p, 10);
			if (p == optarg || *p != '\0') {
				error("Timeout value \"%s\" is not a number",
				    optarg);
				/* NOTREACHED */
			}
			if (longarg < 0) {
				error("Timeout value %ld is negative", longarg);
				/* NOTREACHED */
			}
			if (longarg > INT_MAX) {
				error("Timeout value %ld is too large (> %d)",
				    longarg, INT_MAX);
				/* NOTREACHED */
			}
			timeout = (int)longarg;
			break;

		default:
			usage();
			/* NOTREACHED */
		}
	}

	if (device == NULL) {
		device = pcap_lookupdev(ebuf);
		if (device == NULL)
			error("%s", ebuf);
	}
	*ebuf = '\0';
	pd = pcap_create(device, ebuf);
	if (pd == NULL)
		error("%s", ebuf);
	status = pcap_set_snaplen(pd, 65535);
	if (status != 0)
		error("%s: pcap_set_snaplen failed: %s",
			    device, pcap_statustostr(status));
	if (immediate) {
		status = pcap_set_immediate_mode(pd, 1);
		if (status != 0)
			error("%s: pcap_set_immediate_mode failed: %s",
			    device, pcap_statustostr(status));
	}
	status = pcap_set_timeout(pd, timeout);
	if (status != 0)
		error("%s: pcap_set_timeout failed: %s",
		    device, pcap_statustostr(status));
	status = pcap_activate(pd);
	if (status < 0) {
		/*
		 * pcap_activate() failed.
		 */
		error("%s: %s\n(%s)", device,
		    pcap_statustostr(status), pcap_geterr(pd));
	} else if (status > 0) {
		/*
		 * pcap_activate() succeeded, but it's warning us
		 * of a problem it had.
		 */
		warning("%s: %s\n(%s)", device,
		    pcap_statustostr(status), pcap_geterr(pd));
	}
	if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
		localnet = 0;
		netmask = 0;
		warning("%s", ebuf);
	}
	cmdbuf = copy_argv(&argv[optind]);

	if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
		error("%s", pcap_geterr(pd));

	if (pcap_setfilter(pd, &fcode) < 0)
		error("%s", pcap_geterr(pd));
	if (pcap_setnonblock(pd, nonblock, ebuf) == -1)
		error("pcap_setnonblock failed: %s", ebuf);
	printf("Listening on %s\n", device);
	for (;;) {
		packet_count = 0;
		status = pcap_dispatch(pd, -1, countme,
		    (u_char *)&packet_count);
		if (status < 0)
			break;
		if (status != 0) {
			printf("%d packets seen, %d packets counted after pcap_dispatch returns\n",
			    status, packet_count);
		}
	}
	if (status == -2) {
		/*
		 * We got interrupted, so perhaps we didn't
		 * manage to finish a line we were printing.
		 * Print an extra newline, just in case.
		 */
		putchar('\n');
	}
	(void)fflush(stdout);
	if (status == -1) {
		/*
		 * Error.  Report it.
		 */
		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
		    program_name, pcap_geterr(pd));
	}
	pcap_close(pd);
	exit(status == -1 ? 1 : 0);
}
Esempio n. 26
0
int main(int argc, char** argv) {
	char errbuf[PCAP_ERRBUF_SIZE];
	char* interface = NULL;
	char* outfile = NULL;
	unsigned snaplen = 65536;
	char* start_filter_str = NULL;
	char* stop_filter_str = NULL;
	char* capture_filter_str = NULL;
	int promisc = 0;
	int quiet = 0;
	struct bpf_program start_filter;
	struct bpf_program capture_filter;
	pcap_t* capturer = NULL;
	pcap_dumper_t* dumper = NULL;
	int opt;

	while ((opt = getopt(argc, argv, "i:w:s:b:e:f:phdq")) != -1) {
		switch (opt) {
			case 'i':
				if (interface) panic(1,"interface already given");
				interface = g_strdup(optarg);
				break;
			case 'w':
				if (outfile) panic(3,"output file already given");
				outfile = g_strdup(optarg);
				break;
			case 's':
				snaplen = strtoul(optarg,NULL,10);
				if ( snaplen == 0 )
					panic(4,"invalid snaplen");
				break;
			case 'b':
				if (start_filter_str) panic(5,"start filter already given");
				start_filter_str = g_strdup(optarg);
				break;
			case 'e':
				if (stop_filter_str) panic(6,"stop filter already given");
				stop_filter_str = g_strdup(optarg);
				break;
			case 'f':
				if (capture_filter_str) panic(7,"capture filter already given");
				capture_filter_str = g_strdup(optarg);
				break;
			case 'p':
				promisc = 1;
				break;
			case 'q':
				quiet = 1;
				break;
			case 'd':
				debug_level++;
				break;
			case 'h':
			default:
				usage(0);
				break;
			}
		}

	dprintf(1,"starting with:\n interface: %s\n snaplen: %d\n promisc: %d"
			"\n outfile: %s\n capture filter: %s\n start: %s\n stop: %s\n debug level: %d\n",
			interface ? interface : "to be chosen",
			snaplen,
			promisc,
			outfile ? outfile : "** missing **",
			capture_filter_str ? capture_filter_str : "** none given **",
			start_filter_str ? start_filter_str : "** missing **",
			stop_filter_str ? stop_filter_str : "** missing **",
			debug_level);

	if (! ( start_filter_str && stop_filter_str && outfile ) ) {
		usage(10);
	}

	if (! interface) {
		interface = pcap_lookupdev(errbuf);
		if (!interface) {
			panic(11, "could not obtain an interface: %s\n",errbuf);
		}
	}

#ifdef HAVE_PCAP_OPEN
	if ( ! ( capturer = pcap_open(interface, snaplen, promisc, 1, NULL, errbuf) )) {
#else
	if ( ! ( capturer = pcap_open_live(interface, snaplen, promisc, 1, errbuf) )) {
#endif
		panic(12,"could not open interface '%s' for listener: %s\n",interface,errbuf);
	}

	dprintf(1,"opened listener (%s,%d,%d)\n",interface,snaplen, promisc);

	if (pcap_compile(listener, &start_filter, start_filter_str, 1, 0) < 0) {
		panic(13,"could not compile start filter: %s\n",pcap_geterr(listener));
	}

	dprintf(2,"compiled start filter %s\n",start_filter_str);

	if (pcap_compile(listener, &stop_filter, stop_filter_str, 1, 0) < 0) {
		panic(14,"could not compile stop filter: %s\n",pcap_geterr(listener));
	}

	dprintf(2,"compiled stop filter %s\n",stop_filter_str);

#ifdef HAVE_PCAP_OPEN
	if ( ! ( capturer = pcap_open(interface, snaplen, promisc, 1, NULL, errbuf) )) {
#else
	if ( ! ( capturer = pcap_open_live(interface, snaplen, promisc, 1, errbuf) )) {
#endif
		panic(15,"could not open interface '%s' for capturer: %s\n",interface, errbuf);
	}

	dprintf(1,"opened capturer (%s,%d,%d)\n",interface,snaplen, promisc);

	if (capture_filter_str) {
		if (pcap_compile(capturer, &capture_filter, capture_filter_str, 1, 0) < 0) {
			panic(16,"could not compile capture filter: %s\n",pcap_geterr(capturer));
		}
		if (pcap_setfilter(capturer, &capture_filter) < 0) {
			panic(17,"could not apply start filter to capturer: %s\n",pcap_geterr(capturer));
		}

		dprintf(2,"compiled and set capture filter (%s)\n",capture_filter_str);
	}

	if (pcap_setfilter(listener, &start_filter) < 0) {
		panic(18,"could not apply start filter to listener: %s\n",pcap_geterr(listener));
	}
	dprintf(2,"set start filter on listener\n");


	if (pcap_setnonblock(listener, 0, errbuf) < 0) {
		panic(19,"could not set listener in blocking mode: %s\n",errbuf);
	}
	dprintf(2,"listener -> blocking\n");

	if (pcap_setnonblock(capturer, 1, errbuf) < 0) {
		panic(20,"could not set capturer in non blocking mode: %s\n",errbuf);
	}
	dprintf(2,"capturer -> non_blocking\n");

	if (! (dumper = pcap_dump_open(listener,outfile)) ) {
		panic(21,"open dumper file '%s': %s\n",outfile,pcap_geterr(listener));
	}
	dprintf(2,"opened dumper file '%s'\n",outfile);

	signal(SIGINT, sig_int);
#ifdef SIGQUIT
	signal(SIGQUIT, sig_int);
#endif
#ifdef SIGTERM
	signal(SIGTERM, sig_int);
#endif
#ifdef SIGSTOP
	signal(SIGSTOP, sig_int);
#endif

	keep_going = 1;
	dumping = 0;

	do {
		if (pcap_dispatch(listener, -1, listener_handler, NULL) < 0 ) {
			panic(22,"pcap_dispatch(listener) failed: %s\n",pcap_geterr(listener));
		}

		if (pcap_dispatch(capturer, -1, capture_handler, (void*)dumper) < 0 ) {
			panic(23,"pcap_dispatch(capturer) failed: %s\n",pcap_geterr(capturer));
		}
	} while(keep_going);

	if (!quiet) {
		printf("%d packets captured\n",captured);
	}

	dprintf(1,"done!\n");

	pcap_dump_close(dumper);
	pcap_close(listener);
	pcap_close(capturer);

	return 0;
}
Esempio n. 27
0
/* The pcap capture routine.
*/
int
pcap_capture(fko_srv_options_t *opts)
{
    pcap_t              *pcap;
    char                errstr[PCAP_ERRBUF_SIZE] = {0};
    struct bpf_program  fp;
    int                 res;
    int                 pcap_errcnt = 0;
    int                 pending_break = 0;
    int                 promisc = 0;
    int                 set_direction = 1;
    int                 pcap_file_mode = 0;
    int                 status;
    int                 useconds;
    int                 pcap_dispatch_count;
    int                 max_sniff_bytes;
    int                 is_err;
    pid_t               child_pid;

#if FIREWALL_IPFW
    time_t              now;
#endif

    useconds = strtol_wrapper(opts->config[CONF_PCAP_LOOP_SLEEP],
            0, RCHK_MAX_PCAP_LOOP_SLEEP, NO_EXIT_UPON_ERR, &is_err);
    if(is_err != FKO_SUCCESS)
    {
        log_msg(LOG_ERR, "[*] invalid PCAP_LOOP_SLEEP_value");
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    max_sniff_bytes = strtol_wrapper(opts->config[CONF_MAX_SNIFF_BYTES],
            0, RCHK_MAX_SNIFF_BYTES, NO_EXIT_UPON_ERR, &is_err);
    if(is_err != FKO_SUCCESS)
    {
        log_msg(LOG_ERR, "[*] invalid MAX_SNIFF_BYTES");
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    /* Set promiscuous mode if ENABLE_PCAP_PROMISC is set to 'Y'.
    */
    if(strncasecmp(opts->config[CONF_ENABLE_PCAP_PROMISC], "Y", 1) == 0)
        promisc = 1;

    if(opts->config[CONF_PCAP_FILE] != NULL
            && opts->config[CONF_PCAP_FILE][0] != '\0')
        pcap_file_mode = 1;

    if(pcap_file_mode == 1) {
        log_msg(LOG_INFO, "Reading pcap file: %s",
            opts->config[CONF_PCAP_FILE]);

        pcap = pcap_open_offline(opts->config[CONF_PCAP_FILE], errstr);

        if(pcap == NULL)
        {
            log_msg(LOG_ERR, "[*] pcap_open_offline() error: %s",
                    errstr);
            clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
        }
    }
    else
    {
        log_msg(LOG_INFO, "Sniffing interface: %s",
            opts->config[CONF_PCAP_INTF]);

        pcap = pcap_open_live(opts->config[CONF_PCAP_INTF],
            max_sniff_bytes, promisc, 100, errstr
        );

        if(pcap == NULL)
        {
            log_msg(LOG_ERR, "[*] pcap_open_live() error: %s", errstr);
            clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
        }
    }

    /* Set pcap filters, if any.
    */
    if (opts->config[CONF_PCAP_FILTER][0] != '\0')
    {
        if(pcap_compile(pcap, &fp, opts->config[CONF_PCAP_FILTER], 1, 0) == -1)
        {
            log_msg(LOG_ERR, "[*] Error compiling pcap filter: %s",
                pcap_geterr(pcap)
            );
            clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
        }

        if(pcap_setfilter(pcap, &fp) == -1)
        {
            log_msg(LOG_ERR, "[*] Error setting pcap filter: %s",
                pcap_geterr(pcap)
            );
            clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
        }

        log_msg(LOG_INFO, "PCAP filter is: '%s'", opts->config[CONF_PCAP_FILTER]);

        pcap_freecode(&fp);
    }

    /* Determine and set the data link encapsulation offset.
    */
    switch(pcap_datalink(pcap)) {
        case DLT_EN10MB:
            opts->data_link_offset = 14;
            break;
#if defined(__linux__)
        case DLT_LINUX_SLL:
            opts->data_link_offset = 16;
            break;
#elif defined(__OpenBSD__)
        case DLT_LOOP:
            set_direction = 0;
            opts->data_link_offset = 4;
            break;
#endif
        case DLT_NULL:
            set_direction = 0;
            opts->data_link_offset = 4;
            break;
        default:
            opts->data_link_offset = 0;
            break;
    }

    /* We are only interested on seeing packets coming into the interface.
    */
    if ((opts->pcap_any_direction == 0)
            && (set_direction == 1) && (pcap_file_mode == 0)
            && (pcap_setdirection(pcap, PCAP_D_IN) < 0))
        if(opts->verbose)
            log_msg(LOG_WARNING, "[*] Warning: pcap error on setdirection: %s.",
                pcap_geterr(pcap));

    /* Set our pcap handle nonblocking mode.
     *
     * NOTE: This is simply set to 0 for now until we find a need
     *       to actually use this mode (which when set on a FreeBSD
     *       system, it silently breaks the packet capture).
    */
    if((pcap_file_mode == 0)
            && (pcap_setnonblock(pcap, DEF_PCAP_NONBLOCK, errstr)) == -1)
    {
        log_msg(LOG_ERR, "[*] Error setting pcap nonblocking to %i: %s",
            0, errstr
        );
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    pcap_dispatch_count = strtol_wrapper(opts->config[CONF_PCAP_DISPATCH_COUNT],
            0, RCHK_MAX_PCAP_DISPATCH_COUNT, NO_EXIT_UPON_ERR, &is_err);
    if(is_err != FKO_SUCCESS)
    {
        log_msg(LOG_ERR, "[*] invalid PCAP_DISPATCH_COUNT");
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    /* Initialize our signal handlers. You can check the return value for
     * the number of signals that were *not* set.  Those that were not set
     * will be listed in the log/stderr output.
    */
    if(set_sig_handlers() > 0)
        log_msg(LOG_ERR, "Errors encountered when setting signal handlers.");

    log_msg(LOG_INFO, "Starting fwknopd main event loop.");

    /* Jump into our home-grown packet cature loop.
    */
    while(1)
    {
        /* If we got a SIGCHLD and it was the tcp server, then handle it here.
        */
        if(got_sigchld)
        {
            if(opts->tcp_server_pid > 0)
            {
                child_pid = waitpid(0, &status, WNOHANG);

                if(child_pid == opts->tcp_server_pid)
                {
                    if(WIFSIGNALED(status))
                        log_msg(LOG_WARNING, "TCP server got signal: %i",  WTERMSIG(status));

                    log_msg(LOG_WARNING,
                        "TCP server exited with status of %i. Attempting restart.",
                        WEXITSTATUS(status)
                    );

                    opts->tcp_server_pid = 0;

                    /* Attempt to restart tcp server ? */
                    usleep(1000000);
                    run_tcp_server(opts);
                }
            }

            got_sigchld = 0;
        }

        /* Any signal except USR1, USR2, and SIGCHLD mean break the loop.
        */
        if(got_signal != 0)
        {
            if(got_sigint || got_sigterm || got_sighup)
            {
                pcap_breakloop(pcap);
                pending_break = 1;
            }
            else if(got_sigusr1 || got_sigusr2)
            {
                /* Not doing anything with these yet.
                */
                got_sigusr1 = got_sigusr2 = 0;
                got_signal = 0;
            }
            else
                got_signal = 0;
        }

        res = pcap_dispatch(pcap, pcap_dispatch_count,
            (pcap_handler)&process_packet, (unsigned char *)opts);

        /* Count processed packets
        */
        if(res > 0)
        {
            if(opts->foreground == 1 && opts->verbose > 2)
                log_msg(LOG_DEBUG, "pcap_dispatch() processed: %d packets", res);

            /* Count the set of processed packets (pcap_dispatch() return
             * value) - we use this as a comparison for --packet-limit regardless
             * of SPA packet validity at this point.
            */
            opts->packet_ctr += res;
            if (opts->packet_ctr_limit && opts->packet_ctr >= opts->packet_ctr_limit)
            {
                log_msg(LOG_WARNING,
                    "* Incoming packet count limit of %i reached",
                    opts->packet_ctr_limit
                );

                pcap_breakloop(pcap);
                pending_break = 1;
            }
        }
        /* If there was an error, complain and go on (to an extent before
         * giving up).
        */
        else if(res == -1)
        {
            log_msg(LOG_ERR, "[*] Error from pcap_dispatch: %s",
                pcap_geterr(pcap)
            );

            if(pcap_errcnt++ > MAX_PCAP_ERRORS_BEFORE_BAIL)
            {
                log_msg(LOG_ERR, "[*] %i consecutive pcap errors.  Giving up",
                    pcap_errcnt
                );
                clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
            }
        }
        else if(pending_break == 1 || res == -2)
        {
            /* pcap_breakloop was called, so we bail. */
            log_msg(LOG_INFO, "Gracefully leaving the fwknopd event loop.");
            break;
        }
        else
            pcap_errcnt = 0;

        /* Check for any expired firewall rules and deal with them.
        */
        check_firewall_rules(opts);

#if FIREWALL_IPFW
        /* Purge expired rules that no longer have any corresponding
         * dynamic rules.
        */
        if(opts->fw_config->total_rules > 0)
        {
            time(&now);
            if(opts->fw_config->last_purge < (now - opts->fw_config->purge_interval))
            {
                ipfw_purge_expired_rules(opts);
                opts->fw_config->last_purge = now;
            }
        }
#endif

        usleep(useconds);
    }

    pcap_close(pcap);

    return(0);
}
Esempio n. 28
0
/* Constructor */
Pcap::Pcap(char *dev, int snaplen, char *src_ip, char *dst_ip, int src_port, int dst_port, char *output_file, void (*p)(Packet* pkt))
{
   char errbuf[100];
   char d[] = "any";
   int datalinktype;

   //init variables
   hd = NULL;
   pd = NULL;
   dataLinkOffset = 0;
   isOpen = false;
   process_thread = 0;
   last_pcap_time = 0;
   process_packet = NULL;

   if (dev == NULL) 
   {
      dev = d;	//assume using "any" iface if dev = NULL
   }
   
   hd = pcap_open_live(dev, snaplen, 1, 10, errbuf);
   
   if (hd == NULL) 
   {
      logger->PrintErr("[%s:%d] Pcap cannot listen on device\n", __FILE__, __LINE__);
   } 
   else 
   {
      isOpen = true;
   }

   if ((datalinktype = pcap_datalink(hd)) < 0) 
   {
      destroy();
      logger->PrintErr("[%s:%d] Pcap unable to determine datalink type\n", __FILE__, __LINE__);
   }

   switch(datalinktype) 
   {
      case DLT_EN10MB: 
	 dataLinkOffset = DLT_EN10MB_LEN; 
	 break;
      case DLT_IEEE802: 
	 dataLinkOffset = DLT_IEEE802_LEN; 
	 break;
      case DLT_NULL: 
	 dataLinkOffset = DLT_NULL_LEN; 
	 break;
      case DLT_SLIP: 
	 dataLinkOffset = DLT_SLIP_LEN; 
	 break;
      case DLT_PPP: 
	 dataLinkOffset = DLT_PPP_LEN; 
	 break;
      case DLT_RAW: 
	 dataLinkOffset = DLT_RAW_LEN; 
	 break;
      case DLT_LINUX_SLL: 
	 dataLinkOffset = DLT_LINUX_SLL_LEN; 
	 break;	//this is used to support "any" device type in linux
      default:
	 destroy();
	 logger->PrintErr("[%s:%d] Pcap unknown datalink type\n", __FILE__, __LINE__);
   }

   if (pcap_setnonblock(hd, 0, errbuf) < 0) 
   {	//set the pcap to non-blocking mode
      destroy();
      logger->PrintErr("[%s:%d] Pcap unable to set pcap_setnonblock\n", __FILE__, __LINE__);
   }

   add_filter(src_ip, src_port, dst_ip, dst_port);
   if(output_file)
   {
      add_dump(output_file);
   }
   if(p != NULL) 
   {
      process_packet = p;
   }
}
Esempio n. 29
0
int dp_setnonblock (struct dp_handle * handle, int i, char * errbuf) {
	return pcap_setnonblock (handle->pcap_handle, i, errbuf);
}
Esempio n. 30
0
/* Start capturing on just one interface. Called from cap_start(). */
static void cap_start_one(struct cap_iface *iface, const int promisc) {
   char errbuf[PCAP_ERRBUF_SIZE], *tmp_device;
   int linktype, snaplen, waited;

   /* pcap wants a non-const interface name string */
   tmp_device = xstrdup(iface->name);
   if (iface->filter)
      verbosef("capturing on interface '%s' with filter '%s'",
         tmp_device, iface->filter);
   else
      verbosef("capturing on interface '%s' with no filter", tmp_device);

   /* Open packet capture descriptor. */
   waited = 0;
   for (;;) {
      errbuf[0] = '\0'; /* zero length string */
      iface->pcap = pcap_open_live(
         tmp_device,
         1,          /* snaplen, irrelevant at this point */
         0,          /* promisc, also irrelevant */
         CAP_TIMEOUT_MSEC,
         errbuf);
      if (iface->pcap != NULL)
         break; /* success! */

      if ((opt_wait_secs != -1) && strstr(errbuf, "device is not up")) {
         if ((opt_wait_secs > 0) && (waited >= opt_wait_secs))
            errx(1, "waited %d secs, giving up: pcap_open_live(): %s",
               waited, errbuf);

         verbosef("waited %d secs, interface is not up", waited);
         sleep(1);
         waited++;
      }
      else errx(1, "pcap_open_live(): %s", errbuf);
   }

   /* Work out the linktype and what snaplen we need. */
   linktype = pcap_datalink(iface->pcap);
   verbosef("linktype is %d", linktype);
   if ((linktype == DLT_EN10MB) && opt_want_macs)
      hosts_db_show_macs = 1;
   iface->linkhdr = getlinkhdr(linktype);
   if (iface->linkhdr == NULL)
      errx(1, "unknown linktype %d", linktype);
   if (iface->linkhdr->decoder == NULL)
      errx(1, "no decoder for linktype %d", linktype);
   snaplen = getsnaplen(iface->linkhdr);
   if (opt_want_pppoe) {
      snaplen += PPPOE_HDR_LEN;
      if (linktype != DLT_EN10MB)
         errx(1, "can't do PPPoE decoding on a non-Ethernet linktype");
   }
   verbosef("calculated snaplen minimum %d", snaplen);
#ifdef linux
   /* FIXME: actually due to libpcap moving to mmap (!!!)
    * work out which version and fix the way we do capture
    * on linux:
    */

   /* Ubuntu 9.04 has a problem where requesting snaplen <= 60 will
    * give us 42 bytes, and we need at least 54 for TCP headers.
    *
    * Hack to set minimum snaplen to tcpdump's default:
    */
   snaplen = MAX(snaplen, 96);
#endif
   if (opt_want_snaplen > -1)
      snaplen = opt_want_snaplen;
   verbosef("using snaplen %d", snaplen);

   /* Close and re-open pcap to use the new snaplen. */
   pcap_close(iface->pcap);
   errbuf[0] = '\0'; /* zero length string */
   iface->pcap = pcap_open_live(
      tmp_device,
      snaplen,
      promisc,
      CAP_TIMEOUT_MSEC,
      errbuf);

   if (iface->pcap == NULL)
      errx(1, "pcap_open_live(): %s", errbuf);

   if (errbuf[0] != '\0') /* not zero length anymore -> warning */
      warnx("pcap_open_live() warning: %s", errbuf);

   free(tmp_device);

   if (promisc)
      verbosef("capturing in promiscuous mode");
   else
      verbosef("capturing in non-promiscuous mode");

   cap_set_filter(iface->pcap, iface->filter);
   iface->fd = pcap_fileno(iface->pcap);

   /* set non-blocking */
#ifdef linux
   if (pcap_setnonblock(iface->pcap, 1, errbuf) == -1)
      errx(1, "pcap_setnonblock(): %s", errbuf);
#else
   {
      int one = 1;
      if (ioctl(iface->fd, FIONBIO, &one) == -1)
         err(1, "ioctl(iface->fd, FIONBIO)");
   }
#endif

#ifdef BIOCSETWF
   {
      /* Deny all writes to the socket */
      struct bpf_insn bpf_wfilter[] = { BPF_STMT(BPF_RET+BPF_K, 0) };
      int wf_len = sizeof(bpf_wfilter) / sizeof(struct bpf_insn);
      struct bpf_program pr;

      pr.bf_len = wf_len;
      pr.bf_insns = bpf_wfilter;

      if (ioctl(iface->fd, BIOCSETWF, &pr) == -1)
         err(1, "ioctl(iface->fd, BIOCSETFW)");
      verbosef("filtered out BPF writes");
   }
#endif

#ifdef BIOCLOCK
   /* set "locked" flag (no reset) */
   if (ioctl(iface->fd, BIOCLOCK) == -1)
      err(1, "ioctl(iface->fd, BIOCLOCK)");
   verbosef("locked down BPF for security");
#endif
}