1 /* 2 * ll_addr.c 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: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10 */ 11 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <unistd.h> 15 #include <syslog.h> 16 #include <fcntl.h> 17 #include <sys/ioctl.h> 18 #include <sys/socket.h> 19 #include <netinet/in.h> 20 #include <arpa/inet.h> 21 #include <string.h> 22 23 #include <linux/netdevice.h> 24 #include <linux/if_arp.h> 25 #include <linux/sockios.h> 26 27 #include "rt_names.h" 28 #include "utils.h" 29 30 31 const char *ll_addr_n2a(const unsigned char *addr, int alen, int type, char *buf, int blen) 32 { 33 int i; 34 int l; 35 36 if (alen == 4 && 37 (type == ARPHRD_TUNNEL || type == ARPHRD_SIT || type == ARPHRD_IPGRE)) { 38 return inet_ntop(AF_INET, addr, buf, blen); 39 } 40 if (alen == 16 && type == ARPHRD_TUNNEL6) { 41 return inet_ntop(AF_INET6, addr, buf, blen); 42 } 43 snprintf(buf, blen, "%02x", addr[0]); 44 for (i = 1, l = 2; i < alen && l < blen; i++, l += 3) 45 snprintf(buf + l, blen - l, ":%02x", addr[i]); 46 return buf; 47 } 48 49 /*NB: lladdr is char * (rather than u8 *) because sa_data is char * (1003.1g) */ 50 int ll_addr_a2n(char *lladdr, int len, const char *arg) 51 { 52 if (strchr(arg, '.')) { 53 inet_prefix pfx; 54 if (get_addr_1(&pfx, arg, AF_INET)) { 55 fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg); 56 return -1; 57 } 58 if (len < 4) 59 return -1; 60 memcpy(lladdr, pfx.data, 4); 61 return 4; 62 } else { 63 int i; 64 65 for (i=0; i<len; i++) { 66 int temp; 67 char *cp = strchr(arg, ':'); 68 if (cp) { 69 *cp = 0; 70 cp++; 71 } 72 if (sscanf(arg, "%x", &temp) != 1) { 73 fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg); 74 return -1; 75 } 76 if (temp < 0 || temp > 255) { 77 fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg); 78 return -1; 79 } 80 lladdr[i] = temp; 81 if (!cp) 82 break; 83 arg = cp; 84 } 85 return i+1; 86 } 87 } 88