6 typedef struct line LINE
;
21 /* Removes an entry from our linked list */
23 static int remove_entry(unsigned long int mac
) {
27 LINE
*next
= step
->next
;
29 if (step
->mac
== mac
) {
45 /* Adds an entry to the linked list */
47 static int add_entry(unsigned long int mac
, unsigned long int ip
, char *fqdn
) {
48 LINE
*new = malloc(sizeof(LINE
));
51 new->fqdn
= strdup(fqdn
);
64 /* Converts a MA:CA:DD:RE:SS:00 to an unsigned long int */
66 static unsigned long int macstrtoul(char *mac
) {
71 unsigned long int newmac
= 0;
72 strncpy(macstring
, &mac
[9], 2);
73 newmac
+= (strtoul(macstring
, NULL
, 16) * (unsigned long int)(256 * 256));
74 strncpy(macstring
, &mac
[12], 2);
75 newmac
+= (strtoul(macstring
, NULL
, 16) * (unsigned long int)(256));
76 strncpy(macstring
, &mac
[15], 2);
77 newmac
+= (strtoul(macstring
, NULL
, 16));
82 /* Parses a line from the file and adds it to the linked list */
84 static int add_line(char *line
) {
85 if (strncmp(line
, "dhcp-host=", 10) == 0 &&
86 line
[12] == ':' && line
[15] == ':' && line
[18] == ':' && line
[21] == ':' && line
[24] == ':' &&
90 LINE
*new = malloc(sizeof(LINE
));
92 if (new == NULL
) return -1;
102 new->mac
= macstrtoul(&line
[10]);
104 ip
= strchr(&line
[28], ',');
105 new->fqdn
= strndup(&line
[28], ip
- &line
[28]);
108 macstring
[1] = '\0'; macstring
[2] = '\0';
109 strncpy(macstring
, ip
, (nextip
= strchr(ip
, '.')) - ip
);
110 new->ip
+= (strtoul(macstring
, NULL
, 10) * (unsigned long int)(256 * 256 * 256));
113 macstring
[1] = '\0'; macstring
[2] = '\0';
114 strncpy(macstring
, ip
, (nextip
= strchr(ip
, '.')) - ip
);
115 new->ip
+= (strtoul(macstring
, NULL
, 10) * (unsigned long int)(256 * 256));
118 macstring
[1] = '\0'; macstring
[2] = '\0';
119 strncpy(macstring
, ip
, (nextip
= strchr(ip
, '.')) - ip
);
120 new->ip
+= (strtoul(macstring
, NULL
, 10) * (unsigned long int)(256));
123 macstring
[1] = '\0'; macstring
[2] = '\0';
124 strncpy(macstring
, ip
, (nextip
= strchr(ip
, ',')) - ip
);
125 new->ip
+= (strtoul(macstring
, NULL
, 10));
140 /* Prints out our mac range */
142 static char * print_mac(unsigned long int mac
) {
143 char *macstring
= (char *) malloc(sizeof(char*) * 18);
144 strcpy(macstring
, "00:16:3E:");
145 snprintf(&macstring
[9], 8, "%06lX", mac
);
146 strncpy(&macstring
[15], &macstring
[13], 2);
147 macstring
[13] = macstring
[12];
148 macstring
[12] = macstring
[11];
151 macstring
[17] = '\0';
155 /* And prints out an ip address */
157 static char * print_ip(unsigned long int ipaddress
) {
158 char *dest
= (char *) malloc(sizeof(char*) * 16);
160 ldiv_t ip
= ldiv(ipaddress
, (256*256*256));
162 ip
= ldiv(ip
.rem
, (256*256));
164 ip
= ldiv(ip
.rem
, (256));
168 snprintf(dest
, 16, "%d.%d.%d.%d", a
, b
, c
, d
);
172 /* Print out the dnsmasq format and clean up the linked list */
174 static int print_forget(char *path
) {
175 FILE *fd
= fopen(path
, "w+");
180 char *pretty_mac
= print_mac(this->mac
);
181 char *pretty_ip
= print_ip(this->ip
);
184 fprintf(fd
, "dhcp-host=%s,%s,%s,24h\n", pretty_mac
, this->fqdn
, pretty_ip
);
201 /* Convert the linked list to a more 'defacto' array format */
203 static int ll_array() {
205 array
= malloc(sizeof(LINE
) * listlen
);
209 array
[i
].mac
= step
->mac
;
210 array
[i
].ip
= step
->ip
;
211 array
[i
].fqdn
= step
->fqdn
;
219 /* Compare functions */
221 static int bymac(const void *a
, const void *b
) {
222 LINE
*temp1
= (LINE
*) a
;
223 LINE
*temp2
= (LINE
*) b
;
225 return temp1
->mac
- temp2
->mac
;
228 static int byip(const void *a
, const void *b
) {
229 LINE
*temp1
= (LINE
*) a
;
230 LINE
*temp2
= (LINE
*) b
;
232 return temp1
->ip
- temp2
->ip
;
235 /* Find the first 'free' mac */
237 static unsigned long int nextmac() {
239 for (i
= 0; i
< (listlen
- 1); i
++) {
240 if (array
[i
+1].mac
!= 0 && array
[i
+1].mac
!= array
[i
].mac
+ 1) return array
[i
].mac
+ 1;
242 return array
[listlen
- 1].mac
+ 1;
245 /* Find the first 'free' ip */
246 static unsigned long int nextip() {
248 for (i
= 0; i
< (listlen
- 1); i
++) {
249 if (array
[i
+1].ip
!= array
[i
].ip
+ 1) return array
[i
].ip
+ 1;
251 return array
[listlen
- 1].ip
+ 1;
254 /* Opens the cabinet config */
256 static char * loader(char *cabinet
) {
258 char *pad
= malloc(sizeof(char) * 128);
265 if (pad
== NULL
) return NULL
;
267 snprintf(pad
, 128, "/mnt/netapp/ipservices/%s.conf", cabinet
);
269 if ((fd
= fopen(pad
, "r")) != NULL
) {
272 if (fgets(line
, 128, fd
) > 0)
281 /* Exported functions */
283 int removeOldMac(char *cabinet
, char *mac
) {
284 char *pad
= loader(cabinet
);
289 unsigned long int old_mac
= macstrtoul(mac
);
290 remove_entry(old_mac
);
296 int getNewMac(char *cabinet
, char *fqdn
, char **mac
, char **ip
) {
297 unsigned long int new_mac
, new_ip
;
298 char *pad
= loader(cabinet
);
309 qsort(array
, listlen
, sizeof(LINE
), bymac
);
312 qsort(array
, listlen
, sizeof(LINE
), byip
);
317 *mac
= print_mac(new_mac
);
320 *ip
= print_ip(new_ip
);
322 add_entry(new_mac
, new_ip
, fqdn
);
333 /* Good for unittesting */
336 int main(int argc
, char *argv
[]) {
338 removeOldMac(argv
[1], argv
[2]);
339 } else if (argc
== 3) {
340 getNewMac(argv
[1], argv
[2], NULL
, NULL
);