7 typedef struct line LINE
;
10 unsigned long int mac
;
22 /* Removes an entry from our linked list */
24 static int remove_entry(unsigned long int mac
) {
28 LINE
*next
= step
->next
;
30 if (step
->mac
== mac
) {
46 /* Adds an entry to the linked list */
48 static int add_entry(unsigned long int mac
, unsigned long int ip
, char *fqdn
) {
49 LINE
*new = malloc(sizeof(LINE
));
52 new->fqdn
= strdup(fqdn
);
65 /* Converts a MA:CA:DD:RE:SS:00 to an unsigned long int */
67 static unsigned long int macstrtoul(char *mac
) {
72 unsigned long int newmac
= 0;
73 strncpy(macstring
, &mac
[9], 2);
74 newmac
+= (strtoul(macstring
, NULL
, 16) * (unsigned long int)(256 * 256));
75 strncpy(macstring
, &mac
[12], 2);
76 newmac
+= (strtoul(macstring
, NULL
, 16) * (unsigned long int)(256));
77 strncpy(macstring
, &mac
[15], 2);
78 newmac
+= (strtoul(macstring
, NULL
, 16));
83 /* Parses a line from the file and adds it to the linked list */
85 static int add_line(char *line
) {
86 if (strncmp(line
, "dhcp-host=", 10) == 0 &&
87 line
[12] == ':' && line
[15] == ':' && line
[18] == ':' && line
[21] == ':' && line
[24] == ':' &&
91 LINE
*new = malloc(sizeof(LINE
));
93 if (new == NULL
) return -1;
103 new->mac
= macstrtoul(&line
[10]);
105 ip
= strchr(&line
[28], ',');
106 new->fqdn
= strndup(&line
[28], ip
- &line
[28]);
109 macstring
[1] = '\0'; macstring
[2] = '\0';
110 strncpy(macstring
, ip
, (nextip
= strchr(ip
, '.')) - ip
);
111 new->ip
+= (strtoul(macstring
, NULL
, 10) * (unsigned long int)(256 * 256 * 256));
114 macstring
[1] = '\0'; macstring
[2] = '\0';
115 strncpy(macstring
, ip
, (nextip
= strchr(ip
, '.')) - ip
);
116 new->ip
+= (strtoul(macstring
, NULL
, 10) * (unsigned long int)(256 * 256));
119 macstring
[1] = '\0'; macstring
[2] = '\0';
120 strncpy(macstring
, ip
, (nextip
= strchr(ip
, '.')) - ip
);
121 new->ip
+= (strtoul(macstring
, NULL
, 10) * (unsigned long int)(256));
124 macstring
[1] = '\0'; macstring
[2] = '\0';
125 strncpy(macstring
, ip
, (nextip
= strchr(ip
, ',')) - ip
);
126 new->ip
+= (strtoul(macstring
, NULL
, 10));
141 /* Prints out our mac range */
143 static char * print_mac(unsigned long int mac
) {
144 char *macstring
= (char *) malloc(sizeof(char*) * 18);
145 strcpy(macstring
, "00:16:3E:");
146 snprintf(&macstring
[9], 8, "%06lX", mac
);
147 strncpy(&macstring
[15], &macstring
[13], 2);
148 macstring
[13] = macstring
[12];
149 macstring
[12] = macstring
[11];
152 macstring
[17] = '\0';
156 /* And prints out an ip address */
158 static char * print_ip(unsigned long int ipaddress
) {
159 char *dest
= (char *) malloc(sizeof(char*) * 16);
161 ldiv_t ip
= ldiv(ipaddress
, (256*256*256));
163 ip
= ldiv(ip
.rem
, (256*256));
165 ip
= ldiv(ip
.rem
, (256));
169 snprintf(dest
, 16, "%d.%d.%d.%d", a
, b
, c
, d
);
173 /* Print out the dnsmasq format and clean up the linked list */
175 static int print_forget(char *path
) {
176 FILE *fd
= fopen(path
, "w+");
181 char *pretty_mac
= print_mac(this->mac
);
182 char *pretty_ip
= print_ip(this->ip
);
185 fprintf(fd
, "dhcp-host=%s,%s,%s,24h\n", pretty_mac
, this->fqdn
, pretty_ip
);
202 /* Convert the linked list to a more 'defacto' array format */
204 static int ll_array() {
206 array
= malloc(sizeof(LINE
) * listlen
);
210 array
[i
].mac
= step
->mac
;
211 array
[i
].ip
= step
->ip
;
212 array
[i
].fqdn
= step
->fqdn
;
220 /* Compare functions */
222 static int bymac(const void *a
, const void *b
) {
223 LINE
*temp1
= (LINE
*) a
;
224 LINE
*temp2
= (LINE
*) b
;
226 return temp1
->mac
- temp2
->mac
;
229 static int byip(const void *a
, const void *b
) {
230 LINE
*temp1
= (LINE
*) a
;
231 LINE
*temp2
= (LINE
*) b
;
233 return temp1
->ip
- temp2
->ip
;
236 /* Find the first 'free' mac */
238 static unsigned long int nextmac() {
240 for (i
= 0; i
< (listlen
- 1); i
++) {
241 if (array
[i
+1].mac
!= 0 && array
[i
+1].mac
!= array
[i
].mac
+ 1) return array
[i
].mac
+ 1;
243 return array
[listlen
- 1].mac
+ 1;
246 /* Find the first 'free' ip */
247 static unsigned long int nextip() {
249 for (i
= 0; i
< (listlen
- 1); i
++) {
250 if (array
[i
+1].ip
!= array
[i
].ip
+ 1) return array
[i
].ip
+ 1;
252 return array
[listlen
- 1].ip
+ 1;
255 /* Opens the cabinet config */
257 static char * loader(char *cabinet
) {
259 char *pad
= malloc(sizeof(char) * 128);
266 if (pad
== NULL
) return NULL
;
268 snprintf(pad
, 128, "/mnt/netapp/ipservices/%s.conf", cabinet
);
270 if ((fd
= fopen(pad
, "r")) != NULL
) {
273 if (fgets(line
, 128, fd
) > 0)
282 /* Exported functions */
283 /* TODO: implement better locking */
285 int removeOldMac(char *cabinet
, char *mac
) {
286 char *pad
= loader(cabinet
);
291 unsigned long int old_mac
= macstrtoul(mac
);
292 remove_entry(old_mac
);
299 int getNewMac(char *cabinet
, char *fqdn
, char **mac
, char **ip
) {
300 unsigned long int new_mac
, new_ip
;
301 char *pad
= loader(cabinet
);
312 qsort(array
, listlen
, sizeof(LINE
), bymac
);
315 qsort(array
, listlen
, sizeof(LINE
), byip
);
320 *mac
= print_mac(new_mac
);
323 *ip
= print_ip(new_ip
);
325 add_entry(new_mac
, new_ip
, fqdn
);
336 /* Good for unittesting */
339 int main(int argc
, char *argv
[]) {
341 removeOldMac(argv
[1], argv
[2]);
342 } else if (argc
== 3) {
343 getNewMac(argv
[1], argv
[2], NULL
, NULL
);