コード例 #1
0
DWORD sniffer_thread(THREAD *thread)
{
	int fd;
	fd_set rfds;
	struct timeval tv;
	int count;

	CaptureJob *j = (CaptureJob *)(thread->parameter1);
	fd = pcap_get_selectable_fd(j->pcap);

	dprintf("pcap @ %p, selectable fd is %d", j->pcap, fd);

	while(event_poll(thread->sigterm, 0) == FALSE && j->active) {
		tv.tv_sec = 0;
		tv.tv_usec = 5000;

		FD_ZERO(&rfds);
		FD_SET(pcap_get_selectable_fd(j->pcap), &rfds);

		select(fd+1, &rfds, NULL, NULL, &tv);

		count = pcap_dispatch(j->pcap, 100, packet_handler, (u_char *)(j));
		if (-1 == count)
			dprintf("pcap error: %s", pcap_geterr(j->pcap));

		if(count <= 0) continue;
		if(count) dprintf("dispatched %d packets", count);
	}

	dprintf("and we're done");
	return 0;
}
コード例 #2
0
ファイル: tc_socket.c プロジェクト: 343829084/tcpcopy
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;
}
コード例 #3
0
ファイル: tc_socket.c プロジェクト: changguanghua/tcpcopy
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;
}
コード例 #4
0
ファイル: sniffer.cpp プロジェクト: gtdsj/libtins
int BaseSniffer::get_fd() {
    #ifndef _WIN32
        return pcap_get_selectable_fd(handle);
    #else
        throw std::runtime_error("Method not supported in Windows platform");
    #endif // _WIN32
}
コード例 #5
0
ファイル: sniffer.cpp プロジェクト: Pflanzgurke/libtins
int BaseSniffer::get_fd() {
    #ifndef _WIN32
        return pcap_get_selectable_fd(handle_);
    #else
        throw unsupported_function();
    #endif // _WIN32
}
コード例 #6
0
ファイル: l2_packet.c プロジェクト: kusumi/DragonFlyBSD
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;

	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_datalink(DLT_EN10MB): %s\n",
			pcap_geterr(l2->pcap));
		return -1;
	}
	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);
#ifndef __sun__
	/*
	 * 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 /* __sun__ */

	eloop_register_read_sock(pcap_get_selectable_fd(l2->pcap),
				 l2_packet_receive, l2, l2->pcap);

	return 0;
}
コード例 #7
0
ファイル: socket_pcap.c プロジェクト: mslehto/captagent
int set_raw_filter(unsigned int loc_idx, char *filter) {

        struct bpf_program raw_filter;
        //uint16_t snaplen = 65535;
        int linktype;
        //struct pcap_t *aa;
        int fd = -1;
                
        LERR("APPLY FILTER [%d]\n", loc_idx);        
        if(loc_idx >= MAX_SOCKETS || sniffer_proto[loc_idx] == NULL) return 0;         

        fd = pcap_get_selectable_fd(sniffer_proto[loc_idx]);

        linktype  = profile_socket[loc_idx].link_type ? profile_socket[loc_idx].link_type : DLT_EN10MB;

        if (pcap_compile_nopcap(profile_socket[loc_idx].snap_len ? profile_socket[loc_idx].snap_len : 0xffff, linktype, &raw_filter, filter, 1, 0) == -1) {
                LERR("Failed to compile filter '%s'", filter);
                return -1;
        }

#if ( defined (OS_LINUX) || defined (OS_SOLARIS) )
        if(setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &raw_filter, sizeof(raw_filter)) < 0 ) {
                LERR(" setsockopt filter: [%s] [%d]", strerror(errno), errno);
                return -1;
        }
