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