/* This utility is used to flush and delete all user-defined firewall chains starting with a given prefix. The utility receives the path of the ipchain command (usually /sbin/ipchains) and then the prefix of all chains to remove. The utility do two passes. One to flush the content of every chains and then another to delete the chains. */ #include #include #include #include #include #include static int flush_exec (const char *argv[]) { int ret = -1; pid_t pid = fork(); if (pid == 0){ execv (argv[0],(char**)argv); _exit (-1); }else{ int status; wait (&status); ret = WIFEXITED(status); } return ret; } struct CHAIN{ char *name; CHAIN *next; CHAIN(const char *_name, CHAIN *_next){ next = _next; name = strdup(_name); } ~CHAIN(){ free (name); } }; int main (int argc, char *argv[]) { int ret = -1; if (argc != 3){ fprintf (stderr,"flushchains ipchain-command-path chain-prefix\n"); }else{ const char *cmd = argv[1]; const char *prefix = argv[2]; int len = strlen(prefix); FILE *fin = fopen ("/proc/net/ip_fwnames","r"); if (fin != NULL){ char buf[200]; CHAIN *first = NULL; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ if (strncmp(buf,prefix,len)==0){ char *pt = buf; while (*pt > ' ') pt++; *pt = '\0'; first = new CHAIN (buf,first); } } fclose (fin); const char *args[4]; args[0] = cmd; args[3] = NULL; for (int i=0; i<2; i++){ // We do two passes. One to delete the content of the // chains and the other to delete the chains. // This way we know they are not referenced anymore args[1] = i == 0 ? "--flush" : "--delete-chain"; CHAIN *pt = first; while (pt != NULL){ args[2] = pt->name; flush_exec (args); pt = pt->next; } } while (first != NULL){ CHAIN *next = first->next; delete first; first = next; } } } return ret; }