1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
/*
* Project : ipv6calc
* File : libifinet6.c
* Version : $Id: bcc62b44d5a02661398cd7141ed50d1529d2284b $
* Copyright : 2001-2017 by Peter Bieringer <pb (at) bieringer.de>
*
* Information:
* Function to convert an address string like shown in
* Linux /proc/net/if_inet6 to IPv6 address structure
*
* some hints taken from ifconfig.c (net-tools)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libipv6calc.h"
#include "libipv6calcdebug.h"
#include "libifinet6.h"
/*
* function formats a given Linux /proc/net/if_inet6 format to normal one
*
* in : *addrstring = IPv6 address
* out: *resultstring = result
* ret: ==0: ok, !=0: error
*/
int libifinet6_ifinet6_to_ipv6addrstruct(const char *addrstring, char *resultstring, const size_t resultstring_length, ipv6calc_ipv6addr *ipv6addrp) {
int retval = 1;
char tempstring[IPV6CALC_STRING_MAX];
char addr6p[8][5];
DEBUGPRINT_WA(DEBUG_libifinet6, "Got input '%s'", addrstring);
/* simple test */
if ( strlen(addrstring) != 32 ) {
snprintf(resultstring, resultstring_length, "Error in given hex string, has not 32 chars!");
retval = 1;
return (retval);
};
/* scan address into array */
retval = sscanf(addrstring, "%4s%4s%4s%4s%4s%4s%4s%4s\n", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
if ( retval != 8 ) {
snprintf(resultstring, resultstring_length, "Error splitting string %s, got only %d items!", addrstring, retval);
retval = 1;
return (retval);
};
/* print out into temp string */
snprintf(tempstring, sizeof(tempstring), "%s:%s:%s:%s:%s:%s:%s:%s", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
DEBUGPRINT_WA(DEBUG_libifinet6, "Filled: %s", tempstring);
/* fill structure */
retval = addr_to_ipv6addrstruct(tempstring, resultstring, resultstring_length, ipv6addrp);
return (retval);
};
/*
* function formats a given /proc/net/if_inet6 format to normal one with prefixlength
*
* in : *addrstring = IPv6 address
* out: *resultstring = result
* ret: ==0: ok, !=0: error
*/
int libifinet6_ifinet6_withprefixlength_to_ipv6addrstruct(const char *addrstring, const char *prefixlengthstring, char *resultstring, const size_t resultstring_length, ipv6calc_ipv6addr *ipv6addrp) {
int retval = 1, result, tempint;
char tempstring[IPV6CALC_STRING_MAX];
uint8_t prefixlength = 0;
DEBUGPRINT_WA(DEBUG_libifinet6, "Got input addressstring: '%s', prefixlengthstring: '%s'", addrstring, prefixlengthstring);
/* simple test on prefix length string*/
if ( strlen(prefixlengthstring) != 2 ) {
snprintf(resultstring, resultstring_length, "Given prefixlength hex string '%s' has not 2 chars!", prefixlengthstring);
retval = 1;
return (retval);
};
/* scan prefix length */
result = sscanf(prefixlengthstring, "%2x\n", &tempint);
if ( result != 1 ) {
snprintf(resultstring, resultstring_length, "error splitting string %s, got only %d items!", prefixlengthstring, result);
retval = 1;
return (retval);
};
if ( (tempint < 0) || (tempint > 128) ) {
snprintf(resultstring, resultstring_length, "decimal prefixlength '%d' out of range!", tempint);
retval = 1;
return (retval);
};
prefixlength = (uint8_t) tempint;
/* convert plain address */
result = libifinet6_ifinet6_to_ipv6addrstruct(addrstring, tempstring, sizeof(tempstring), ipv6addrp);
if ( result != 0 ) {
snprintf(resultstring, resultstring_length, "%s", tempstring);
retval = 1;
return (retval);
};
/* set prefix length */
ipv6addrp->prefixlength = (uint8_t) prefixlength;
ipv6addrp->flag_prefixuse = 1;
DEBUGPRINT_WA(DEBUG_libifinet6, "Print: '%s'", resultstring);
retval = 0;
return (retval);
};
/*
* function formats a given IPv6 address to Linux /proc/net/if_inet6 format
*
* in : *addrstring = IPv6 address
* out: *resultstring = result
* ret: ==0: ok, !=0: error
*/
int libifinet6_ipv6addrstruct_to_ifinet6(const ipv6calc_ipv6addr *ipv6addrp, char *resultstring, const size_t resultstring_length) {
int retval = 1;
char tempstring[IPV6CALC_STRING_MAX];
/* print out array */
snprintf(tempstring, sizeof(tempstring), "%08x%08x%08x%08x %02x", (unsigned int) ipv6addr_getdword(ipv6addrp, 0), (unsigned int) ipv6addr_getdword(ipv6addrp, 1), (unsigned int) ipv6addr_getdword(ipv6addrp, 2), (unsigned int) ipv6addr_getdword(ipv6addrp, 3), (unsigned int) ipv6addrp->typeinfo & IPV6_ADDR_SCOPE_MASK);
if ( (*ipv6addrp).flag_prefixuse == 1 ) {
snprintf(resultstring, resultstring_length, "%s %02x", tempstring, (unsigned int) ipv6addrp->prefixlength);
} else {
snprintf(resultstring, resultstring_length, "%s", tempstring);
};
DEBUGPRINT_WA(DEBUG_libifinet6, "print out: %s", resultstring);
retval = 0;
return (retval);
};
|