#endif

        //free(BPF_code);
        pcap_freecode( (struct bpf_program *) &raw_filter);

        return 1;

}
コード例 #8
0
ファイル: drv_tuntap.c プロジェクト: 0x0d/lorcon
/* Monitor, inject, and injmon are all the same method, open a new vap */
int tuntap_openmon_cb(lorcon_t *context) {
	char *parent;
	char pcaperr[PCAP_ERRBUF_SIZE];
	struct mac80211_lorcon *extras = (struct mac80211_lorcon *) context->auxptr;
	short flags;
	struct ifreq if_req;
	struct sockaddr_ll sa_ll;

	if (ifconfig_delta_flags(context->ifname, context->errstr,
							 (IFF_UP | IFF_RUNNING | IFF_PROMISC)) < 0) {
		return -1;
	}

	pcaperr[0] = '\0';

	if ((context->pcap = pcap_open_live(context->ifname, LORCON_MAX_PACKET_LEN, 
										1, 1000, pcaperr)) == NULL) {
		snprintf(context->errstr, LORCON_STATUS_MAX, "%s", pcaperr);
		return -1;
	}

	context->capture_fd = pcap_get_selectable_fd(context->pcap);

	context->dlt = pcap_datalink(context->pcap);

	context->inject_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

	if (context->inject_fd < 0) {
		snprintf(context->errstr, LORCON_STATUS_MAX, "failed to create injection "
				 "socket: %s", strerror(errno));
		pcap_close(context->pcap);
		return -1;
	}

	memset(&if_req, 0, sizeof(if_req));
	memcpy(if_req.ifr_name, context->ifname, IFNAMSIZ);
	if_req.ifr_name[IFNAMSIZ - 1] = 0;
	if (ioctl(context->inject_fd, SIOCGIFINDEX, &if_req) < 0) {
		snprintf(context->errstr, LORCON_STATUS_MAX, "failed to get interface idex: %s",
				 strerror(errno));
		close(context->inject_fd);
		pcap_close(context->pcap);
		return -1;
	}

	memset(&sa_ll, 0, sizeof(sa_ll));
	sa_ll.sll_family = AF_PACKET;
	sa_ll.sll_protocol = htons(ETH_P_80211_RAW);
	sa_ll.sll_ifindex = if_req.ifr_ifindex;
	if (bind(context->inject_fd, (struct sockaddr *) &sa_ll, sizeof(sa_ll)) != 0) {
		snprintf(context->errstr, LORCON_STATUS_MAX, "failed to bind injection "
				 "socket: %s", strerror(errno));
		close(context->inject_fd);
		pcap_close(context->pcap);
		return -1;
	}

	return 1;
}
コード例 #9
0
ファイル: ports.c プロジェクト: fp7-alien/xDPd-Virtualization
static rofl_result_t netfpga_init_port(switch_port_t* port){




	struct ifreq interface;
	netfpga_port_t* nport = (netfpga_port_t*)malloc(sizeof(*nport));

	
	char *useless;

	
	
		//fprintf(stderr, "device=  %s  \n",dev);
	useless = pcap_lookupdev(port->name); //test if device exist// gives char pointer, why not pcap_if_t?
	if (useless == NULL) {
		ROFL_ERR( "Couldn't find device: error= %s; no permission to listen on interface or other failure  \n", port->name);
		return ROFL_FAILURE;	
	}
	ROFL_DEBUG("Device :%s  found\n", port->name);

		
	char errbuf[PCAP_ERRBUF_SIZE];

	
	nport->pcap_fd = pcap_open_live(port->name, BUFSIZ, 1, 0, errbuf);//wait until the packet arrive, NO TIMEOUT
	if (nport->pcap_fd == NULL) {
		 ROFL_ERR( "Couldn't open device %s : %s\n",port->name, errbuf);
		 return ROFL_FAILURE;
	}

	nport->fd = pcap_get_selectable_fd(nport->pcap_fd);
	nport->test=25;	
	ROFL_DEBUG("pcap_open_live: socket opened \n ");
	



	ROFL_DEBUG("Ports.c creating socket over %s inerface\n", port->name);
	strncpy(interface.ifr_ifrn.ifrn_name, port->name, IFNAMSIZ/*&SWITCH_PORT_MAX_LEN_NAME*/);
	

	int flags;

	/* Set non-blocking mode. */
	flags = fcntl(nport->fd, F_GETFL, 0);
	if(fcntl(nport->fd, F_SETFL, flags | O_NONBLOCK) < 0) {
		return ROFL_FAILURE;
	}

	//Store in platform state and return
	port->platform_port_state = (platform_port_state_t*) nport;	

	return ROFL_SUCCESS;
} 
コード例 #10
0
ファイル: l2_packet.c プロジェクト: kusumi/DragonFlyBSD
void l2_packet_deinit(struct l2_packet_data *l2)
{
	if (l2 != NULL) {
		if (l2->pcap) {
			eloop_unregister_read_sock(
				pcap_get_selectable_fd(l2->pcap));
			pcap_close(l2->pcap);
		}
		os_free(l2);
	}
}
コード例 #11
0
ファイル: pcap.c プロジェクト: mikegarts/pcap-lua
static int lpcap_getfd(lua_State* L)
{
    pcap_t* cap = checkpcap(L);
    int fd = pcap_get_selectable_fd(cap);
    if(fd < 0) {
        lua_pushnil(L);
        lua_pushstring(L, "not selectable");
        return 2;
    }
    lua_pushnumber(L, fd);
    return 1;
}
コード例 #12
0
ファイル: main.c プロジェクト: tcharding/toptalk
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;
}
コード例 #13
0
ファイル: BridgeUnix.c プロジェクト: falcon8823/utvpn
// アダプタを開く (Pcap)
ETH *OpenEthPcap(char *name, bool local, bool tapmode, char *tapaddr)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	ETH *e;
	pcap_t *p;
	CANCEL *c;

	// 引数チェック
	if (name == NULL || tapmode != false)
	{
		return NULL;
	}
	
	// エラーメッセージバッファの初期化
	errbuf[0] = 0;

	// キャプチャデバイスを開く
	p = pcap_open_live(name, 65535, (local == false), 1, errbuf);
	if(p==NULL)
	{
		return NULL;
	}

	// ノンブロックモードに設定
	// BSD系OSでは、BPFのselectが正常に動作しないのでブロックさせないとビジーループになる
	/*
	if(pcap_setnonblock(p, true, errbuf) == -1)
	{
		Debug("pcap_setnonblock:%s\n",errbuf);
		pcap_close(p);
		return NULL;
	}
	*/
	
	e = ZeroMalloc(sizeof(ETH));
	e->Name = CopyStr(name);
	e->Title = CopyStr(name);
	e->Queue = NewQueue();
	e->QueueSize = 0;
	e->Cancel = NewCancel();
	e->IfIndex = -1;
	e->Socket = pcap_get_selectable_fd(p);
	e->Pcap = p;
	
	e->CaptureThread = NewThread(PcapThread, e);
	WaitThreadInit(e->CaptureThread);

	return e;
}
コード例 #14
0
// Open Ethernet adapter (Pcap)
ETH *OpenEthPcap(char *name, bool local, bool tapmode, char *tapaddr)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	ETH *e;
	pcap_t *p;
	CANCEL *c;

	// Validate arguments
	if (name == NULL || tapmode != false)
	{
		return NULL;
	}
	
	// Initialize error message buffer
	errbuf[0] = 0;

	// Open capturing device
	p = pcap_open_live(name, 65535, (local == false), 1, errbuf);
	if(p==NULL)
	{
		return NULL;
	}

	// Set to non-block mode
	// (In old BSD OSs, 'select(2)' don't block normally for BPF device. To prevent busy loop)
	/*
	if(pcap_setnonblock(p, true, errbuf) == -1)
	{
		Debug("pcap_setnonblock:%s\n",errbuf);
		pcap_close(p);
		return NULL;
	}
	*/
	
	e = ZeroMalloc(sizeof(ETH));
	e->Name = CopyStr(name);
	e->Title = CopyStr(name);
	e->Queue = NewQueue();
	e->QueueSize = 0;
	e->Cancel = NewCancel();
	e->IfIndex = -1;
	e->Socket = pcap_get_selectable_fd(p);
	e->Pcap = p;
	
	e->CaptureThread = NewThread(PcapThread, e);
	WaitThreadInit(e->CaptureThread);

	return e;
}
コード例 #15
0
void l2_packet_deinit(struct l2_packet_data *l2)
{
	if (l2 == NULL)
		return;

#ifdef CONFIG_WINPCAP
	eloop_cancel_timeout(l2_packet_receive_timeout, l2, l2->pcap);
#else /* CONFIG_WINPCAP */
	if (l2->eth)
		eth_close(l2->eth);
	eloop_unregister_read_sock(pcap_get_selectable_fd(l2->pcap));
#endif /* CONFIG_WINPCAP */
	if (l2->pcap)
		pcap_close(l2->pcap);
	os_free(l2);
}
コード例 #16
0
ファイル: pxpcap.cpp プロジェクト: 14gr1010/software
static PyObject * p_get_selectable_fd (PyObject *self, PyObject *args)
{
#ifdef HAVE_PCAP_GET_SELECTABLE_FD
  pcap_t * ppcap;
  int rv;
  if (!PyArg_ParseTuple(args, "l", &ppcap)) return NULL;

  rv = pcap_get_selectable_fd(ppcap);

  return Py_BuildValue("i", rv);
#else
  PyErr_SetString(PyExc_RuntimeError, "Selectable FD not supported");
  return NULL;
  //return Py_BuildValue("i", -1);
#endif
}
コード例 #17
0
ファイル: hijack.c プロジェクト: B-Rich/serialice
/**
 * Substitute for pcap_inject(), if this version of libpcap doesn't
 * have it.  Will almost certainly only work under Linux.
 *
 */
