diff options
author | Chengyi Zhao <chengyi1.zhao@archermind.com> | 2013-07-10 19:17:02 +0800 |
---|---|---|
committer | Zhang zhengguang <zhengguang.zhang@intel.com> | 2014-10-31 16:06:20 +0800 |
commit | 5bd77bc62bc47d5752a9060cb887883a9d1b9844 (patch) | |
tree | fe5e6cf319fe3558b7b431e768c922fc362f4bab /gdhcp/common.c | |
parent | c7d7214b511b0fa8b43f21b3b87416051fa9ef29 (diff) | |
download | connman-5bd77bc62bc47d5752a9060cb887883a9d1b9844.tar.gz connman-5bd77bc62bc47d5752a9060cb887883a9d1b9844.tar.bz2 connman-5bd77bc62bc47d5752a9060cb887883a9d1b9844.zip |
Tethering: Add interface that save lease in DHCP information
Change-Id: Ia09c875954d8a20a3e6c39f87076780d8a6582e4
Diffstat (limited to 'gdhcp/common.c')
-rw-r--r-- | gdhcp/common.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/gdhcp/common.c b/gdhcp/common.c index 45278a88..ac6b1250 100644 --- a/gdhcp/common.c +++ b/gdhcp/common.c @@ -144,6 +144,71 @@ int dhcp_end_option(uint8_t *optionptr) return i; } +/* get a rough idea of how long an option will be */ +static const uint8_t len_of_option_as_string[] = { + [OPTION_IP] = sizeof("255.255.255.255 "), + [OPTION_STRING] = 1, + [OPTION_U8] = sizeof("255 "), + [OPTION_U16] = sizeof("65535 "), + [OPTION_U32] = sizeof("4294967295 "), +}; + +static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) +{ + return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); +} + +/* Create "opt_value1 option_value2 ..." string */ +char *malloc_option_value_string(uint8_t *option, GDHCPOptionType type) +{ + unsigned upper_length; + int len, optlen; + char *dest, *ret; + + len = option[OPT_LEN - OPT_DATA]; + type &= OPTION_TYPE_MASK; + optlen = dhcp_option_lengths[type]; + if (optlen == 0) + return NULL; + upper_length = len_of_option_as_string[type] * + ((unsigned)len / (unsigned)optlen); + dest = ret = g_malloc(upper_length + 1); + if (ret == NULL) + return NULL; + + while (len >= optlen) { + switch (type) { + case OPTION_IP: + dest += sprint_nip(dest, "", option); + break; + case OPTION_U16: { + uint16_t val_u16 = get_be16(option); + dest += sprintf(dest, "%u", val_u16); + break; + } + case OPTION_U32: { + uint32_t val_u32 = get_be32(option); + dest += sprintf(dest, "%u", val_u32); + break; + } + case OPTION_STRING: + memcpy(dest, option, len); + dest[len] = '\0'; + return ret; + default: + break; + } + option += optlen; + len -= optlen; + if (len <= 0) + break; + *dest++ = ' '; + *dest = '\0'; + } + + return ret; +} + uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len, int code, uint16_t *option_len, int *option_count) { |