Skip to content
Snippets Groups Projects
network.c 3.74 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*
     * Copyright (C) 2024 iopsys Software Solutions AB
     *
     * This program is free software; you can redistribute it and/or modify
     * it under the terms of the GNU Lesser General Public License version 2.1
     * as published by the Free Software Foundation
     *
     *	  Author: Amin Ben Romdhane <amin.benromdhane@iopsys.eu>
     *
     */
    
    #include "utils.h"
    
    #define TCP_WMEM_PATH "/proc/sys/net/ipv4/tcp_wmem"
    #define TCP_CONGESTION_CONTROL_PATH "/proc/sys/net/ipv4/tcp_congestion_control"
    
    /*************************************************************
    * COMMON FUNCTIONS
    **************************************************************/
    static int read_file_content(const char *file_path, char *buffer, size_t buffer_size)
    {
    	int fd = open(file_path, O_RDONLY);
    	if (fd == -1)
    		return -1;
    
    	ssize_t bytes_read = read(fd, buffer, buffer_size - 1);
    	if (bytes_read == -1) {
    		close(fd);
    		return -1;
    	}
    
    	buffer[bytes_read] = '\0';  // Null-terminate the buffer
    	close(fd);
    
    	return 0;
    }
    
    static int read_tcp_write_memory_limits(int *min_size, int *default_size, int *max_size)
    {
    	char buffer[128] = {0};
    
    	// Read TCP memory settings
    	if (read_file_content(TCP_WMEM_PATH, buffer, sizeof(buffer)) == -1)
    		return -1;
    
    	// Parse the memory sizes from the file contents
    	if (sscanf(buffer, "%d %d %d", min_size, default_size, max_size) != 3)
    		return -1;
    
    	return 0;
    }
    
    static int get_supported_congestion_controls(char *output, size_t output_size)
    {
    	const char *delim = " ";
    	char *token, buffer[128];
    	size_t pos = 0;
    
    	// Read available congestion control algorithms
    	if (read_file_content(TCP_CONGESTION_CONTROL_PATH, buffer, sizeof(buffer)) == -1)
    		return -1;
    
    	// Parse the supported algorithms and store them in the output buffer
    	token = strtok(buffer, delim);
    
    	while (token != NULL) {
    		if (strstr(token, "reno"))
    			pos += snprintf(&output[pos], output_size - pos, "Reno,");
    		else if (strstr(token, "cubic"))
    			pos += snprintf(&output[pos], output_size - pos, "Cubic,");
    		else if (strstr(token, "newreno"))
    			pos += snprintf(&output[pos], output_size - pos, "New Reno,");
    		else if (strstr(token, "vegas"))
    			pos += snprintf(&output[pos], output_size - pos, "Vegas,");
    		else if (strstr(token, "tahoe"))
    			pos += snprintf(&output[pos], output_size - pos, "Tahoe,");
    
    		token = strtok(NULL, delim);
    	}
    
    	// Remove the trailing comma, if any
    	if (pos > 0)
    		output[pos - 1] = '\0';
    
    	return 0;
    }
    
    /*************************************************************
    * GET & SET PARAM
    **************************************************************/
    static int get_DeviceInfoNetworkProperties_MaxTCPWindowSize(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
    {
    	int min = 0, def = 0, max = 0;
    
    	int res = read_tcp_write_memory_limits(&min, &def, &max);
    	dmasprintf(value, "%d", !res ? max : 0);
    	return 0;
    }
    
    static int get_DeviceInfoNetworkProperties_TCPImplementation(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
    {
    	char list[256] = {0};
    
    	int res = get_supported_congestion_controls(list, sizeof(list));
    	*value = dmstrdup(!res ? list : "");
    	return 0;
    }
    
    /**********************************************************************************************************************************
    *                                            OBJ & LEAF DEFINITION
    ***********************************************************************************************************************************/
    /* *** Device.DeviceInfo.NetworkProperties. *** */
    DMLEAF tDeviceInfoNetworkPropertiesParams[] = {
    /* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
    {"MaxTCPWindowSize", &DMREAD, DMT_UNINT, get_DeviceInfoNetworkProperties_MaxTCPWindowSize, NULL, BBFDM_BOTH},
    {"TCPImplementation", &DMREAD, DMT_STRING, get_DeviceInfoNetworkProperties_TCPImplementation, NULL, BBFDM_BOTH},
    {0}
    };