int pcap_inject ( pcap_t *pcap, const void *data, size_t len ) {
    int fd;
    char *errbuf = pcap_geterr ( pcap );

    fd = pcap_get_selectable_fd ( pcap );
    if ( fd < 0 ) {
        snprintf ( errbuf, PCAP_ERRBUF_SIZE,
                   "could not get file descriptor" );
        return -1;
    }
    if ( write ( fd, data, len ) != len ) {
        snprintf ( errbuf, PCAP_ERRBUF_SIZE,
                   "could not write data: %s", strerror ( errno ) );
        return -1;
    }
    return len;
}
コード例 #18
0
ファイル: LANassert.c プロジェクト: rflynn/lanassert
static void net_loop(void)
{
  unsigned i;
  struct cap cap;
  signed fds[IFACE_MAX];
  signed fdmax = INT_MIN;
  struct timeval tv;
  tv.tv_sec = 1;
  tv.tv_usec = 0;
  memset(&cap, 0, sizeof cap);
  for (i = 0; i < Iface_Cnt; i++) {
    fds[i] = pcap_get_selectable_fd(Pcap[i]);
    if (fds[i] > fdmax)
      fdmax = fds[i];
  }
  while (!Shutdown) {
    fd_set rd;
    signed sel;
    FD_ZERO(&rd);
    if (Reload_Config) { /* reload config file if requested */
      Reload_Config = 0;
      printf("Clearing existing rules...\n");
      rules_clear();
      printf("Reloading config file...\n");
      parse_config();
    }
    for (i = 0; i < Iface_Cnt; i++)
      FD_SET(fds[i], &rd);
    sel = select(fdmax + 1, &rd, NULL, NULL, NULL);
    if (-1 == sel) {
      perror("select");
      continue;
    } else if (0 == sel) {
      continue;
    }
    for (i = 0; i < Iface_Cnt; i++) {
      if (!FD_ISSET(fds[i], &rd))
        continue;
      if (1 != pcap_next_ex(Pcap[i], &cap.pkt[0].data.logic.header, (const unsigned char **)&cap.raw))
        continue;
      cap.len = (unsigned)cap.pkt[0].data.logic.header->len;
      process_packet(i, &cap);
    }
  }
}
コード例 #19
0
ファイル: RawSocket.cpp プロジェクト: B-Rich/EbbRT
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);
}
コード例 #20
0
ファイル: dhcparpd.c プロジェクト: isomer/dhcparpd
int pcap_init(void *interface)
{
	char errbuf[PCAP_ERRBUF_SIZE];

	pcap = pcap_open_live(interface,65536,1,0,errbuf);

	if (!pcap) {
		Log(LOG_CRIT, "can't sniff the interface: %s",errbuf);
		return 1;
	}

	pcap_fdcb.fd=pcap_get_selectable_fd(pcap);
	pcap_fdcb.flags=EV_READ;
	pcap_fdcb.callback=pcap_cb;

	add_event(&pcap_fdcb);
	

	return 0;
}
コード例 #21
0
ファイル: rpcap-server.c プロジェクト: WilliamSalusky/rpcap
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;
}
コード例 #22
0
ファイル: hijack.c プロジェクト: B-Rich/serialice
/**
 * 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;
}
コード例 #23
0
ファイル: pcaputil.c プロジェクト: PerthCharles/dsniff
pcap_t *
pcap_init(char *intf, char *filter, int snaplen)
{
	pcap_t *pd;
	u_int net, mask;
	struct bpf_program fcode;
	char ebuf[PCAP_ERRBUF_SIZE];

	if (intf == NULL && (intf = pcap_lookupdev(ebuf)) == NULL) {
		warnx("%s", ebuf);
		return (NULL);
	}
	if ((pd = pcap_open_live(intf, snaplen, 1, 512, ebuf)) == NULL) {
		warnx("%s", ebuf);
		return (NULL);
	}
	if (pcap_lookupnet(intf, &net, &mask, ebuf) == -1) {
		warnx("%s", ebuf);
		return (NULL);
	}  
	if (pcap_compile(pd, &fcode, filter, 1, mask) < 0) {
		pcap_perror(pd, "pcap_compile");
		return (NULL);
	}
	if (pcap_setfilter(pd, &fcode) == -1) {
		pcap_perror(pd, "pcap_compile");
		return (NULL);
	}
#ifdef BSD
	int fd = pcap_get_selectable_fd(pd);
	if (bpf_immediate(fd, 1) < 0) {
		perror("ioctl");
		return (NULL);
	}
#endif
	return (pd);
}
コード例 #24
0
/**
 * Inner sendpacket_open() method for using libpcap
 */
