// nat disable intface extface // 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::disableNat(const int argc, char **argv) { int i; int addrCount = atoi(argv[4]); const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { ALOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { ALOGE("Missing Argument"); errno = EINVAL; return -1; } setForwardRules(false, intIface, extIface); routesOp(false, intIface, extIface, argv, addrCount); if (--natCount <= 0) { // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 setDefaults(); } return 0; }
// nat disable intface extface // 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::disableNat(const int argc, char **argv) { char cmd[255]; int i; int addrCount = atoi(argv[4]); const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { LOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { LOGE("Missing Argument"); errno = EINVAL; return -1; } setForwardRules(false, intIface, extIface); tableNumber = secondaryTableCtrl->findTableNumber(extIface); if (tableNumber != -1) { for (i = 0; i < addrCount; i++) { snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, tableNumber + BASE_TABLE_NUMBER); // if the interface has gone down these will be gone already and give errors // ignore them. runCmd(IP_PATH, cmd); snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]), argv[5+i], tableNumber + BASE_TABLE_NUMBER); runCmd(IP_PATH, cmd); } runCmd(IP_PATH, "route flush cache"); } if (--natCount <= 0) { // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 setDefaults(); } return 0; }
int CJobRunner::exec(ECommand cmd, const ItemList &urls, bool destIsSystem) { itsAutoSkip=itsCancelClicked=itsModified=false; switch(cmd) { case CMD_INSTALL: setCaption(i18n("Installing")); break; case CMD_DELETE: setCaption(i18n("Uninstalling")); break; case CMD_ENABLE: setCaption(i18n("Enabling")); break; case CMD_MOVE: setCaption(i18n("Moving")); break; case CMD_UPDATE: setCaption(i18n("Updating")); itsModified=true; break; case CMD_REMOVE_FILE: setCaption(i18n("Removing")); break; default: case CMD_DISABLE: setCaption(i18n("Disabling")); } itsDestIsSystem=destIsSystem; itsUrls=urls; if(CMD_INSTALL==cmd) qSort(itsUrls.begin(), itsUrls.end()); // Sort list of fonts so that we have type1 fonts followed by their metrics... else if(CMD_MOVE==cmd) addEnableActions(itsUrls); itsIt=itsUrls.constBegin(); itsEnd=itsUrls.constEnd(); itsPrev=itsEnd; itsProgress->setValue(0); itsProgress->setRange(0, itsUrls.count()+1); itsProgress->show(); itsCmd=cmd; itsCurrentFile=QString(); itsStatusLabel->setText(QString()); setPage(PAGE_PROGRESS); QTimer::singleShot(0, this, SLOT(doNext())); QTimer::singleShot(constInterfaceCheck, this, SLOT(checkInterface())); itsActionLabel->startAnimation(); int rv=KDialog::exec(); if(itsTempDir) { delete itsTempDir; itsTempDir=0L; } return rv; }
// nat disable intface extface // 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::disableNat(const int argc, char **argv) { char cmd[255]; int i; int addrCount = atoi(argv[4]); const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { ALOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { ALOGE("Missing Argument"); errno = EINVAL; return -1; } setForwardRules(false, intIface, extIface); tableNumber = secondaryTableCtrl->findTableNumber(extIface); if (tableNumber != -1) { for (i = 0; i < addrCount; i++) { secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]); secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]); } runCmd(IP_PATH, "route flush cache"); } if (--natCount <= 0) { // handle decrement to 0 case (do reset to defaults) and erroneous dec below 0 setDefaults(); } ALOGI("disableNat: natCount = %d", natCount); return 0; }
// 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::enableNat(const int argc, char **argv) { int i; int addrCount = atoi(argv[4]); const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; ALOGV("enableNat(intIface=<%s>, extIface=<%s>)",intIface, extIface); if (!checkInterface(intIface) || !checkInterface(extIface)) { ALOGE("Invalid interface specified"); errno = ENODEV; return -1; } /* Bug: b/9565268. "enableNat wlan0 wlan0". For now we fail until java-land is fixed */ if (!strcmp(intIface, extIface)) { ALOGE("Duplicate interface specified: %s %s", intIface, extIface); errno = EINVAL; return -1; } if (argc < 5 + addrCount) { ALOGE("Missing Argument"); errno = EINVAL; return -1; } if (routesOp(true, intIface, extIface, argv, addrCount)) { ALOGE("Error setting route rules"); routesOp(false, intIface, extIface, argv, addrCount); errno = ENODEV; return -1; } // add this if we are the first added nat if (natCount == 0) { const char *cmd[] = { IPTABLES_PATH, "-t", "nat", "-A", LOCAL_NAT_POSTROUTING, "-o", extIface, "-j", "MASQUERADE" }; if (runCmd(ARRAY_SIZE(cmd), cmd)) { ALOGE("Error seting postroute rule: iface=%s", extIface); // unwind what's been done, but don't care about success - what more could we do? routesOp(false, intIface, extIface, argv, addrCount); setDefaults(); return -1; } } if (setForwardRules(true, intIface, extIface) != 0) { ALOGE("Error setting forward rules"); routesOp(false, intIface, extIface, argv, addrCount); if (natCount == 0) { setDefaults(); } errno = ENODEV; return -1; } /* Always make sure the drop rule is at the end */ const char *cmd1[] = { IPTABLES_PATH, "-D", LOCAL_FORWARD, "-j", "DROP" }; runCmd(ARRAY_SIZE(cmd1), cmd1); const char *cmd2[] = { IPTABLES_PATH, "-A", LOCAL_FORWARD, "-j", "DROP" }; runCmd(ARRAY_SIZE(cmd2), cmd2); natCount++; return 0; }
/* Función que comprueba si el formato del fichero de configuración es correcto*/ int formatOK(FILE * p, int * errorMemoria) { int numNames = 0; // Número de nombres de la primera linea int numInterfaces = 0; // Número de interfaces char name[TAM]; // Almacena el nombre de las interfaces para compararlos con los de la primera línea char * interfaces = NULL; // Reserva dinámica de memoria para almacenar el nombre de las interfaces char head[TAM]; // Cadena que almacena la primera línea del fichero sin en el número de interfaces int oct1; // Recoge el primero octeto de la dirección int oct2; // Recoge el segundo octeto de la dirección int oct3; // Recoge el tercer octeto de la dirección int oct4; // Recoge el cuarto octeto de la dirección int i = 0; // Contador 1 int j = 0; // Contador 2 int flag = 0; // Bandera 1 int equal = 0; // Bandera 2 NODO1 * tableForwarding = NULL; // Puntero al primer elemento de la lista con la tabla de reenvío NODO1 * forwardingAux = NULL; // Auxiliar lista con la tabla de reenvío NODO1 * dirRepeat = NULL; // Puntero a nodo para recorrer la lista e ir comparando NODO3 * first = NULL; // Puntero a lista con cabecera NODO3 * aux = NULL; // Auxiliar lista cabecera fscanf(p,"%d", &numInterfaces); // Almacena el número de interfaces que debe haber fgets(head,TAM,p); // Guarda en cabecera la primera línea del fichero (sin el número de interfaces) for(i=0; i<=TAM; i++) { if((isspace(head[i]) != 0) && ((head[i+1] >= 'a' && head[i+1] <= 'z') || (head[i+1] >= 'A' && head[i+1] <= 'Z') || (head[i+1] >= '0' && head[i+1] <= '9'))) // El número de nombres de la primera linea es igual al número de espacios numNames++; else if(head[i] == '\n') i = TAM +1; // Hace que finalice el bucle } i = 0; // Devuelve i a 0 while(isspace(head[i]) != 0) // Quita los espacios iniciales de la cabecera { i++; } if(numNames == numInterfaces) // Si el número de nombres es igual al de interfaces, hay que comprobar el resto de líneas, si no => Error { if(fscanf(p,"%d.%d.%d.%d",&oct1,&oct2,&oct3,&oct4) == 4) // Si las direcciones tienen el formato correcto, comprueba los nombres { fgets(name, TAM, p); while(isspace(name[j]) != 0) // Quita los espacios del nombre { j++; } while(!feof(p)) // Recorre todo el fichero para comprobar que los nombres han sido dados en la cabecera { while(head[i] != '\n' && equal == 0) { while((name[j] != head[i]) && (head[i] != '\n')) { i++; j = 1; } if(head[i] == '\n') equal = -1; i++; j++; if(name[j] == '\n') { equal = 1; j = 1; i = 1; } } if((oct1 > 255)||(oct2 > 255)||(oct3 > 255)||(oct4 != 0)) // Comprueba que los octetos no sean mayores de 255 equal = -1; if((fscanf(p,"%d.%d.%d.%d",&oct1,&oct2,&oct3,&oct4) != 4) && (equal == -1)) // Si el formato de la dirección es erróneo o hay error en los nombres flag = 1; // => Error fgets(name, TAM, p); if(equal == 1) equal = 0; } } else // Si el formato de las direcciones es incorrecto => Error flag = 1; } else // Si el número de nombres no es igual al de interfaces => Error flag = 1; if(flag == 0) // Si no ha habido error en los casos contemplados anteriormente, comprobamos otros errores { interfaces = (char *) calloc(TAM, sizeof(char)); // Reserva dinámica de memoria para almacena el nombre de las interfaces if(interfaces != NULL) // Reserva correcta { fseek(p, 0, SEEK_SET); // Pone el puntero a fichero de nuevo al principio. fscanf(p,"%d",&numInterfaces); // Almacena el número de interfaces fgets(head, TAM, p); // Lee la primera línea para tener el puntero al comienzo de la tabla fscanf(p,"%d.%d.%d.%d",&oct1,&oct2,&oct3,&oct4); // Almacena la dirección de la siguiente interfaz fscanf(p,"%s",interfaces); // Nombre de la interfaz correspondiente a la dirección anterior while(!feof(p)) // Crea una lista de numInterfaces nodos, para que sirva como tabla de reenvio { forwardingAux = makeNodeConf(oct1, oct2, oct3, oct4, interfaces, errorMemoria); // Crea los nodos linksNodeConf(forwardingAux, &tableForwarding); // Enlaza la lista fscanf(p,"%d.%d.%d.%d",&oct1,&oct2,&oct3,&oct4); // Almacena la dirección de la siguiente interfaz fscanf(p,"%s",interfaces); // Nombre de la interfaz correspondiente a la dirección anterior } dirRepeat = tableForwarding->sig; // El puntero para comprobar si está repetida va un nodo por delante flag = checkRepeat(tableForwarding, dirRepeat); // Llamada para comprobar si hay alguna dirección repetida if(flag == 0) // Si aún no se ha encontrado el error, seguimos comprobando { fseek(p, 0, SEEK_SET); // Pone el puntero a fichero de nuevo al principio fscanf(p,"%d",&numInterfaces); // Almacena el número de interfaces while(numInterfaces > 0) // Bucle para crear una lista con los nombres de la primera linea { fscanf(p,"%s",interfaces); // Guarda el primer nombre aux = makeNodeHead(interfaces, errorMemoria); // Crea los nodos de la lista linksNodeHead(aux, &first); // Enlaza los nodos de la lista numInterfaces--; } flag = checkInterface(tableForwarding,first); // Comprueba si hay algún nombre en la primera línea que luego no lleve dirección asignada } } else // Error de reserva { printf("Error 6: error de memoria\n"); (*errorMemoria) = 1; } } free(interfaces); // Libera la reserva dinámica de memoria removeHead(&first); // Elimina la lista con la cabecera removeConf(&tableForwarding); // Elimina la lista con la tabla de reenvio return (flag); }
// 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::enableNat(const int argc, char **argv) { char cmd[255]; int i; int addrCount = atoi(argv[4]); int ret = 0; const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { LOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { LOGE("Missing Argument"); errno = EINVAL; return -1; } tableNumber = secondaryTableCtrl->findTableNumber(extIface); if (tableNumber != -1) { for(i = 0; i < addrCount && ret == 0; i++) { snprintf(cmd, sizeof(cmd), "%s rule add from %s table %d", getVersion(argv[5+i]), argv[5+i], tableNumber + BASE_TABLE_NUMBER); ret |= runCmd(IP_PATH, cmd); if (ret) LOGE("IP rule %s got %d", cmd, ret); snprintf(cmd, sizeof(cmd), "route add %s dev %s table %d", argv[5+i], intIface, tableNumber + BASE_TABLE_NUMBER); ret |= runCmd(IP_PATH, cmd); if (ret) LOGE("IP route %s got %d", cmd, ret); } runCmd(IP_PATH, "route flush cache"); } if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) { if (tableNumber != -1) { for (i = 0; i < addrCount; i++) { snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, tableNumber + BASE_TABLE_NUMBER); runCmd(IP_PATH, cmd); snprintf(cmd, sizeof(cmd), "%s rule del from %s table %d", getVersion(argv[5+i]), argv[5+i], tableNumber + BASE_TABLE_NUMBER); runCmd(IP_PATH, cmd); } runCmd(IP_PATH, "route flush cache"); } LOGE("Error setting forward rules"); errno = ENODEV; return -1; } natCount++; // add this if we are the first added nat if (natCount == 1) { snprintf(cmd, sizeof(cmd), "-t nat -A POSTROUTING -o %s -j MASQUERADE", extIface); if (runCmd(IPTABLES_PATH, cmd)) { LOGE("Error seting postroute rule: %s", cmd); // unwind what's been done, but don't care about success - what more could we do? for (i = 0; i < addrCount; i++) { snprintf(cmd, sizeof(cmd), "route del %s dev %s table %d", argv[5+i], intIface, tableNumber + BASE_TABLE_NUMBER); runCmd(IP_PATH, cmd); } setDefaults(); return -1; } if (runCmd(IPTABLES_PATH, "-t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu")) LOGW("Unable to set TCPMSS rule (may not be supported by kernel)."); } return 0; }
// 0 1 2 3 4 5 // nat enable intface extface addrcnt nated-ipaddr/prelength int NatController::enableNat(const int argc, char **argv) { char cmd[255]; int i; int addrCount = atoi(argv[4]); int ret = 0; const char *intIface = argv[2]; const char *extIface = argv[3]; int tableNumber; if (!checkInterface(intIface) || !checkInterface(extIface)) { ALOGE("Invalid interface specified"); errno = ENODEV; return -1; } if (argc < 5 + addrCount) { ALOGE("Missing Argument"); errno = EINVAL; return -1; } tableNumber = secondaryTableCtrl->findTableNumber(extIface); if (tableNumber != -1) { for(i = 0; i < addrCount; i++) { ret |= secondaryTableCtrl->modifyFromRule(tableNumber, ADD, argv[5+i]); //ALPS00338128 //ignore the result to protect the tether class from stoping the tethering secondaryTableCtrl->modifyLocalRoute(tableNumber, ADD, intIface, argv[5+i]); } runCmd(IP_PATH, "route flush cache"); } if (ret != 0 || setForwardRules(true, intIface, extIface) != 0) { if (tableNumber != -1) { for (i = 0; i < addrCount; i++) { secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]); secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]); } runCmd(IP_PATH, "route flush cache"); } ALOGE("Error setting forward rules"); errno = ENODEV; return -1; } /* Always make sure the drop rule is at the end */ snprintf(cmd, sizeof(cmd), "-D natctrl_FORWARD -j DROP"); runCmd(IPTABLES_PATH, cmd); snprintf(cmd, sizeof(cmd), "-A natctrl_FORWARD -j DROP"); runCmd(IPTABLES_PATH, cmd); natCount++; ALOGI("enablenat: natCount = %d", natCount); // add this if we are the first added nat if (natCount == 1) { snprintf(cmd, sizeof(cmd), "-t nat -A natctrl_nat_POSTROUTING -o %s -j MASQUERADE", extIface); if (runCmd(IPTABLES_PATH, cmd)) { ALOGE("Error seting postroute rule: %s", cmd); // unwind what's been done, but don't care about success - what more could we do? for (i = 0; i < addrCount; i++) { secondaryTableCtrl->modifyLocalRoute(tableNumber, DEL, intIface, argv[5+i]); secondaryTableCtrl->modifyFromRule(tableNumber, DEL, argv[5+i]); } setDefaults(); return -1; } } return 0; }