blob: bcfd84a035e19fd87e0466ca18df0e806033f2d4 [file] [log] [blame]
#include <stdlib.h>
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <unistd.h>
#include <netdb.h>
#include "kvextract.h"
#include "utils.h"
void free_kv_pairs(struct kvpair* pairs) {
while (pairs) {
struct kvpair* next_pair = pairs->next_pair;
free(pairs);
pairs = next_pair;
}
}
int get_pair_from_file(const char* filepath, const char* key,
struct kvpair** pair) {
if (!pair)
return KV_FAIL;
*pair = (struct kvpair*) malloc(sizeof(struct kvpair));
if (!*pair) {
fprintf(stderr, "failed allocating kvpair buffer\n");
return KV_FAIL;
}
int len;
memset(*pair, 0, sizeof(struct kvpair));
len = read_file_as_string(filepath, (*pair)->value, sizeof((*pair)->value));
if (len < 0) {
free(*pair);
*pair = NULL;
return KV_NOTHING;
}
rstrip((*pair)->value);
assert(strlen(key) < MAX_KV_LENGTH);
strcpy((*pair)->key, key);
return KV_OK;
}
struct kvpair* extract_kv_pairs(struct kvextractparams* params) {
int family, i, rv;
struct ifaddrs* ifa;
char mac_buf[32];
struct kvpair* pair_head;
struct kvpair* pair_tail;
pair_head = pair_tail = NULL;
// Get the data for the model of the device
if (get_pair_from_file(params->platform_path, "model", &pair_tail) != KV_OK) {
fprintf(stderr, "failed getting kv for %s\n", params->platform_path);
return NULL;
}
pair_head = pair_tail;
// Now get the serial # of the device
if (get_pair_from_file(params->serial_path, "serial",
&(pair_tail->next_pair)) != KV_OK) {
fprintf(stderr, "failed getting kv for %s\n", params->serial_path);
free_kv_pairs(pair_head);
return NULL;
}
pair_tail = pair_tail->next_pair;
// Now get the IP address information
for (ifa = params->ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL)
continue;
family = ifa->ifa_addr->sa_family;
if (family == AF_INET || family == AF_INET6) {
// IPV4 or IPV6 address, check if it's for one of the interfaces
// we care about.
for (i = 0; i < params->num_interfaces; i++) {
if (!strcmp(ifa->ifa_name, params->interfaces_to_check[i])) {
// Matches our interface, add a new kvpair
pair_tail->next_pair = (struct kvpair*) malloc(sizeof(struct kvpair));
if (!pair_tail->next_pair) {
fprintf(stderr, "failed allocating kvpair buffer\n");
free_kv_pairs(pair_head);
return NULL;
}
pair_tail = pair_tail->next_pair;
memset(pair_tail, 0, sizeof(struct kvpair));
rv = params->name_info_resolver(ifa->ifa_addr,
(family == AF_INET) ? sizeof(struct sockaddr_in) :
sizeof(struct sockaddr_in6), pair_tail->value,
sizeof(pair_tail->value), NULL, 0, NI_NUMERICHOST);
if (rv != 0) {
fprintf(stderr, "getnameinfo(): %s\n", gai_strerror(rv));
free_kv_pairs(pair_head);
return NULL;
}
strcpy(pair_tail->key, (family == AF_INET) ? "ip" : "ip6");
break;
}
}
}
}
// Now get the MAC address information from the interfaces
for (i = 0; i < params->num_interfaces; i++) {
if (!params->interface_to_mac(params->interfaces_to_check[i], mac_buf,
sizeof(mac_buf))) {
pair_tail->next_pair = (struct kvpair*) malloc(sizeof(struct kvpair));
if (!pair_tail->next_pair) {
fprintf(stderr, "failed allocating memory for kvpair\n");
free_kv_pairs(pair_head);
return NULL;
}
pair_tail = pair_tail->next_pair;
memset(pair_tail, 0, sizeof(struct kvpair));
strcpy(pair_tail->key, "hw");
strcpy(pair_tail->value, mac_buf);
}
}
// Now add the logtype
if (params->logtype && strlen(params->logtype) > 0) {
pair_tail->next_pair = (struct kvpair*) malloc(sizeof(struct kvpair));
if (!pair_tail->next_pair) {
fprintf(stderr, "failed allocating memory for kvpair\n");
free_kv_pairs(pair_head);
return NULL;
}
pair_tail = pair_tail->next_pair;
memset(pair_tail, 0, sizeof(struct kvpair));
strcpy(pair_tail->key, "logtype");
strcpy(pair_tail->value, params->logtype);
}
return pair_head;
}