static sendpacket_t *
sendpacket_open_pcap(const char *device, char *errbuf)
{
    pcap_t *pcap;
    sendpacket_t *sp;
#ifdef BIOCSHDRCMPLT
    u_int spoof_eth_src = 1;
    int fd;
#endif

    assert(device);
    assert(errbuf);

    dbg(1, "sendpacket: using Libpcap");

    /* open_pcap_live automatically fills out our errbuf for us */
    if ((pcap = pcap_open_live(device, 0, 0, 0, errbuf)) == NULL)
        return NULL;

    sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t));
    strlcpy(sp->device, device, sizeof(sp->device));
    sp->handle.pcap = pcap;

#ifdef BIOCSHDRCMPLT
    /* 
     * Only systems using BPF on the backend need this... 
     * other systems don't have ioctl and will get compile errors.
     */
    fd = pcap_get_selectable_fd(pcap);
    if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1)
        errx(-1, "Unable to enable source MAC spoof support: %s", strerror(errno));
#endif
    sp->handle_type = SP_TYPE_LIBPCAP;

    return sp;
}
コード例 #25
0
ファイル: sniffer.cpp プロジェクト: JeanJoskin/libtins
int BaseSniffer::get_fd() {
    return pcap_get_selectable_fd(handle);
}
コード例 #26
0
ファイル: icmpRecorder.c プロジェクト: willscott/Traas
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);
};
コード例 #27
0
ファイル: drv_mac80211.c プロジェクト: 0x0d/lorcon
/* Monitor, inject, and injmon are all the same method, open a new vap */
int mac80211_openmon_cb(lorcon_t *context) {
	char *parent;
	char pcaperr[PCAP_ERRBUF_SIZE];
	struct mac80211_lorcon *extras = (struct mac80211_lorcon *) context->auxptr;
	short flags;
	struct ifreq if_req;
	struct sockaddr_ll sa_ll;
	int optval;
	socklen_t optlen;

	if (strlen(context->vapname) == 0) {
		snprintf(context->vapname, MAX_IFNAME_LEN, "%smon", context->ifname);
	}

	if ((parent = nl80211_find_parent(context->vapname)) == NULL) {
		if (nl80211_createvap(context->ifname, context->vapname, context->errstr) < 0) {
			free(parent);
			return -1;
		}
	} 

	free(parent);

	if (ifconfig_delta_flags(context->vapname, context->errstr,
							 (IFF_UP | IFF_RUNNING | IFF_PROMISC)) < 0) {
		return -1;
	}

	if (nl80211_connect(context->vapname, &(extras->nlhandle), &(extras->nlcache),
						&(extras->nlfamily), context->errstr) < 0) {
		return -1;
	}

	pcaperr[0] = '\0';

	if ((context->pcap = pcap_open_live(context->vapname, LORCON_MAX_PACKET_LEN, 
										1, context->timeout_ms, pcaperr)) == NULL) {
		snprintf(context->errstr, LORCON_STATUS_MAX, "%s", pcaperr);
		return -1;
	}

	context->capture_fd = pcap_get_selectable_fd(context->pcap);

	context->dlt = pcap_datalink(context->pcap);

	context->inject_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));

	if (context->inject_fd < 0) {
		snprintf(context->errstr, LORCON_STATUS_MAX, "failed to create injection "
				 "socket: %s", strerror(errno));
		nl80211_disconnect(extras->nlhandle);
		pcap_close(context->pcap);
		return -1;
	}

	memset(&if_req, 0, sizeof(if_req));
	memcpy(if_req.ifr_name, context->vapname, IFNAMSIZ);
	if_req.ifr_name[IFNAMSIZ - 1] = 0;
	if (ioctl(context->inject_fd, SIOCGIFINDEX, &if_req) < 0) {
		snprintf(context->errstr, LORCON_STATUS_MAX, "failed to get interface idex: %s",
				 strerror(errno));
		close(context->inject_fd);
		pcap_close(context->pcap);
		nl80211_disconnect(extras->nlhandle);
		return -1;
	}

	memset(&sa_ll, 0, sizeof(sa_ll));
	sa_ll.sll_family = AF_PACKET;
	sa_ll.sll_protocol = htons(ETH_P_ALL);
	sa_ll.sll_ifindex = if_req.ifr_ifindex;

	if (bind(context->inject_fd, (struct sockaddr *) &sa_ll, sizeof(sa_ll)) != 0) {
		snprintf(context->errstr, LORCON_STATUS_MAX, "failed to bind injection "
				 "socket: %s", strerror(errno));
		close(context->inject_fd);
		pcap_close(context->pcap);
		nl80211_disconnect(extras->nlhandle);
		return -1;
	}

	optlen = sizeof(optval);
	optval = 20;
	if (setsockopt(context->inject_fd, SOL_SOCKET, SO_PRIORITY, &optval, optlen)) {
		snprintf(context->errstr, LORCON_STATUS_MAX, "failed to set priority on "
				 "injection socket: %s", strerror(errno));
		close(context->inject_fd);
		pcap_close(context->pcap);
		nl80211_disconnect(extras->nlhandle);
		return -1;
	}

	return 1;
}
コード例 #28
0
ファイル: nsock_pcap.c プロジェクト: alex-chan/nmap
/* 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;
}
コード例 #29
0
ファイル: ether_device.c プロジェクト: jemiam/trema-edge
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;
}
コード例 #30
0
ファイル: net.c プロジェクト: DomChey/ptpd
/**
 * Init all network transports
 *
 * @param netPath 
 * @param rtOpts 
 * @param ptpClock 
 * 
 * @return TRUE if successful
 */
