Home | History | Annotate | Download | only in lib
      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 (at) 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