int load_allow_hosts(IniContext *pIniContext, \ in_addr_t **allow_ip_addrs, int *allow_ip_count) { int count; IniItem *pItem; IniItem *pItemStart; IniItem *pItemEnd; char *pItemValue; char *pStart; char *pEnd; char *p; char *pTail; int alloc_count; int nHeadLen; int i; in_addr_t addr; char hostname[256]; if ((pItemStart=iniGetValuesEx(NULL, "allow_hosts", \ pIniContext, &count)) == NULL) { *allow_ip_count = -1; /* -1 means match any ip address */ *allow_ip_addrs = NULL; return 0; } pItemEnd = pItemStart + count; for (pItem=pItemStart; pItem<pItemEnd; pItem++) { if (strcmp(pItem->value, "*") == 0) { *allow_ip_count = -1; /* -1 means match any ip address*/ *allow_ip_addrs = NULL; return 0; } } alloc_count = count; *allow_ip_count = 0; *allow_ip_addrs = (in_addr_t *)malloc(sizeof(in_addr_t) * alloc_count); if (*allow_ip_addrs == NULL) { logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, errno: %d, error info: %s.", \ __LINE__, (int)sizeof(in_addr_t) * alloc_count, \ errno, STRERROR(errno)); return errno != 0 ? errno : ENOMEM; } for (pItem=pItemStart; pItem<pItemEnd; pItem++) { if (*(pItem->value) == '\0') { continue; } pStart = strchr(pItem->value, '['); if (pStart == NULL) { addr = getIpaddrByName(pItem->value, NULL, 0); if (addr == INADDR_NONE) { logWarning("file: "__FILE__", line: %d, " \ "invalid host name: %s", \ __LINE__, pItem->value); } else { if (alloc_count < (*allow_ip_count) + 1) { alloc_count = (*allow_ip_count) + \ (pItemEnd - pItem); *allow_ip_addrs = (in_addr_t *)realloc( *allow_ip_addrs, sizeof(in_addr_t)*alloc_count); if (*allow_ip_addrs == NULL) { logError("file: "__FILE__", line: %d, "\ "malloc %d bytes fail, " \ "errno: %d, error info: %s", \ __LINE__, (int)sizeof(in_addr_t) * alloc_count, \ errno, STRERROR(errno)); return errno != 0 ? errno : ENOMEM; } } (*allow_ip_addrs)[*allow_ip_count] = addr; (*allow_ip_count)++; } continue; } pEnd = strchr(pStart, ']'); if (pEnd == NULL) { logWarning("file: "__FILE__", line: %d, " \ "invalid host name: %s, expect \"]\"", \ __LINE__, pItem->value); continue; } pItemValue = strdup(pItem->value); if (pItemValue == NULL) { logWarning("file: "__FILE__", line: %d, " \ "strdup fail, " \ "errno: %d, error info: %s.", \ __LINE__, errno, STRERROR(errno)); continue; } nHeadLen = pStart - pItem->value; pStart = pItemValue + nHeadLen; pEnd = pItemValue + (pEnd - pItem->value); pTail = pEnd + 1; memcpy(hostname, pItem->value, nHeadLen); p = pStart + 1; //skip [ while (p <= pEnd) { char *pNumStart1; char *pNumStart2; int nStart; int nEnd; int nNumLen1; int nNumLen2; char end_ch1; char end_ch2; char szFormat[16]; while (*p == ' ' || *p == '\t') //trim prior spaces { p++; } pNumStart1 = p; while (*p >='0' && *p <= '9') { p++; } nNumLen1 = p - pNumStart1; while (*p == ' ' || *p == '\t') //trim tail spaces { p++; } if (!(*p == ',' || *p == '-' || *p == ']')) { logWarning("file: "__FILE__", line: %d, " \ "invalid char \"%c\" in host name: %s",\ __LINE__, *p, pItem->value); break; } end_ch1 = *p; *(pNumStart1 + nNumLen1) = '\0'; if (nNumLen1 == 0) { logWarning("file: "__FILE__", line: %d, " \ "invalid host name: %s, " \ "empty entry before \"%c\"", \ __LINE__, pItem->value, end_ch1); break; } nStart = atoi(pNumStart1); if (end_ch1 == '-') { p++; //skip - /* trim prior spaces */ while (*p == ' ' || *p == '\t') { p++; } pNumStart2 = p; while (*p >='0' && *p <= '9') { p++; } nNumLen2 = p - pNumStart2; /* trim tail spaces */ while (*p == ' ' || *p == '\t') { p++; } if (!(*p == ',' || *p == ']')) { logWarning("file: "__FILE__", line: %d, " \ "invalid char \"%c\" in host name: %s",\ __LINE__, *p, pItem->value); break; } end_ch2 = *p; *(pNumStart2 + nNumLen2) = '\0'; if (nNumLen2 == 0) { logWarning("file: "__FILE__", line: %d, " \ "invalid host name: %s, " \ "empty entry before \"%c\"", \ __LINE__, pItem->value, end_ch2); break; } nEnd = atoi(pNumStart2); } else { nEnd = nStart; } if (alloc_count < *allow_ip_count+(nEnd - nStart + 1)) { alloc_count = *allow_ip_count + (nEnd - nStart) + (pItemEnd - pItem); *allow_ip_addrs = (in_addr_t *)realloc( *allow_ip_addrs, sizeof(in_addr_t)*alloc_count); if (*allow_ip_addrs == NULL) { logError("file: "__FILE__", line: %d, "\ "malloc %d bytes fail, " \ "errno: %d, error info: %s.", \ __LINE__, \ (int)sizeof(in_addr_t) * \ alloc_count,\ errno, STRERROR(errno)); free(pItemValue); return errno != 0 ? errno : ENOMEM; } } sprintf(szFormat, "%%0%dd%%s", nNumLen1); for (i=nStart; i<=nEnd; i++) { sprintf(hostname + nHeadLen, szFormat, \ i, pTail); addr = getIpaddrByName(hostname, NULL, 0); if (addr == INADDR_NONE) { logWarning("file: "__FILE__", line: %d, " \ "invalid host name: %s", \ __LINE__, hostname); } else { (*allow_ip_addrs)[*allow_ip_count]=addr; (*allow_ip_count)++; } } p++; } free(pItemValue); } if (*allow_ip_count == 0) { logWarning("file: "__FILE__", line: %d, " \ "allow ip count: 0", __LINE__); } if (*allow_ip_count > 0) { qsort(*allow_ip_addrs, *allow_ip_count, sizeof(in_addr_t), \ cmp_by_ip_addr_t); } /* printf("*allow_ip_count=%d\n", *allow_ip_count); for (i=0; i<*allow_ip_count; i++) { struct in_addr address; address.s_addr = (*allow_ip_addrs)[i]; printf("%s\n", inet_ntoa(address)); } */ return 0; }
int load_allow_hosts(IniContext *pIniContext, \ in_addr_t **allow_ip_addrs, int *allow_ip_count) { int result; int count; IniItem *pItem; IniItem *pItemStart; IniItem *pItemEnd; char item_value[256]; char *pStart; char *pEnd; int alloc_count; int nHeadLen; int nValueLen; int i; in_addr_t addr; char hostname[256]; if ((pItemStart=iniGetValuesEx(NULL, "allow_hosts", \ pIniContext, &count)) == NULL) { *allow_ip_count = -1; /* -1 means match any ip address */ *allow_ip_addrs = NULL; return 0; } pItemEnd = pItemStart + count; for (pItem=pItemStart; pItem<pItemEnd; pItem++) { if (strcmp(pItem->value, "*") == 0) { *allow_ip_count = -1; /* -1 means match any ip address*/ *allow_ip_addrs = NULL; return 0; } } alloc_count = count; *allow_ip_count = 0; *allow_ip_addrs = (in_addr_t *)malloc(sizeof(in_addr_t) * alloc_count); if (*allow_ip_addrs == NULL) { logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, errno: %d, error info: %s.", \ __LINE__, (int)sizeof(in_addr_t) * alloc_count, \ errno, STRERROR(errno)); return errno != 0 ? errno : ENOMEM; } for (pItem=pItemStart; pItem<pItemEnd; pItem++) { if (*(pItem->value) == '\0') { continue; } pStart = strchr(pItem->value, '['); if (pStart == NULL) { if (strchr(pItem->value, '/') != NULL) //CIDR addresses { if ((result=parse_cidr_ips(pItem->value, allow_ip_addrs, &alloc_count, allow_ip_count, pItemEnd - pItem)) != 0) { return result; } continue; } addr = getIpaddrByName(pItem->value, NULL, 0); if (addr == INADDR_NONE) { logWarning("file: "__FILE__", line: %d, " \ "invalid host name: %s", \ __LINE__, pItem->value); } else { if ((result=check_realloc_allow_ips(allow_ip_addrs, &alloc_count, (*allow_ip_count) + (pItemEnd - pItem))) != 0) { return result; } (*allow_ip_addrs)[*allow_ip_count] = addr; (*allow_ip_count)++; } continue; } pEnd = strchr(pStart, ']'); if (pEnd == NULL) { logError("file: "__FILE__", line: %d, " \ "invalid host name: %s, expect \"]\"", \ __LINE__, pItem->value); return EINVAL; } nValueLen = strlen(pItem->value); if (nValueLen >= (int)sizeof(item_value)) { logError("file: "__FILE__", line: %d, " \ "hostname too long, exceeds %d bytes", \ __LINE__, (int)sizeof(item_value)); return EINVAL; } memcpy(item_value, pItem->value, nValueLen + 1); nHeadLen = pStart - pItem->value; memcpy(hostname, pItem->value, nHeadLen); result = parse_range_hosts(pItem->value, item_value + nHeadLen, item_value + (pEnd - pItem->value), hostname, nHeadLen, allow_ip_addrs, &alloc_count, allow_ip_count, pItemEnd - pItem); if (result != 0) { return result; } } if (*allow_ip_count == 0) { logWarning("file: "__FILE__", line: %d, " \ "allow ip count: 0", __LINE__); } if (*allow_ip_count > 0) { qsort(*allow_ip_addrs, *allow_ip_count, sizeof(in_addr_t), \ cmp_by_ip_addr_t); } logDebug("allow_ip_count=%d", *allow_ip_count); for (i=0; i<*allow_ip_count; i++) { struct in_addr address; address.s_addr = (*allow_ip_addrs)[i]; logDebug("%d. %s", i + 1, inet_ntoa(address)); } return 0; }