suricata
util-ioctl.c
Go to the documentation of this file.
1 /* Copyright (C) 2010 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Eric Leblond <eric@regit.org>
22  * \author Victor Julien <victor@inliniac.net>
23  */
24 
25 #include "suricata-common.h"
26 #include "util-ioctl.h"
27 #include "conf.h"
28 #include "decode.h"
29 #include "decode-sll.h"
30 
31 #ifdef HAVE_SYS_IOCTL_H
32 #include <sys/ioctl.h>
33 #endif
34 
35 #ifdef HAVE_LINUX_ETHTOOL_H
36 #include <linux/types.h>
37 #include <linux/ethtool.h>
38 #ifdef HAVE_LINUX_SOCKIOS_H
39 #include <linux/sockios.h>
40 #else
41 #error "ethtool.h present but sockios.h is missing"
42 #endif /* HAVE_LINUX_SOCKIOS_H */
43 #endif /* HAVE_LINUX_ETHTOOL_H */
44 
45 #ifdef HAVE_NET_IF_H
46 #include <net/if.h>
47 #endif
48 
49 #ifdef OS_WIN32
50 #include "win32-syscall.h"
51 #endif
52 
53 /**
54  * \brief output a majorant of hardware header length
55  *
56  * \param Name of a network interface
57  */
58 static int GetIfaceMaxHWHeaderLength(const char *pcap_dev)
59 {
60  if ((!strcmp("eth", pcap_dev))
61  ||
62  (!strcmp("br", pcap_dev))
63  ||
64  (!strcmp("bond", pcap_dev))
65  ||
66  (!strcmp("wlan", pcap_dev))
67  ||
68  (!strcmp("tun", pcap_dev))
69  ||
70  (!strcmp("tap", pcap_dev))
71  ||
72  (!strcmp("lo", pcap_dev))) {
73  /* Add possible VLAN tag or Qing headers */
74  return 8 + ETHERNET_HEADER_LEN;
75  }
76 
77  if (!strcmp("ppp", pcap_dev))
78  return SLL_HEADER_LEN;
79  /* SLL_HEADER_LEN is the biggest one and
80  add possible VLAN tag and Qing headers */
81  return 8 + SLL_HEADER_LEN;
82 }
83 
84 
85 /**
86  * \brief output the link MTU
87  *
88  * \param Name of link
89  * \retval -1 in case of error, 0 if MTU can not be found
90  */
91 int GetIfaceMTU(const char *pcap_dev)
92 {
93 #if defined SIOCGIFMTU
94  struct ifreq ifr;
95  int fd;
96 
97  (void)strlcpy(ifr.ifr_name, pcap_dev, sizeof(ifr.ifr_name));
98  fd = socket(AF_INET, SOCK_DGRAM, 0);
99  if (fd == -1) {
100  return -1;
101  }
102 
103  if (ioctl(fd, SIOCGIFMTU, (char *)&ifr) < 0) {
104  SCLogWarning("Failure when trying to get MTU via ioctl for '%s': %s (%d)", pcap_dev,
105  strerror(errno), errno);
106  close(fd);
107  return -1;
108  }
109  close(fd);
110  SCLogInfo("%s: MTU %d", pcap_dev, ifr.ifr_mtu);
111  return ifr.ifr_mtu;
112 #elif defined OS_WIN32
113  return GetIfaceMTUWin32(pcap_dev);
114 #else
115  /* ioctl is not defined, let's pretend returning 0 is ok */
116  return 0;
117 #endif
118 }
119 
120 /**
121  * \brief output max packet size for a link
122  *
123  * This does a best effort to find the maximum packet size
124  * for the link. In case of uncertainty, it will output a
125  * majorant to be sure avoid the cost of dynamic allocation.
126  *
127  * \param Name of a network interface
128  * \retval 0 in case of error
129  */
130 int GetIfaceMaxPacketSize(const char *pcap_dev)
131 {
132  if ((pcap_dev == NULL) || strlen(pcap_dev) == 0)
133  return 0;
134 
135  int mtu = GetIfaceMTU(pcap_dev);
136  switch (mtu) {
137  case 0:
138  case -1:
139  return 0;
140  }
141  int ll_header = GetIfaceMaxHWHeaderLength(pcap_dev);
142  if (ll_header == -1) {
143  /* be conservative, choose a big one */
144  ll_header = 16;
145  }
146  return ll_header + mtu;
147 }
148 
149 #ifdef SIOCGIFFLAGS
150 /**
151  * \brief Get interface flags.
152  * \param ifname Inteface name.
153  * \return Interface flags or -1 on error
154  */
155 int GetIfaceFlags(const char *ifname)
156 {
157  struct ifreq ifr;
158 
159  int fd = socket(AF_INET, SOCK_DGRAM, 0);
160  if (fd < 0) {
161  return -1;
162  }
163 
164  memset(&ifr, 0, sizeof(ifr));
165  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
166 
167  if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
168  SCLogError("%s: failed to get device flags: %s", ifname, strerror(errno));
169  close(fd);
170  return -1;
171  }
172 
173  close(fd);
174 #ifdef OS_FREEBSD
175  int flags = (ifr.ifr_flags & 0xffff) | (ifr.ifr_flagshigh << 16);
176  return flags;
177 #else
178  return ifr.ifr_flags;
179 #endif
180 }
181 #endif
182 
183 #ifdef SIOCSIFFLAGS
184 /**
185  * \brief Set interface flags.
186  * \param ifname Inteface name.
187  * \param flags Flags to set.
188  * \return Zero on success.
189  */
190 int SetIfaceFlags(const char *ifname, int flags)
191 {
192  struct ifreq ifr;
193 
194  int fd = socket(AF_INET, SOCK_DGRAM, 0);
195  if (fd < 0) {
196  return -1;
197  }
198 
199  memset(&ifr, 0, sizeof(ifr));
200  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
201 #ifdef OS_FREEBSD
202  ifr.ifr_flags = flags & 0xffff;
203  ifr.ifr_flagshigh = flags >> 16;
204 #else
205  ifr.ifr_flags = (uint16_t)flags;
206 #endif
207 
208  if (ioctl(fd, SIOCSIFFLAGS, &ifr) == -1) {
209  SCLogError("%s: unable to set device flags: %s", ifname, strerror(errno));
210  close(fd);
211  return -1;
212  }
213 
214  close(fd);
215  return 0;
216 }
217 #endif /* SIOCGIFFLAGS */
218 
219 #ifdef SIOCGIFCAP
220 int GetIfaceCaps(const char *ifname)
221 {
222  struct ifreq ifr;
223 
224  int fd = socket(AF_INET, SOCK_DGRAM, 0);
225  if (fd < 0) {
226  return -1;
227  }
228 
229  memset(&ifr, 0, sizeof(ifr));
230  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
231 
232  if (ioctl(fd, SIOCGIFCAP, &ifr) == -1) {
233  SCLogError("%s: unable to get device caps: %s", ifname, strerror(errno));
234  close(fd);
235  return -1;
236  }
237 
238  close(fd);
239  return ifr.ifr_curcap;
240 }
241 #endif
242 #ifdef SIOCSIFCAP
243 int SetIfaceCaps(const char *ifname, int caps)
244 {
245  struct ifreq ifr;
246 
247  int fd = socket(AF_INET, SOCK_DGRAM, 0);
248  if (fd < 0) {
249  return -1;
250  }
251 
252  memset(&ifr, 0, sizeof(ifr));
253  strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
254  ifr.ifr_reqcap = caps;
255 
256  if (ioctl(fd, SIOCSIFCAP, &ifr) == -1) {
257  SCLogError("%s: unable to set caps: %s", ifname, strerror(errno));
258  close(fd);
259  return -1;
260  }
261 
262  close(fd);
263  return 0;
264 }
265 #endif
266 
267 
268 #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
269 static int GetEthtoolValue(const char *dev, int cmd, uint32_t *value)
270 {
271  struct ifreq ifr;
272  int fd;
273  struct ethtool_value ethv;
274 
275  fd = socket(AF_INET, SOCK_DGRAM, 0);
276  if (fd == -1) {
277  return -1;
278  }
279  (void)strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
280 
281  ethv.cmd = cmd;
282  ifr.ifr_data = (void *) &ethv;
283  if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
284  SCLogWarning("%s: failed to get SIOCETHTOOL ioctl: %s", dev, strerror(errno));
285  close(fd);
286  return -1;
287  }
288 
289  *value = ethv.data;
290  close(fd);
291  return 0;
292 }
293 
294 static int SetEthtoolValue(const char *dev, int cmd, uint32_t value)
295 {
296  struct ifreq ifr;
297  int fd;
298  struct ethtool_value ethv;
299 
300  fd = socket(AF_INET, SOCK_DGRAM, 0);
301  if (fd == -1) {
302  return -1;
303  }
304  (void)strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
305 
306  ethv.cmd = cmd;
307  ethv.data = value;
308  ifr.ifr_data = (void *) &ethv;
309  if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
310  SCLogWarning("%s: failed to set SIOCETHTOOL ioctl: %s", dev, strerror(errno));
311  close(fd);
312  return -1;
313  }
314 
315  close(fd);
316  return 0;
317 }
318 
319 static int GetIfaceOffloadingLinux(const char *dev, int csum, int other)
320 {
321  int ret = 0;
322  uint32_t value = 0;
323 
324  if (csum) {
325  const char *rx = "unset", *tx = "unset";
326  int csum_ret = 0;
327 #ifdef ETHTOOL_GRXCSUM
328  if (GetEthtoolValue(dev, ETHTOOL_GRXCSUM, &value) == 0 && value != 0) {
329  rx = "SET";
330  csum_ret = 1;
331  }
332 #endif
333 #ifdef ETHTOOL_GTXCSUM
334  if (GetEthtoolValue(dev, ETHTOOL_GTXCSUM, &value) == 0 && value != 0) {
335  tx = "SET";
336  csum_ret = 1;
337  }
338 #endif
339  if (csum_ret == 0)
340  SCLogPerf("%s: NIC offloading: RX %s TX %s", dev, rx, tx);
341  else {
342  SCLogWarning("%s: NIC offloading: RX %s TX %s. Run: ethtool -K %s rx off tx off", dev,
343  rx, tx, dev);
344  ret = 1;
345  }
346  }
347 
348  if (other) {
349  const char *lro = "unset", *gro = "unset", *tso = "unset", *gso = "unset";
350  const char *sg = "unset";
351  int other_ret = 0;
352 #ifdef ETHTOOL_GGRO
353  if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) {
354  gro = "SET";
355  other_ret = 1;
356  }
357 #endif
358 #ifdef ETHTOOL_GTSO
359  if (GetEthtoolValue(dev, ETHTOOL_GTSO, &value) == 0 && value != 0) {
360  tso = "SET";
361  other_ret = 1;
362  }
363 #endif
364 #ifdef ETHTOOL_GGSO
365  if (GetEthtoolValue(dev, ETHTOOL_GGSO, &value) == 0 && value != 0) {
366  gso = "SET";
367  other_ret = 1;
368  }
369 #endif
370 #ifdef ETHTOOL_GSG
371  if (GetEthtoolValue(dev, ETHTOOL_GSG, &value) == 0 && value != 0) {
372  sg = "SET";
373  other_ret = 1;
374  }
375 #endif
376 #ifdef ETHTOOL_GFLAGS
377  if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) {
378  if (value & ETH_FLAG_LRO) {
379  lro = "SET";
380  other_ret = 1;
381  }
382  }
383 #endif
384  if (other_ret == 0) {
385  SCLogPerf("%s: NIC offloading: SG: %s, GRO: %s, LRO: %s, TSO: %s, GSO: %s", dev, sg,
386  gro, lro, tso, gso);
387  } else {
388  SCLogWarning("%s: NIC offloading: SG: %s, GRO: %s, LRO: %s, TSO: %s, GSO: %s. Run: "
389  "ethtool -K %s sg off gro off lro off tso off gso off",
390  dev, sg, gro, lro, tso, gso, dev);
391  ret = 1;
392  }
393  }
394  return ret;
395 }
396 
397 static int DisableIfaceOffloadingLinux(LiveDevice *ldev, int csum, int other)
398 {
399  int ret = 0;
400  uint32_t value = 0;
401 
402  if (ldev == NULL)
403  return -1;
404 
405  const char *dev = ldev->dev;
406 
407  if (csum) {
408 #ifdef ETHTOOL_GRXCSUM
409  if (GetEthtoolValue(dev, ETHTOOL_GRXCSUM, &value) == 0 && value != 0) {
410  SCLogPerf("%s: disabling rxcsum offloading", dev);
411  SetEthtoolValue(dev, ETHTOOL_SRXCSUM, 0);
413  }
414 #endif
415 #ifdef ETHTOOL_GTXCSUM
416  if (GetEthtoolValue(dev, ETHTOOL_GTXCSUM, &value) == 0 && value != 0) {
417  SCLogPerf("%s: disabling txcsum offloading", dev);
418  SetEthtoolValue(dev, ETHTOOL_STXCSUM, 0);
420  }
421 #endif
422  }
423  if (other) {
424 #ifdef ETHTOOL_GGRO
425  if (GetEthtoolValue(dev, ETHTOOL_GGRO, &value) == 0 && value != 0) {
426  SCLogPerf("%s: disabling gro offloading", dev);
427  SetEthtoolValue(dev, ETHTOOL_SGRO, 0);
429  }
430 #endif
431 #ifdef ETHTOOL_GTSO
432  if (GetEthtoolValue(dev, ETHTOOL_GTSO, &value) == 0 && value != 0) {
433  SCLogPerf("%s: disabling tso offloading", dev);
434  SetEthtoolValue(dev, ETHTOOL_STSO, 0);
436  }
437 #endif
438 #ifdef ETHTOOL_GGSO
439  if (GetEthtoolValue(dev, ETHTOOL_GGSO, &value) == 0 && value != 0) {
440  SCLogPerf("%s: disabling gso offloading", dev);
441  SetEthtoolValue(dev, ETHTOOL_SGSO, 0);
443  }
444 #endif
445 #ifdef ETHTOOL_GSG
446  if (GetEthtoolValue(dev, ETHTOOL_GSG, &value) == 0 && value != 0) {
447  SCLogPerf("%s: disabling sg offloading", dev);
448  SetEthtoolValue(dev, ETHTOOL_SSG, 0);
449  ldev->offload_orig |= OFFLOAD_FLAG_SG;
450  }
451 #endif
452 #ifdef ETHTOOL_GFLAGS
453  if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) {
454  if (value & ETH_FLAG_LRO) {
455  SCLogPerf("%s: disabling lro offloading", dev);
456  SetEthtoolValue(dev, ETHTOOL_SFLAGS, value & ~ETH_FLAG_LRO);
458  }
459  }
460 #endif
461  }
462  return ret;
463 }
464 
465 static int RestoreIfaceOffloadingLinux(LiveDevice *ldev)
466 {
467  if (ldev == NULL)
468  return -1;
469 
470  const char *dev = ldev->dev;
471 
472 #ifdef ETHTOOL_GRXCSUM
473  if (ldev->offload_orig & OFFLOAD_FLAG_RXCSUM) {
474  SCLogPerf("%s: restoring rxcsum offloading", dev);
475  SetEthtoolValue(dev, ETHTOOL_SRXCSUM, 1);
476  }
477 #endif
478 #ifdef ETHTOOL_GTXCSUM
479  if (ldev->offload_orig & OFFLOAD_FLAG_TXCSUM) {
480  SCLogPerf("%s: restoring txcsum offloading", dev);
481  SetEthtoolValue(dev, ETHTOOL_STXCSUM, 1);
482  }
483 #endif
484 #ifdef ETHTOOL_GGRO
485  if (ldev->offload_orig & OFFLOAD_FLAG_GRO) {
486  SCLogPerf("%s: restoring gro offloading", dev);
487  SetEthtoolValue(dev, ETHTOOL_SGRO, 1);
488  }
489 #endif
490 #ifdef ETHTOOL_GTSO
491  if (ldev->offload_orig & OFFLOAD_FLAG_TSO) {
492  SCLogPerf("%s: restoring tso offloading", dev);
493  SetEthtoolValue(dev, ETHTOOL_STSO, 1);
494  }
495 #endif
496 #ifdef ETHTOOL_GGSO
497  if (ldev->offload_orig & OFFLOAD_FLAG_GSO) {
498  SCLogPerf("%s: restoring gso offloading", dev);
499  SetEthtoolValue(dev, ETHTOOL_SGSO, 1);
500  }
501 #endif
502 #ifdef ETHTOOL_GSG
503  if (ldev->offload_orig & OFFLOAD_FLAG_SG) {
504  SCLogPerf("%s: restoring sg offloading", dev);
505  SetEthtoolValue(dev, ETHTOOL_SSG, 1);
506  }
507 #endif
508 #ifdef ETHTOOL_GFLAGS
509  if (ldev->offload_orig & OFFLOAD_FLAG_LRO) {
510  uint32_t value = 0;
511  if (GetEthtoolValue(dev, ETHTOOL_GFLAGS, &value) == 0) {
512  SCLogPerf("%s: restoring lro offloading", dev);
513  SetEthtoolValue(dev, ETHTOOL_SFLAGS, value & ETH_FLAG_LRO);
514  }
515  }
516 #endif
517  return 0;
518 }
519 
520 #endif /* defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL */
521 
522 #ifdef SIOCGIFCAP
523 static int GetIfaceOffloadingBSD(const char *ifname)
524 {
525  int ret = 0;
526  int if_caps = GetIfaceCaps(ifname);
527  if (if_caps == -1) {
528  return -1;
529  }
530  SCLogDebug("if_caps %X", if_caps);
531 
532  if (if_caps & IFCAP_RXCSUM) {
533  SCLogWarning("%s: RXCSUM activated can lead to capture problems. Run: ifconfig %s -rxcsum",
534  ifname, ifname);
535  ret = 1;
536  }
537 #ifdef IFCAP_TOE
538  if (if_caps & (IFCAP_TSO|IFCAP_TOE|IFCAP_LRO)) {
539  SCLogWarning("%s: TSO, TOE or LRO activated can lead to capture problems. Run: ifconfig %s "
540  "-tso -toe -lro",
541  ifname, ifname);
542  ret = 1;
543  }
544 #else
545  if (if_caps & (IFCAP_TSO|IFCAP_LRO)) {
546  SCLogWarning(
547  "%s: TSO or LRO activated can lead to capture problems. Run: ifconfig %s -tso -lro",
548  ifname, ifname);
549  ret = 1;
550  }
551 #endif
552  return ret;
553 }
554 #endif
555 
556 #ifdef SIOCSIFCAP
557 static int DisableIfaceOffloadingBSD(LiveDevice *ldev)
558 {
559  int ret = 0;
560 
561  if (ldev == NULL)
562  return -1;
563 
564  const char *ifname = ldev->dev;
565  int if_caps = GetIfaceCaps(ifname);
566  int set_caps = if_caps;
567  if (if_caps == -1) {
568  return -1;
569  }
570  SCLogDebug("if_caps %X", if_caps);
571 
572  if (if_caps & IFCAP_RXCSUM) {
573  SCLogPerf("%s: disabling rxcsum offloading", ifname);
574  set_caps &= ~IFCAP_RXCSUM;
575  }
576  if (if_caps & IFCAP_TXCSUM) {
577  SCLogPerf("%s: disabling txcsum offloading", ifname);
578  set_caps &= ~IFCAP_TXCSUM;
579  }
580 #ifdef IFCAP_RXCSUM_IPV6
581  if (if_caps & IFCAP_RXCSUM_IPV6) {
582  SCLogPerf("%s: disabling rxcsum6 offloading", ifname);
583  set_caps &= ~IFCAP_RXCSUM_IPV6;
584  }
585 #endif
586 #ifdef IFCAP_TXCSUM_IPV6
587  if (if_caps & IFCAP_TXCSUM_IPV6) {
588  SCLogPerf("%s: disabling txcsum6 offloading", ifname);
589  set_caps &= ~IFCAP_TXCSUM_IPV6;
590  }
591 #endif
592 #ifdef IFCAP_TOE
593  if (if_caps & (IFCAP_TSO|IFCAP_TOE|IFCAP_LRO)) {
594  SCLogPerf("%s: disabling tso|toe|lro offloading", ifname);
595  set_caps &= ~(IFCAP_TSO|IFCAP_LRO);
596  }
597 #else
598  if (if_caps & (IFCAP_TSO|IFCAP_LRO)) {
599  SCLogPerf("%s: disabling tso|lro offloading", ifname);
600  set_caps &= ~(IFCAP_TSO|IFCAP_LRO);
601  }
602 #endif
603  if (set_caps != if_caps) {
604  if (if_caps & IFCAP_RXCSUM)
606  if (if_caps & IFCAP_TSO)
608 #ifdef IFCAP_TOE
609  if (if_caps & IFCAP_TOE)
611 #endif
612  if (if_caps & IFCAP_LRO)
614 
615  SetIfaceCaps(ifname, set_caps);
616  }
617  return ret;
618 }
619 
620 static int RestoreIfaceOffloadingBSD(LiveDevice *ldev)
621 {
622  int ret = 0;
623 
624  if (ldev == NULL)
625  return -1;
626 
627  const char *ifname = ldev->dev;
628  int if_caps = GetIfaceCaps(ifname);
629  int set_caps = if_caps;
630  if (if_caps == -1) {
631  return -1;
632  }
633  SCLogDebug("if_caps %X", if_caps);
634 
635  if (ldev->offload_orig & OFFLOAD_FLAG_RXCSUM) {
636  SCLogPerf("%s: restoring rxcsum offloading", ifname);
637  set_caps |= IFCAP_RXCSUM;
638  }
639  if (ldev->offload_orig & OFFLOAD_FLAG_TSO) {
640  SCLogPerf("%s: restoring tso offloading", ifname);
641  set_caps |= IFCAP_TSO;
642  }
643 #ifdef IFCAP_TOE
644  if (ldev->offload_orig & OFFLOAD_FLAG_TOE) {
645  SCLogPerf("%s: restoring toe offloading", ifname);
646  set_caps |= IFCAP_TOE;
647  }
648 #endif
649  if (ldev->offload_orig & OFFLOAD_FLAG_LRO) {
650  SCLogPerf("%s: restoring lro offloading", ifname);
651  set_caps |= IFCAP_LRO;
652  }
653 
654  if (set_caps != if_caps) {
655  SetIfaceCaps(ifname, set_caps);
656  }
657  return ret;
658 }
659 #endif
660 
661 /**
662  * \brief output offloading status of the link
663  *
664  * Test interface for offloading features. If one of them is
665  * activated then suricata mays received packets merge at reception.
666  * The result is oversized packets and this may cause some serious
667  * problem in some capture mode where the size of the packet is
668  * limited (AF_PACKET in V2 more for example).
669  *
670  * \param Name of link
671  * \param csum check if checksums are offloaded
672  * \param other check if other things are offloaded: TSO, GRO, etc.
673  * \retval -1 in case of error, 0 if none, 1 if some
674  */
675 int GetIfaceOffloading(const char *dev, int csum, int other)
676 {
677 #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
678  return GetIfaceOffloadingLinux(dev, csum, other);
679 #elif defined SIOCGIFCAP
680  return GetIfaceOffloadingBSD(dev);
681 #elif defined OS_WIN32
682  return GetIfaceOffloadingWin32(dev, csum, other);
683 #else
684  return 0;
685 #endif
686 }
687 
688 int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
689 {
690  /* already set */
691  if (dev->offload_orig != 0)
692  return 0;
693 #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
694  return DisableIfaceOffloadingLinux(dev, csum, other);
695 #elif defined SIOCSIFCAP
696  return DisableIfaceOffloadingBSD(dev);
697 #elif defined OS_WIN32
698  return DisableIfaceOffloadingWin32(dev, csum, other);
699 #else
700  return 0;
701 #endif
702 
703 }
704 
706 {
707  if (dev->offload_orig != 0) {
708 #if defined HAVE_LINUX_ETHTOOL_H && defined SIOCETHTOOL
709  RestoreIfaceOffloadingLinux(dev);
710 #elif defined SIOCSIFCAP
711  RestoreIfaceOffloadingBSD(dev);
712 #elif defined OS_WIN32
713  RestoreIfaceOffloadingWin32(dev);
714 #endif
715  }
716 }
717 
718 int GetIfaceRSSQueuesNum(const char *dev)
719 {
720 #if defined HAVE_LINUX_ETHTOOL_H && defined ETHTOOL_GRXRINGS
721  struct ifreq ifr;
722  struct ethtool_rxnfc nfccmd;
723  int fd;
724 
725  (void)strlcpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name));
726  fd = socket(AF_INET, SOCK_DGRAM, 0);
727  if (fd == -1) {
728  SCLogWarning("%s: failed to open socket for ioctl: %s", dev, strerror(errno));
729  return -1;
730  }
731 
732  nfccmd.cmd = ETHTOOL_GRXRINGS;
733  ifr.ifr_data = (void*) &nfccmd;
734 
735  if (ioctl(fd, SIOCETHTOOL, (char *)&ifr) < 0) {
736  if (errno != ENOTSUP) {
737  SCLogWarning("%s: failed get number of RSS queue ioctl: %s", dev, strerror(errno));
738  }
739  close(fd);
740  return 0;
741  }
742  close(fd);
743  SCLogInfo("%s: RX RSS queues: %d", dev, (int)nfccmd.data);
744  return (int)nfccmd.data;
745 #else
746  return 0;
747 #endif
748 }
win32-syscall.h
SLL_HEADER_LEN
#define SLL_HEADER_LEN
Definition: decode-sll.h:27
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
LiveDevice_
Definition: util-device.h:39
OFFLOAD_FLAG_TOE
#define OFFLOAD_FLAG_TOE
Definition: util-device.h:30
OFFLOAD_FLAG_TSO
#define OFFLOAD_FLAG_TSO
Definition: util-device.h:24
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
GetIfaceMaxPacketSize
int GetIfaceMaxPacketSize(const char *pcap_dev)
output max packet size for a link
Definition: util-ioctl.c:130
decode.h
GetIfaceRSSQueuesNum
int GetIfaceRSSQueuesNum(const char *dev)
Definition: util-ioctl.c:718
RestoreIfaceOffloading
void RestoreIfaceOffloading(LiveDevice *dev)
Definition: util-ioctl.c:705
LiveDevice_::dev
char * dev
Definition: util-device.h:40
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
decode-sll.h
ETHERNET_HEADER_LEN
#define ETHERNET_HEADER_LEN
Definition: decode-ethernet.h:27
conf.h
LiveDevice_::offload_orig
uint32_t offload_orig
Definition: util-device.h:53
GetIfaceOffloading
int GetIfaceOffloading(const char *dev, int csum, int other)
output offloading status of the link
Definition: util-ioctl.c:675
DisableIfaceOffloading
int DisableIfaceOffloading(LiveDevice *dev, int csum, int other)
Definition: util-ioctl.c:688
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
OFFLOAD_FLAG_GSO
#define OFFLOAD_FLAG_GSO
Definition: util-device.h:25
OFFLOAD_FLAG_SG
#define OFFLOAD_FLAG_SG
Definition: util-device.h:23
flags
uint8_t flags
Definition: decode-gre.h:0
suricata-common.h
OFFLOAD_FLAG_GRO
#define OFFLOAD_FLAG_GRO
Definition: util-device.h:26
SCLogPerf
#define SCLogPerf(...)
Definition: util-debug.h:230
OFFLOAD_FLAG_LRO
#define OFFLOAD_FLAG_LRO
Definition: util-device.h:27
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
util-ioctl.h
OFFLOAD_FLAG_RXCSUM
#define OFFLOAD_FLAG_RXCSUM
Definition: util-device.h:28
OFFLOAD_FLAG_TXCSUM
#define OFFLOAD_FLAG_TXCSUM
Definition: util-device.h:29
GetIfaceMTU
int GetIfaceMTU(const char *pcap_dev)
output the link MTU
Definition: util-ioctl.c:91