blob: 09e504d7998fd1421b9c4ff99e681e3e0d8845c1 [file] [log] [blame]
Jerome Stanislaus597482d2016-03-04 14:08:46 -07001/************************************************************************
2Copyright (c) 2016, The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28************************************************************************/
29
30/**
31 * @file datatop_ip_table_poll.c
32 * @brief Adds ability for TP Tables, Rules and Routes data collection
33 Unlike other polls, this is intended for running as a separate
34 thread as it can cause delays of > 3sec per poll
35 *
36 */
37
38#include <stdio.h>
39#include <string.h>
40#include <stdlib.h>
41#include <unistd.h>
42#include <time.h>
43#include <pthread.h>
44#include "datatop_interface.h"
45#include "datatop_fileops.h"
46#include "datatop_str.h"
47#include "datatop_polling.h"
48
49#define DTOP_IPTRR_POLL_PERIOD 5.00
50
51/**
52* @struct dtop_ip_table_vars
53* @brief Struct used to hold necessary variables for /proc/stat dpg
54*
55* @var dtop_ip_table_vars::line
56* Array of strings where necessary dp names and values are held.
57* @var dtop_ip_table_vars::line_count
58* Number of lines the file is that the dpg represents.
59*/
60struct dtop_ip_table_vars {
61 char *out_dir;
62}dtop_ip_table_storage;
63
64struct dtop_linked_list *ip_dpg_list = NULL;
65
66pthread_mutex_t dtop_ip_table_lock;
67
68/**
69 * @brief Perform IP table command and store it in a file
70 *
71 * @param dpg Struct that polled data is added to.
72 * @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
73 * @return DTOP_POLL_OK - Poll of dpg successful.
74 */
75int dtop_ip_table_poll(struct dtop_data_point_gatherer *dpg)
76{
77 FILE *fd;
78 FILE *fo = (FILE *)dpg->file;
79 char buf[1001];
80
81 time_t rawtime;
82 struct tm * timeinfo;
83
84 if(fo == NULL)
85 {
86 fprintf(stderr, "Could not fopen: %s\n", dpg->file);
87 return DTOP_POLL_IO_ERR;
88 }
89
90 time ( &rawtime );
91 timeinfo = gmtime ( &rawtime );
92
93 fprintf ( fo, "============\nStart: %s==========\n", asctime (timeinfo) );
94 fflush(fo);
95
96 /* redirect stderr to output file */
97 dup2(fileno(fo), 2);
98
99 fd = popen((char *)dpg->priv, "r");
100 if(fd == NULL)
101 {
102 fprintf(stderr, "Could not popen: %s\n", (char *)dpg->priv);
103 return DTOP_POLL_IO_ERR;
104 }
105
106 while(fgets(buf, 1000, fd) != NULL)
107 {
108 fputs(buf, fo);
109 }
110
111 fprintf ( fo, "============\nEnd: %s==========\n\n", asctime (timeinfo) );
112 fflush(fo);
113 pclose(fd);
114 return DTOP_POLL_OK;
115}
116
117/**
118 * @brief Frees dynamically allocated IP table dpg.
119 *
120 * Frees the memory of the dpg along with it's data_points
121 * and other malloc'd memory no longer needed.
122 *
123 * @param dpg Dpg to deconstruct and deallocate memory for.
124 */
125static void dtop_ip_table_dpg_deconstructor
126 (struct dtop_data_point_gatherer *dpset)
127{
Jerome Stanislaus597482d2016-03-04 14:08:46 -0700128 free(dpset->prefix);
129 if(dpset->file)
130 {
131 fclose((FILE *)dpset->file);
132 }
133
134 free(dpset);
135}
136
137/**
138 * @brief Registers a new IP table dpg to the list.
139 *
140 * @param dpg Dpg to construct and allocate memory for.
141 */
142void dtop_ip_table_register(struct dtop_data_point_gatherer *dpg)
143{
144 if (dpg)
145 ip_dpg_list = dtop_add_linked_list(dpg, ip_dpg_list);
146}
147
148/**
149 * @brief Open the files for writing the output for each dpg.
150 *
151 * @param None
152 */
153int dtop_ip_table_init_files()
154{
155 struct dtop_data_point_gatherer *dpset;
156 struct dtop_linked_list *curr_ptr = ip_dpg_list;
157 FILE *fd;
158
159 while(curr_ptr)
160 {
161 dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
162 fd = fopen(dpset->prefix, "a+");
163 if(!fd)
164 {
165 fprintf(stderr, "Could not fopen: %s\n", dpset->prefix);
166 return DTOP_POLL_IO_ERR;
167 }
168 dpset->file = (char *)fd;
169 curr_ptr = curr_ptr->next_ptr;
170 }
171 return DTOP_POLL_OK;
172}
173
174/**
175 * @brief Perform cleanup of IP table dgp list at exit.
176 *
177 * @param None
178 */
179void dtop_ip_table_poll_cleanup()
180{
Jerome Stanislaus597482d2016-03-04 14:08:46 -0700181 pthread_mutex_lock(&dtop_ip_table_lock);
182 deconstruct_dpgs(ip_dpg_list);
183 dtop_rem_linked_list(ip_dpg_list);
184 pthread_mutex_unlock(&dtop_ip_table_lock);
185
186}
187
188/**
189 * @brief The thread to poll for IP table data.
190 *
191 * @param arg ptr
192 */
193void *dtop_ip_table_start_poll(void *arg)
194{
195 time_t start_t, curr_t;
196 double diff_t = 9999999.00; /* some high # > DTOP_IPTRR_POLL_PERIOD */
197 int ret = DTOP_POLL_OK;
198
Sean Tranchetti48ccbdb2018-04-03 15:18:51 -0600199 (void) arg;
200
Jerome Stanislaus597482d2016-03-04 14:08:46 -0700201 if (pthread_mutex_init(&dtop_ip_table_lock, NULL) != 0)
202 {
203 printf("\n mutex init failed\n");
204 return NULL;
205 }
206
207 atexit(dtop_ip_table_poll_cleanup);
208
209 if(DTOP_POLL_OK != ( ret = dtop_ip_table_init_files()))
210 {
211 return NULL;
212 }
213
214 while(1)
215 {
216 struct dtop_linked_list *curr_ptr = ip_dpg_list;
217 struct dtop_data_point_gatherer *dpset;
218
219 pthread_mutex_lock(&dtop_ip_table_lock);
220
221 if (diff_t >= DTOP_IPTRR_POLL_PERIOD)
222 {
223 printf("Poll for IP Tables, Rules & Routes\n");
224 time(&start_t);
225 while (curr_ptr)
226 {
227 dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
228 dpset->poll(dpset);
229 curr_ptr = curr_ptr->next_ptr;
230 }
231 }
232 pthread_mutex_unlock(&dtop_ip_table_lock);
233
234 /* sleep for 500 milliseconds */
235 usleep(500 * 1000);
236 time(&curr_t);
237 diff_t = difftime(curr_t, start_t);
238 }
239 return NULL;
240}
241
242/**
243 * @brief Creates a dpg for ip table command
244 *
245 * Dynamically allocates memory for dpg which is then added to a linked list
246 * via the dtop_register(dpg) function call.
247 *
248 * @param data_points dtop_data_point struct that dpg points to.
249 * @param storage dtop_ip_table_vars struct that holds relevant dpg variables.
250 */
251/*static void construct_ip_table_dpg(struct dtop_data_point
252 *data_points, struct dtop_ip_table_vars *command, int dp_count)
253*/
254static void construct_ip_table_dpg(char *command)
255{
256 struct dtop_data_point_gatherer *dpg = malloc
257 (sizeof(struct dtop_data_point_gatherer));
258 char *file_name = (char *)malloc(strlen(command)+ 1 + 1 + strlen(dtop_ip_table_storage.out_dir) + 4);
259 int i, fname_start_ind;
260
261 strcpy(file_name, dtop_ip_table_storage.out_dir);
262 strcat(file_name, "/");
263
264 fname_start_ind = strlen(file_name);
265 strcat(file_name, command);
266 strcat(file_name, ".txt");
267
268 for(i=fname_start_ind; file_name[i]; i++)
269 {
270 if(file_name[i] == ' ')
271 file_name[i] = '_';
272 if(file_name[i] == '/')
273 file_name[i] = '-';
274 }
275
276 dpg->prefix = file_name;
277 dpg->poll = dtop_ip_table_poll;
278 dpg->priv = (char *)command;
279 dpg->file = NULL;
280 dpg->deconstruct = dtop_ip_table_dpg_deconstructor;
281
282 dtop_ip_table_register(dpg);
283}
284
285/*
286 * @brief Scans "/proc/stat" in order to autodetect dps.
287 *
288 * Searches through "/proc/stat" file for all available data
289 * points to create as dp structs.
290 *
291 * @param storage dtop_ip_table_vars struct where relevant variables are stored.
292 */
293
294/**
295 * @brief Calls dtop_search for "/proc/stat" file.
296 */
297void dtop_ip_table_init(char *out_dir)
298{
299 dtop_ip_table_storage.out_dir = out_dir;
300 construct_ip_table_dpg("ip xfrm state show");
301 construct_ip_table_dpg("ip xfrm policy show");
302 construct_ip_table_dpg("ip addr");
303 construct_ip_table_dpg("iptables -t raw -L -n -v");
304 construct_ip_table_dpg("iptables -t mangle -L -n -v");
305 construct_ip_table_dpg("iptables -L -n -v");
306 construct_ip_table_dpg("iptables -t nat -L -n -v");
307 construct_ip_table_dpg("ip6tables -t raw -L -n -v");
308 construct_ip_table_dpg("ip6tables -t mangle -L -n -v");
309 construct_ip_table_dpg("ip6tables -L -n -v");
310 construct_ip_table_dpg("ip6tables -t nat -L -n -v");
311 construct_ip_table_dpg("ip rule show");
312 construct_ip_table_dpg("ip -6 rule show");
313 construct_ip_table_dpg("ip route show table all");
314 construct_ip_table_dpg("ip -6 route show table all");
315 construct_ip_table_dpg("ip route show table rmnet_data0");
316 construct_ip_table_dpg("ip route show table rmnet_data1");
317 construct_ip_table_dpg("ip route show table rmnet_data2");
318 construct_ip_table_dpg("ip route show table rmnet_data6");
319 construct_ip_table_dpg("ip route show table rmnet_data7");
320 construct_ip_table_dpg("ip route show table r_rmnet_data0");
321 construct_ip_table_dpg("ip route show table r_rmnet_data1");
322 construct_ip_table_dpg("ip route show table r_rmnet_data2");
323 construct_ip_table_dpg("ip route show table r_rmnet_data6");
324 construct_ip_table_dpg("ip route show table r_rmnet_data7");
325 construct_ip_table_dpg("ip -6 route show table rmnet_data0");
326 construct_ip_table_dpg("ip -6 route show table rmnet_data1");
327 construct_ip_table_dpg("ip -6 route show table rmnet_data2");
328 construct_ip_table_dpg("ip -6 route show table rmnet_data6");
329 construct_ip_table_dpg("ip -6 route show table rmnet_data7");
330 construct_ip_table_dpg("ip -6 route show table r_rmnet_data0");
331 construct_ip_table_dpg("ip -6 route show table r_rmnet_data1");
332 construct_ip_table_dpg("ip -6 route show table r_rmnet_data2");
333 construct_ip_table_dpg("ip -6 route show table r_rmnet_data6");
334 construct_ip_table_dpg("ip -6 route show table r_rmnet_data7");
335 construct_ip_table_dpg("ip route show table wlan0");
336 construct_ip_table_dpg("ip -6 route show table wlan0");
337 construct_ip_table_dpg("ip route show table dummy0");
338 construct_ip_table_dpg("ip -6 route show table dummy0");
339 construct_ip_table_dpg("cat /proc/net/xfrm_stat");
340 construct_ip_table_dpg("cat /proc/sys/net/ipv4/ip_forward");
341 construct_ip_table_dpg("cat /proc/sys/net/ipv6/conf/all/forwarding");
342
343 printf("Poll for IP Tables, Rules & Routes every 5 seconds\n");
344}