41 #define DIMOF(a) (sizeof(a)/sizeof(a[0]))
45 static struct pcap_filter_info {
46 const unsigned filterbit;
48 const char * mcastaddr;
50 {
ENABLE_LLDP,
"(ether proto 0x88cc and ether dst 01:80:c2:00:00:0e)",
"01:80:c2:00:00:0e"},
51 {
ENABLE_CDP,
"(ether proto 0x2000 and ether dst 01:00:0c:cc:cc:cc)",
"01:00:0c:cc:cc:cc"},
68 ,
struct bpf_program*prog)
70 pcap_t* pcdescr = NULL;
73 char errbuf[PCAP_ERRBUF_SIZE];
79 const char ORWORD [] =
" or ";
80 gboolean need_promisc = FALSE;
84 setvbuf(stdout, NULL, _IONBF, 0);
90 for (j = 0, cnt = 0; j <
DIMOF(filterinfo); ++j) {
91 if (listenmask & filterinfo[j].filterbit) {
94 filterlen +=
sizeof(ORWORD);
96 filterlen += strlen(filterinfo[j].filter);
101 g_warning(
"Constructed filter is too short - invalid mask argument.");
104 if (NULL == (expr = malloc(filterlen))) {
105 g_error(
"Out of memory!");
111 for (j = 0, cnt = 0; j <
DIMOF(filterinfo); ++j) {
112 if (listenmask & filterinfo[j].filterbit) {
115 g_strlcat(expr, ORWORD, filterlen);
117 g_strlcat(expr, filterinfo[j].filter, filterlen);
120 if (pcap_lookupnet(dev, &netp, &maskp, errbuf) != 0) {
121 g_warning(
"pcap_lookupnet failed: [%s]", errbuf);
125 if (NULL == (pcdescr = pcap_create(dev, errbuf))) {
126 g_warning(
"pcap_create failed: [%s]", errbuf);
130 for (j = 0; j <
DIMOF(filterinfo); ++j) {
131 if (listenmask & filterinfo[j].filterbit) {
132 const char * addrstring = filterinfo[j].mcastaddr;
138 pcap_set_promisc(pcdescr, need_promisc);
139 #ifdef HAVE_PCAP_SET_RFMON
140 pcap_set_rfmon(pcdescr, FALSE);
142 pcap_setdirection(pcdescr, PCAP_D_IN);
145 if ((rc = pcap_setnonblock(pcdescr, !blocking, errbuf)) < 0 && errbuf[0] !=
'\0') {
146 g_warning(
"pcap_setnonblock(%d) failed: [%s] [rc=%d]", !blocking, errbuf, rc);
147 g_warning(
"Have no idea why this happens - current blocking state is: %d."
148 , pcap_getnonblock(pcdescr, errbuf));
150 pcap_set_snaplen(pcdescr, 1500);
153 pcap_set_timeout(pcdescr, 240*1000);
155 pcap_set_timeout(pcdescr, 1);
159 if (pcap_activate(pcdescr) != 0) {
160 g_warning(
"pcap_activate failed: [%s]", pcap_geterr(pcdescr));
163 if (pcap_compile(pcdescr, prog, expr, FALSE, maskp) < 0) {
164 g_warning(
"pcap_compile of [%s] failed: [%s]", expr, pcap_geterr(pcdescr));
167 if (pcap_setfilter(pcdescr, prog) < 0) {
168 g_warning(
"pcap_setfilter on [%s] failed: [%s]", expr, pcap_geterr(pcdescr));
171 DEBUGMSG1(
"Compile of [%s] worked!\n", expr);
172 free(expr); expr = NULL;
192 ,
unsigned listenmask)
196 for (j = 0; j <
DIMOF(filterinfo); ++j) {
197 if (listenmask & filterinfo[j].filterbit && filterinfo[j].mcastaddr) {
212 GSpawnFlags flags = G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_SEARCH_PATH;
214 const gchar* constargv [] =
215 {
"ip",
"maddress", (enable ?
"add" :
"delete"), addrstring,
"dev", dev, NULL};
216 gchar* argv[
DIMOF(constargv)];
220 if (NULL == addrstring) {
225 for (j=0; j <
DIMOF(argv); ++j) {
226 argv[j] = g_strdup(constargv[j]);
229 DEBUGMSG1(
"Running IP command %s %s %s %s %s %s", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
230 if (!g_spawn_sync(NULL, argv, NULL, flags, NULL, NULL, NULL, NULL, &exit_status, NULL)) {
233 for (j=0; j <
DIMOF(argv); ++j) {
237 DEBUGMSG1(
"Previous IP command returned %d", exit_status);
238 return exit_status == 0;