直接读/data/misc/ethernet/ipconfig.txt文件显示乱码
C语言实现方式
使用如下方式读取ipconfig.txt
代码结构
Android.mk
data.c
data.h
ipconfig.c
ipconfig.h
main.c
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= main.c data.c ipconfig.c
#LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_CFLAGS += -Wall -Wno-unused-parameter -Wextra
# -Wno-implicit-function-declaration
LOCAL_SHARED_LIBRARIES := \
libcutils \
liblog \
libandroidfw \
libutils \
libbinder \
libjsoncpp
LOCAL_MODULE := ipcnfigstore
include $(BUILD_EXECUTABLE)
data.c
#define _GNU_SOURCE
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "data.h"
uint16_t convertBigEndianUInt16(uint16_t value)
{
union { uint16_t value; unsigned char data[2]; } aux = { 0x4142 };
if (aux.data[0] == 0x41)
{
return value;
}
aux.data[0] = (value >> 8) & 0xff;
aux.data[1] = value & 0xff;
return aux.value;
}
uint32_t convertBigEndianUInt32(uint32_t value)
{
union { uint32_t value; unsigned char data[4]; } aux = { 0x41424344 };
if (aux.data[0] == 0x41)
{
return value;
}
aux.data[0] = (value >> 24) & 0xff;
aux.data[1] = (value >> 16) & 0xff;
aux.data[2] = (value >> 8) & 0xff;
aux.data[3] = value & 0xff;
return aux.value;
}
bool readPackedLink(FILE *stream, struct IPConfigLink *link)
{
char **address = &link->address;
uint32_t *prefix = &link->prefix;
if (!readPackedString(stream, address))
{
return false;
}
if (!readPackedUInt32(stream, prefix))
{
return false;
}
return true;
}
bool readPackedRoute(FILE *stream, struct IPConfigRoute *route)
{
char **destinationAddress = &route->destination.address;
uint32_t *destinationPrefix = &route->destination.prefix;
char **nextHop = &route->nextHop;
uint32_t haveDestination = 0;
uint32_t haveNextHop = 0;
if (!readPackedUInt32(stream, &haveDestination))
{
return false;
}
if (haveDestination)
{
if (!readPackedString(stream, destinationAddress))
{
return false;
}
if (!readPackedUInt32(stream, destinationPrefix))
{
return false;
}
}
if (!readPackedUInt32(stream, &haveNextHop))
{
return false;
}
if (haveNextHop)
{
if (!readPackedString(stream, nextHop))
{
return false;
}
}
return true;
}
bool readPackedString(FILE *stream, char **string)
{
uint16_t length = 0;
if (!readPackedUInt16(stream, &length))
{
return false;
}
while (length == 0)
{
if (fseek(stream, sizeof(uint16_t), SEEK_CUR) == -1)
{
return false;
}
if (!readPackedUInt16(stream, &length))
{
return false;
}
}
*string = calloc(1, length + 1);
if (!*string)
{
return false;
}
if (fread(*string, length, 1, stream) != 1)
{
if (!feof(stream))
{
free(*string);
return false;
}
}
return true;
}
bool readPackedUInt16(FILE *stream, uint16_t *value)
{
uint16_t buffer = 0;
if (fread(&buffer, sizeof buffer, 1, stream) != 1)
{
return false;
}
*value = convertBigEndianUInt16(buffer);
return true;
}
bool readPackedUInt32(FILE *stream, uint32_t *value)
{
uint32_t buffer = 0;
if (fread(&buffer, sizeof buffer, 1, stream) != 1)
{
return false;
}
*value = convertBigEndianUInt32(buffer);
return true;
}
bool writePackedRoute(struct IPConfigRoute *route, FILE *stream)
{
struct IPConfigLink *destination = &route->destination;
if (destination->address && destination->prefix)
{
if (!writePackedUInt32(1, stream))
{
return false;
}
if (!writePackedString(destination->address, stream))
{
return false;
}
if (!writePackedUInt32(destination->prefix, stream))
{
return false;
}
}
else
{
if (!writePackedUInt32(0, stream))
{
return false;
}
}
if (route->nextHop)
{
if (!writePackedUInt32(1, stream))
{
return false;
}
if (!writePackedString(route->nextHop, stream))
{
return false;
}
}
else
{
if (!writePackedUInt32(0, stream))
{
return false;
}
}
return true;
}
bool writePackedLink(struct IPConfigLink *link, FILE *stream)
{
if (!writePackedString(link->address, stream))
{
return false;
}
if (!writePackedUInt32(link->prefix, stream))
{
return false;
}
return true;
}
bool writePackedString(char *string, FILE *stream)
{
size_t stringLength = strlen(string);
if (!writePackedUInt16(stringLength, stream))
{
return false;
}
return fwrite(string, stringLength, 1, stream) == 1;
}
bool writePackedUInt16(uint16_t value, FILE *stream)
{
uint16_t buffer = convertBigEndianUInt16(value);
return fwrite(&buffer, sizeof buffer, 1, stream) == 1;
}
bool writePackedUInt32(uint32_t value, FILE *stream)
{
uint32_t buffer = convertBigEndianUInt32(value);
return fwrite(&buffer, sizeof buffer, 1, stream) == 1;
}
bool readUnpackedLine(FILE *stream, char **line)
{
char *cursor = NULL;
*line = calloc(1, BUFSIZ);
if (!*line)
{
return false;
}
cursor = *line;
while (cursor - *line < BUFSIZ)
{
int character = fgetc(stream);
if (character == EOF || character == '\n')
{
break;
}
*cursor++ = character;
}
return true;
}
bool parseUnpackedPair(char *line, char **key, char **value)
{
char *next = strchr(line, ':');
if (!next)
{
return false;
}
*key = strndup(line, next - line);
if (!*key)
{
return false;
}
while (*++next && isspace(*next));
*value = strdup(next);
if (!*value)
{
free(*key);
return false;
}
return true;
}
bool parseUnpackedRoute(char *string, struct IPConfigRoute *route)
{
char *next = strchr(string, ' ');
if (next)
{
*next = 0;
if (!parseUnpackedLink(string, &route->destination))
{
return false;
}
string = ++next;
}
route->nextHop = strdup(string);
if (!route->nextHop)
{
return false;
}
return true;
}
bool parseUnpackedLink(char *string, struct IPConfigLink *link)
{
char *next = strchr(string, '/');
if (!next)
{
return false;
}
link->address = strndup(string, next - string);
if (!link->address)
{
return false;
}
if (!parseUnpackedUInt32(++next, &link->prefix))
{
free(link->address);
return false;
}
return true;
}
bool parseUnpackedUInt32(char *string, uint32_t *integer)
{
char *terminator = NULL;
unsigned long value = strtoul(string, &terminator, 10);
if (*terminator)
{
return false;
}
*integer = value % UINT32_MAX;
return true;
}
data.h
#ifndef IPCONFIG_DATA_H
#define IPCONFIG_DATA_H
#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include "ipconfig.h"
uint16_t convertBigEndianUInt16(uint16_t value);
uint32_t convertBigEndianUInt32(uint32_t value);
bool readPackedRoute(FILE *stream, struct IPConfigRoute *route);
bool readPackedLink(FILE *stream, struct IPConfigLink *link);
bool readPackedString(FILE *stream, char **string);
bool readPackedUInt16(FILE *stream, uint16_t *value);
bool readPackedUInt32(FILE *stream, uint32_t *value);
bool writePackedRoute(struct IPConfigRoute *route, FILE *stream);
bool writePackedLink(struct IPConfigLink *link, FILE *stream);
bool writePackedString(char *string, FILE *stream);
bool writePackedUInt16(uint16_t value, FILE *stream);
bool writePackedUInt32(uint32_t value, FILE *stream);
bool readUnpackedLine(FILE *stream, char **line);
bool parseUnpackedPair(char *line, char **key, char **value);
bool parseUnpackedRoute(char *string, struct IPConfigRoute *route);
bool parseUnpackedLink(char *string, struct IPConfigLink *link);
bool parseUnpackedUInt32(char *string, uint32_t *integer);
#endif
ipconfig.c
#define _DEFAULT_SOURCE
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include "data.h"
#include "ipconfig.h"
#include "error.h"
#define calculateElementCount(array) (sizeof array / sizeof *array)
static const uint32_t IPConfigFileMinimumVersion = 1;
static const uint32_t IPConfigFileMaximumVersion = 3;
static char *IPConfigTerminatorKey = "eos";
static struct IPConfigAttributeKey IPConfigVersion1AttributeKeys[] =
{
{"id", IntegerIPConfigAttributeType},
{"ipAssignment", StringIPConfigAttributeType},
{"linkAddress", LinkIPConfigAttributeType},
{"gateway", StringIPConfigAttributeType},
{"dns", StringIPConfigAttributeType},
{"proxySettings", StringIPConfigAttributeType},
{"proxyHost", StringIPConfigAttributeType},
{"proxyPort", IntegerIPConfigAttributeType},
{"proxyPac", StringIPConfigAttributeType},
{"exclusionList", StringIPConfigAttributeType},
{"eos", TerminalIPConfigAttributeType}
};
static size_t IPConfigVersion1AttributeKeyCount =
calculateElementCount(IPConfigVersion1AttributeKeys);
static struct IPConfigAttributeKey IPConfigVersion2AttributeKeys[] =
{
{"id", IntegerIPConfigAttributeType},
{"ipAssignment", StringIPConfigAttributeType},
{"linkAddress", LinkIPConfigAttributeType},
{"gateway", RouteIPConfigAttributeType},
{"dns", StringIPConfigAttributeType},
{"proxySettings", StringIPConfigAttributeType},
{"proxyHost", StringIPConfigAttributeType},
{"proxyPort", IntegerIPConfigAttributeType},
{"proxyPac", StringIPConfigAttributeType},
{"exclusionList", StringIPConfigAttributeType},
{"eos", TerminalIPConfigAttributeType}
};
static size_t IPConfigVersion2AttributeKeyCount =
calculateElementCount(IPConfigVersion2AttributeKeys);
static struct IPConfigAttributeKey IPConfigVersion3AttributeKeys[] =
{
{"id", StringIPConfigAttributeType},
{"ipAssignment", StringIPConfigAttributeType},
{"linkAddress", LinkIPConfigAttributeType},
{"gateway", RouteIPConfigAttributeType},
{"dns", StringIPConfigAttributeType},
{"proxySettings", StringIPConfigAttributeType},
{"proxyHost", StringIPConfigAttributeType},
{"proxyPort", IntegerIPConfigAttributeType},
{"proxyPac", StringIPConfigAttributeType},
{"exclusionList", StringIPConfigAttributeType},
{"eos", TerminalIPConfigAttributeType}
};
static size_t IPConfigVersion3AttributeKeyCount =
calculateElementCount(IPConfigVersion3AttributeKeys);
static enum IPConfigAttributeType getAttributeType(uint32_t version, char *key)
{
size_t keyLength = strlen(key);
struct IPConfigAttributeKey *keys = NULL;
size_t count = 0;
switch (version)
{
case 1:
keys = IPConfigVersion1AttributeKeys;
count = IPConfigVersion1AttributeKeyCount;
break;
case 2:
keys = IPConfigVersion2AttributeKeys;
count = IPConfigVersion2AttributeKeyCount;
break;
case 3:
keys = IPConfigVersion3AttributeKeys;
count = IPConfigVersion3AttributeKeyCount;
break;
default:
break;
};
for (size_t index = 0; index < count; index++)
{
char *candidate = keys[index].key;
size_t maximumLength = strlen(candidate);
if (keyLength > maximumLength)
{
maximumLength = keyLength;
}
if (!strncmp(candidate, key, maximumLength))
{
return keys[index].type;
}
}
return InvalidIPConfigAttributeType;
}
static void appendAttribute(struct IPConfigAttribute *attribute,
struct IPConfig *config)
{
if (!config->attributes)
{
config->attributes = attribute;
}
else
{
struct IPConfigAttribute *previous = config->attributes;
while (previous->next)
{
previous = previous->next;
}
previous->next = attribute;
}
}
bool readPackedIPConfig(FILE *stream, struct IPConfig *config)
{
if (!readPackedUInt32(stream, &config->version))
{
printError("failed to read file version");
return NULL;
}
if (config->version < IPConfigFileMinimumVersion ||
config->version > IPConfigFileMaximumVersion)
{
printError("unrecognized file version");
return NULL;
}
while (!feof(stream))
{
struct IPConfigAttribute *attribute = NULL;
attribute = calloc(1, sizeof(struct IPConfigAttribute));
if (!attribute)
{
printLibraryError("calloc");
deinitializeIPConfig(config);
return NULL;
}
appendAttribute(attribute, config);
if (!readPackedString(stream, &attribute->key))
{
printError("failed to read attribute key");
deinitializeIPConfig(config);
return NULL;
}
attribute->type = getAttributeType(config->version,
attribute->key);
if (attribute->type == InvalidIPConfigAttributeType)
{
printError("unrecognized attribute key");
deinitializeIPConfig(config);
return NULL;
}
else if (attribute->type == TerminalIPConfigAttributeType)
{
break;
}
else if (attribute->type == IntegerIPConfigAttributeType)
{
uint32_t *integer = &attribute->value.integer;
if (!readPackedUInt32(stream, integer))
{
printError("failed to read integer");
deinitializeIPConfig(config);
return NULL;
}
}
else if (attribute->type == StringIPConfigAttributeType)
{
char **string = &attribute->value.string;
if (!readPackedString(stream, string))
{
printError("failed to read string");
deinitializeIPConfig(config);
return NULL;
}
}
else if (attribute->type == LinkIPConfigAttributeType)
{
if (!readPackedLink(stream, &attribute->value.link))
{
printError("failed to read link");
deinitializeIPConfig(config);
return NULL;
}
}
else if (attribute->type == RouteIPConfigAttributeType)
{
if (!readPackedRoute(stream, &attribute->value.route))
{
printError("failed to read route");
deinitializeIPConfig(config);
return NULL;
}
}
}
return config;
}
void deinitializeIPConfig(struct IPConfig *config)
{
struct IPConfigAttribute *next = NULL;
struct IPConfigAttribute *attribute = config->attributes;
while (attribute)
{
union IPConfigValue *value = &attribute->value;
if (attribute->type == StringIPConfigAttributeType)
{
free(value->string);
}
else if (attribute->type == LinkIPConfigAttributeType)
{
free(value->link.address);
}
else if (attribute->type == RouteIPConfigAttributeType)
{
if (value->route.destination.address)
{
free(value->route.destination.address);
}
if (value->route.nextHop)
{
free(value->route.nextHop);
}
}
next = attribute->next;
free(attribute->key);
free(attribute);
attribute = next;
}
}
bool writePackedIPConfig(struct IPConfig *config, FILE *stream)
{
bool terminated = false;
struct IPConfigAttribute *attribute = config->attributes;
if (!writePackedUInt32(config->version, stream))
{
printError("failed to write file version");
return false;
}
while (attribute)
{
union IPConfigValue *value = &attribute->value;
if (!writePackedString(attribute->key, stream))
{
printError("failed to write key");
return false;
}
if (attribute->type == TerminalIPConfigAttributeType)
{
terminated = true;
break;
}
else if (attribute->type == IntegerIPConfigAttributeType)
{
if (!writePackedUInt32(value->integer, stream))
{
printError("failed to write integer");
return false;
}
}
else if (attribute->type == StringIPConfigAttributeType)
{
if (!writePackedString(value->string, stream))
{
printError("failed to write string");
return false;
}
}
else if (attribute->type == LinkIPConfigAttributeType)
{
if (!writePackedLink(&value->link, stream))
{
printError("failed to write link");
return false;
}
}
else if (attribute->type == RouteIPConfigAttributeType)
{
if (!writePackedRoute(&value->route, stream))
{
printError("failed to write route");
return false;
}
}
attribute = attribute->next;
}
if (!terminated)
{
if (!writePackedString(IPConfigTerminatorKey, stream))
{
printError("failed to write terminator");
return false;
}
}
return true;
}
bool writeUnpackedIPConfig(struct IPConfig *config, FILE *stream)
{
struct IPConfigAttribute *attribute = config->attributes;
while (attribute)
{
if (attribute->type == IntegerIPConfigAttributeType)
{
fprintf(stream, "%s: %" PRIu32 "\n",
attribute->key,
attribute->value.integer);
}
else if (attribute->type == StringIPConfigAttributeType)
{
fprintf(stream, "%s: %s\n",
attribute->key,
attribute->value.string);
}
else if (attribute->type == LinkIPConfigAttributeType)
{
struct IPConfigLink *link = &attribute->value.link;
fprintf(stream, "%s: %s/%" PRIu32 "\n",
attribute->key,
link->address,
link->prefix);
}
else if (attribute->type == RouteIPConfigAttributeType)
{
struct IPConfigRoute *route = &attribute->value.route;
struct IPConfigLink *destination = &route->destination;
if (destination->address && destination->prefix)
{
fprintf(stream, "%s: %s/%" PRIu32 " %s\n",
attribute->key,
destination->address,
destination->prefix,
route->nextHop);
}
else
{
fprintf(stream, "%s: %s\n",
attribute->key,
route->nextHop);
}
}
attribute = attribute->next;
}
return true;
}
bool readUnpackedIPConfig(FILE *stream, struct IPConfig *config)
{
if (config->version < IPConfigFileMinimumVersion ||
config->version > IPConfigFileMaximumVersion)
{
printError("unrecognized file version");
return false;
}
while (!feof(stream))
{
char *line = NULL;
char *value = NULL;
struct IPConfigAttribute *attribute = NULL;
attribute = calloc(1, sizeof(struct IPConfigAttribute));
if (!attribute)
{
printLibraryError("calloc");
deinitializeIPConfig(config);
return false;
}
appendAttribute(attribute, config);
if (!readUnpackedLine(stream, &line))
{
printError("failed to read line");
deinitializeIPConfig(config);
return false;
}
if (strlen(line) == 0)
{
free(line);
if (feof(stream))
{
attribute->key = strdup(IPConfigTerminatorKey);
break;
}
continue;
}
if (!parseUnpackedPair(line, &attribute->key, &value))
{
printError("failed to read pair");
deinitializeIPConfig(config);
free(line);
return false;
}
free(line);
attribute->type = getAttributeType(config->version,
attribute->key);
if (!attribute->type)
{
printError("unrecognized attribute type");
deinitializeIPConfig(config);
free(value);
return false;
}
else if (attribute->type == IntegerIPConfigAttributeType)
{
uint32_t *integer = &attribute->value.integer;
if (!parseUnpackedUInt32(value, integer))
{
printError("failed to read integer");
deinitializeIPConfig(config);
free(value);
return false;
}
free(value);
}
else if (attribute->type == StringIPConfigAttributeType)
{
attribute->value.string = value;
}
else if (attribute->type == LinkIPConfigAttributeType)
{
if (!parseUnpackedLink(value, &attribute->value.link))
{
printError("failed to read link");
deinitializeIPConfig(config);
free(value);
return false;
}
free(value);
}
else if (attribute->type == RouteIPConfigAttributeType)
{
struct IPConfigRoute *route = &attribute->value.route;
if (!parseUnpackedRoute(value, route))
{
printError("failed to read route");
deinitializeIPConfig(config);
free(value);
return false;
}
free(value);
}
}
return true;
}
void printConfig(struct IPConfig *config) {
struct IPConfigAttribute *attribute = config->attributes;
while (attribute)
{
if (attribute->type == RouteIPConfigAttributeType) {
struct IPConfigRoute *route = &attribute->value.route;
struct IPConfigLink *destination = &route->destination;
if (destination->address && destination->prefix) {
printf("%s: %s/%" PRIu32 " %s\n",attribute->key,destination->address,destination->prefix,route->nextHop);
}
if (strcmp(attribute->key,"gateway") == 0) {
strcpy(static_cfg[2],route->nextHop);
}
}
if (strcmp(attribute->key,"linkAddress") == 0) {
struct IPConfigLink *link = &attribute->value.link;
strcpy(static_cfg[0],attribute->value.string);
ipv4_prefixlen2str(link->prefix,static_cfg[1]);
strcpy(static_cfg[5],static_cfg[0]);
char str[25];
sprintf(str,"/%d",link->prefix);
strcat(static_cfg[5],str);
} else if (strcmp(attribute->key,"dns") == 0) {
if (strlen(static_cfg[3]) != 0) {
strcpy(static_cfg[4],attribute->value.string);
} else {
strcpy(static_cfg[3],attribute->value.string);
}
}
//printf("%d,%s:%s --> ", attribute->type, attribute->key, attribute->value.string);
attribute = attribute->next;
}
//printf("\n");
}
bool genPackedDHCPIPConfig(struct IPConfig *config) {
if (config->version < IPConfigFileMinimumVersion ||
config->version > IPConfigFileMaximumVersion)
{
printError("unrecognized file version");
return false;
}
char static_cfg[3][40] = {
"ipAssignment: DHCP",
"proxySettings: NONE",
"id: eth0"
};
for (int i = 0; i < 3; i++ ) {
// printf("%s\n", static_cfg[i]);
// char *line = NULL;
char *value = NULL;
struct IPConfigAttribute *attribute = NULL;
attribute = calloc(1, sizeof(struct IPConfigAttribute));
if (!attribute)
{
printLibraryError("calloc");
deinitializeIPConfig(config);
return false;
}
appendAttribute(attribute, config);
if (!parseUnpackedPair(static_cfg[i], &attribute->key, &value))
{
printError("failed to read pair");
deinitializeIPConfig(config);
free(static_cfg[i]);
return false;
}
attribute->type = getAttributeType(config->version,
attribute->key);
if (!attribute->type)
{
printError("unrecognized attribute type");
deinitializeIPConfig(config);
free(value);
return false;
}
else if (attribute->type == IntegerIPConfigAttributeType)
{
uint32_t *integer = &attribute->value.integer;
if (!parseUnpackedUInt32(value, integer))
{
printError("failed to read integer");
deinitializeIPConfig(config);
free(value);
return false;
}
free(value);
}
else if (attribute->type == StringIPConfigAttributeType)
{
attribute->value.string = value;
}
else if (attribute->type == LinkIPConfigAttributeType)
{
if (!parseUnpackedLink(value, &attribute->value.link))
{
printError("failed to read link");
deinitializeIPConfig(config);
free(value);
return false;
}
free(value);
}
else if (attribute->type == RouteIPConfigAttributeType)
{
struct IPConfigRoute *route = &attribute->value.route;
if (!parseUnpackedRoute(value, route))
{
printError("failed to read route");
deinitializeIPConfig(config);
free(value);
return false;
}
free(value);
}
}
return true;
}
bool genPackedIPConfig(struct IPConfig *config, char *linkAddress, char *gw, char *dns1, char *dns2)
{
if (config->version < IPConfigFileMinimumVersion ||
config->version > IPConfigFileMaximumVersion)
{
printError("unrecognized file version");
return false;
}
char static_cfg[7][100] = {
"ipAssignment: STATIC",
"linkAddress: ",
"gateway: ",
"dns: ",
"dns: ",
"proxySettings: NONE",
"id: eth0"
};
strcat(static_cfg[1], linkAddress);
strcat(static_cfg[2], gw);
strcat(static_cfg[3], dns1);
strcat(static_cfg[4], dns2);
for (int i = 0; i < 7; i++ ) {
// printf("%s\n", static_cfg[i]);
// char *line = NULL;
char *value = NULL;
struct IPConfigAttribute *attribute = NULL;
attribute = calloc(1, sizeof(struct IPConfigAttribute));
if (!attribute)
{
printLibraryError("calloc");
deinitializeIPConfig(config);
return false;
}
appendAttribute(attribute, config);
if (!parseUnpackedPair(static_cfg[i], &attribute->key, &value))
{
printError("failed to read pair");
deinitializeIPConfig(config);
free(static_cfg[i]);
return false;
}
attribute->type = getAttributeType(config->version,
attribute->key);
if (!attribute->type)
{
printError("unrecognized attribute type");
deinitializeIPConfig(config);
free(value);
return false;
}
else if (attribute->type == IntegerIPConfigAttributeType)
{
uint32_t *integer = &attribute->value.integer;
if (!parseUnpackedUInt32(value, integer))
{
printError("failed to read integer");
deinitializeIPConfig(config);
free(value);
return false;
}
free(value);
}
else if (attribute->type == StringIPConfigAttributeType)
{
attribute->value.string = value;
}
else if (attribute->type == LinkIPConfigAttributeType)
{
if (!parseUnpackedLink(value, &attribute->value.link))
{
printError("failed to read link");
deinitializeIPConfig(config);
free(value);
return false;
}
free(value);
}
else if (attribute->type == RouteIPConfigAttributeType)
{
struct IPConfigRoute *route = &attribute->value.route;
if (!parseUnpackedRoute(value, route))
{
printError("failed to read route");
deinitializeIPConfig(config);
free(value);
return false;
}
free(value);
}
}
return true;
}
int ipv4_prefixlen2str(int prefixlen, char* ip_str)
{
//char tmp[16] = {0};
//char* p = tmp;
unsigned int ip_num = 0;
if (ip_str == NULL) return -1;
if (prefixlen > 32) return -1;
// fast...
if (prefixlen == 8) strcpy(ip_str, "255.0.0.0");
if (prefixlen == 16) strcpy(ip_str, "255.255.0.0");
if (prefixlen == 24) strcpy(ip_str, "255.255.255.0");
if (prefixlen == 32) strcpy(ip_str, "255.255.255.255");
// just in case
for (int i = prefixlen, j = 31; i > 0; i--, j--)
{
//unsigned int tmp = (1<<j);
//printf("%d tmp: %08x\n", i, tmp);
ip_num += (1<<j);
}
//printf("ip_num: %08x\n", ip_num);
sprintf(ip_str, "%u.%u.%u.%u", (ip_num>>24)&0xff, (ip_num>>16)&0xff, (ip_num>>8)&0xff, ip_num&0xff);
return 0;
}
/*
int ipv4_str2prefixlen(const char* ip_str)
{
int ret = 0;
unsigned int ip_num = 0;
unsigned char c1,c2,c3,c4;
int cnt = 0;
ret = sscanf(ip_str, "%hhu.%hhu.%hhu.%hhu", &c1, &c2, &c3, &c4);
ip_num = c1<<24 | c2<<16 | c3<<8 | c4;
// fast...
if (ip_num == 0xffffffff) return 32;
if (ip_num == 0xffffff00) return 24;
if (ip_num == 0xffff0000) return 16;
if (ip_num == 0xff000000) return 6;
// just in case
for (int i = 0; i < 32; i++)
{
//unsigned int tmp = (ip_num<<i);
//printf("%d tmp: %x\n", i+1, tmp);
if ((ip_num<<i) & 0x80000000)
cnt++;
else
break;
}
//printf("cnt: %d\n", cnt);
return cnt;
}
*/
ipconfig.h
#ifndef IPCONFIG_H
#define IPCONFIG_H
#include <stdbool.h>
#include <inttypes.h>
enum IPConfigAttributeType
{
InvalidIPConfigAttributeType = -1,
TerminalIPConfigAttributeType = 0,
IntegerIPConfigAttributeType = 1,
StringIPConfigAttributeType = 2,
LinkIPConfigAttributeType = 3,
RouteIPConfigAttributeType = 4
};
struct IPConfigAttributeKey
{
char *key;
enum IPConfigAttributeType type;
};
struct IPConfigLink
{
char *address;
uint32_t prefix;
};
struct IPConfigRoute
{
struct IPConfigLink destination;
char *nextHop;
};
union IPConfigValue
{
uint32_t integer;
char *string;
struct IPConfigLink link;
struct IPConfigRoute route;
};
struct IPConfigAttribute
{
enum IPConfigAttributeType type;
char *key;
union IPConfigValue value;
struct IPConfigAttribute *next;
};
struct IPConfig
{
uint32_t version;
struct IPConfigAttribute *attributes;
};
extern struct IPConfig config;
// extern char static_cfg[4][100] = {
// "", //ip mask
// "", //gateway
// "", //dns1
// "" //dns2
// };
extern char static_cfg[6][100];
bool readPackedIPConfig(FILE *stream, struct IPConfig *config);
bool readUnpackedIPConfig(FILE *stream, struct IPConfig *config);
bool writePackedIPConfig(struct IPConfig *config, FILE *stream);
bool writeUnpackedIPConfig(struct IPConfig *config, FILE *stream);
void deinitializeIPConfig(struct IPConfig *config);
int writeipconfig(int argc, char *argv[]);
void printConfig(struct IPConfig *config);
bool genPackedIPConfig(struct IPConfig *config, char *linkAddress, char *gw, char *dns1, char *dns2);
bool genPackedDHCPIPConfig(struct IPConfig *config);
int ipv4_prefixlen2str(int prefixlen, char* ip_str);
int ipv4_str2prefixlen(const char* ip_str);
#endif
main.c
#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "ipconfig.h"
#include "error.h"
static void usage(FILE *stream)
{
fprintf(stream, "usage: ipconfigstore OPTION\n");
fprintf(stream, "\n");
fprintf(stream, "Options:\n");
fprintf(stream, " -p VERSION Pack IP configuration\n");
fprintf(stream, " -u Unpack IP configuration\n");
fprintf(stream, "\n");
}
int main(int argc, char *argv[])
{
int option = 0;
struct IPConfig config = {0};
option = getopt(argc, argv, "hp:u");
if (option == 'h')
{
usage(stdout);
return EXIT_SUCCESS;
}
else if (option == 'p')
{
config.version = *optarg - 0x30;
if (!readUnpackedIPConfig(stdin, &config))
{
return EXIT_FAILURE;
}
if (!writePackedIPConfig(&config, stdout))
{
return EXIT_FAILURE;
}
deinitializeIPConfig(&config);
}
else if (option == 'u')
{
FILE *pFile;
pFile = fopen("/data/misc/ethernet/ipconfig.txt", "r");
if(pFile == NULL)//文件指针为空时的措施
{
printf("can not open the file");
fclose(pFile);
return 0;
}
if (!readPackedIPConfig(pFile, &config))
{
return EXIT_FAILURE;
}
if (!writeUnpackedIPConfig(&config, stdout))
{
return EXIT_FAILURE;
}
deinitializeIPConfig(&config);
fclose(pFile);
}
else
{
usage(stderr);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
编译完将生成的ipcnfigstore文件push到 /data目录下给可执行权限
执行结果截图如下(显示结果就是/data/misc/ethernet/ipconfig.txt内容)
源码GitHub地址:
git clone git@github.com:hejiangzhou1/readIpconfig.git