Android读ipconfig.txt配置文件乱码

直接读/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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值