Beispiel #1
0
// for test
void show_default_info(webs_t wp)
{
	// int ret=0;

	websDone(wp, 200);	// Let header in first packet, and bellow
	// information in second packet.

	websWrite(wp, "Vendor:%s\n", VENDOR);
	websWrite(wp, "ModelName:%s\n", MODEL_NAME);

	websWrite(wp, "Firmware Version:%s%s , %s\n", CYBERTAN_VERSION, MINOR_VERSION, __DATE__);
	websWrite(wp, "#:%s\n", SERIAL_NUMBER);
	websWrite(wp, "Boot Version:%s\n", nvram_safe_get("boot_ver"));
	/*
	 * begin Svbeasoft modifications 
	 */
	// ret = websWrite(wp, "CodePattern:%s\n", CODE_PATTERN);
	// #if LOCALE == EUROPE
	// ret = websWrite(wp, "Country:Europe\n");
	// #elif LOCALE == JAPAN
	// ret = websWrite(wp, "Country:Japan\n");
	// #else
	// ret = websWrite(wp, "Country:US\n");
	// #endif
	// ret = websWrite(wp, "\n");

	websWrite(wp, "RF Status:%s\n", (nvram_match("wl0_hwaddr", "")
					 || nvram_match("wl_gmode", "-1")) ? "disabled" : "enabled");

	websWrite(wp, "RF Firmware Version:%s%s\n", CYBERTAN_VERSION, MINOR_VERSION);
	// #if LOCALE == EUROPE
	// ret = websWrite(wp, "RF Domain:ETSI (channel 1~%s)\n",
	// WL_MAX_CHANNEL);
	// #elif LOCALE == JAPAN
	// ret = websWrite(wp, "RF Domain:JPN (channel 1~%s)\n", WL_MAX_CHANNEL);
	// #else
	// ret = websWrite(wp, "RF Domain:US (channel 1~%s)\n", WL_MAX_CHANNEL);
	// #endif

	websWrite(wp, "RF Domain:Worldwide (channel 1~%s)\n", WL_MAX_CHANNEL);
	websWrite(wp, "RF Channel:%s\n", nvram_safe_get("wl0_channel"));
	websWrite(wp, "RF SSID:%s\n", nvram_safe_get("wl0_ssid"));

	websWrite(wp, "\n-----Dynamic Information\n");

	websWrite(wp, "RF Mac Address:%s\n", nvram_safe_get("wl0_hwaddr"));
	websWrite(wp, "LAN Mac Address:%s\n", nvram_safe_get("lan_hwaddr"));
	websWrite(wp, "WAN Mac Address:%s\n", nvram_safe_get("wan_hwaddr"));
	if (check_hw_type() == BCM4702_CHIP)
		websWrite(wp, "Hardware Version:1.x\n");
	else
		websWrite(wp, "Hardware Version:2.0\n");

	websWrite(wp, "Device Serial No.:%s\n", nvram_safe_get("get_sn"));

	websWrite(wp, "\n");	// The last char must be '\n'

	return;
}
Beispiel #2
0
const char *default_wlif(void)
{
	switch (check_hw_type()) {
	case HW_BCM4702:
	case HW_BCM4704_BCM5325F:
	case HW_BCM4704_BCM5325F_EWC:
		return "eth2";
	}
	return "eth1";
	
}
Beispiel #3
0
static int backup_main(int argc, char **argv)
{
	backup_t data;
	unsigned int size;
	char *p;
	char s[512];
	char tmp[128];
	int r;

	getall(data.buffer);

	data.sig = V1;
	data.hwid = check_hw_type();

	p = data.buffer;
	while (*p != 0) p += strlen(p) + 1;

	size = (sizeof(data) - sizeof(data.buffer)) + (p - data.buffer) + 1;

	strcpy(tmp, "/tmp/nvramXXXXXX");
	mktemp(tmp);
	if (f_write(tmp, &data, size, 0, 0) != size) {
		printf("Error saving file.\n");
		return 1;
	}
	sprintf(s, "gzip < %s > %s", tmp, argv[1]);
	r = system(s);
	unlink(tmp);

	if (r != 0) {
		unlink(argv[1]);
		printf("Error compressing file.\n");
		return 1;
	}

	printf("Saved.\n");
	return 0;
}
Beispiel #4
0
int get_model(void)
{
	int hw;
	char *c;

	hw = check_hw_type();

	switch (strtoul(nvram_safe_get("melco_id"), NULL, 16)) {
	case 0x29115:
    case 0x30061:
		return MODEL_WZRG54;
	case 0x30182:
		return MODEL_WHRG54S;
	case 0x30189:
		return MODEL_WHRHPG54;
	case 0xCA020906:
		return MODEL_WBRG54;
	case 0x30026:
    	return MODEL_WZRHPG54;
    case 0x30083:
        return MODEL_WZRRSG54;
    case 0x30103:
    	return MODEL_WZRRSG54HP;
    case 0x28100:
    	return MODEL_WVRG54NF;
    case 0x29130:
    	return MODEL_WHR3AG54;
	case 0x290441DD:
		return MODEL_WHR2A54G54;
	case 0x32093:
		return MODEL_WHRG125;
	case 0x30153:
	case 0x31095:
		return MODEL_WZRG108;
	case 0x31120:
		return MODEL_WZRG300N;
	case 0:
		break;
	default:
		return MODEL_UNKNOWN;
	}

	switch (strtoul(nvram_safe_get("buffalo_id"), NULL, 16)) {
	case 0x29BB0332:
		return MODEL_WBR2G54;
	case 0x29129:
		return MODEL_WLA2G54L;
	case 0:
		break;
	default:
		return MODEL_UNKNOWN;
	}

	if (nvram_match("boardtype", "bcm94710ap")) {
		if (nvram_match("boardnum", "mn700")) return MODEL_MN700;
		if (nvram_match("ModelId", "WX-5565")) return MODEL_TM2300;
	}
	
	if (hw == HW_UNKNOWN) return MODEL_UNKNOWN;

/*
	if (hw == HW_BCM5354G) {
		if (nvram_match("boardrev", "0x11")) {
			return MODEL_WRH54G;
		}
	}
*/

#ifdef CONFIG_BCMWL5
	if (hw == HW_BCM4718) {
		if (nvram_match("boot_hw_model", "WRT610N") ||
		    nvram_match("boot_hw_model", "E300"))
			return MODEL_WRT610Nv2;
		if (nvram_match("boot_hw_model", "E4200"))
			return MODEL_E4200;
		switch (strtoul(nvram_safe_get("boardtype"), NULL, 0)) {
		case 0xd4cf:
			if (nvram_match("boardrev", "0x1204")) return MODEL_F7D4301;
			break;
		case 0xa4cf:
			if (nvram_match("boardrev", "0x1100")) return MODEL_F5D8235v3;
			if (nvram_match("boardrev", "0x1102")) {
				FILE *fp;
				unsigned char s[18];
				uint32 sig = TRX_MAGIC;
				sprintf(s, MTD_DEV(%dro), 1);
				if ((fp = fopen(s, "rb"))) {
					fread(&sig, sizeof(sig), 1, fp);
					fclose(fp);
				}
				switch (sig) {
				case TRX_MAGIC_F7D3301:
					return MODEL_F7D3301;
				case TRX_MAGIC_F7D3302:
					return MODEL_F7D3302;
				default:
					return MODEL_F7D4302;
				}
			}
			break;
		}
	}
Beispiel #5
0
const char *default_wanif(void)
{
	return ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
		(check_hw_type() == HW_BCM4712)) ? "vlan1" : "eth1";
}
Beispiel #6
0
int do_led(int which, int mode)
{
//				    WLAN  DIAG  WHITE AMBER DMZ   AOSS  BRIDG MYST/USB 5G
//				    ----- ----- ----- ----- ----- ----- ----- -----    -- 
	static int wrt54g[]	= { 255,  1,    2,    3,    7,    255,  255,  255,    255};
	static int wrtsl[]	= { 255,  1,    5,    7,    0,    255,  255,  255,    255};
	static int whrg54[]	= { 2,    7,    255,  255,  255,  6,    1,    3	 ,    255};
	static int wbr2g54[]	= { 255,  -1,   255,  255,  255,  -6,   255,  255,    255};
	static int wzrg54[]	= { 2,    7,    255,  255,  255,  6,    255,  255,    255};
	static int wr850g1[]	= { 7,    3,    255,  255,  255,  255,  255,  255,    255};
	static int wr850g2[]	= { 0,    1,    255,  255,  255,  255,  255,  255,    255};
	static int wtr54gs[]	= { 1,    -1,   255,  255,  255,  255,  255,  255,    255};
	static int dir320[]	= { -99,   1,     4,    3,  255,  255,  255,   -5,    255};
	static int h618b[]	= { 255,  -1,   255,  255,  255,   -5,   -3,   -4,    255};
	static int wl1600gl[]	= { 1,    -5, 	  0,  255,  255,  2,    255,  255,    255};
	static int wrt310nv1[]	= { 255,   1,     9,    3,  255,  255,  255,  255,    255};
	static int wrt160nv1[]	= { 255,   1,     5,    3,  255,  255,  255,  255,    255};
#ifdef CONFIG_BCMWL5
	static int wnr3500[]	= { 255, 255,     2,  255,  255,   -1,  255,  255,    255};
	static int wnr2000v2[]	= { 255, 255,   255,  255,  255,   -7,  255,  255,    255};
	static int f7d[]	= { 255, 255,   255,  255,   12,   13,  255,   14,    255};
	static int wrt160nv3[]	= { 255,   1,     4,    2,  255,  255,  255,  255,    255};
	static int e900[]	= { 255,  -6,     8,  255,  255,  255,  255,  255,    255};
	static int e1000v2[]	= { 255,  -6,     8,    7,  255,  255,  255,  255,    255};
	static int e3200[]	= { 255,  -3,   255,  255,  255,  255,  255,  255,    255};
	static int wrt320n[]	= { 255,   2,     3,    4,  255,  255,  255,  255,    255};
	static int wrt610nv2[]	= { 255,   5,     3,    0,  255,  255,  255,   -7,    255};
	static int e4200[]		= { 255,   5,    -3,  255,  255,  255,  255,  255,    255};
	static int rtn10u[]		= { 255, 255,   255,  255,  255,   -7,  255,   -8,    255};
	static int rtn10p[]		= { 255,  -6,   255,  255,  255,   -7,  255,  255,    255};
	static int rtn12b1[]	= {  -5, 255,   255,  255,  255,  255,  255,  225,    255};
	static int rtn15u[]		= {   1, 255,     3,  255,  255,  255,  255,   -9,    255};
	static int rtn53[]		= {   0, -17,   255,  255,  255,  255,  255,  255,    255};
	static int rtn66u[]		= { 255, -12,   255,  255,  255,  255,  255,   15,     13};
	static int w1800r[] 	= { 255, -13,   255,  255,  255,  255,  255,  -12,     -5};
	static int l600n[]  	= { 255, 255,   255,  255,  255,  -7,   255,  -8,      -5};
	static int dir620c1[]   = { -6,   -8,   255,  255,  255,  -7,   255,  255,     -5};
	static int wndr3700v3[] = { 255, 255,     2,  255,  255,  -1,   255,  255,    255};
	static int d1800h[]     = { -12, -13,     8,  255,  255,  -10,  255,    15, 255,   11};
	static int tdn6[]       = { 255,  -6,     8,  255,  255,  255,  255,   255, 255,  255};

#endif

	char s[16];
	int n;
	int b = 255, c = 255;
	int ret = 255;

	if ((which < 0) || (which >= LED_COUNT)) return ret;

	switch (nvram_match("led_override", "1") ? MODEL_UNKNOWN : get_model()) {
	case MODEL_WRT54G:
		if (check_hw_type() == HW_BCM4702) {
			// G v1.x
			if ((which != LED_DIAG) && (which != LED_DMZ)) return ret;
			b = (which == LED_DMZ) ? 1 : 4;
			if (mode != LED_PROBE) {
				if (f_read_string("/proc/sys/diag", s, sizeof(s)) > 0) {
					n = atoi(s);
					sprintf(s, "%u", mode ? (n | b) : (n & ~b));
					f_write_string("/proc/sys/diag", s, 0, 0);
				}
			}
			return b;
		}
		switch (which) {
		case LED_AMBER:
		case LED_WHITE:
			if (!supports(SUP_WHAM_LED)) return ret;
			break;
		}
		b = wrt54g[which];
		break;
	case MODEL_WTR54GS:
		b = wtr54gs[which];
		break;
	case MODEL_WRTSL54GS:
		b = wrtsl[which];
		break;
	case MODEL_WHRG54S:
	case MODEL_WHRHPG54:
	case MODEL_WHRG125:
		b = whrg54[which];
		break;
	case MODEL_WZRG54:
	case MODEL_WZRHPG54:
	case MODEL_WZRRSG54:
	case MODEL_WZRRSG54HP:
	case MODEL_WVRG54NF:
	case MODEL_WHR2A54G54:
	case MODEL_WHR3AG54:
	case MODEL_WZRG108:
		b = wzrg54[which];
		break;
/*		
	case MODEL_WHR2A54G54:
		if (which != LED_DIAG) return ret;
		b = 7;
		break;
*/
	case MODEL_WBRG54:
		if (which != LED_DIAG) return ret;
		b = 7;
		break;
	case MODEL_WBR2G54:
		b = wbr2g54[which];
		break;
	case MODEL_WR850GV1:
		b = wr850g1[which];
		break;
	case MODEL_WR850GV2:
	case MODEL_WR100:
		b = wr850g2[which];
		break;
	case MODEL_WL500GP:
		if (which != LED_DIAG) return ret;
		b = -1;	// power light
		break;
	case MODEL_WL500W:
		if (which != LED_DIAG) return ret;
		b = -5;	// power light
		break;
	case MODEL_DIR320:
		b = dir320[which];
		break;
	case MODEL_H618B:
		b = h618b[which];
		break;
	case MODEL_WL1600GL:
		b = wl1600gl[which];
		break;
	case MODEL_WL500GPv2:
	case MODEL_WL500GD:
	case MODEL_WL520GU:
	case MODEL_WL330GE:
		if (which != LED_DIAG) return ret;
		b = -99;	// Invert power light as diag indicator
		break;
#ifdef CONFIG_BCMWL5
	case MODEL_RTN12:
		if (which != LED_DIAG) return ret;
		b = -2;	// power light
		break;
	case MODEL_RTN10:
	case MODEL_RTN16:
		if (which != LED_DIAG) return ret;
		b = -1;	// power light
		break;
	case MODEL_RTN15U:
		b = rtn15u[which];
		break;
	case MODEL_RTN53:
	case MODEL_RTN53A1:
		b = rtn53[which];
		break;
	case MODEL_RTN66U:
		b = rtn66u[which];
		break;
	case MODEL_W1800R:
		b = w1800r[which];
		break;
	case MODEL_D1800H:
		if (which == LED_DIAG) {
			// power led gpio: 0x02 - white, 0x13 - red 
			b = (mode) ? 13 : 2;
			c = (mode) ? 2 : 13;
		} else
			b = d1800h[which];
		break;
	case MODEL_WNDR3700v3:
		b = wndr3700v3[which];
		break;
	case MODEL_WNR3500L:
	case MODEL_WNR3500LV2:
		if (which == LED_DIAG) {
			// power led gpio: 0x03 - green, 0x07 - amber
			b = (mode) ? 7 : 3;
			c = (mode) ? 3 : 7;
		} else
			b = wnr3500[which];
		break;
	case MODEL_WNR2000v2:
		if (which == LED_DIAG) {
			// power led gpio: 0x01 - green, 0x02 - amber
			b = (mode) ? 2 : 1;
			c = (mode) ? 1 : 2;
		} else
			b = wnr2000v2[which];
		break;
	case MODEL_F7D3301:
	case MODEL_F7D3302:
	case MODEL_F7D4301:
	case MODEL_F7D4302:
	case MODEL_F5D8235v3:
		if (which == LED_DIAG) {
			// power led gpio: 10 - green, 11 - red
			b = (mode) ? 11 : -10;
			c = (mode) ? -10 : 11;
		} else
			b = f7d[which];
		break;
	case MODEL_E1000v2:
		b = e1000v2[which];
		break;
	case MODEL_E900:
	case MODEL_E1500:
	case MODEL_E1550:
	case MODEL_E2500:
		b = e900[which];
		break;
	case MODEL_E3200:
		b = e3200[which];
		break;
	case MODEL_WRT160Nv3:
		b = wrt160nv3[which];
		break;
	case MODEL_WRT320N:
		b = wrt320n[which];
		break;
	case MODEL_WRT610Nv2:
		b = wrt610nv2[which];
		break;
	case MODEL_E4200:
		b = e4200[which];
		break;
	case MODEL_RTN10U:
		b = rtn10u[which];
		break;
	case MODEL_RTN10P:
		b = rtn10p[which];
		break;
	case MODEL_RTN12B1:
		b = rtn12b1[which];
		break;
	case MODEL_L600N:
		b = l600n[which];
		break;
	case MODEL_DIR620C1:
		b = dir620c1[which];
	case MODEL_TDN60: //bwq518
	case MODEL_TDN6:
		b = tdn6[which];
		break;
#endif
/*
	case MODEL_RT390W:
		break;
*/
	case MODEL_MN700:
		if (which != LED_DIAG) return ret;
		b = 6;
		break;
	case MODEL_WLA2G54L:
		if (which != LED_DIAG) return ret;
		b = 1;
		break;
	case MODEL_WRT300N:
		if (which != LED_DIAG) return ret;
		b = 1;
		break;
	case MODEL_WRT310Nv1:
		b = wrt310nv1[which];
		break;
	case MODEL_WRT160Nv1:
		b = wrt160nv1[which];
		break;
	default:
		sprintf(s, "led_%s", led_names[which]);
		if (nvget_gpio(s, &b, &n)) {
			if ((mode != LED_PROBE) && (n)) mode = !mode;
			ret = (n) ? b : ((b) ? -b : -99);
			goto SET;
		}
		return ret;
	}

	ret = b;
	if (b < 0) {
		if (b == -99) b = 0; // -0 substitute
			else b = -b;
	}
	else if (mode != LED_PROBE) {
		mode = !mode;
	}

SET:
	if (b < 16) {
		if (mode != LED_PROBE) {
			gpio_write(1 << b, mode);

			if (c < 0) {
				if (c == -99) c = 0;
				else c = -c;
			}
			else mode = !mode;
			if (c < 16) gpio_write(1 << c, mode);
		}
	}

	return ret;
}
Beispiel #7
0
static int restore_main(int argc, char **argv)
{
	char *name;
	int test;
	int force;
	int commit;
	backup_t data;
	unsigned int size;
	char s[512];
	char tmp[128];
	unsigned long hw;
	char current[NVRAM_SPACE];
	char *b, *bk, *bv;
	char *c, *ck, *cv;
	int nset;
	int nunset;
	int nsame;
	int cmp;
	int i;

	test = 0;
	force = 0;
	commit = 1;
	name = NULL;
	for (i = 1; i < argc; ++i) {
		if (argv[i][0] == '-') {
			if (strcmp(argv[i], "--test") == 0) {
				test = 1;
			}
			else if (strcmp(argv[i], "--force") == 0) {
				force = 1;
			}
			else if (strcmp(argv[i], "--forceall") == 0) {
				force = 2;
			}
			else if (strcmp(argv[i], "--nocommit") == 0) {
				commit = 0;
			}
			else {
				help();
			}
		}
		else {
			name = argv[i];
		}
	}
	if (!name) help();

	strcpy(tmp, "/tmp/nvramXXXXXX");
	mktemp(tmp);
	sprintf(s, "gzip -d < %s > %s", name, tmp);
	if (system(s) != 0) {
		unlink(tmp);
		printf("Error decompressing file.\n");
		return 1;
	}

	size = f_size(tmp);
	if ((size <= (sizeof(data) - sizeof(data.buffer))) || (size > sizeof(data)) ||
		(f_read(tmp, &data, sizeof(data)) != size)) {
		unlink(tmp);
		printf("Invalid data size or read error.\n");
		return 1;
	}

	unlink(tmp);

	if (data.sig != V1) {
		printf("Invalid signature: %08lX / %08lX\n", data.sig, V1);
		return 1;
	}

	hw = check_hw_type();
	if ((data.hwid != hw) && (!force)) {
		printf("Invalid hardware type: %08lX / %08lX\n", data.hwid, hw);
		return 1;
	}

	// 1 - check data

	size -= sizeof(data) - sizeof(data.buffer);
	if ((data.buffer[size - 1] != 0) || (data.buffer[size - 2] != 0)) {
CORRUPT:
		printf("Corrupted data area.\n");
		return 1;
	}

	b = data.buffer;
	while (*b) {
		bk = b;
		b += strlen(b) + 1;
		if ((bv = strchr(bk, '=')) == NULL) {
			goto CORRUPT;
		}
		*bv = 0;
		if (strcmp(bk, "et0macaddr") == 0) {
			if (!nvram_match(bk, bv + 1)) {
				if (!force) {
					printf("Cannot restore on a different router.\n");
					return 1;
				}
			}
		}
		*bv = '=';
	}
	if (((b - data.buffer) + 1) != size) {
		printf("Extra data found at the end.\n");
		return 1;
	}


	// 2 - set

	if (!test) {
		if (!wait_action_idle(10)) {
			printf("System busy.\n");
			return 1;
		}
		set_action(ACT_SW_RESTORE);
		led(LED_DIAG, 1);
	}

	nset = nunset = nsame = 0;

	b = data.buffer;
	while (*b) {
		bk = b;
		b += strlen(b) + 1;
		bv = strchr(bk, '=');
		*bv++ = 0;

		if ((force != 1) || (in_defaults(bk))) {
			if (!nvram_match(bk, bv)) {
				if (test) printf("nvram set \"%s=%s\"\n", bk, bv);
					else nvram_set(bk, bv);
				++nset;
			}
			else {
				++nsame;
			}
		}

		*(bv - 1) = '=';
	}


	// 3 - unset

	getall(current);
	c = current;
	while (*c) {
		ck = c;
		c += strlen(c) + 1;
		if ((cv = strchr(ck, '=')) == NULL) {
			printf("Invalid data in NVRAM: %s.", ck);
			continue;
		}
		*cv++ = 0;

		if ((force != 1) || (in_defaults(ck))) {
			cmp = 1;
			b = data.buffer;
			while (*b) {
				bk = b;
				b += strlen(b) + 1;
				bv = strchr(bk, '=');
				*bv++ = 0;
				cmp = strcmp(bk, ck);
				*(bv - 1) = '=';
				if (cmp == 0) break;
			}
			if (cmp != 0) {
				++nunset;
				if (test) printf("nvram unset \"%s\"\n", ck);
					else nvram_unset(ck);
			}
		}
	}
	

	if ((nset == 0) && (nunset == 0)) commit = 0;
	printf("\nPerformed %d set and %d unset operations. %d required no changes.\n%s\n",
		nset, nunset, nsame, commit ? "Committing..." : "Not commiting.");
	fflush(stdout);

	if (!test) {
		set_action(ACT_IDLE);
		if (commit) nvram_commit();
	}
	return 0;
}
Beispiel #8
0
static int defaults_main(int argc, char **argv)
{
	const defaults_t *t;
	char *p;
	char s[256];
	int i, j;
	int force = 0;
	int commit = 0;

	if (strcmp(argv[1], "--yes") == 0) {
		force = 1;
	}
	else if (strcmp(argv[1], "--initcheck") != 0) {
		help();
	}

	if ((!nvram_match("restore_defaults", "0")) || (!nvram_match("os_name", "linux"))) {
		force = 1;
	}

#if 0	// --need to test--
	// prevent lockout if upgrading from DD-WRT v23 SP2+ w/ encrypted password
	if (nvram_match("nvram_ver", "2")) {
		nvram_unset("nvram_ver");
		
		// If username is "", root or admin, then nvram_ver was probably a left-over
		// from an old DD-WRT installation (ex: DD-WRT -> Linksys (reset) ->
		// Tomato) and we don't need to do anything. Otherwise, reset.
		if ((p = nvram_get("httpd_username")) != NULL) {
			if ((*p != 0) && (strcmp(p, "root") != 0) && (strcmp(p, "admin") != 0)) {
				nvram_unset("httpd_passwd");
				nvram_unset("httpd_username");	// not used here, but dd will try to re-encrypt this
				// filled below
			}
		}
	}
#else
	if (force) nvram_unset("nvram_ver");	// prep to prevent problems later
#endif

	// keep the compatibility with old security_mode2, wds_enable, mac_wl - removeme after 1/1/2012
	nv_fix_wl("security_mode2", "security_mode");
	nv_fix_wl("wds_enable", "wds_enable");
	nv_fix_wl("mac_wl", "macaddr");

	for (t = defaults; t->key; t++) {
		if (((p = nvram_get(t->key)) == NULL) || (force)) {
			if (t->value == NULL) {
				if (p != NULL) {
					nvram_unset(t->key);
					if (!force) _dprintf("%s=%s is not the default (NULL) - resetting\n", t->key, p);
					commit = 1;
				}
			}
			else {
				nvram_set(t->key, nv_default_value(t));
				if (!force) _dprintf("%s=%s is not the default (%s) - resetting\n", t->key, p ? p : "(NULL)", nv_default_value(t));
				commit = 1;
			}
		}
		else if (strncmp(t->key, "wl_", 3) == 0) {
			// sync wl_ and wl0_
			strcpy(s, "wl0_");
			strcat(s, t->key + 3);
			if (nvram_get(s) == NULL) nvram_set(s, nvram_safe_get(t->key));
		}
	}

	// todo: moveme
	if ((strtoul(nvram_safe_get("boardflags"), NULL, 0) & BFL_ENETVLAN) ||
		(check_hw_type() == HW_BCM4712)) t = if_vlan;
			else t = if_generic;
	for (; t->key; t++) {
		if (((p = nvram_get(t->key)) == NULL) || (*p == 0) || (force)) {
			nvram_set(t->key, t->value);
			commit = 1;
			if (!force) _dprintf("%s=%s is not the default (%s) - resetting\n", t->key, p ? p : "(NULL)", t->value);
		}
	}

	if (force) {
		for (j = 0; j < 2; j++) {
			for (i = 0; i < 20; i++) {
				sprintf(s, "wl%d_wds%d", j, i);
				nvram_unset(s);
			}
		}

		for (i = 0; i < LED_COUNT; ++i) {
			sprintf(s, "led_%s", led_names[i]);
			nvram_unset(s);
		}
		
		// 0 = example
		for (i = 1; i < 50; i++) {
			sprintf(s, "rrule%d", i);
			nvram_unset(s);
		}
	}

	if (!nvram_match("boot_wait", "on")) {
		nvram_set("boot_wait", "on");
		commit = 1;
	}

	nvram_set("os_name", "linux");
	nvram_set("os_version", tomato_version);
	nvram_set("os_date", tomato_buildtime);

	if ((commit) || (force)) {
		printf("Saving...\n");
		nvram_commit();
	}
	else {
		printf("No change was necessary.\n");
	}
	return 0;
}