File: libifinet6.c

package info (click to toggle)
ipv6calc 4.1.0-0.3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,676 kB
  • sloc: ansic: 101,567; sh: 6,796; perl: 3,867; xml: 1,475; makefile: 909
file content (140 lines) | stat: -rw-r--r-- 4,790 bytes parent folder | download | duplicates (2)
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);
};