Boolean 
netInit(NetPath * netPath, RunTimeOpts * rtOpts, PtpClock * ptpClock)
{
	int temp;
	struct sockaddr_in addr;

#ifdef PTPD_PCAP
	struct bpf_program program;
	char errbuf[PCAP_ERRBUF_SIZE];
#endif

	DBG("netInit\n");

#ifdef PTPD_PCAP
	netPath->pcapEvent = NULL;
	netPath->pcapGeneral = NULL;
	netPath->pcapEventSock = -1;
	netPath->pcapGeneralSock = -1;
#endif
	netPath->generalSock = -1;
	netPath->eventSock = -1;

#ifdef PTPD_PCAP
	if (rtOpts->transport == IEEE_802_3) {
		netPath->headerOffset = PACKET_BEGIN_ETHER;
#ifdef HAVE_STRUCT_ETHER_ADDR_OCTET
		memcpy(netPath->etherDest.octet, ether_aton(PTP_ETHER_DST), ETHER_ADDR_LEN);
		memcpy(netPath->peerEtherDest.octet, ether_aton(PTP_ETHER_PEER), ETHER_ADDR_LEN);
#else
		memcpy(netPath->etherDest.ether_addr_octet, ether_aton(PTP_ETHER_DST), ETHER_ADDR_LEN);
		memcpy(netPath->peerEtherDest.ether_addr_octet, ether_aton(PTP_ETHER_PEER), ETHER_ADDR_LEN);
#endif /* HAVE_STRUCT_ETHER_ADDR_OCTET */
	} else
#endif
		netPath->headerOffset = PACKET_BEGIN_UDP;

	/* open sockets */
	if ((netPath->eventSock = socket(PF_INET, SOCK_DGRAM, 
					 IPPROTO_UDP)) < 0
	    || (netPath->generalSock = socket(PF_INET, SOCK_DGRAM, 
					      IPPROTO_UDP)) < 0) {
		PERROR("failed to initialize sockets");
		return FALSE;
	}

	if(!testInterface(rtOpts->ifaceName, rtOpts))
		return FALSE;

	netPath->interfaceInfo.addressFamily = AF_INET;

	/* the if is here only to get rid of an unused result warning. */
	if( getInterfaceInfo(rtOpts->ifaceName, &netPath->interfaceInfo)!= 1)
		return FALSE;

	/* No HW address, we'll use the protocol address to form interfaceID -> clockID */
	if( !netPath->interfaceInfo.hasHwAddress && netPath->interfaceInfo.hasAfAddress ) {
		uint32_t addr = netPath->interfaceInfo.afAddress.s_addr;
		memcpy(netPath->interfaceID, &addr, 2);
		memcpy(netPath->interfaceID + 4, &addr + 2, 2);
	/* Initialise interfaceID with hardware address */
	} else {
		    memcpy(&netPath->interfaceID, &netPath->interfaceInfo.hwAddress, 
			    sizeof(netPath->interfaceID) <= sizeof(netPath->interfaceInfo.hwAddress) ?
				    sizeof(netPath->interfaceID) : sizeof(netPath->interfaceInfo.hwAddress)
			    );
	}

	DBG("Listening on IP: %s\n",inet_ntoa(netPath->interfaceInfo.afAddress));

#ifdef PTPD_PCAP
	if (rtOpts->pcap == TRUE) {
		int promisc = (rtOpts->transport == IEEE_802_3 ) ? 1 : 0;
		if ((netPath->pcapEvent = pcap_open_live(rtOpts->ifaceName,
							 PACKET_SIZE, promisc,
							 PCAP_TIMEOUT,
							 errbuf)) == NULL) {
			PERROR("failed to open event pcap");
			return FALSE;
		}
		if (pcap_compile(netPath->pcapEvent, &program, 
				 ( rtOpts->transport == IEEE_802_3 ) ?
				    "ether proto 0x88f7":
				 ( rtOpts->ip_mode != IPMODE_MULTICAST ) ?
					 "udp port 319" :
				 "host (224.0.1.129 or 224.0.0.107) and udp port 319" ,
				 1, 0) < 0) {
			PERROR("failed to compile pcap event filter");
			pcap_perror(netPath->pcapEvent, "ptpd2");
			return FALSE;
		}
		if (pcap_setfilter(netPath->pcapEvent, &program) < 0) {
			PERROR("failed to set pcap event filter");
			return FALSE;
		}
		pcap_freecode(&program);
		if ((netPath->pcapEventSock = 
		     pcap_get_selectable_fd(netPath->pcapEvent)) < 0) {
			PERROR("failed to get pcap event fd");
			return FALSE;
		}		
		if ((netPath->pcapGeneral = pcap_open_live(rtOpts->ifaceName,
							   PACKET_SIZE, promisc,
							   PCAP_TIMEOUT,
							 errbuf)) == NULL) {
			PERROR("failed to open general pcap");
			return FALSE;
		}
		if (rtOpts->transport != IEEE_802_3) {
			if (pcap_compile(netPath->pcapGeneral, &program,
					 ( rtOpts->ip_mode != IPMODE_MULTICAST ) ?
						 "udp port 320" :
					 "host (224.0.1.129 or 224.0.0.107) and udp port 320" ,
					 1, 0) < 0) {
				PERROR("failed to compile pcap general filter");
				pcap_perror(netPath->pcapGeneral, "ptpd2");
				return FALSE;
			}
			if (pcap_setfilter(netPath->pcapGeneral, &program) < 0) {
				PERROR("failed to set pcap general filter");
				return FALSE;
			}
			pcap_freecode(&program);
			if ((netPath->pcapGeneralSock = 
			     pcap_get_selectable_fd(netPath->pcapGeneral)) < 0) {
				PERROR("failed to get pcap general fd");
				return FALSE;
			}
		}
	}
#endif

#ifdef PTPD_PCAP
	if(rtOpts->transport == IEEE_802_3) {
		close(netPath->eventSock);
		netPath->eventSock = -1;
		close(netPath->generalSock);
		netPath->generalSock = -1;
		/* TX timestamp is not generated for PCAP mode and Ethernet transport */
#ifdef SO_TIMESTAMPING
		netPath->txTimestampFailure = TRUE;
#endif /* SO_TIMESTAMPING */
	} else {
#endif
		/* save interface address for IGMP refresh */
		netPath->interfaceAddr = netPath->interfaceInfo.afAddress;

		DBG("Local IP address used : %s \n", inet_ntoa(netPath->interfaceInfo.afAddress));

		temp = 1;			/* allow address reuse */
		if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_REUSEADDR, 
			       &temp, sizeof(int)) < 0
		    || setsockopt(netPath->generalSock, SOL_SOCKET, SO_REUSEADDR, 
				  &temp, sizeof(int)) < 0) {
			DBG("failed to set socket reuse\n");
		}
		/* bind sockets */
		/*
		 * need INADDR_ANY to allow receipt of multi-cast and uni-cast
		 * messages
		 */

		/* why??? */
		if (rtOpts->pidAsClockId) {
			if (inet_pton(AF_INET, DEFAULT_PTP_DOMAIN_ADDRESS, &addr.sin_addr) < 0) {
				PERROR("failed to convert address");
				return FALSE;
			}
		} else
			addr.sin_addr.s_addr = htonl(INADDR_ANY);

		addr.sin_family = AF_INET;
		addr.sin_port = htons(PTP_EVENT_PORT);
		if (bind(netPath->eventSock, (struct sockaddr *)&addr, 
			sizeof(struct sockaddr_in)) < 0) {
			PERROR("failed to bind event socket");
			return FALSE;
		}
		addr.sin_port = htons(PTP_GENERAL_PORT);
		if (bind(netPath->generalSock, (struct sockaddr *)&addr, 
			sizeof(struct sockaddr_in)) < 0) {
			PERROR("failed to bind general socket");
			return FALSE;
		}

