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