xref: /aosp_15_r20/external/iproute2/lib/ll_addr.c (revision de1e4e894b0c224df933550f0afdecc354b238c4)
1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker  * ll_addr.c
3*de1e4e89SAndroid Build Coastguard Worker  *
4*de1e4e89SAndroid Build Coastguard Worker  *		This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker  *		modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker  *		as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker  *		2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker  *
9*de1e4e89SAndroid Build Coastguard Worker  * Authors:	Alexey Kuznetsov, <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker  */
11*de1e4e89SAndroid Build Coastguard Worker 
12*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
13*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <syslog.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <fcntl.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <sys/ioctl.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <sys/socket.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <netinet/in.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <arpa/inet.h>
21*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
22*de1e4e89SAndroid Build Coastguard Worker 
23*de1e4e89SAndroid Build Coastguard Worker #include <linux/netdevice.h>
24*de1e4e89SAndroid Build Coastguard Worker #include <linux/if_arp.h>
25*de1e4e89SAndroid Build Coastguard Worker #include <linux/sockios.h>
26*de1e4e89SAndroid Build Coastguard Worker 
27*de1e4e89SAndroid Build Coastguard Worker #include "rt_names.h"
28*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
29*de1e4e89SAndroid Build Coastguard Worker 
30*de1e4e89SAndroid Build Coastguard Worker 
ll_addr_n2a(const unsigned char * addr,int alen,int type,char * buf,int blen)31*de1e4e89SAndroid Build Coastguard Worker const char *ll_addr_n2a(const unsigned char *addr, int alen, int type, char *buf, int blen)
32*de1e4e89SAndroid Build Coastguard Worker {
33*de1e4e89SAndroid Build Coastguard Worker 	int i;
34*de1e4e89SAndroid Build Coastguard Worker 	int l;
35*de1e4e89SAndroid Build Coastguard Worker 
36*de1e4e89SAndroid Build Coastguard Worker 	if (alen == 4 &&
37*de1e4e89SAndroid Build Coastguard Worker 	    (type == ARPHRD_TUNNEL || type == ARPHRD_SIT || type == ARPHRD_IPGRE)) {
38*de1e4e89SAndroid Build Coastguard Worker 		return inet_ntop(AF_INET, addr, buf, blen);
39*de1e4e89SAndroid Build Coastguard Worker 	}
40*de1e4e89SAndroid Build Coastguard Worker 	if (alen == 16 && type == ARPHRD_TUNNEL6) {
41*de1e4e89SAndroid Build Coastguard Worker 		return inet_ntop(AF_INET6, addr, buf, blen);
42*de1e4e89SAndroid Build Coastguard Worker 	}
43*de1e4e89SAndroid Build Coastguard Worker 	snprintf(buf, blen, "%02x", addr[0]);
44*de1e4e89SAndroid Build Coastguard Worker 	for (i = 1, l = 2; i < alen && l < blen; i++, l += 3)
45*de1e4e89SAndroid Build Coastguard Worker 		snprintf(buf + l, blen - l, ":%02x", addr[i]);
46*de1e4e89SAndroid Build Coastguard Worker 	return buf;
47*de1e4e89SAndroid Build Coastguard Worker }
48*de1e4e89SAndroid Build Coastguard Worker 
49*de1e4e89SAndroid Build Coastguard Worker /*NB: lladdr is char * (rather than u8 *) because sa_data is char * (1003.1g) */
ll_addr_a2n(char * lladdr,int len,const char * arg)50*de1e4e89SAndroid Build Coastguard Worker int ll_addr_a2n(char *lladdr, int len, const char *arg)
51*de1e4e89SAndroid Build Coastguard Worker {
52*de1e4e89SAndroid Build Coastguard Worker 	if (strchr(arg, '.')) {
53*de1e4e89SAndroid Build Coastguard Worker 		inet_prefix pfx;
54*de1e4e89SAndroid Build Coastguard Worker 		if (get_addr_1(&pfx, arg, AF_INET)) {
55*de1e4e89SAndroid Build Coastguard Worker 			fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg);
56*de1e4e89SAndroid Build Coastguard Worker 			return -1;
57*de1e4e89SAndroid Build Coastguard Worker 		}
58*de1e4e89SAndroid Build Coastguard Worker 		if (len < 4)
59*de1e4e89SAndroid Build Coastguard Worker 			return -1;
60*de1e4e89SAndroid Build Coastguard Worker 		memcpy(lladdr, pfx.data, 4);
61*de1e4e89SAndroid Build Coastguard Worker 		return 4;
62*de1e4e89SAndroid Build Coastguard Worker 	} else {
63*de1e4e89SAndroid Build Coastguard Worker 		int i;
64*de1e4e89SAndroid Build Coastguard Worker 
65*de1e4e89SAndroid Build Coastguard Worker 		for (i=0; i<len; i++) {
66*de1e4e89SAndroid Build Coastguard Worker 			int temp;
67*de1e4e89SAndroid Build Coastguard Worker 			char *cp = strchr(arg, ':');
68*de1e4e89SAndroid Build Coastguard Worker 			if (cp) {
69*de1e4e89SAndroid Build Coastguard Worker 				*cp = 0;
70*de1e4e89SAndroid Build Coastguard Worker 				cp++;
71*de1e4e89SAndroid Build Coastguard Worker 			}
72*de1e4e89SAndroid Build Coastguard Worker 			if (sscanf(arg, "%x", &temp) != 1) {
73*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg);
74*de1e4e89SAndroid Build Coastguard Worker 				return -1;
75*de1e4e89SAndroid Build Coastguard Worker 			}
76*de1e4e89SAndroid Build Coastguard Worker 			if (temp < 0 || temp > 255) {
77*de1e4e89SAndroid Build Coastguard Worker 				fprintf(stderr, "\"%s\" is invalid lladdr.\n", arg);
78*de1e4e89SAndroid Build Coastguard Worker 				return -1;
79*de1e4e89SAndroid Build Coastguard Worker 			}
80*de1e4e89SAndroid Build Coastguard Worker 			lladdr[i] = temp;
81*de1e4e89SAndroid Build Coastguard Worker 			if (!cp)
82*de1e4e89SAndroid Build Coastguard Worker 				break;
83*de1e4e89SAndroid Build Coastguard Worker 			arg = cp;
84*de1e4e89SAndroid Build Coastguard Worker 		}
85*de1e4e89SAndroid Build Coastguard Worker 		return i+1;
86*de1e4e89SAndroid Build Coastguard Worker 	}
87*de1e4e89SAndroid Build Coastguard Worker }
88