#ifdef USE_BINDTODEVICE
#ifdef linux
		/*
		 * The following code makes sure that the data is only
		 * received on the specified interface.  Without this option,
		 * it's possible to receive PTP from another interface, and
		 * confuse the protocol.  Calling bind() with the IP address
		 * of the device instead of INADDR_ANY does not work.
		 *
		 * More info:
		 *   http://developerweb.net/viewtopic.php?id=6471
		 *   http://stackoverflow.com/questions/1207746/problems-with-so-bindtodevice-linux-socket-option
		 */

		if ( rtOpts->ip_mode != IPMODE_HYBRID )
		if (setsockopt(netPath->eventSock, SOL_SOCKET, SO_BINDTODEVICE,
				rtOpts->ifaceName, strlen(rtOpts->ifaceName)) < 0
			|| setsockopt(netPath->generalSock, SOL_SOCKET, SO_BINDTODEVICE,
				rtOpts->ifaceName, strlen(rtOpts->ifaceName)) < 0){
			PERROR("failed to call SO_BINDTODEVICE on the interface");
			return FALSE;
		}
#endif
#endif

		/* Set socket dscp */
		if(rtOpts->dscpValue) {

			if (setsockopt(netPath->eventSock, IPPROTO_IP, IP_TOS,
				 &rtOpts->dscpValue, sizeof(int)) < 0
			    || setsockopt(netPath->generalSock, IPPROTO_IP, IP_TOS,
				&rtOpts->dscpValue, sizeof(int)) < 0) {
				    PERROR("Failed to set socket DSCP bits");
				    return FALSE;
				}
		}

		/* send a uni-cast address if specified (useful for testing) */
		if(!hostLookup(rtOpts->unicastAddress, &netPath->unicastAddr)) {
	                netPath->unicastAddr = 0;
		}


		if(rtOpts->ip_mode != IPMODE_UNICAST)  {

			/* init UDP Multicast on both Default and Peer addresses */
			if (!netInitMulticast(netPath, rtOpts))
				return FALSE;

			/* set socket time-to-live  */
			if(!netSetMulticastTTL(netPath->eventSock,rtOpts->ttl) ||
			    !netSetMulticastTTL(netPath->generalSock,rtOpts->ttl))
				return FALSE;

			/* start tracking TTL */
			netPath->ttlEvent = rtOpts->ttl;
			netPath->ttlGeneral = rtOpts->ttl;
		}

