/* $Id$ * * This generates the network table. * * Copyright (C) 1994-1998 by the Massachusetts Institute of Technology. * For copying and distribution information, please see the file * . */ #include #include #include #include #include #include #include #include "util.h" EXEC SQL INCLUDE sqlca; RCSID("$Header$"); char *whoami = "network.gen"; char *db = "moira/moira"; char *cidr_from_inaddr(struct in_addr in); int main(int argc, char **argv) { FILE *out = stdout; char *outf = NULL, *cidr = NULL, address[BUFSIZ], outft[MAXPATHLEN]; struct timeval now; struct in_addr addr, maskaddr; EXEC SQL BEGIN DECLARE SECTION; int id, saddr; char name[SUBNET_NAME_SIZE], description[SUBNET_DESCRIPTION_SIZE]; char mask[SUBNET_MASK_SIZE]; EXEC SQL END DECLARE SECTION; EXEC SQL CONNECT :db; if (argc == 2) { outf = argv[1]; sprintf(outft, "%s~", outf); if (!(out = fopen(outft, "w"))) { fprintf(stderr, "unable to open %s for output\n", outf); exit(MR_OCONFIG); } } else if (argc != 1) { fprintf(stderr, "usage: %s [outfile]\n", argv[0]); exit(MR_ARGS); } else outf = NULL; EXEC SQL WHENEVER SQLERROR GOTO sqlerr; gettimeofday(&now, NULL); fprintf(out, "; MIT Network Table\n;\n"); fprintf(out, "; \t%cAuthor: $\n", '$'); fprintf(out, "; \t%cDate: $\n", '$'); fprintf(out, "; \t%cRevision: $\n;\n", '$'); fprintf(out, "; Network table generated by Moira at %s;\n", ctime(&now.tv_sec)); EXEC SQL DECLARE x CURSOR FOR SELECT name, snet_id, saddr, mask, description FROM subnet ORDER BY saddr; EXEC SQL OPEN x; while (1) { EXEC SQL FETCH x INTO :name, :id, :saddr, :mask, :description; if (sqlca.sqlcode) break; if (id == 0) continue; if (!*strtrim(name)) continue; addr.s_addr = htonl(saddr); maskaddr.s_addr = htonl(atoi(mask)); cidr = cidr_from_inaddr(maskaddr); strcpy(address, inet_ntoa(addr)); if (cidr) strcat(address, cidr); fprintf(out, "NETWORK : %-16.16s : %-15.15s : %s\n", name, address, strtrim(description)); } EXEC SQL CLOSE x; EXEC SQL COMMIT; fprintf(out, "; End of automatically generated network table\n"); if (fclose(out)) { perror("close failed"); exit(MR_CCONFIG); } if (outf) fix_file(outf); exit(MR_SUCCESS); sqlerr: db_error(sqlca.sqlcode); exit(MR_DBMS_ERR); } char *cidr_from_inaddr(struct in_addr in) { char *ptr1, *ptr2, *address, *out; int a, b, c, d, addr, i, j = 0, k = 0; int bits[32]; address = inet_ntoa(in); ptr1 = ptr2 = address; ptr2 = (char *)strchr(ptr1, '.'); if (!ptr2) return(NULL); a = atoi(ptr1); ptr1 = ptr2 + 1; ptr2 = (char *)strchr(ptr1, '.'); if (!ptr2) return(NULL); b = atoi(ptr1); ptr1 = ptr2 + 1; ptr2 = (char *)strchr(ptr1, '.'); if (!ptr2) return(NULL); c = atoi(ptr1); ptr1 = ptr2 + 1; d = atoi(ptr1); if (a < 0 || a > 255 || b < 0 || b > 255 || c < 0 || c > 255 || d < 0 || d > 255) return(NULL); addr = d + (c*256) + (b*256*256) + (a*256*256*256); for (i = 0; i < 32; i++) { bits[i] = (addr & 1); addr = (addr >> 1); } while (bits[j] == 0) { j++; if (j > 31) break; } while (bits[j] == 1) { j++; k++; if (j > 31) break; } if (j != 32) return(NULL); out = (char *)malloc(20); if (!out) exit(MR_NO_MEM); sprintf(out, "/%i", k); return(out); }