iproute2/tipc/misc.c
<<
>>
Prefs
   1/*
   2 * misc.c       Miscellaneous TIPC helper functions.
   3 *
   4 *              This program is free software; you can redistribute it and/or
   5 *              modify it under the terms of the GNU General Public License
   6 *              as published by the Free Software Foundation; either version
   7 *              2 of the License, or (at your option) any later version.
   8 *
   9 * Authors:     Richard Alpe <richard.alpe@ericsson.com>
  10 */
  11
  12#include <stdio.h>
  13#include <stdint.h>
  14#include <linux/tipc.h>
  15#include <string.h>
  16#include <sys/ioctl.h>
  17#include <sys/socket.h>
  18#include <unistd.h>
  19#include <errno.h>
  20#include "misc.h"
  21
  22#define IN_RANGE(val, low, high) ((val) <= (high) && (val) >= (low))
  23
  24uint32_t str2addr(char *str)
  25{
  26        unsigned int z, c, n;
  27        char dummy;
  28
  29        if (sscanf(str, "%u.%u.%u%c", &z, &c, &n, &dummy) != 3) {
  30                fprintf(stderr, "invalid network address, syntax: Z.C.N\n");
  31                return 0;
  32        }
  33
  34        if (IN_RANGE(z, 0, 255) && IN_RANGE(c, 0, 4095) && IN_RANGE(n, 0, 4095))
  35                return tipc_addr(z, c, n);
  36
  37        fprintf(stderr, "invalid network address \"%s\"\n", str);
  38        return 0;
  39}
  40
  41static int is_hex(char *arr, int last)
  42{
  43        int i;
  44
  45        while (!arr[last])
  46                last--;
  47
  48        for (i = 0; i <= last; i++) {
  49                if (!IN_RANGE(arr[i], '0', '9') &&
  50                    !IN_RANGE(arr[i], 'a', 'f') &&
  51                    !IN_RANGE(arr[i], 'A', 'F'))
  52                        return 0;
  53        }
  54        return 1;
  55}
  56
  57static int is_name(char *arr, int last)
  58{
  59        int i;
  60        char c;
  61
  62        while (!arr[last])
  63                last--;
  64
  65        if (last > 15)
  66                return 0;
  67
  68        for (i = 0; i <= last; i++) {
  69                c = arr[i];
  70                if (!IN_RANGE(c, '0', '9') && !IN_RANGE(c, 'a', 'z') &&
  71                    !IN_RANGE(c, 'A', 'Z') && c != '-' && c != '_' &&
  72                    c != '.' && c != ':' && c != '@')
  73                        return 0;
  74        }
  75        return 1;
  76}
  77
  78int str2nodeid(char *str, uint8_t *id)
  79{
  80        int len = strlen(str);
  81        int i;
  82
  83        if (len > 32)
  84                return -1;
  85
  86        if (is_name(str, len - 1)) {
  87                memcpy(id, str, len);
  88                return 0;
  89        }
  90        if (!is_hex(str, len - 1))
  91                return -1;
  92
  93        str[len] = '0';
  94        for (i = 0; i < 16; i++) {
  95                if (sscanf(&str[2 * i], "%2hhx", &id[i]) != 1)
  96                        break;
  97        }
  98        return 0;
  99}
 100
 101int str2key(char *str, struct tipc_aead_key *key)
 102{
 103        int len = strlen(str);
 104        int ishex = 0;
 105        int i;
 106
 107        /* Check if the input is a hex string (i.e. 0x...) */
 108        if (len > 2 && strncmp(str, "0x", 2) == 0) {
 109            ishex = is_hex(str + 2, len - 2 - 1);
 110            if (ishex) {
 111                len -= 2;
 112                str += 2;
 113            }
 114        }
 115
 116        if (len > TIPC_AEAD_KEYLEN_MAX)
 117                return -1;
 118
 119        /* Obtain key: */
 120        if (!ishex) {
 121                key->keylen = len;
 122                memcpy(key->key, str, len);
 123        } else {
 124                /* Convert hex string to key */
 125                key->keylen = (len + 1) / 2;
 126                for (i = 0; i < key->keylen; i++) {
 127                        if (i == 0 && len % 2 != 0) {
 128                                if (sscanf(str, "%1hhx", &key->key[0]) != 1)
 129                                        return -1;
 130                                str += 1;
 131                                continue;
 132                        }
 133                        if (sscanf(str, "%2hhx", &key->key[i]) != 1)
 134                                return -1;
 135                        str += 2;
 136                }
 137        }
 138
 139        return 0;
 140}
 141
 142void nodeid2str(uint8_t *id, char *str)
 143{
 144        int i;
 145
 146        if (is_name((char *)id, 15)) {
 147                memcpy(str, id, 16);
 148                return;
 149        }
 150
 151        for (i = 0; i < 16; i++)
 152                sprintf(&str[2 * i], "%02x", id[i]);
 153
 154        for (i = 31; str[i] == '0'; i--)
 155                str[i] = 0;
 156}
 157
 158void hash2nodestr(uint32_t hash, char *str)
 159{
 160        struct tipc_sioc_nodeid_req nr = {};
 161        int sd;
 162
 163        sd = socket(AF_TIPC, SOCK_RDM, 0);
 164        if (sd < 0) {
 165                fprintf(stderr, "opening TIPC socket: %s\n", strerror(errno));
 166                return;
 167        }
 168        nr.peer = hash;
 169        if (!ioctl(sd, SIOCGETNODEID, &nr))
 170                nodeid2str((uint8_t *)nr.node_id, str);
 171        close(sd);
 172}
 173