icwmp/diagnostic.c

239 lines
11 KiB
C

/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2021 iopsys Software Solutions AB
* Author Imen Bhiri <imen.bhiri@pivasoftware.com>
* Author: Amin Ben Ramdhane <amin.benramdhane@pivasoftware.com>
* Author: Omar Kallel <omar.kallel@pivasoftware.com>
*/
#include <string.h>
#include "common.h"
#include "diagnostic.h"
#include "ubus_utils.h"
#include "log.h"
#include "event.h"
struct diagnostic_input {
char *input_name;
char *parameter_name;
char *value;
};
#define DOWNLOAD_NUMBER_INPUTS 7
#define UPLOAD_NUMBER_INPUTS 8
#define IPPING_NUMBER_INPUTS 7
#define SESERVERSELECT_NUMBER_INPUTS 6
#define TRACEROUTE_NUMBER_INPUTS 8
#define UDPECHO_NUMBER_INPUTS 9
#define NSLKUP_NUMBER_INPUTS 5
#define IP_DIAGNOSTICS_OBJECT "Device.IP.Diagnostics."
#define DNS_DIAGNOSTICS_OBJECT "Device.DNS.Diagnostics."
#define DOWNLOAD_DIAG_ACT_NAME "DownloadDiagnostics()"
#define UPLOAD_DIAG_ACT_NAME "UploadDiagnostics()"
#define IPPING_DIAG_ACT_NAME "IPPing()"
#define SERVER_SELECTION_DIAG_ACT_NAME "ServerSelectionDiagnostics()"
#define TRACE_ROUTE_DIAG_ACT_NAME "TraceRoute()"
#define UDPECHO_DIAG_ACT_NAME "UDPEchoDiagnostics()"
#define NSLOOKUP_DIAG_ACT_NAME "NSLookupDiagnostics()"
struct diagnostic_input download_diagnostics_array[DOWNLOAD_NUMBER_INPUTS] = {
{ "Interface", "Device.IP.Diagnostics.DownloadDiagnostics.Interface", NULL },
{ "DownloadURL", "Device.IP.Diagnostics.DownloadDiagnostics.DownloadURL", NULL },
{ "DSCP", "Device.IP.Diagnostics.DownloadDiagnostics.DSCP", NULL },
{ "EthernetPriority", "Device.IP.Diagnostics.DownloadDiagnostics.EthernetPriority", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.DownloadDiagnostics.ProtocolVersion", NULL },
{ "NumberOfConnections", "Device.IP.Diagnostics.DownloadDiagnostics.NumberOfConnections", NULL },
{ "EnablePerConnectionResults", "Device.IP.Diagnostics.DownloadDiagnostics.EnablePerConnection", NULL },
//{"TimeBasedTestDuration","Device.IP.Diagnostics.DownloadDiagnostics.TimeBasedTestDuration",NULL},
//{"TimeBasedTestMeasurementInterval","Device.IP.Diagnostics.DownloadDiagnostics.TimeBasedTestMeasurementInterval",NULL},
//{"TimeBasedTestMeasurementOffset","Device.IP.Diagnostics.DownloadDiagnostics.TimeBasedTestMeasurementOffset",NULL}
};
struct diagnostic_input upload_diagnostics_array[UPLOAD_NUMBER_INPUTS] = {
{ "Interface", "Device.IP.Diagnostics.UploadDiagnostics.Interface", NULL },
{ "UploadURL", "Device.IP.Diagnostics.UploadDiagnostics.UploadURL", NULL },
{ "TestFileLength", "Device.IP.Diagnostics.UploadDiagnostics.TestFileLength", NULL },
{ "DSCP", "Device.IP.Diagnostics.UploadDiagnostics.DSCP", NULL },
{ "EthernetPriority", "Device.IP.Diagnostics.UploadDiagnostics.EthernetPriority", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.UploadDiagnostics.ProtocolVersion", NULL },
{ "NumberOfConnections", "Device.IP.Diagnostics.UploadDiagnostics.NumberOfConnections", NULL },
{ "EnablePerConnectionResults", "Device.IP.Diagnostics.UploadDiagnostics.EnablePerConnection", NULL },
//{"TimeBasedTestDuration","Device.IP.Diagnostics.UploadDiagnostics.TimeBasedTestDuration",NULL},
//{"TimeBasedTestMeasurementInterval","Device.IP.Diagnostics.UploadDiagnostics.TimeBasedTestMeasurementInterval",NULL},
//{"TimeBasedTestMeasurementOffset","Device.IP.Diagnostics.UploadDiagnostics.TimeBasedTestMeasurementOffset",NULL}
};
struct diagnostic_input ipping_diagnostics_array[IPPING_NUMBER_INPUTS] = { //
{ "Host", "Device.IP.Diagnostics.IPPing.Host", NULL },
{ "NumberOfRepetitions", "Device.IP.Diagnostics.IPPing.NumberOfRepetitions", NULL },
{ "Timeout", "Device.IP.Diagnostics.IPPing.Timeout", NULL },
{ "Interface", "Device.IP.Diagnostics.IPPing.Interface", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.IPPing.ProtocolVersion", NULL },
{ "DSCP", "Device.IP.Diagnostics.IPPing.DSCP", NULL },
{ "DataBlockSize", "Device.IP.Diagnostics.IPPing.DataBlockSize", NULL }
};
struct diagnostic_input seserverselection_diagnostics_array[SESERVERSELECT_NUMBER_INPUTS] = { //
{ "Interface", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Interface", NULL },
{ "Protocol", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Protocol", NULL },
{ "HostList", "Device.IP.Diagnostics.ServerSelectionDiagnostics.HostList", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.ServerSelectionDiagnostics.ProtocolVersion", NULL },
{ "NumberOfRepetitions", "Device.IP.Diagnostics.ServerSelectionDiagnostics.NumberOfRepetitions", NULL },
{ "Timeout", "Device.IP.Diagnostics.ServerSelectionDiagnostics.Timeout", NULL }
};
struct diagnostic_input traceroute_diagnostics_array[TRACEROUTE_NUMBER_INPUTS] = { //
{ "Interface", "Device.IP.Diagnostics.TraceRoute.Interface", NULL },
{ "Host", "Device.IP.Diagnostics.TraceRoute.Host", NULL },
{ "NumberOfTries", "Device.IP.Diagnostics.TraceRoute.NumberOfTries", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.TraceRoute.ProtocolVersion", NULL },
{ "Timeout", "Device.IP.Diagnostics.TraceRoute.Timeout", NULL },
{ "DataBlockSize", "Device.IP.Diagnostics.TraceRoute.DataBlockSize", NULL },
{ "DSCP", "Device.IP.Diagnostics.TraceRoute.DSCP", NULL },
{ "MaxHopCount", "Device.IP.Diagnostics.TraceRoute.MaxHopCount", NULL }
};
struct diagnostic_input udpecho_diagnostics_array[UDPECHO_NUMBER_INPUTS] = {
{ "Interface", "Device.IP.Diagnostics.UDPEchoDiagnostics.Interface", NULL },
{ "Host", "Device.IP.Diagnostics.UDPEchoDiagnostics.Host", NULL },
{ "Port", "Device.IP.Diagnostics.UDPEchoDiagnostics.Port", NULL },
{ "NumberOfRepetitions", "Device.IP.Diagnostics.UDPEchoDiagnostics.NumberOfRepetitions", NULL },
{ "Timeout", "Device.IP.Diagnostics.UDPEchoDiagnostics.Timeout", NULL },
{ "DataBlockSize", "Device.IP.Diagnostics.UDPEchoDiagnostics.DataBlockSize", NULL },
{ "DSCP", "Device.IP.Diagnostics.UDPEchoDiagnostics.DSCP", NULL },
{ "InterTransmissionTime", "Device.IP.Diagnostics.UDPEchoDiagnostics.InterTransmissionTime", NULL },
{ "ProtocolVersion", "Device.IP.Diagnostics.UDPEchoDiagnostics.ProtocolVersion", NULL },
//{"EnableIndividualPacketResults","Device.IP.Diagnostics.UDPEchoDiagnostics.EnableIndividualPacketResults",NULL}
};
struct diagnostic_input nslookup_diagnostics_array[NSLKUP_NUMBER_INPUTS] = { //
{ "Interface", "Device.DNS.Diagnostics.NSLookupDiagnostics.Interface", NULL },
{ "HostName", "Device.DNS.Diagnostics.NSLookupDiagnostics.HostName", NULL },
{ "DNSServer", "Device.DNS.Diagnostics.NSLookupDiagnostics.DNSServer", NULL },
{ "NumberOfRepetitions", "Device.DNS.Diagnostics.NSLookupDiagnostics.NumberOfRepetitions", NULL },
{ "Timeout", "Device.DNS.Diagnostics.NSLookupDiagnostics.Timeout", NULL }
};
static bool set_specific_diagnostic_object_parameter_structure_value(struct diagnostic_input (*diagnostics_array)[], int number_inputs, char *parameter, char *value)
{
int i;
for (i = 0; i < number_inputs; i++) {
if (parameter && (*diagnostics_array)[i].parameter_name && strcmp((*diagnostics_array)[i].parameter_name, parameter) == 0) {
FREE((*diagnostics_array)[i].value);
(*diagnostics_array)[i].value = strdup(value ? value : "");
return true;
}
}
return false;
}
bool set_diagnostic_parameter_structure_value(char *parameter_name, char *value) //returns false in case the parameter is not among diagnostics parameters
{
return set_specific_diagnostic_object_parameter_structure_value(&download_diagnostics_array, DOWNLOAD_NUMBER_INPUTS, parameter_name, value) || set_specific_diagnostic_object_parameter_structure_value(&upload_diagnostics_array, UPLOAD_NUMBER_INPUTS, parameter_name, value) ||
set_specific_diagnostic_object_parameter_structure_value(&ipping_diagnostics_array, IPPING_NUMBER_INPUTS, parameter_name, value) || set_specific_diagnostic_object_parameter_structure_value(&nslookup_diagnostics_array, NSLKUP_NUMBER_INPUTS, parameter_name, value) ||
set_specific_diagnostic_object_parameter_structure_value(&traceroute_diagnostics_array, TRACEROUTE_NUMBER_INPUTS, parameter_name, value) || set_specific_diagnostic_object_parameter_structure_value(&udpecho_diagnostics_array, UDPECHO_NUMBER_INPUTS, parameter_name, value) ||
set_specific_diagnostic_object_parameter_structure_value(&seserverselection_diagnostics_array, SESERVERSELECT_NUMBER_INPUTS, parameter_name, value);
}
void empty_ubus_callback(struct ubus_request *req __attribute__((unused)), int type __attribute__((unused)), struct blob_attr *msg __attribute__((unused))) {}
static int cwmp_diagnostics_operate(char *diagnostics_object, char *action_name, struct diagnostic_input diagnostics_array[], int number_inputs)
{
int e, i;
struct blob_buf b = { 0 };
memset(&b, 0, sizeof(struct blob_buf));
blob_buf_init(&b, 0);
bb_add_string(&b, "path", diagnostics_object);
bb_add_string(&b, "action", action_name);
void *tbl = blobmsg_open_table(&b, "input");
for (i = 0; i < number_inputs; i++) {
if (diagnostics_array[i].value == NULL || diagnostics_array[i].value[0] == '\0')
continue;
bb_add_string(&b, diagnostics_array[i].input_name, diagnostics_array[i].value);
}
blobmsg_close_table(&b, tbl);
e = icwmp_ubus_invoke(USP_OBJECT_NAME, "operate", b.head, empty_ubus_callback, NULL);
blob_buf_free(&b);
if (e)
return -1;
return 0;
}
int cwmp_download_diagnostics()
{
if (cwmp_diagnostics_operate(IP_DIAGNOSTICS_OBJECT, DOWNLOAD_DIAG_ACT_NAME, download_diagnostics_array, DOWNLOAD_NUMBER_INPUTS) == -1)
return -1;
CWMP_LOG(INFO, "Download diagnostic is successfully executed");
cwmp_root_cause_event_ipdiagnostic();
return 0;
}
int cwmp_upload_diagnostics()
{
if (cwmp_diagnostics_operate(IP_DIAGNOSTICS_OBJECT, UPLOAD_DIAG_ACT_NAME, upload_diagnostics_array, UPLOAD_NUMBER_INPUTS) == -1)
return -1;
CWMP_LOG(INFO, "Upload diagnostic is successfully executed");
cwmp_root_cause_event_ipdiagnostic();
return 0;
}
int cwmp_ip_ping_diagnostics()
{
if (cwmp_diagnostics_operate(IP_DIAGNOSTICS_OBJECT, IPPING_DIAG_ACT_NAME, ipping_diagnostics_array, IPPING_NUMBER_INPUTS) == -1)
return -1;
CWMP_LOG(INFO, "IPPing diagnostic is successfully executed");
cwmp_root_cause_event_ipdiagnostic();
return 0;
}
int cwmp_nslookup_diagnostics()
{
if (cwmp_diagnostics_operate(DNS_DIAGNOSTICS_OBJECT, NSLOOKUP_DIAG_ACT_NAME, nslookup_diagnostics_array, NSLKUP_NUMBER_INPUTS) == -1)
return -1;
CWMP_LOG(INFO, "Nslookup diagnostic is successfully executed");
cwmp_root_cause_event_ipdiagnostic();
return 0;
}
int cwmp_traceroute_diagnostics()
{
if (cwmp_diagnostics_operate(IP_DIAGNOSTICS_OBJECT, TRACE_ROUTE_DIAG_ACT_NAME, traceroute_diagnostics_array, TRACEROUTE_NUMBER_INPUTS) == -1)
return -1;
CWMP_LOG(INFO, "Trace Route diagnostic is successfully executed");
cwmp_root_cause_event_ipdiagnostic();
return 0;
}
int cwmp_udp_echo_diagnostics()
{
if (cwmp_diagnostics_operate(IP_DIAGNOSTICS_OBJECT, UDPECHO_DIAG_ACT_NAME, udpecho_diagnostics_array, UDPECHO_NUMBER_INPUTS) == -1)
return -1;
CWMP_LOG(INFO, "UDPEcho diagnostic is successfully executed");
cwmp_root_cause_event_ipdiagnostic();
return 0;
}
int cwmp_serverselection_diagnostics()
{
if (cwmp_diagnostics_operate(IP_DIAGNOSTICS_OBJECT, SERVER_SELECTION_DIAG_ACT_NAME, seserverselection_diagnostics_array, SESERVERSELECT_NUMBER_INPUTS) == -1)
return -1;
CWMP_LOG(INFO, "Server Selection diagnostic is successfully executed");
cwmp_root_cause_event_ipdiagnostic();
return 0;
}