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