From afec0fd5cae5b552db5a014858007cba4503503c Mon Sep 17 00:00:00 2001 From: "Christopher N. Hesse" Date: Thu, 9 Feb 2017 19:17:06 +0100 Subject: [PATCH] macloader: Rework mac address half classification * Don't return in the middle of a function, set the return code and jump to the exit point instead. * Close file pointers properly. * Unify error code returns (macloader will always exit with -1 on error now). Change-Id: I32ac8ea85fcbabed45550a4d176ac999eff9f9e9 --- macloader/macaddr_mappings.h | 146 +++++++++++++++++ macloader/macloader.c | 310 +++++++++++++++-------------------- 2 files changed, 281 insertions(+), 175 deletions(-) create mode 100644 macloader/macaddr_mappings.h diff --git a/macloader/macaddr_mappings.h b/macloader/macaddr_mappings.h new file mode 100644 index 00000000..56d3666c --- /dev/null +++ b/macloader/macaddr_mappings.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2017, The LineageOS Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MACADDR_MAPPINGS_H +#define MACADDR_MAPPINGS_H + +#define MAX_RANGE_ENTRIES 100 +#define RANGE_ENTRY_LEN 9 + +enum Type { + NONE, + MURATA, + SEMCOSH, + SEMCOVE, + SEMCO3RD, + SEMCO, + WISOL, + TYPE_MAX = WISOL +}; + +struct company_range { + int type; + char macaddrs[MAX_RANGE_ENTRIES][RANGE_ENTRY_LEN]; +}; + +/* + * address mappings from http://hwaddress.com + */ + +static const struct company_range murata_ranges = { + .type = MURATA, + .macaddrs = { + "00:0e:6d", + "00:13:e0", + "00:21:e8", + "00:26:e8", + "00:37:6d", + "00:60:57", + "00:ae:fa", + "04:46:65", + "10:5f:06", + "10:a5:d0", + "10:d5:42", + "14:7d:c5", + "1c:99:4c", + "20:02:af", + "40:f3:08", + "44:a7:cf", + "5c:da:d4", + "5c:f8:a1", + "60:21:c0", + "60:f1:89", + "78:4b:87", + "78:52:1a", + "88:30:8a", + "90:b6:86", + "98:f1:70", + "a0:cc:2b", + "a4:08:ea", + "b0:72:bf", + "b8:d7:af", + "c8:14:79", + "d0:e4:4a", + "d8:c4:6a", + "dc:ef:ca", + "f0:27:65", + "fc:c2:de", + "fc:db:b3" + } +}; + +static const struct company_range semcosh_ranges = { + .type = SEMCOSH, + .macaddrs = { + "34:23:ba", + "38:aa:3c", + "5c:0a:5b", + "88:32:9b", + "90:18:7c", + "cc:3a:61" + } +}; + +static const struct company_range semco3rd_ranges = { + .type = SEMCO3RD, + .macaddrs = { + "2c:0e:3d", + "54:88:0e", + "84:38:38", + "8c:f5:a3", + "ac:36:13", + "ac:5f:3e", + "b4:79:a7", + "c0:97:27", + "c0:bd:d1", + "c8:ba:94", + "d0:25:44", + "e8:50:8b", + "ec:1f:72", + "ec:9b:f3", + "f0:25:b7", + "f4:09:d8", + "f8:04:2e" + } +}; + +static const struct company_range semco_ranges = { + .type = SEMCO, + .macaddrs = { + "4c:66:41", + "51:f6:6b", + "d8:c4:e9", + "ec:9b:f3" + } +}; + +static const struct company_range wisol_ranges = { + .type = WISOL, + .macaddrs = { + "48:5a:3f", + "70:2c:1f" + } +}; + +static const struct company_range *all_ranges[TYPE_MAX] = { + &murata_ranges, + &semcosh_ranges, + &semco3rd_ranges, + &semco_ranges, + &wisol_ranges +}; + +#endif // MACADDR_MAPPINGS_H diff --git a/macloader/macloader.c b/macloader/macloader.c index 212d6712..7596d47c 100644 --- a/macloader/macloader.c +++ b/macloader/macloader.c @@ -34,15 +34,7 @@ #include -enum Type { - NONE, - MURATA, - SEMCOSH, - SEMCOVE, - SEMCO3RD, - SEMCO, - WISOL -}; +#include "macaddr_mappings.h" static int wifi_change_nvram_calibration(const char *nvram_file, const char *type) @@ -54,7 +46,8 @@ static int wifi_change_nvram_calibration(const char *nvram_file, char nvram_str[1024] = { 0 }; if (nvram_file == NULL || type == NULL) { - return -1; + ret = -1; + goto out; } ret = stat(nvram_file, &sb); @@ -62,7 +55,8 @@ static int wifi_change_nvram_calibration(const char *nvram_file, ALOGE("Failed to check for NVRAM calibration file '%s' - error: %s", nvram_file, strerror(errno)); - return -1; + ret = -1; + goto out; } ALOGD("Using NVRAM calibration file: %s\n", nvram_file); @@ -71,7 +65,8 @@ static int wifi_change_nvram_calibration(const char *nvram_file, if (fd < 0) { ALOGE("Failed to open wifi nvram config path %s - error: %s", WIFI_DRIVER_NVRAM_PATH_PARAM, strerror(errno)); - return -1; + ret = -1; + goto out; } len = strlen(nvram_file) + 1; @@ -112,7 +107,6 @@ static int wifi_change_nvram_calibration(const char *nvram_file, ALOGD("NVRAM calibration file set to '%s'\n", nvram_str); - ret = 0; out: if (fd != -1) { close(fd); @@ -120,12 +114,39 @@ out: return ret; } +static int classify_macaddr_half(char const *macaddr_half) +{ + int type = NONE; + unsigned int i, j; + char const *macaddr; + + for (i = 0; i < TYPE_MAX; i++) { + for (j = 0; j < MAX_RANGE_ENTRIES; j++) { + macaddr = all_ranges[i]->macaddrs[j]; + if (macaddr[0] == '\0') { + break; + } + // macaddr_half is guaranteed to be null terminated + if (strcasecmp(macaddr_half, macaddr) == 0) { + type = all_ranges[i]->type; + goto exit; + } + } + } + +exit: + if (type != NONE) { + ALOGV("Found CID type: %d", type); + } + return type; +} + int main() { - FILE* file; - FILE* cidfile; + FILE* file = NULL; + FILE* cidfile = NULL; char* str; - char mac_addr_half[9]; - int ret = -1; + char mac_addr_half[RANGE_ENTRY_LEN + 1] = {0}; + int ret = 0; int amode; enum Type type = NONE; @@ -134,189 +155,128 @@ int main() { if (file == 0) { fprintf(stderr, "open(%s) failed\n", MACADDR_PATH); ALOGE("Can't open %s\n", MACADDR_PATH); - return -1; + ret = -1; + goto out; } /* get and compare mac addr */ - str = fgets(mac_addr_half, 9, file); + str = fgets(mac_addr_half, RANGE_ENTRY_LEN, file); fclose(file); if (str == 0) { fprintf(stderr, "fgets() from file %s failed\n", MACADDR_PATH); ALOGE("Can't read from %s\n", MACADDR_PATH); - return -1; + ret = -1; + goto out; } - /* murata - ref: http://hwaddress.com/?q=ACT */ - if (strncasecmp(mac_addr_half, "00:0e:6d", 9) == 0 || - strncasecmp(mac_addr_half, "00:13:e0", 9) == 0 || - strncasecmp(mac_addr_half, "00:21:e8", 9) == 0 || - strncasecmp(mac_addr_half, "00:26:e8", 9) == 0 || - strncasecmp(mac_addr_half, "00:37:6d", 9) == 0 || - strncasecmp(mac_addr_half, "00:60:57", 9) == 0 || - strncasecmp(mac_addr_half, "00:ae:fa", 9) == 0 || - strncasecmp(mac_addr_half, "04:46:65", 9) == 0 || - strncasecmp(mac_addr_half, "10:5f:06", 9) == 0 || - strncasecmp(mac_addr_half, "10:a5:d0", 9) == 0 || - strncasecmp(mac_addr_half, "10:d5:42", 9) == 0 || - strncasecmp(mac_addr_half, "14:7d:c5", 9) == 0 || - strncasecmp(mac_addr_half, "1c:99:4c", 9) == 0 || - strncasecmp(mac_addr_half, "20:02:af", 9) == 0 || - strncasecmp(mac_addr_half, "40:f3:08", 9) == 0 || - strncasecmp(mac_addr_half, "44:a7:cf", 9) == 0 || - strncasecmp(mac_addr_half, "5c:da:d4", 9) == 0 || - strncasecmp(mac_addr_half, "5c:f8:a1", 9) == 0 || - strncasecmp(mac_addr_half, "60:21:c0", 9) == 0 || - strncasecmp(mac_addr_half, "60:f1:89", 9) == 0 || - strncasecmp(mac_addr_half, "78:4b:87", 9) == 0 || - strncasecmp(mac_addr_half, "78:52:1a", 9) == 0 || - strncasecmp(mac_addr_half, "88:30:8a", 9) == 0 || - strncasecmp(mac_addr_half, "90:b6:86", 9) == 0 || - strncasecmp(mac_addr_half, "98:f1:70", 9) == 0 || - strncasecmp(mac_addr_half, "a0:cc:2b", 9) == 0 || - strncasecmp(mac_addr_half, "a4:08:ea", 9) == 0 || - strncasecmp(mac_addr_half, "b0:72:bf", 9) == 0 || - strncasecmp(mac_addr_half, "b8:d7:af", 9) == 0 || - strncasecmp(mac_addr_half, "c8:14:79", 9) == 0 || - strncasecmp(mac_addr_half, "d0:e4:4a", 9) == 0 || - strncasecmp(mac_addr_half, "d8:c4:6a", 9) == 0 || - strncasecmp(mac_addr_half, "dc:ef:ca", 9) == 0 || - strncasecmp(mac_addr_half, "f0:27:65", 9) == 0 || - strncasecmp(mac_addr_half, "fc:c2:de", 9) == 0 || - strncasecmp(mac_addr_half, "fc:db:b3", 9) == 0) { - type = MURATA; + type = classify_macaddr_half(mac_addr_half); + if (type == NONE) { + /* delete cid file if no specific type */ + ALOGD("Deleting file %s\n", CID_PATH); + remove(CID_PATH); + ret = 0; + goto out; } - /* semcosh */ - if (strncasecmp(mac_addr_half, "34:23:ba", 9) == 0 || - strncasecmp(mac_addr_half, "38:aa:3c", 9) == 0 || - strncasecmp(mac_addr_half, "5c:0a:5b", 9) == 0 || - strncasecmp(mac_addr_half, "88:32:9b", 9) == 0 || - strncasecmp(mac_addr_half, "90:18:7c", 9) == 0 || - strncasecmp(mac_addr_half, "cc:3a:61", 9) == 0) { - type = SEMCOSH; - } + const char *nvram_file; + const char *type_str; + struct passwd *pwd; + int fd; - /* semco3rd */ - if (strncasecmp(mac_addr_half, "2c:0e:3d", 9) == 0 || - strncasecmp(mac_addr_half, "54:88:0e", 9) == 0 || - strncasecmp(mac_addr_half, "84:38:38", 9) == 0 || - strncasecmp(mac_addr_half, "8c:f5:a3", 9) == 0 || - strncasecmp(mac_addr_half, "ac:36:13", 9) == 0 || - strncasecmp(mac_addr_half, "ac:5f:3e", 9) == 0 || - strncasecmp(mac_addr_half, "b4:79:a7", 9) == 0 || - strncasecmp(mac_addr_half, "c0:97:27", 9) == 0 || - strncasecmp(mac_addr_half, "c0:bd:d1", 9) == 0 || - strncasecmp(mac_addr_half, "c8:ba:94", 9) == 0 || - strncasecmp(mac_addr_half, "d0:25:44", 9) == 0 || - strncasecmp(mac_addr_half, "e8:50:8b", 9) == 0 || - strncasecmp(mac_addr_half, "ec:1f:72", 9) == 0 || - strncasecmp(mac_addr_half, "ec:9b:f3", 9) == 0 || - strncasecmp(mac_addr_half, "f0:25:b7", 9) == 0 || - strncasecmp(mac_addr_half, "f4:09:d8", 9) == 0 || - strncasecmp(mac_addr_half, "f8:04:2e", 9) == 0) { - type = SEMCO3RD; + switch(type) { + case MURATA: + type_str = "murata"; + break; + case SEMCOSH: + type_str = "semcosh"; + break; + case SEMCOVE: + type_str = "semcove"; + break; + case SEMCO3RD: + type_str = "semco3rd"; + break; + case SEMCO: + type_str = "semco"; + break; + case WISOL: + type_str = "wisol"; + break; + default: + ALOGE("Unknown CID type: %d", type); + ret = -1; + goto out; } - /* semco */ - if (strncasecmp(mac_addr_half, "4c:66:41", 9) == 0 || - strncasecmp(mac_addr_half, "51:f6:6b", 9) == 0 || - strncasecmp(mac_addr_half, "ec:9b:f3", 9) == 0 || - strncasecmp(mac_addr_half, "d8:c4:e9", 9) == 0) { - type = SEMCO; - } + ALOGI("Settting wifi type to %s in %s\n", type_str, CID_PATH); - /* wisol */ - if (strncasecmp(mac_addr_half, "48:5a:3f", 9) == 0 || - strncasecmp(mac_addr_half, "70:2c:1f", 9) == 0) { - type = WISOL; + /* open cid file */ + cidfile = fopen(CID_PATH, "w"); + if (cidfile == NULL) { + fprintf(stderr, + "open(%s) failed: %s\n", + CID_PATH, + strerror(errno)); + ALOGE("Can't open %s: %s\n", CID_PATH, strerror(errno)); + ret = -1; + goto out; } - if (type != NONE) { - const char *nvram_file; - const char *type_str; - struct passwd *pwd; - int fd; - - /* open cid file */ - cidfile = fopen(CID_PATH, "w"); - if(cidfile == 0) { - fprintf(stderr, "open(%s) failed\n", CID_PATH); - ALOGE("Can't open %s\n", CID_PATH); - return -1; - } + ret = fputs(type_str, cidfile); + if (ret != 0) { + ALOGE("Can't write to %s\n", CID_PATH); + ret = -1; + goto out; + } - switch(type) { - case NONE: - return -1; - case MURATA: - type_str = "murata"; - break; - case SEMCOSH: - type_str = "semcosh"; - break; - case SEMCOVE: - type_str = "semcove"; - break; - case SEMCO3RD: - type_str = "semco3rd"; - break; - case SEMCO: - type_str = "semco"; - break; - case WISOL: - type_str = "wisol"; - break; - } + /* Change permissions of cid file */ + ALOGD("Change permissions of %s\n", CID_PATH); - ALOGI("Settting wifi type to %s in %s\n", type_str, CID_PATH); + fd = fileno(cidfile); + amode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + ret = fchmod(fd, amode); + if (ret != 0) { + ALOGE("Can't set permissions on %s - %s\n", + CID_PATH, strerror(errno)); + ret = -1; + goto out; + } - ret = fputs(type_str, cidfile); - if (ret != 0) { - ALOGE("Can't write to %s\n", CID_PATH); - return 1; - } + pwd = getpwnam("system"); + if (pwd == NULL) { + ALOGE("Failed to find 'system' user - %s\n", + strerror(errno)); + ret = -1; + goto out; + } - /* Change permissions of cid file */ - ALOGD("Change permissions of %s\n", CID_PATH); + ret = fchown(fd, pwd->pw_uid, pwd->pw_gid); + if (ret != 0) { + ALOGE("Failed to change owner of %s - %s\n", + CID_PATH, strerror(errno)); + ret = -1; + goto out; + } - fd = fileno(cidfile); - amode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - ret = fchmod(fd, amode); + nvram_file = WIFI_DRIVER_NVRAM_PATH; + if (nvram_file != NULL) { + ret = wifi_change_nvram_calibration(nvram_file, type_str); if (ret != 0) { - fclose(cidfile); - ALOGE("Can't set permissions on %s - %s\n", - CID_PATH, strerror(errno)); - return 1; - } - - pwd = getpwnam("system"); - if (pwd == NULL) { - fclose(cidfile); - ALOGE("Failed to find 'system' user - %s\n", - strerror(errno)); - return 1; + ret = -1; + goto out; } + } - ret = fchown(fd, pwd->pw_uid, pwd->pw_gid); +out: + if (file) { + fclose(file); + } + if (cidfile) { fclose(cidfile); - if (ret != 0) { - ALOGE("Failed to change owner of %s - %s\n", - CID_PATH, strerror(errno)); - return 1; - } - - nvram_file = WIFI_DRIVER_NVRAM_PATH; - if (nvram_file != NULL) { - ret = wifi_change_nvram_calibration(nvram_file, type_str); - if (ret != 0) { - return 1; - } - } - } else { - /* delete cid file if no specific type */ - ALOGD("Deleting file %s\n", CID_PATH); - remove(CID_PATH); } - return 0; + if (ret < 0) { + ALOGE("Macloader error return code: %d", ret); + } + + return ret; }