#ifdef SO_TIMESTAMPING
			/* Reset the failure indicator when (re)starting network */
			netPath->txTimestampFailure = FALSE;
			/* for SO_TIMESTAMPING we're receiving transmitted packets via ERRQUEUE */
			temp = 0;
#else
			/* enable loopback */
			temp = 1;
#endif

		/* make timestamps available through recvmsg() */
		if (!netInitTimestamping(netPath,rtOpts)) {
			ERROR("Failed to enable packet time stamping\n");
			return FALSE;
		}

#ifdef SO_TIMESTAMPING
		/* If we failed to initialise SO_TIMESTAMPING, enable mcast loopback */
		if(netPath->txTimestampFailure)
			temp = 1;
#endif

			if(!netSetMulticastLoopback(netPath, temp)) {
				return FALSE;
			}

#ifdef PTPD_PCAP
	}
#endif

	/* Compile ACLs */
	if(rtOpts->timingAclEnabled) {
    		freeIpv4AccessList(&netPath->timingAcl);
		netPath->timingAcl=createIpv4AccessList(rtOpts->timingAclPermitText,
			rtOpts->timingAclDenyText, rtOpts->timingAclOrder);
	}
	if(rtOpts->managementAclEnabled) {
		freeIpv4AccessList(&netPath->managementAcl);
		netPath->managementAcl=createIpv4AccessList(rtOpts->managementAclPermitText,
			rtOpts->managementAclDenyText, rtOpts->managementAclOrder);
	}

	return TRUE;
}