• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdlib.h>
2 #include <netinet/ether.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <errno.h>
6 
7 #define ETHER_FILE_PATH "/etc/ethers"
8 #define BUFFER_SIZE     200
9 
ether_aton_r(const char * x,struct ether_addr * p_a)10 struct ether_addr *ether_aton_r (const char *x, struct ether_addr *p_a)
11 {
12 	struct ether_addr a;
13 	char *y;
14 	for (int ii = 0; ii < 6; ii++) {
15 		unsigned long int n;
16 		if (ii != 0) {
17 			if (x[0] != ':') return 0; /* bad format */
18 			else x++;
19 		}
20 		n = strtoul (x, &y, 16);
21 		x = y;
22 		if (n > 0xFF) return 0; /* bad byte */
23 		a.ether_addr_octet[ii] = n;
24 	}
25 	if (x[0] != 0) return 0; /* bad format */
26 	*p_a = a;
27 	return p_a;
28 }
29 
ether_aton(const char * x)30 struct ether_addr *ether_aton (const char *x)
31 {
32 	static struct ether_addr a;
33 	return ether_aton_r (x, &a);
34 }
35 
ether_ntoa_r(const struct ether_addr * p_a,char * x)36 char *ether_ntoa_r (const struct ether_addr *p_a, char *x) {
37 	char *y;
38 	y = x;
39 	for (int ii = 0; ii < 6; ii++) {
40 		x += sprintf (x, ii == 0 ? "%.2X" : ":%.2X", p_a->ether_addr_octet[ii]);
41 	}
42 	return y;
43 }
44 
ether_ntoa(const struct ether_addr * p_a)45 char *ether_ntoa (const struct ether_addr *p_a) {
46 	static char x[18];
47 	return ether_ntoa_r (p_a, x);
48 }
49 
ether_line(const char * line,struct ether_addr * addr,char * hostname)50 int ether_line(const char *line, struct ether_addr *addr, char *hostname)
51 {
52 	char buf[BUFFER_SIZE], *ch, *ptr = NULL;
53 	if (line[0] == '#') {
54 		errno = EINVAL;
55 		return -1;
56 	}
57 	strcpy(buf, line);
58 	ch = strchr(buf, '#');
59 	if (ch)
60 		*ch = '\0';
61 	ch = strtok_r(buf, " \t\n", &ptr);
62 	ch = strtok_r(NULL, " \t\n", &ptr);
63 	if (ch == NULL) {
64 		errno = EINVAL;
65 		return -1;
66 	}
67 	strcpy(hostname, ch);
68 
69 	unsigned int ret;
70 	ch = &buf[0];
71 	for (int i = 0; i < 6; i++) {
72 		ch = strtok_r(ch, ":", &ptr);
73 		if (ch == NULL || sscanf(ch, "%x", &ret) != 1) {
74 			errno = EINVAL;
75 			return -1;
76 		}
77 		addr->ether_addr_octet[i] = (uint8_t)ret;
78 		ch = NULL;
79 	}
80 
81 	return 0;
82 }
83 
ether_ntohost(char * hostname,const struct ether_addr * addr)84 int ether_ntohost(char *hostname, const struct ether_addr *addr)
85 {
86 	FILE *f = NULL;
87 	char buf[BUFFER_SIZE + 1];
88 	char temp_name[BUFFER_SIZE];
89 	struct ether_addr *temp_addr;
90 
91 	if (!(f = fopen(ETHER_FILE_PATH, "r")))
92 		return ENOENT;
93 	temp_addr = (struct ether_addr *)malloc(sizeof(struct ether_addr));
94 	if (temp_addr == NULL) {
95 		fclose(f);
96 		return ENOMEM;
97 	}
98 	while (fgets(buf, BUFFER_SIZE, f)) {
99 		if (ether_line(buf, temp_addr, temp_name) != 0)
100 			continue;
101 		if (memcmp(addr, temp_addr, 6) == 0) {
102 			strcpy(hostname, temp_name);
103 			free(temp_addr);
104 			fclose(f);
105 			return 0;
106 		}
107 	}
108 
109 	free(temp_addr);
110 	fclose(f);
111 	return -1;
112 }
113 
114 
ether_hostton(const char * hostname,struct ether_addr * addr)115 int ether_hostton(const char *hostname, struct ether_addr *addr)
116 {
117 	FILE *f = NULL;
118 	char buf[BUFFER_SIZE + 1];
119 	char temp_name[BUFFER_SIZE];
120 	struct ether_addr *temp_addr;
121 
122 	temp_addr = (struct ether_addr *)malloc(sizeof(struct ether_addr));
123 	if (temp_addr == NULL)
124 		return ENOMEM;
125 	if (!(f = fopen(ETHER_FILE_PATH, "r"))) {
126 		free(temp_addr);
127 		return ENOENT;
128 	}
129 	while (fgets(buf, BUFFER_SIZE, f)) {
130 		if (ether_line(buf, temp_addr, temp_name) != 0)
131 			continue;
132 		if (strcmp(hostname, temp_name) == 0) {
133 			memcpy(addr, temp_addr, 6);
134 			free(temp_addr);
135 			fclose(f);
136 			return 0;
137 		}
138 	}
139 
140 	free(temp_addr);
141 	fclose(f);
142 	return -1;
143 }
144