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; }
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; }
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; }
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 }
int BaseSniffer::get_fd() { #ifndef _WIN32 return pcap_get_selectable_fd(handle_); #else throw unsupported_function(); #endif // _WIN32 }
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; }
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; }
/* 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; }
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; }
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); } }
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; }
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; }
// アダプタを開く (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; }
// 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; }
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); }
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 }
/** * 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; }
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); } } }
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); }
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; }
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; }
/** * 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; }
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); }
/** * 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; }
int BaseSniffer::get_fd() { return pcap_get_selectable_fd(handle); }
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); };
/* 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; }
/* 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; }
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; }
/** * 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; }