new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / rootcheck / check_rc_if.c
1 /* Copyright (C) 2009 Trend Micro Inc.
2  * All right reserved.
3  *
4  * This program is a free software; you can redistribute it
5  * and/or modify it under the terms of the GNU General Public
6  * License (version 2) as published by the FSF - Free Software
7  * Foundation
8  */
9
10 #ifndef WIN32
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <sys/ioctl.h>
14 #include <net/if.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <string.h>
19
20 #ifdef SOLARIS
21 #include <stropts.h>
22 #include <sys/sockio.h>
23 #endif
24
25 #include "headers/debug_op.h"
26 #include "headers/defs.h"
27 #include "rootcheck.h"
28
29 #ifndef IFCONFIG
30 #define IFCONFIG "ifconfig %s | grep PROMISC > /dev/null 2>&1"
31 #endif
32
33 /* Prototypes */
34 static int run_ifconfig(const char *ifconfig);
35
36
37 /* Execute the ifconfig command
38  * Returns 1 if the interface is in promiscuous mode
39  */
40 static int run_ifconfig(const char *ifconfig)
41 {
42     char nt[OS_SIZE_1024 + 1];
43
44     snprintf(nt, OS_SIZE_1024, IFCONFIG, ifconfig);
45     if (system(nt) == 0) {
46         return (1);
47     }
48
49     return (0);
50 }
51
52 /* Check all interfaces for promiscuous mode */
53 void check_rc_if()
54 {
55     int _fd, _errors = 0, _total = 0;
56     struct ifreq tmp_str[16];
57
58     struct ifconf _if;
59     struct ifreq *_ir;
60     struct ifreq *_ifend;
61     struct ifreq _ifr;
62
63     _fd = socket(AF_INET, SOCK_DGRAM, 0);
64     if (_fd < 0) {
65         merror("%s: Error checking interfaces (socket)", ARGV0);
66         return;
67     }
68
69     memset(tmp_str, 0, sizeof(struct ifreq) * 16);
70     _if.ifc_len = sizeof(tmp_str);
71     _if.ifc_buf = (caddr_t)(tmp_str);
72
73     if (ioctl(_fd, SIOCGIFCONF, &_if) < 0) {
74         close(_fd);
75         merror("%s: Error checking interfaces (ioctl)", ARGV0);
76         return;
77     }
78
79     _ifend = (struct ifreq *) (void *) ((char *)tmp_str + _if.ifc_len);
80     _ir = tmp_str;
81
82     /* Loop over all interfaces */
83     for (; _ir < _ifend; _ir++) {
84         strncpy(_ifr.ifr_name, _ir->ifr_name, sizeof(_ifr.ifr_name));
85
86         /* Get information from each interface */
87         if (ioctl(_fd, SIOCGIFFLAGS, (char *)&_ifr) == -1) {
88             continue;
89         }
90
91         _total++;
92
93         if ((_ifr.ifr_flags & IFF_PROMISC) ) {
94             char op_msg[OS_SIZE_1024 + 1];
95             if (run_ifconfig(_ifr.ifr_name)) {
96                 snprintf(op_msg, OS_SIZE_1024, "Interface '%s' in promiscuous"
97                          " mode.", _ifr.ifr_name);
98                 notify_rk(ALERT_SYSTEM_CRIT, op_msg);
99             } else {
100                 snprintf(op_msg, OS_SIZE_1024, "Interface '%s' in promiscuous"
101                          " mode, but ifconfig is not showing it"
102                          "(probably trojaned).", _ifr.ifr_name);
103                 notify_rk(ALERT_ROOTKIT_FOUND, op_msg);
104             }
105             _errors++;
106         }
107     }
108     close(_fd);
109
110     if (_errors == 0) {
111         char op_msg[OS_SIZE_1024 + 1];
112         snprintf(op_msg, OS_SIZE_1024, "No problem detected on ifconfig/ifs."
113                  " Analyzed %d interfaces.", _total);
114         notify_rk(ALERT_OK, op_msg);
115     }
116
117     return;
118 }
119
120 #else /* WIN32 */
121
122 /* Not implemented on Windows */
123 void check_rc_if()
124 {
125     return;
126 }
127
128 #endif /* WIN32 */
129