1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00
RIOT/sys/net/network_layer/ipv6/addr/ipv6_addr.c
Leandro Lanzieri 4d4f6ae1d6 net/ipv6: Return string pointer when splitting IPv6 interface.
Right now 'ipv6_addr_split_iface' assumes that the interface specifier
will always be a number (based on GNRC way of identifying interfaces),
but this may not be always the case.In order to be able to use the
Network Interface API, interfaces should be referred by their name.

This changes 'ipv6_addr_split_iface' so it returns a pointer to the
string that specifies the interface.
2019-11-15 14:02:50 +01:00

160 lines
3.6 KiB
C

/*
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for
* more details.
*/
/**
* @{
*
* @file
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "net/ipv6/addr.h"
#ifdef MODULE_FMT
#include "fmt.h"
#else
#include <stdio.h>
#endif
const ipv6_addr_t ipv6_addr_unspecified = IPV6_ADDR_UNSPECIFIED;
const ipv6_addr_t ipv6_addr_loopback = IPV6_ADDR_LOOPBACK;
const ipv6_addr_t ipv6_addr_link_local_prefix = IPV6_ADDR_LINK_LOCAL_PREFIX;
const ipv6_addr_t ipv6_addr_solicited_node_prefix = IPV6_ADDR_SOLICITED_NODE_PREFIX;
const ipv6_addr_t ipv6_addr_all_nodes_if_local = IPV6_ADDR_ALL_NODES_IF_LOCAL;
const ipv6_addr_t ipv6_addr_all_nodes_link_local = IPV6_ADDR_ALL_NODES_LINK_LOCAL;
const ipv6_addr_t ipv6_addr_all_routers_if_local = IPV6_ADDR_ALL_ROUTERS_IF_LOCAL;
const ipv6_addr_t ipv6_addr_all_routers_link_local = IPV6_ADDR_ALL_ROUTERS_LINK_LOCAL;
const ipv6_addr_t ipv6_addr_all_routers_site_local = IPV6_ADDR_ALL_ROUTERS_SITE_LOCAL;
bool ipv6_addr_equal(const ipv6_addr_t *a, const ipv6_addr_t *b)
{
return (a->u64[0].u64 == b->u64[0].u64) &&
(a->u64[1].u64 == b->u64[1].u64);
}
uint8_t ipv6_addr_match_prefix(const ipv6_addr_t *a, const ipv6_addr_t *b)
{
uint8_t prefix_len = 0;
if ((a == NULL) || (b == NULL)) {
return 0;
}
if (a == b) {
return 128;
}
for (int i = 0; i < 16; i++) {
/* if bytes are equal add 8 */
if (a->u8[i] == b->u8[i]) {
prefix_len += 8;
}
else {
uint8_t xor = (a->u8[i] ^ b->u8[i]);
/* while bits from byte equal add 1 */
for (int j = 0; j < 8; j++) {
if ((xor & 0x80) == 0) {
prefix_len++;
xor = xor << 1;
}
else {
break;
}
}
break;
}
}
return prefix_len;
}
void ipv6_addr_init_prefix(ipv6_addr_t *out, const ipv6_addr_t *prefix,
uint8_t bits)
{
uint8_t bytes;
if (bits > 128) {
bits = 128;
}
bytes = bits / 8;
memcpy(out, prefix, bytes);
if (bits % 8) {
uint8_t mask = 0xff << (8 - (bits - (bytes * 8)));
out->u8[bytes] &= ~mask;
out->u8[bytes] |= (prefix->u8[bytes] & mask);
}
}
void ipv6_addr_init_iid(ipv6_addr_t *out, const uint8_t *iid, uint8_t bits)
{
uint8_t unaligned_bits, bytes, pos;
if (bits > 128) {
bits = 128;
}
unaligned_bits = bits % 8;
bytes = bits / 8;
pos = (IPV6_ADDR_BIT_LEN / 8) - bytes;
if (unaligned_bits) {
uint8_t mask = 0xff << unaligned_bits;
out->u8[pos - 1] &= mask;
out->u8[pos - 1] |= (*iid & ~mask);
iid++;
}
memcpy(&(out->u8[pos]), iid, bytes);
}
char *ipv6_addr_split_str(char *addr_str, char seperator)
{
char *sep = addr_str;
while (*(++sep)) {
if (*sep == seperator) {
*sep++ = '\0';
break;
}
}
return *sep ? sep : NULL;
}
int ipv6_addr_split_int(char *addr_str, char separator, int _default)
{
char *val = ipv6_addr_split_str(addr_str, separator);
return val ? atoi(val) : _default;
}
void ipv6_addr_print(const ipv6_addr_t *addr)
{
assert(addr);
char addr_str[IPV6_ADDR_MAX_STR_LEN];
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str));
#ifdef MODULE_FMT
print_str(addr_str);
#else
printf("%s", addr_str);
#endif
}
/**
* @}
*/