/* 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 #include #include using namespace std; 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; } int main (int argc, char *argv[]) { int ret = -1; if (argc != 4 && argc != 3){ fprintf (stderr,"flushchains ipchain-command-path chain-prefix [ table ]\n"); }else{ const char *cmd = argv[1]; const char *prefix = argv[2]; const char *table = argv[3]; int len = strlen(prefix); vector chains; // We support both ipchains and iptables FILE *fin = fopen ("/proc/net/ip_fwnames","r"); if (fin != NULL){ char buf[200]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ if (strncmp(buf,prefix,len)==0){ char *pt = buf; while (*pt > ' ') pt++; *pt = '\0'; chains.push_back(buf); } } fclose (fin); }else{ char tmp[200]; snprintf (tmp,sizeof(tmp)-1 ,"%s --table %s --list -n | grep \"Chain %s\" | (while read a b c; do echo $b; done)" ,cmd,table,prefix); fin = popen (tmp,"r"); if (fin != NULL){ char buf[200]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ if (strncmp(buf,prefix,len)==0){ char *pt = buf; while (*pt > ' ') pt++; *pt = '\0'; chains.push_back(buf); } } pclose (fin); } } const char *args[6]; int pos1 = 1; int pos2 = 2; args[0] = cmd; if (table != NULL){ pos1 = 3; pos2 = 4; args[1] = "-t"; args[2] = table; args[5] = NULL; }else{ 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[pos1] = i == 0 ? "--flush" : "--delete-chain"; for (unsigned j=0; j