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