summaryrefslogtreecommitdiffstats
path: root/datatop/src/datatop_ip_table_poll.c
diff options
context:
space:
mode:
Diffstat (limited to 'datatop/src/datatop_ip_table_poll.c')
-rw-r--r--datatop/src/datatop_ip_table_poll.c346
1 files changed, 346 insertions, 0 deletions
diff --git a/datatop/src/datatop_ip_table_poll.c b/datatop/src/datatop_ip_table_poll.c
new file mode 100644
index 0000000..980eb4c
--- /dev/null
+++ b/datatop/src/datatop_ip_table_poll.c
@@ -0,0 +1,346 @@
+/************************************************************************
+Copyright (c) 2016, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+************************************************************************/
+
+/**
+ * @file datatop_ip_table_poll.c
+ * @brief Adds ability for TP Tables, Rules and Routes data collection
+ Unlike other polls, this is intended for running as a separate
+ thread as it can cause delays of > 3sec per poll
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <pthread.h>
+#include "datatop_interface.h"
+#include "datatop_fileops.h"
+#include "datatop_str.h"
+#include "datatop_polling.h"
+
+#define DTOP_IPTRR_POLL_PERIOD 5.00
+
+/**
+* @struct dtop_ip_table_vars
+* @brief Struct used to hold necessary variables for /proc/stat dpg
+*
+* @var dtop_ip_table_vars::line
+* Array of strings where necessary dp names and values are held.
+* @var dtop_ip_table_vars::line_count
+* Number of lines the file is that the dpg represents.
+*/
+struct dtop_ip_table_vars {
+ char *out_dir;
+}dtop_ip_table_storage;
+
+struct dtop_linked_list *ip_dpg_list = NULL;
+
+pthread_mutex_t dtop_ip_table_lock;
+
+/**
+ * @brief Perform IP table command and store it in a file
+ *
+ * @param dpg Struct that polled data is added to.
+ * @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
+ * @return DTOP_POLL_OK - Poll of dpg successful.
+ */
+int dtop_ip_table_poll(struct dtop_data_point_gatherer *dpg)
+{
+ FILE *fd;
+ FILE *fo = (FILE *)dpg->file;
+ char buf[1001];
+
+ time_t rawtime;
+ struct tm * timeinfo;
+
+ if(fo == NULL)
+ {
+ fprintf(stderr, "Could not fopen: %s\n", dpg->file);
+ return DTOP_POLL_IO_ERR;
+ }
+
+ time ( &rawtime );
+ timeinfo = gmtime ( &rawtime );
+
+ fprintf ( fo, "============\nStart: %s==========\n", asctime (timeinfo) );
+ fflush(fo);
+
+ /* redirect stderr to output file */
+ dup2(fileno(fo), 2);
+
+ fd = popen((char *)dpg->priv, "r");
+ if(fd == NULL)
+ {
+ fprintf(stderr, "Could not popen: %s\n", (char *)dpg->priv);
+ return DTOP_POLL_IO_ERR;
+ }
+
+ while(fgets(buf, 1000, fd) != NULL)
+ {
+ fputs(buf, fo);
+ }
+
+ fprintf ( fo, "============\nEnd: %s==========\n\n", asctime (timeinfo) );
+ fflush(fo);
+ pclose(fd);
+ return DTOP_POLL_OK;
+}
+
+/**
+ * @brief Frees dynamically allocated IP table dpg.
+ *
+ * Frees the memory of the dpg along with it's data_points
+ * and other malloc'd memory no longer needed.
+ *
+ * @param dpg Dpg to deconstruct and deallocate memory for.
+ */
+static void dtop_ip_table_dpg_deconstructor
+ (struct dtop_data_point_gatherer *dpset)
+{
+ int i;
+ free(dpset->prefix);
+ if(dpset->file)
+ {
+ fclose((FILE *)dpset->file);
+ }
+
+ free(dpset);
+}
+
+/**
+ * @brief Registers a new IP table dpg to the list.
+ *
+ * @param dpg Dpg to construct and allocate memory for.
+ */
+void dtop_ip_table_register(struct dtop_data_point_gatherer *dpg)
+{
+ if (dpg)
+ ip_dpg_list = dtop_add_linked_list(dpg, ip_dpg_list);
+}
+
+/**
+ * @brief Open the files for writing the output for each dpg.
+ *
+ * @param None
+ */
+int dtop_ip_table_init_files()
+{
+ struct dtop_data_point_gatherer *dpset;
+ struct dtop_linked_list *curr_ptr = ip_dpg_list;
+ FILE *fd;
+
+ while(curr_ptr)
+ {
+ dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
+ fd = fopen(dpset->prefix, "a+");
+ if(!fd)
+ {
+ fprintf(stderr, "Could not fopen: %s\n", dpset->prefix);
+ return DTOP_POLL_IO_ERR;
+ }
+ dpset->file = (char *)fd;
+ curr_ptr = curr_ptr->next_ptr;
+ }
+ return DTOP_POLL_OK;
+}
+
+/**
+ * @brief Perform cleanup of IP table dgp list at exit.
+ *
+ * @param None
+ */
+void dtop_ip_table_poll_cleanup()
+{
+ struct dtop_data_point_gatherer *dpset;
+ struct dtop_linked_list *curr_ptr = ip_dpg_list;
+
+ pthread_mutex_lock(&dtop_ip_table_lock);
+ deconstruct_dpgs(ip_dpg_list);
+ dtop_rem_linked_list(ip_dpg_list);
+ pthread_mutex_unlock(&dtop_ip_table_lock);
+
+}
+
+/**
+ * @brief The thread to poll for IP table data.
+ *
+ * @param arg ptr
+ */
+void *dtop_ip_table_start_poll(void *arg)
+{
+ time_t start_t, curr_t;
+ double diff_t = 9999999.00; /* some high # > DTOP_IPTRR_POLL_PERIOD */
+ int ret = DTOP_POLL_OK;
+
+ if (pthread_mutex_init(&dtop_ip_table_lock, NULL) != 0)
+ {
+ printf("\n mutex init failed\n");
+ return NULL;
+ }
+
+ atexit(dtop_ip_table_poll_cleanup);
+
+ if(DTOP_POLL_OK != ( ret = dtop_ip_table_init_files()))
+ {
+ return NULL;
+ }
+
+ while(1)
+ {
+ struct dtop_linked_list *curr_ptr = ip_dpg_list;
+ struct dtop_data_point_gatherer *dpset;
+
+ pthread_mutex_lock(&dtop_ip_table_lock);
+
+ if (diff_t >= DTOP_IPTRR_POLL_PERIOD)
+ {
+ printf("Poll for IP Tables, Rules & Routes\n");
+ time(&start_t);
+ while (curr_ptr)
+ {
+ dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
+ dpset->poll(dpset);
+ curr_ptr = curr_ptr->next_ptr;
+ }
+ }
+ pthread_mutex_unlock(&dtop_ip_table_lock);
+
+ /* sleep for 500 milliseconds */
+ usleep(500 * 1000);
+ time(&curr_t);
+ diff_t = difftime(curr_t, start_t);
+ }
+ return NULL;
+}
+
+/**
+ * @brief Creates a dpg for ip table command
+ *
+ * Dynamically allocates memory for dpg which is then added to a linked list
+ * via the dtop_register(dpg) function call.
+ *
+ * @param data_points dtop_data_point struct that dpg points to.
+ * @param storage dtop_ip_table_vars struct that holds relevant dpg variables.
+ */
+/*static void construct_ip_table_dpg(struct dtop_data_point
+ *data_points, struct dtop_ip_table_vars *command, int dp_count)
+*/
+static void construct_ip_table_dpg(char *command)
+{
+ struct dtop_data_point_gatherer *dpg = malloc
+ (sizeof(struct dtop_data_point_gatherer));
+ char *file_name = (char *)malloc(strlen(command)+ 1 + 1 + strlen(dtop_ip_table_storage.out_dir) + 4);
+ int i, fname_start_ind;
+
+ strcpy(file_name, dtop_ip_table_storage.out_dir);
+ strcat(file_name, "/");
+
+ fname_start_ind = strlen(file_name);
+ strcat(file_name, command);
+ strcat(file_name, ".txt");
+
+ for(i=fname_start_ind; file_name[i]; i++)
+ {
+ if(file_name[i] == ' ')
+ file_name[i] = '_';
+ if(file_name[i] == '/')
+ file_name[i] = '-';
+ }
+
+ dpg->prefix = file_name;
+ dpg->poll = dtop_ip_table_poll;
+ dpg->priv = (char *)command;
+ dpg->file = NULL;
+ dpg->deconstruct = dtop_ip_table_dpg_deconstructor;
+
+ dtop_ip_table_register(dpg);
+}
+
+/*
+ * @brief Scans "/proc/stat" in order to autodetect dps.
+ *
+ * Searches through "/proc/stat" file for all available data
+ * points to create as dp structs.
+ *
+ * @param storage dtop_ip_table_vars struct where relevant variables are stored.
+ */
+
+/**
+ * @brief Calls dtop_search for "/proc/stat" file.
+ */
+void dtop_ip_table_init(char *out_dir)
+{
+ dtop_ip_table_storage.out_dir = out_dir;
+ construct_ip_table_dpg("ip xfrm state show");
+ construct_ip_table_dpg("ip xfrm policy show");
+ construct_ip_table_dpg("ip addr");
+ construct_ip_table_dpg("iptables -t raw -L -n -v");
+ construct_ip_table_dpg("iptables -t mangle -L -n -v");
+ construct_ip_table_dpg("iptables -L -n -v");
+ construct_ip_table_dpg("iptables -t nat -L -n -v");
+ construct_ip_table_dpg("ip6tables -t raw -L -n -v");
+ construct_ip_table_dpg("ip6tables -t mangle -L -n -v");
+ construct_ip_table_dpg("ip6tables -L -n -v");
+ construct_ip_table_dpg("ip6tables -t nat -L -n -v");
+ construct_ip_table_dpg("ip rule show");
+ construct_ip_table_dpg("ip -6 rule show");
+ construct_ip_table_dpg("ip route show table all");
+ construct_ip_table_dpg("ip -6 route show table all");
+ construct_ip_table_dpg("ip route show table rmnet_data0");
+ construct_ip_table_dpg("ip route show table rmnet_data1");
+ construct_ip_table_dpg("ip route show table rmnet_data2");
+ construct_ip_table_dpg("ip route show table rmnet_data6");
+ construct_ip_table_dpg("ip route show table rmnet_data7");
+ construct_ip_table_dpg("ip route show table r_rmnet_data0");
+ construct_ip_table_dpg("ip route show table r_rmnet_data1");
+ construct_ip_table_dpg("ip route show table r_rmnet_data2");
+ construct_ip_table_dpg("ip route show table r_rmnet_data6");
+ construct_ip_table_dpg("ip route show table r_rmnet_data7");
+ construct_ip_table_dpg("ip -6 route show table rmnet_data0");
+ construct_ip_table_dpg("ip -6 route show table rmnet_data1");
+ construct_ip_table_dpg("ip -6 route show table rmnet_data2");
+ construct_ip_table_dpg("ip -6 route show table rmnet_data6");
+ construct_ip_table_dpg("ip -6 route show table rmnet_data7");
+ construct_ip_table_dpg("ip -6 route show table r_rmnet_data0");
+ construct_ip_table_dpg("ip -6 route show table r_rmnet_data1");
+ construct_ip_table_dpg("ip -6 route show table r_rmnet_data2");
+ construct_ip_table_dpg("ip -6 route show table r_rmnet_data6");
+ construct_ip_table_dpg("ip -6 route show table r_rmnet_data7");
+ construct_ip_table_dpg("ip route show table wlan0");
+ construct_ip_table_dpg("ip -6 route show table wlan0");
+ construct_ip_table_dpg("ip route show table dummy0");
+ construct_ip_table_dpg("ip -6 route show table dummy0");
+ construct_ip_table_dpg("cat /proc/net/xfrm_stat");
+ construct_ip_table_dpg("cat /proc/sys/net/ipv4/ip_forward");
+ construct_ip_table_dpg("cat /proc/sys/net/ipv6/conf/all/forwarding");
+
+ printf("Poll for IP Tables, Rules & Routes every 5 seconds\n");
+}