#include "rules.h" #include "objects.h" #include "services.h" void dump_resolv(int verbose) { /* pointers to current object */ rulenum *ruleptr; objlist *objptr; services *svcptr; /* indicates what we have processed on this iteration */ int srcflag=0; int dstflag=0; int svcflag=0; /* indicates if object is a group of subobjects */ int srcgroup=0; int dstgroup=0; int svcgroup=0; /* number of objects currently processed */ int src_group_count=0; int dst_group_count=0; int svc_group_count=0; /* current object number */ int srcrule=0; int dstrule=0; int svcrule=0; /* buffer used to send current service to resolv_svc() */ char *resolv_rule; /* contains install and action strings */ char install[LNSIZE]; char action[LNSIZE]; /* current loop number */ int loopcount=0; /* start at the head of the list */ ruleptr = head->count_link; objptr = ohead->nodelink; svcptr = shead->nodelink; /* allocate space for current line */ if((resolv_rule = malloc(LNSIZE)) == NULL) { fprintf(stderr,"dump_resolv: malloc failed\n"); exit(1); } /* header at top of page */ printf("%10cSource Address%13cSource IP%5cSource Netmask",' ',' ',' '); printf("%6cDestination Address%5cDestination IP%5cDest Netmask",' ',' ',' '); printf("%7cService%7cPort%4cType%2cInstall%1cAct\n",' ',' ',' ',' ',' '); /* * This is the main loop. It increments after all of source, destination and * services have been processed and ruleptr rules are NULL */ while(ruleptr->count_link != NULL) { printf("%2d ",ruleptr->rulecount); /* copy install and action to be printed at the end */ sprintf(install,"%s",ruleptr->install); sprintf(action,"%s",ruleptr->action); srcgroup=dstgroup=svcgroup=0; loopcount=0; srcrule=0; dstrule=0; svcrule=0; src_group_count=0; dst_group_count=0; svc_group_count=0; /* * This is the other major loop. It determines whether we are dealing with a main * or subrule for each object, and stops when all of the targets are NULL */ do { srcflag=dstflag=svcflag=0; loopcount++; srctop: /* Process Source Groups */ if(srcgroup > 0) { objptr = ohead->nodelink; while((objptr->nodelink != NULL) && (ruleptr->src[srcrule] != NULL)) { /* does the current object match the rule we're working on? */ if(strcmp(ruleptr->src[srcrule],objptr->objname) == 0) { /* now that we found the group, see if there's any entries left * to be printed */ if(objptr->group[src_group_count] != NULL) { printf("%2c%3c%-28s",' ',' ',objptr->group[src_group_count]); find_group(objptr->group[src_group_count]); src_group_count++; srcflag=1; } else { /* Doing three things here: * 1.On the loop around where the object is now NULL, the * next ruleptr->src[srcrule] is not printed * 2.Indicate a record has been printed with srcflag=1 * 3.Increment srcrule, as we just printed one */ if(objptr->group[src_group_count] == NULL) { srcrule++; srcgroup=0; /* can't just set src_group_count=0 and reprocess. Would involve * too much manipulation of srcgroup and srcrule. Same for dst and * svc */ if(ruleptr->src[srcrule] != NULL) { srcflag=1; goto srctop; } } } } objptr = objptr->nodelink; } } else { /* Process Source services. These may be group elements, but * never will it be before we determine if its a group or not */ if(srcgroup == 0) { if(ruleptr->src[srcrule] != NULL) { if(srcrule > 0) printf("%3c",' '); srcflag=1; /* resolv_src() takes the current rule, and just finds the * object we're looking for, and prints it */ if((resolv_src(ruleptr->src[srcrule]) == 1)) { srcgroup=1; src_group_count=0; } else { srcgroup=0; srcrule++; } } } } /* Begin of processing destination hostname and destination IP address */ dsttop: if(dstgroup > 0) { objptr = ohead->nodelink; while((objptr->nodelink != NULL) && (ruleptr->dst[dstrule] != NULL)) { if(strcmp(ruleptr->dst[dstrule],objptr->objname) == 0) { if(objptr->group[dst_group_count] != NULL) { dstflag=1; if(srcflag == 0) printf("%5c%28c%16c%16c ",' ',' ',' ',' '); printf("%2c%-28s",' ',objptr->group[dst_group_count]); find_group(objptr->group[dst_group_count]); dst_group_count++; } else if(objptr->group[dst_group_count] == NULL) { dstgroup=0; dstrule++; if(ruleptr->dst[dstrule] != NULL) { dstflag=1; goto dsttop; } } } objptr = objptr->nodelink; } } else { /* Process Destination Groups */ if(dstgroup == 0) { /* Process Destination Services */ if(ruleptr->dst[dstrule] != NULL) { dstflag=1; if(srcflag == 0) printf("%6c%28c%16c%16c",' ',' ',' ',' '); if((resolv_dst(ruleptr->dst[dstrule]) == 1)) { dstgroup=1; dst_group_count=0; } else { dstgroup=0; dstrule++; } } } } /* Begin of processing services and service types */ svctop: /* Process Group Services */ if(svcgroup > 0) { svcptr = shead->nodelink; /* truncate those long ICMP service listings on groups only */ if((svc_group_count > 3) && (verbose == 0)) { svcgroup=0; sprintf(ruleptr->svc[svcrule]," More..."); goto svctop; } while((svcptr->nodelink != NULL) && (ruleptr->svc[svcrule] != NULL)) { if(strcmp(ruleptr->svc[svcrule],svcptr->svcname) == 0) { if(svcptr->group[svc_group_count] != NULL) { svcflag=1; printf("%2c",' '); if((srcflag == 0) && (dstflag == 0)) { printf(" %5c%28c%16c%16c",' ',' ',' ',' '); printf("%28c%16c%16c",' ',' ',' '); } else { if(dstflag == 0) printf(" %28c%16c%16c",' ',' ',' '); } find_services(svcptr->group[svc_group_count]); svc_group_count++; } else if(svcptr->group[svc_group_count] == NULL) { svcgroup=0; svcrule++; if(ruleptr->svc[svcrule] != NULL) { svcflag=1; goto svctop; } } } svcptr = svcptr->nodelink; } } else { if(svcgroup == 0) { /* Process Services */ if(ruleptr->svc[svcrule] != NULL) { svcflag=1; if((srcflag == 0) && (dstflag == 0)) { printf(" %5c%28c%16c%16c",' ',' ',' ',' '); printf("%28c%16c%16c",' ',' ',' '); } else { if(dstflag == 0) printf(" %28c%16c%16c",' ',' ',' '); } if((resolv_svc(ruleptr->svc[svcrule]) == 1)) { svcgroup=1; svc_group_count=0; } else { svcgroup=0; svcrule++; } } } } /* If anything was printed on this line, print a carriage return */ if((srcflag == 1) || (dstflag == 1) || (svcflag == 1)) { if(loopcount == 1) printf(" %s %s",install,action); printf("\n"); } /* continue while at least some data is being printed */ } while((ruleptr->src[srcrule] != NULL) || (srcflag == 1) || (ruleptr->dst[dstrule] != NULL) || (dstflag == 1) || (ruleptr->svc[svcrule] != NULL) || (svcflag == 1)); /* print a carriage return seperating rules */ printf("\n"); /* advance pointer to next rule */ ruleptr = ruleptr->count_link; } } /* Description: * Find current source, and print out associated information */ int resolv_src(char *rule_src) { objlist *objptr; objptr = ohead->nodelink; while(objptr->nodelink != NULL) { if(strcmp(rule_src,objptr->objname) == 0) { if(strcmp(objptr->type,"group") == 0) { printf("%-28s%16s%16s ",rule_src,objptr->ipaddr,objptr->netmask); return 1; } else printf("%-28s%16s%16s ",objptr->objname,objptr->ipaddr,objptr->netmask); return 0; } objptr = objptr->nodelink; } /* Can't find a match for source */ if(rule_src != NULL) printf("%-28s%16c%16c ",rule_src,' ',' '); return 0; } /* Description: * Find current destination, and print out associated information */ int resolv_dst(char *rule_dst) { objlist *objptr; objptr = ohead->nodelink; while(objptr->nodelink != NULL) { if(strcmp(rule_dst,objptr->objname) == 0) { if(strcmp(objptr->type,"group") == 0) { printf("%-28s%16s%16s ",rule_dst,objptr->ipaddr,objptr->netmask); return 1; } printf("%-28s%16s%16s ",objptr->objname,objptr->ipaddr,objptr->netmask); return 0; } objptr = objptr->nodelink; } /* Can't find a match for destination */ if(rule_dst != NULL) printf("%-28s%16c%16c ",rule_dst,' ',' '); return 0; } /* Description: * This one is somewhat more involved, because there seems to be quite a few * screwed up cases. Find the current service, and make sure it is the * correct length and content for what we're looking for */ int resolv_svc(char *rule_serv) { services *svcptr; int i=0; /* used to store service before printing, * so its length and content can be modified */ char port[LNSIZE]; char svcname[LNSIZE]; char type[LNSIZE]; svcptr = shead->nodelink; while(svcptr->nodelink != NULL) { if(strcmp(rule_serv,svcptr->svcname) == 0) { /* make a copy to not corrupt real data */ sprintf(svcname,"%s",svcptr->svcname); /* simple hack to cut down the length if not a character */ for(i=0;i 10)) { svcname[i] = '\0'; } } sprintf(port,"%s",svcptr->port); /* get rid of some of those ports with weird names */ /* also make sure there is at least one char written */ for(i=0;iport);i++) { if((port[i] == ',') && (i > 1)) { port[i] = '\0'; } } if(strcmp(svcptr->type,"group") == 0) { printf("%-11s%18c",svcname,' '); return 1; } else { sprintf(type,"%s",svcptr->type); if(strlen(type) > 10) type[11] = '\0'; printf("%-13s:%-9s %5s",svcname,port,type); return 0; } } svcptr = svcptr->nodelink; } /* looked thru whole list, and didn't find any matches */ /* I think if we make it here, something really went wrong... */ /*if((svcflag == 0) && (rule_serv != NULL)) {*/ if(rule_serv != NULL) { /* not resolution was found -- just print it out */ if(strlen(rule_serv) > 10) rule_serv[11] = '\0'; printf("%-11s%18c",rule_serv,' '); } /* we know at this point the current object is not a group */ return 0; }