| #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; |
| } |