Get ConnectionRequestURL using ioctl if ifstatus returns empty

This commit is contained in:
Vivek Kumar Dutta 2021-12-13 10:14:07 +00:00
parent 2486dffd24
commit b22628c0dd
4 changed files with 92 additions and 30 deletions

View file

@ -66,32 +66,6 @@ static int get_ip_iface_sysfs(const struct uci_section *data, const char *name,
return get_net_iface_sysfs(section_name((struct uci_section *)data), name, value);
}
static int parse_proc_intf6_line(const char *line, const char *device, char *ipstr, size_t str_len)
{
char ip6buf[INET6_ADDRSTRLEN] = {0}, dev[32] = {0};
unsigned int ip[4], prefix;
sscanf(line, "%8x%8x%8x%8x %*s %x %*s %*s %31s",
&ip[0], &ip[1], &ip[2], &ip[3],
&prefix, dev);
if (strcmp(dev, device) != 0)
return -1;
ip[0] = htonl(ip[0]);
ip[1] = htonl(ip[1]);
ip[2] = htonl(ip[2]);
ip[3] = htonl(ip[3]);
inet_ntop(AF_INET6, ip, ip6buf, INET6_ADDRSTRLEN);
snprintf(ipstr, str_len, "%s/%u", ip6buf, prefix);
if (strncmp(ipstr, "fe80:", 5) != 0)
return -1;
return 0;
}
static bool proc_intf6_line_exists(char *parent_section, char *address)
{
struct uci_section *s = NULL;

View file

@ -230,14 +230,18 @@ static int network_get_ipaddr(char *iface, int ipver, char **value)
/*#Device.ManagementServer.ConnectionRequestURL!UCI:cwmp/cpe,cpe/port*/
static int get_management_server_connection_request_url(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{
char *ip = NULL, *port = NULL, *iface = NULL, *ip_version = NULL;
char *ip = NULL, *port = NULL, *interface = NULL, *iface_name = NULL, *ip_version = NULL;
dmuci_get_option_value_string("cwmp", "cpe", "default_wan_interface", &iface);
dmuci_get_option_value_string("cwmp", "cpe", "default_wan_interface", &interface);
dmuci_get_option_value_string("cwmp", "cpe", "interface", &iface_name);
dmuci_get_option_value_string("cwmp", "acs", "ip_version", &ip_version);
network_get_ipaddr(iface, ip_version&&ip_version[0]=='6'?6:4, &ip);
dmuci_get_option_value_string("cwmp", "cpe", "port", &port);
if (network_get_ipaddr(interface, *ip_version == '6' ? 6 : 4, &ip) == -1) {
// get ip from ioctl
ip = (*ip_version == '6') ? get_ipv6(iface_name) : ioctl_get_ipv4(iface_name);
}
if (ip[0] != '\0' && port[0] != '\0') {
char *path;

View file

@ -1649,3 +1649,84 @@ int check_browse_section(struct uci_section *s, void *data)
return 0;
return -1;
}
int parse_proc_intf6_line(const char *line, const char *device, char *ipstr, size_t str_len)
{
char ip6buf[INET6_ADDRSTRLEN] = {0}, dev[32] = {0};
unsigned int ip[4], prefix;
sscanf(line, "%8x%8x%8x%8x %*s %x %*s %*s %31s",
&ip[0], &ip[1], &ip[2], &ip[3],
&prefix, dev);
if (strcmp(dev, device) != 0)
return -1;
ip[0] = htonl(ip[0]);
ip[1] = htonl(ip[1]);
ip[2] = htonl(ip[2]);
ip[3] = htonl(ip[3]);
inet_ntop(AF_INET6, ip, ip6buf, INET6_ADDRSTRLEN);
snprintf(ipstr, str_len, "%s/%u", ip6buf, prefix);
if (strncmp(ipstr, "fe80:", 5) != 0)
return -1;
return 0;
}
// Get IPv4 address assigned to an interface using ioctl
// return ==> dynamically allocated IPv4 address on success,
// ==> empty string on failure
// Note: Ownership of returned dynamically allocated IPv4 address is with caller
char *ioctl_get_ipv4(char *interface_name)
{
int fd;
struct ifreq ifr;
char *ip = "";
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1)
goto exit;
ifr.ifr_addr.sa_family = AF_INET;
DM_STRNCPY(ifr.ifr_name, interface_name, IFNAMSIZ);
if (ioctl(fd, SIOCGIFADDR, &ifr) == -1)
goto exit;
ip = dmstrdup(inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr )->sin_addr));
exit:
close(fd);
return ip;
}
char *get_ipv6(char *interface_name)
{
FILE *fp = NULL;
char buf[512] = {0};
char ipstr[64] = {0};
fp = fopen(PROC_INTF6, "r");
if (fp == NULL)
return "";
while (fgets(buf, 512, fp) != NULL) {
ipstr[0] = '\0';
if (parse_proc_intf6_line(buf, interface_name, ipstr, sizeof(ipstr)) == 0) {
if (strlen(ipstr) != 0) {
char *slash = strchr(ipstr, '/');
if (slash)
*slash = '\0';
}
break;
}
}
fclose(fp);
return (*ipstr) ? dmstrdup(ipstr) : "";
}

View file

@ -298,4 +298,7 @@ unsigned long file_system_size(const char *path, const enum fs_size_type_enum ty
char *replace_char(char *str, char find, char replace);
char *replace_str(const char *str, const char *substr, const char *replacement);
int check_browse_section(struct uci_section *s, void *data);
int parse_proc_intf6_line(const char *line, const char *device, char *ipstr, size_t str_len);
char *ioctl_get_ipv4(char *interface_name);
char *get_ipv6(char *interface_name);
#endif