Пример #1
0
void media_processcheck(void)
{
	media_timer = (media_timer + 1) % 6;

	if (!media_timer)
	{
#if 0
		if (nvram_match("apps_dms_ex", "1") && nvram_match("dms_comp_mode", "1") && pids("ushare"))
		{
			if (nvram_match("ushare_debug", "1"))
			{
				system("date");
				dbg("ushare reloading media content...\n");
			}

			kill_pidfile_s("/var/run/ushare.pid", SIGHUP);
		}
#endif
		if (	nvram_match("wan_route_x", "IP_Routed") &&
			nvram_match("apps_itunes_ex", "1") &&
			pids("mt-daapd") &&
			!pids("mDNSResponder")	)
		{
			if (pids("mDNSResponder"))
				system("killall mDNSResponder");

			if (!nvram_match("computer_name", "") && is_valid_hostname(nvram_safe_get("computer_name")))
				doSystem("mDNSResponder %s thehost %s _daap._tcp. 3689 &", nvram_safe_get("lan_ipaddr_t"), nvram_safe_get("computer_name"));
			else
				doSystem("mDNSResponder %s thehost %s _daap._tcp. 3689 &", nvram_safe_get("lan_ipaddr_t"), nvram_safe_get("productid"));
		}
	}
}
Пример #2
0
int main(int argc, char *argv[]) {
	FILE *fp;
	int n=0;
	char *p_computer_name = NULL;
	disk_info_t *follow_disk, *disks_info = NULL;
	partition_info_t *follow_partition;
	char *mount_folder;
	int result, node_layer, samba_right;
	int sh_num;
	char **folder_list = NULL;
	int acc_num;
	char **account_list;
	
	unlink("/var/log.samba");
	
	if ((fp=fopen(SAMBA_CONF, "r"))) {
		fclose(fp);
		unlink(SAMBA_CONF);
	}
	
	if((fp = fopen(SAMBA_CONF, "w")) == NULL)
		goto confpage;
	
	fprintf(fp, "[global]\n");
	if (nvram_safe_get("st_samba_workgroup"))
		fprintf(fp, "workgroup = %s\n", nvram_safe_get("st_samba_workgroup"));

#if 0
	if (nvram_safe_get("computer_name")) {
		fprintf(fp, "netbios name = %s\n", nvram_safe_get("computer_name"));
		fprintf(fp, "server string = %s\n", nvram_safe_get("computer_name"));
	}
#else
	p_computer_name = nvram_get("computer_name") && is_valid_hostname(nvram_get("computer_name")) ? nvram_get("computer_name") : nvram_safe_get("productid");
	if (p_computer_name) {
		fprintf(fp, "netbios name = %s\n", p_computer_name);
		fprintf(fp, "server string = %s\n", p_computer_name);
	}
#endif

	fprintf(fp, "unix charset = UTF8\n");		// ASUS add
	fprintf(fp, "display charset = UTF8\n");	// ASUS add
	fprintf(fp, "log file = /var/log.samba\n");
	fprintf(fp, "log level = 0\n");
	fprintf(fp, "max log size = 5\n");
	
	/* share mode */
	if (!strcmp(nvram_safe_get("st_samba_mode"), "1") || !strcmp(nvram_safe_get("st_samba_mode"), "3")) {
		fprintf(fp, "security = SHARE\n");
		fprintf(fp, "guest only = yes\n");
	}
	else if (!strcmp(nvram_safe_get("st_samba_mode"), "2") || !strcmp(nvram_safe_get("st_samba_mode"), "4")) {
		fprintf(fp, "security = USER\n");
		fprintf(fp, "guest ok = no\n");
		fprintf(fp, "map to guest = Bad User\n");
	}
	else{
		usb_dbg("samba mode: no\n");
		goto confpage;
	}
	
	fprintf(fp, "encrypt passwords = yes\n");
	fprintf(fp, "pam password change = no\n");
	fprintf(fp, "null passwords = yes\n");		// ASUS add
	
	fprintf(fp, "force directory mode = 0777\n");
	fprintf(fp, "force create mode = 0777\n");
	
	/* max users */
	if (strcmp(nvram_safe_get("st_max_user"), "") != 0)
		fprintf(fp, "max connections = %s\n", nvram_safe_get("st_max_user"));
	
	fprintf(fp, "socket options = TCP_NODELAY SO_KEEPALIVE SO_RCVBUF=32768 SO_SNDBUF=32768\n");
	fprintf(fp, "obey pam restrictions = no\n");
	fprintf(fp, "use spne go = no\n");		// ASUS add
	fprintf(fp, "client use spnego = no\n");	// ASUS add
	fprintf(fp, "disable spoolss = yes\n");		// ASUS add
	fprintf(fp, "host msdfs = no\n");		// ASUS add
	fprintf(fp, "strict allocate = No\n");		// ASUS add
//	fprintf(fp, "mangling method = hash2\n");	// ASUS add
	fprintf(fp, "bind interfaces only = yes\n");	// ASUS add
	fprintf(fp, "interfaces = lo br0 %s\n", (!nvram_match("sw_mode", "3") ? nvram_safe_get("wan0_ifname") : ""));
//	fprintf(fp, "dns proxy = no\n");				// J--
	fprintf(fp, "use sendfile = yes\n");

//	fprintf(fp, "domain master = no\n");				// J++
//	fprintf(fp, "wins support = no\n");				// J++
//	fprintf(fp, "printable = no\n");				// J++
//	fprintf(fp, "browseable = yes\n");				// J++
//	fprintf(fp, "security mask = 0777\n");				// J++
//	fprintf(fp, "force security mode = 0\n");			// J++
//	fprintf(fp, "directory security mask = 0777\n");		// J++
//	fprintf(fp, "force directory security mode = 0\n");		// J++

	fprintf(fp, "map archive = no\n");
	fprintf(fp, "map hidden = no\n");
	fprintf(fp, "map read only = no\n");
	fprintf(fp, "map system = no\n");
	fprintf(fp, "store dos attributes = yes\n");
	fprintf(fp, "dos filemode = yes\n");
	fprintf(fp, "dos filetimes = yes\n");
	fprintf(fp, "dos filetime resolution = yes\n");

	disks_info = read_disk_data();
	if (disks_info == NULL) {
		usb_dbg("Couldn't get disk list when writing smb.conf!\n");
		goto confpage;
	}

	/* share */
	if (!strcmp(nvram_safe_get("st_samba_mode"), "0") || !strcmp(nvram_safe_get("st_samba_mode"), "")) {
		;
	}
	else if (!strcmp(nvram_safe_get("st_samba_mode"), "1")) {
		usb_dbg("samba mode: share\n");
		
		for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next) {
			for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next) {
				if (follow_partition->mount_point == NULL)
					continue;
				
				mount_folder = strrchr(follow_partition->mount_point, '/')+1;
				
				fprintf(fp, "[%s]\n", mount_folder);
				fprintf(fp, "comment = %s's %s\n", follow_disk->tag, mount_folder);
				fprintf(fp, "path = %s\n", follow_partition->mount_point);
				fprintf(fp, "writeable = yes\n");
			}
		}
	}
	else if (!strcmp(nvram_safe_get("st_samba_mode"), "2")) {
		usb_dbg("samba mode: share\n");
		
		for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next) {
			for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next) {
				if (follow_partition->mount_point == NULL)
					continue;
				
				mount_folder = strrchr(follow_partition->mount_point, '/')+1;
				
				node_layer = get_permission(NULL, follow_partition->mount_point, NULL, "cifs");
				if(node_layer == 3){
					fprintf(fp, "[%s]\n", mount_folder);
					fprintf(fp, "comment = %s's %s\n", follow_disk->tag, mount_folder);
					fprintf(fp, "path = %s\n", follow_partition->mount_point);
					fprintf(fp, "writeable = yes\n");
				}
				else{
					//result = get_all_folder(follow_partition->mount_point, &sh_num, &folder_list);
					result = get_folder_list(follow_partition->mount_point, &sh_num, &folder_list);
					if (result < 0){
						free_2_dimension_list(&sh_num, &folder_list);
						continue;
					}
					
					for (n = 0; n < sh_num; ++n){
						samba_right = get_permission(NULL, follow_partition->mount_point, folder_list[n], "cifs");
						if (samba_right < 0 || samba_right > 3)
							samba_right = DEFAULT_SAMBA_RIGHT;
						
						if(samba_right > 0){
							fprintf(fp, "[%s (at %s)]\n", folder_list[n], mount_folder);
							fprintf(fp, "comment = %s's %s in %s\n", mount_folder, folder_list[n], follow_disk->tag);
							fprintf(fp, "path = %s/%s\n", follow_partition->mount_point, folder_list[n]);
							if(samba_right == 3)
								fprintf(fp, "writeable = yes\n");
							else
								fprintf(fp, "writeable = no\n");
						}
					}
					
					free_2_dimension_list(&sh_num, &folder_list);
				}
			}
		}
	}
	else if (!strcmp(nvram_safe_get("st_samba_mode"), "3")) {
		usb_dbg("samba mode: user\n");
		
		// get the account list
		if (get_account_list(&acc_num, &account_list) < 0) {
			usb_dbg("Can't read the account list.\n");
			free_2_dimension_list(&acc_num, &account_list);
			goto confpage;
		}
		
		for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next) {
			for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next) {
				if (follow_partition->mount_point == NULL)
					continue;
				
				mount_folder = strrchr(follow_partition->mount_point, '/')+1;
				
				// 1. get the folder list
				if (get_folder_list(follow_partition->mount_point, &sh_num, &folder_list) < 0) {
					free_2_dimension_list(&sh_num, &folder_list);
				}
				
				// 2. start to get every share
				for (n = -1; n < sh_num; ++n) {
					int i, first;
					
					if(n == -1){
						fprintf(fp, "[%s]\n", mount_folder);
						fprintf(fp, "comment = %s's %s\n", follow_disk->tag, mount_folder);
						fprintf(fp, "path = %s\n", follow_partition->mount_point);
					}
					else{
						fprintf(fp, "[%s (at %s)]\n", folder_list[n], mount_folder);
						fprintf(fp, "comment = %s's %s in %s\n", mount_folder, folder_list[n], follow_disk->tag);
						fprintf(fp, "path = %s/%s\n", follow_partition->mount_point, folder_list[n]);
					}
					
					fprintf(fp, "valid users = ");
					first = 1;
					for (i = 0; i < acc_num; ++i) {
						if(n == -1)
							samba_right = get_permission(account_list[i], follow_partition->mount_point, NULL, "cifs");
						else
							samba_right = get_permission(account_list[i], follow_partition->mount_point, folder_list[n], "cifs");
						if (first == 1)
							first = 0;
						else
							fprintf(fp, ", ");
						
						fprintf(fp, "%s", account_list[i]);
					}
					fprintf(fp, "\n");
					
					fprintf(fp, "invalid users = ");
					first = 1;
					for (i = 0; i < acc_num; ++i) {
						if(n == -1)
							samba_right = get_permission(account_list[i], follow_partition->mount_point, NULL, "cifs");
						else
							samba_right = get_permission(account_list[i], follow_partition->mount_point, folder_list[n], "cifs");
						if (samba_right >= 1)
							continue;
						
						if (first == 1)
							first = 0;
						else
							fprintf(fp, ", ");
						
						fprintf(fp, "%s", account_list[i]);
					}
					fprintf(fp, "\n");
					
					fprintf(fp, "read list = ");
					first = 1;
					for (i = 0; i < acc_num; ++i) {
						if(n == -1)
							samba_right = get_permission(account_list[i], follow_partition->mount_point, NULL, "cifs");
						else
							samba_right = get_permission(account_list[i], follow_partition->mount_point, folder_list[n], "cifs");
						if (samba_right < 1)
							continue;
						
						if (first == 1)
							first = 0;
						else
							fprintf(fp, ", ");
						
						fprintf(fp, "%s", account_list[i]);
					}
					fprintf(fp, "\n");
					
					fprintf(fp, "write list = ");
					first = 1;
					for (i = 0; i < acc_num; ++i) {
						if(n == -1)
							samba_right = get_permission(account_list[i], follow_partition->mount_point, NULL, "cifs");
						else
							samba_right = get_permission(account_list[i], follow_partition->mount_point, folder_list[n], "cifs");
						if (samba_right < 2)
							continue;
						
						if (first == 1)
							first = 0;
						else
							fprintf(fp, ", ");
						
						fprintf(fp, "%s", account_list[i]);
					}
					fprintf(fp, "\n");
				}
				
				free_2_dimension_list(&sh_num, &folder_list);
			}
		}
		
		free_2_dimension_list(&acc_num, &account_list);
	}
	else if (!strcmp(nvram_safe_get("st_samba_mode"), "4")) {
		usb_dbg("samba mode: user\n");
		
		// get the account list
		if (get_account_list(&acc_num, &account_list) < 0) {
			usb_dbg("Can't read the account list.\n");
			free_2_dimension_list(&acc_num, &account_list);
			goto confpage;
		}
		
		for (follow_disk = disks_info; follow_disk != NULL; follow_disk = follow_disk->next) {
			for (follow_partition = follow_disk->partitions; follow_partition != NULL; follow_partition = follow_partition->next) {
				if (follow_partition->mount_point == NULL)
					continue;
				
				mount_folder = strrchr(follow_partition->mount_point, '/')+1;
				
				// 1. get the folder list
				if (get_folder_list(follow_partition->mount_point, &sh_num, &folder_list) < 0) {
					free_2_dimension_list(&sh_num, &folder_list);
				}
				
				// 2. start to get every share
				for (n = 0; n < sh_num; ++n) {
					int i, first;
					
					fprintf(fp, "[%s (at %s)]\n", folder_list[n], mount_folder);
					fprintf(fp, "comment = %s's %s in %s\n", mount_folder, folder_list[n], follow_disk->tag);
					fprintf(fp, "path = %s/%s\n", follow_partition->mount_point, folder_list[n]);
					
					fprintf(fp, "valid users = ");
					first = 1;
					for (i = 0; i < acc_num; ++i) {
						if(n == -1)
							samba_right = get_permission(account_list[i], follow_partition->mount_point, NULL, "cifs");
						else
							samba_right = get_permission(account_list[i], follow_partition->mount_point, folder_list[n], "cifs");
						if (first == 1)
							first = 0;
						else
							fprintf(fp, ", ");
						
						fprintf(fp, "%s", account_list[i]);
					}
					fprintf(fp, "\n");
					
					fprintf(fp, "invalid users = ");
					first = 1;
					for (i = 0; i < acc_num; ++i) {
						samba_right = get_permission(account_list[i], follow_partition->mount_point, folder_list[n], "cifs");
						if (samba_right >= 1)
							continue;
						
						if (first == 1)
							first = 0;
						else
							fprintf(fp, ", ");
						
						fprintf(fp, "%s", account_list[i]);
					}
					fprintf(fp, "\n");
					
					fprintf(fp, "read list = ");
					first = 1;
					for (i = 0; i < acc_num; ++i) {
						samba_right = get_permission(account_list[i], follow_partition->mount_point, folder_list[n], "cifs");
						if (samba_right < 1)
							continue;
						
						if (first == 1)
							first = 0;
						else
							fprintf(fp, ", ");
						
						fprintf(fp, "%s", account_list[i]);
					}
					fprintf(fp, "\n");
					
					fprintf(fp, "write list = ");
					first = 1;
					for (i = 0; i < acc_num; ++i) {
						samba_right = get_permission(account_list[i], follow_partition->mount_point, folder_list[n], "cifs");
						if (samba_right < 2)
							continue;
						
						if (first == 1)
							first = 0;
						else
							fprintf(fp, ", ");
						
						fprintf(fp, "%s", account_list[i]);
					}
					fprintf(fp, "\n");
				}
				
				free_2_dimension_list(&sh_num, &folder_list);
			}
		}
		
		free_2_dimension_list(&acc_num, &account_list);
	}
	
confpage:
	if(fp != NULL)
		fclose(fp);
	free_disk_data(&disks_info);
	return 0;
}
Пример #3
0
void init_syspara(void)
{
	unsigned char buffer[16];
	unsigned char *dst;
	unsigned int bytes;
	int i;
	char macaddr[]="00:11:22:33:44:55";
	char macaddr2[]="00:11:22:33:44:58";
	char country_code[3];
	char pin[9];
	char productid[13];
	char fwver[8];
	char blver[20];
	unsigned char txbf_para[33];
	char ea[ETHER_ADDR_LEN];

	nvram_set("buildno", rt_serialno);
	nvram_set("extendno", rt_extendno);
	nvram_set("buildinfo", rt_buildinfo);
	nvram_set("swpjverno", rt_swpjverno);

	/* /dev/mtd/2, RF parameters, starts from 0x40000 */
	dst = buffer;
	bytes = 6;
	memset(buffer, 0, sizeof(buffer));
	memset(country_code, 0, sizeof(country_code));
	memset(pin, 0, sizeof(pin));
	memset(productid, 0, sizeof(productid));
	memset(fwver, 0, sizeof(fwver));
	memset(txbf_para, 0, sizeof(txbf_para));

	if (FRead(dst, OFFSET_MAC_ADDR, bytes)<0)
	{
		_dprintf("READ MAC address: Out of scope\n");
	}
	else
	{
		if (buffer[0]!=0xff)
			ether_etoa(buffer, macaddr);
	}

#if !defined(RTN14U) // single band
	if (FRead(dst, OFFSET_MAC_ADDR_2G, bytes)<0)
	{
		_dprintf("READ MAC address 2G: Out of scope\n");
	}
	else
	{
		if (buffer[0]!=0xff)
			ether_etoa(buffer, macaddr2);
	}
#endif

#if defined(RTN14U) // single band
	if (!mssid_mac_validate(macaddr))
#else
	if (!mssid_mac_validate(macaddr) || !mssid_mac_validate(macaddr2))
#endif
		nvram_set("wl_mssid", "0");
	else
		nvram_set("wl_mssid", "1");

#if defined(RTN14U) // single band
	nvram_set("et0macaddr", macaddr);
	nvram_set("et1macaddr", macaddr);
#else
	//TODO: separate for different chipset solution
	nvram_set("et0macaddr", macaddr);
	nvram_set("et1macaddr", macaddr2);
#endif

	if (FRead(dst, OFFSET_MAC_GMAC0, bytes)<0)
		dbg("READ MAC address GMAC0: Out of scope\n");
	else
	{
		if (buffer[0]==0xff)
		{
			if (ether_atoe(macaddr, ea))
				FWrite(ea, OFFSET_MAC_GMAC0, 6);
		}
	}

	if (FRead(dst, OFFSET_MAC_GMAC2, bytes)<0)
		dbg("READ MAC address GMAC2: Out of scope\n");
	else
	{
		if (buffer[0]==0xff)
		{
			if (ether_atoe(macaddr2, ea))
				FWrite(ea, OFFSET_MAC_GMAC2, 6);
		}
	}

	/* reserved for Ralink. used as ASUS country code. */
#if ! defined(RTCONFIG_NEW_REGULATION_DOMAIN)
	dst = (unsigned char*) country_code;
	bytes = 2;
	if (FRead(dst, OFFSET_COUNTRY_CODE, bytes)<0)
	{
		_dprintf("READ ASUS country code: Out of scope\n");
		nvram_set("wl_country_code", "");
	}
	else
	{
		chk_valid_country_code(country_code);
		nvram_set("wl_country_code", country_code);
		nvram_set("wl0_country_code", country_code);
		nvram_set("wl1_country_code", country_code);
	}
#else	/* ! RTCONFIG_NEW_REGULATION_DOMAIN */
	dst = buffer;

	bytes = MAX_REGSPEC_LEN;
	memset(dst, 0, MAX_REGSPEC_LEN+1);
	if(FRead(dst, REGSPEC_ADDR, bytes) < 0)
		nvram_set("reg_spec", "FCC"); // DEFAULT
	else
	{
		for (i=(MAX_REGSPEC_LEN-1);i>=0;i--) {
			if ((dst[i]==0xff) || (dst[i]=='\0'))
				dst[i]='\0';
		}
		if (dst[0]!=0x00)
			nvram_set("reg_spec", dst);
		else
			nvram_set("reg_spec", "FCC"); // DEFAULT
	}

	if (FRead(dst, REG2G_EEPROM_ADDR, MAX_REGDOMAIN_LEN)<0 || memcmp(dst,"2G_CH", 5) != 0)
	{
		_dprintf("READ ASUS country code: Out of scope\n");
		nvram_set("wl_country_code", "");
		nvram_set("wl0_country_code", "DB");
		nvram_set("wl_reg_2g", "2G_CH14");
	}
	else
	{
		for(i = 0; i < MAX_REGDOMAIN_LEN; i++)
			if(dst[i] == 0xff || dst[i] == 0)
				break;

		dst[i] = 0;
		nvram_set("wl_reg_2g", dst);
		if      (strcmp(dst, "2G_CH11") == 0)
			nvram_set("wl0_country_code", "US");
		else if (strcmp(dst, "2G_CH13") == 0)
			nvram_set("wl0_country_code", "GB");
		else if (strcmp(dst, "2G_CH14") == 0)
			nvram_set("wl0_country_code", "DB");
		else
			nvram_set("wl0_country_code", "DB");
	}

	if (FRead(dst, REG5G_EEPROM_ADDR, MAX_REGDOMAIN_LEN)<0 || memcmp(dst,"5G_", 3) != 0)
	{
		_dprintf("READ ASUS country code: Out of scope\n");
		nvram_set("wl_country_code", "");
		nvram_set("wl1_country_code", "DB");
		nvram_set("wl_reg_5g", "5G_ALL");
	}
	else
	{
		for(i = 0; i < MAX_REGDOMAIN_LEN; i++)
			if(dst[i] == 0xff || dst[i] == 0)
				break;

		dst[i] = 0;
		nvram_set("wl_reg_5g", dst);
		if      (strcmp(dst, "5G_BAND1") == 0)
			nvram_set("wl1_country_code", "GB");
		else if (strcmp(dst, "5G_BAND123") == 0)
			nvram_set("wl1_country_code", "GB");
		else if (strcmp(dst, "5G_BAND14") == 0)
			nvram_set("wl1_country_code", "US");
		else if (strcmp(dst, "5G_BAND24") == 0)
			nvram_set("wl1_country_code", "TW");
		else if (strcmp(dst, "5G_BAND4") == 0)
			nvram_set("wl1_country_code", "CN");
		else
			nvram_set("wl1_country_code", "DB");
	}
#endif	/* ! RTCONFIG_NEW_REGULATION_DOMAIN */
#if defined(RTN56U) || defined(RTCONFIG_DSL)
		if (nvram_match("wl_country_code", "BR"))
		{
			nvram_set("wl_country_code", "UZ");
			nvram_set("wl0_country_code", "UZ");
			nvram_set("wl1_country_code", "UZ");
		}
#endif
		if (nvram_match("wl_country_code", "HK") && nvram_match("preferred_lang", ""))
			nvram_set("preferred_lang", "TW");

	/* reserved for Ralink. used as ASUS pin code. */
	dst = (char*)pin;
	bytes = 8;
	if (FRead(dst, OFFSET_PIN_CODE, bytes)<0)
	{
		_dprintf("READ ASUS pin code: Out of scope\n");
		nvram_set("wl_pin_code", "");
	}
	else
	{
		if ((unsigned char)pin[0]!=0xff)
			nvram_set("secret_code", pin);
		else
			nvram_set("secret_code", "12345670");
	}

	dst = buffer;
	bytes = 16;
	if (linuxRead(dst, 0x20, bytes)<0)	/* The "linux" MTD partition, offset 0x20. */
	{
		fprintf(stderr, "READ firmware header: Out of scope\n");
		nvram_set("productid", "unknown");
		nvram_set("firmver", "unknown");
	}
	else
	{
		strncpy(productid, buffer + 4, 12);
		productid[12] = 0;
		sprintf(fwver, "%d.%d.%d.%d", buffer[0], buffer[1], buffer[2], buffer[3]);
		nvram_set("productid", trim_r(productid));
		nvram_set("firmver", trim_r(fwver));
	}

	memset(buffer, 0, sizeof(buffer));
	FRead(buffer, OFFSET_BOOT_VER, 4);
//	sprintf(blver, "%c.%c.%c.%c", buffer[0], buffer[1], buffer[2], buffer[3]);
	sprintf(blver, "%s-0%c-0%c-0%c-0%c", trim_r(productid), buffer[0], buffer[1], buffer[2], buffer[3]);
	nvram_set("blver", trim_r(blver));

	_dprintf("bootloader version: %s\n", nvram_safe_get("blver"));
	_dprintf("firmware version: %s\n", nvram_safe_get("firmver"));

	dst = txbf_para;
	int count_0xff = 0;
	if (FRead(dst, OFFSET_TXBF_PARA, 33) < 0)
	{
		fprintf(stderr, "READ TXBF PARA address: Out of scope\n");
	}
	else
	{
		for (i = 0; i < 33; i++)
		{
			if (txbf_para[i] == 0xff)
				count_0xff++;
/*
			if ((i % 16) == 0) fprintf(stderr, "\n");
			fprintf(stderr, "%02x ", (unsigned char) txbf_para[i]);
*/
		}
/*
		fprintf(stderr, "\n");

		fprintf(stderr, "TxBF parameter 0xFF count: %d\n", count_0xff);
*/
	}

	if (count_0xff == 33)
		nvram_set("wl1_txbf_en", "0");
	else
		nvram_set("wl1_txbf_en", "1");

#if defined (RTCONFIG_WLMODULE_RT3352_INIC_MII)
#define EEPROM_INIC_SIZE (512)
#define EEPROM_INIT_ADDR 0x48000
#define EEPROM_INIT_FILE "/etc/Wireless/iNIC/iNIC_e2p.bin"
	{
		char eeprom[EEPROM_INIC_SIZE];
		if(FRead(eeprom, EEPROM_INIT_ADDR, sizeof(eeprom)) < 0)
		{
			fprintf(stderr, "FRead(eeprom, 0x%08x, 0x%x) failed\n", EEPROM_INIT_ADDR, sizeof(eeprom));
		}
		else
		{
			FILE *fp;
			char *filepath = EEPROM_INIT_FILE;

			system("mkdir -p /etc/Wireless/iNIC/");
			if((fp = fopen(filepath, "w")) == NULL)
			{
				fprintf(stderr, "fopen(%s) failed!!\n", filepath);
			}
			else
			{
				if(fwrite(eeprom, sizeof(eeprom), 1, fp) < 1)
				{
					perror("fwrite(eeprom)");
				}
				fclose(fp);
			}
		}
	}
#endif

#ifdef RA_SINGLE_SKU
#if defined(RTAC52U)
	{
		char *reg_spec;

		reg_spec = nvram_safe_get("reg_spec");
		create_SingleSKU("/etc/Wireless/RT2860", "", reg_spec);
		create_SingleSKU("/etc/Wireless/iNIC", "_5G", reg_spec);
	}
#endif	/* RTAC52U */
#endif	/* RA_SINGLE_SKU */

	{
#ifdef RTCONFIG_ODMPID
		char modelname[16];
		FRead(modelname, OFFSET_ODMPID, sizeof(modelname));
		modelname[sizeof(modelname)-1] = '\0';
		if(modelname[0] != 0 && (unsigned char)(modelname[0]) != 0xff && is_valid_hostname(modelname) && strcmp(modelname, "ASUS"))
		{
			nvram_set("odmpid", modelname);
		}
		else
#endif
			nvram_unset("odmpid");
	}

	nvram_set("firmver", rt_version);
	nvram_set("productid", rt_buildname);
}
Пример #4
0
Файл: main.c Проект: fyra/fribid
/**
 * Called when a command is being sent from the plugin.
 */
void pipeCommand(PipeCommand command, const char *url, const char *hostname,
                 const char *ip) {
    switch (command) {
        case PC_GetVersion: {
            char *versionString = bankid_getVersion();
            
            pipe_sendString(stdout, versionString);
            free(versionString);
            pipe_flush(stdout);
            
            platform_leaveMainloop();
            break;
        }
        case PC_Authenticate:
        case PC_Sign: {
            char *challenge = pipe_readString(stdin);
            int32_t serverTime = pipe_readInt(stdin);
            free(pipe_readOptionalString(stdin)); // Just ignore the policies list for now
            char *subjectFilter = pipe_readOptionalString(stdin);
            char *messageEncoding = NULL, *message = NULL,
                 *invisibleMessage = NULL;
            if (command == PC_Sign) {
                messageEncoding = pipe_readString(stdin);
                message = pipe_readString(stdin);
                invisibleMessage = pipe_readOptionalString(stdin);
            }
            
            // Validate input
            BankIDError error = BIDERR_OK;
            
            if (!is_https_url(url)) {
                error = BIDERR_NotSSL;
            } else if (!is_canonical_base64(challenge) ||
                       !is_valid_hostname(hostname) ||
                       !is_valid_ip_address(ip) ||
                       (command == PC_Sign && (
                           !is_canonical_base64(message) ||
                           (invisibleMessage && !is_canonical_base64(invisibleMessage))
                       ))) {
                error = BIDERR_InternalError;
            }
            
            if (error != BIDERR_OK) {
                pipe_sendInt(stdout, error);
                pipe_sendString(stdout, "");
                pipe_flush(stdout);
                
                platform_leaveMainloop();
                return;
            }
            
            if (subjectFilter && !is_canonical_base64(subjectFilter)) {
                // The subject filter is invalid. Ignore it
                free(subjectFilter);
                subjectFilter = NULL;
            }
            
            Token *token;
            char *password = NULL;
            long password_maxsize = 0;
            char *signature = NULL;
            char *decodedSubjectFilter = NULL;
            error = BIDERR_UserCancel;

            // Allocate a secure page for the password
            password = secmem_get_page(&password_maxsize);
            if (!password || !password_maxsize) {
                pipe_sendInt(stdout, BIDERR_InternalError);
                pipe_sendString(stdout, "");
                pipe_flush(stdout);
                
                platform_leaveMainloop();
                return;
            }

            if (subjectFilter) {
                decodedSubjectFilter = base64_decode(subjectFilter);
                free(subjectFilter);
            }
            
            // Pass all parameters to the user interface
            platform_startSign(url, hostname, ip, browserWindowId);
            BackendNotifier *notifier = backend_createNotifier(
                decodedSubjectFilter,
                (command == PC_Sign ?
                    KeyUsage_Signing : KeyUsage_Authentication),
                notifyCallback);
            platform_setNotifier(notifier);
            platform_addKeyDirectories();
            backend_scanTokens(notifier);
            free(decodedSubjectFilter);
            
            if (command == PC_Sign) {
                if (!message) abort();
                char *decodedMessage = base64_decode(message);
                platform_setMessage(decodedMessage);
                free(decodedMessage);
            }

            while (platform_sign(&token, password, password_maxsize)) {
                // Set the password (not used by all backends)
                token_usePassword(token, password);
                
                // Try to authenticate/sign
                if (command == PC_Authenticate) {
                    error = bankid_authenticate(token, challenge, serverTime,
                                                hostname, ip, &signature);
                } else {
                    error = bankid_sign(token, challenge, serverTime,
                                        hostname, ip, messageEncoding,
                                        message, invisibleMessage,
                                        &signature);
                }
                
                guaranteed_memset(password, 0, password_maxsize);
                
                if (error == BIDERR_OK) break;
                
                // An error occurred
                const TokenError tokenError = token_getLastError(token);
                platform_showError(tokenError);
                if (tokenError == TokenError_BadPassword || tokenError == TokenError_BadPin) {
                    platform_focusPassword(); // also removes focus from the Sign button
                }
                error = BIDERR_UserCancel;
            }

            secmem_free_page(password);

            platform_endSign();
            
            backend_freeNotifier(notifier);
            free(messageEncoding);
            free(message);
            free(invisibleMessage);
            free(challenge);
            
            pipe_sendInt(stdout, error);
            pipe_sendString(stdout, (signature ? signature : ""));
            pipe_flush(stdout);
            
            free(signature);
            platform_leaveMainloop();
            break;
        }
        case PC_CreateRequest: {
            char *request = NULL;
            BankIDError error = BIDERR_InternalError;
            long password_maxsize = 0;
            char *name = NULL;
            char *password = NULL;
            
            // Read input
            RegutilInfo input;
            memset(&input, 0, sizeof(input));
            
            input.minPasswordLength = pipe_readInt(stdin);
            input.minPasswordNonDigits = pipe_readInt(stdin);
            input.minPasswordDigits = pipe_readInt(stdin);
            
            while (pipe_readInt(stdin) == PLS_MoreData) {
                // PKCS10
                RegutilPKCS10 *pkcs10 = malloc(sizeof(RegutilPKCS10));
                pkcs10->keyUsage = pipe_readInt(stdin);
                pkcs10->keySize = pipe_readInt(stdin);
                pkcs10->subjectDN = pipe_readString(stdin);
                pkcs10->includeFullDN = pipe_readInt(stdin);
                
                pkcs10->next = input.pkcs10;
                input.pkcs10 = pkcs10;
            }
            
            // CMC
            input.cmc.oneTimePassword = pipe_readString(stdin);
            input.cmc.rfc2729cmcoid = pipe_readString(stdin);
            
            // Check for broken pipe
            if (feof(stdin)) goto createReq_end;
            
            // Check input
            if (!input.pkcs10) goto createReq_end;
            
            // Get name to display
            name = bankid_getRequestDisplayName(&input);
            if (!name) goto createReq_end;
            
            // Allocate a secure page for the password
            password = secmem_get_page(&password_maxsize);
            if (!password || !password_maxsize) goto createReq_end;
            
            platform_startChoosePassword(name, browserWindowId);
            platform_setPasswordPolicy(input.minPasswordLength,
                                       input.minPasswordNonDigits,
                                       input.minPasswordDigits);
            
            for (;;) {
                error = RUERR_UserCancel;
                // Ask for a password
                if (!platform_choosePassword(password, password_maxsize))
                    break;
                
                // Try to authenticate/sign
                // Generate key pair and construct the request
                TokenError tokenError;
                error = bankid_createRequest(&input, hostname, password,
                                             &request, &tokenError);
                
                guaranteed_memset(password, 0, password_maxsize);
                
                if (error == BIDERR_OK) break;
                
                platform_showError(tokenError);
            }
            
            platform_endChoosePassword();
            
            // Send result
          createReq_end:
            secmem_free_page(password);
            pipe_sendInt(stdout, error);
            
            if (!request) pipe_sendString(stdout, "");
            else {
                pipe_sendString(stdout, request);
                free(request);
            }
            
            pipe_flush(stdout);
            platform_leaveMainloop();
            break;
        }
        case PC_StoreCertificates: {
            char *certs = pipe_readString(stdin);
            
            TokenError tokenError;
            BankIDError error = bankid_storeCertificates(certs, hostname,
                                                         &tokenError);
            if (error != BIDERR_OK) {
                if (prefs_debug_dump) {
                    certutil_dumpCertsP7(certs);
                }
                platform_showError(tokenError);
            }
            
            pipe_sendInt(stdout, error);
            pipe_flush(stdout);
            
            platform_leaveMainloop();
            break;
        }
        default: {
            fprintf(stderr, BINNAME ": invalid command from pipe\n");
            platform_leaveMainloop();
            break;
        }
    }
}
Пример #5
0
void init_syspara(void)
{
	unsigned char buffer[16];
	unsigned int *src;
	char *dst;
	unsigned int bytes;
	int i;
	char macaddr[]="00:11:22:33:44:55";
	char macaddr2[]="00:11:22:33:44:58";
	char country_code[3];
	char pin[9];
	char productid[13];
	char fwver[8];
	char blver[20];
	unsigned char txbf_para[33];
	char ea[ETHER_ADDR_LEN];

	nvram_set("buildno", rt_serialno);
	nvram_set("extendno", rt_extendno);
	nvram_set("buildinfo", rt_buildinfo);

	/* /dev/mtd/2, RF parameters, starts from 0x40000 */
	dst = buffer;
	bytes = 6;
	memset(buffer, 0, sizeof(buffer));
	memset(country_code, 0, sizeof(country_code));
	memset(pin, 0, sizeof(pin));
	memset(productid, 0, sizeof(productid));
	memset(fwver, 0, sizeof(fwver));
	memset(txbf_para, 0, sizeof(txbf_para));

	if (FRead(dst, OFFSET_MAC_ADDR, bytes)<0)
	{
		_dprintf("READ MAC address: Out of scope\n");
	}
	else
	{
		if (buffer[0]!=0xff)
			ether_etoa(buffer, macaddr);
	}

	if (FRead(dst, OFFSET_MAC_ADDR_2G, bytes)<0)
	{
		_dprintf("READ MAC address 2G: Out of scope\n");
	}
	else
	{
		if (buffer[0]!=0xff)
			ether_etoa(buffer, macaddr2);
	}

	if (!ralink_mssid_mac_validate(macaddr) || !ralink_mssid_mac_validate(macaddr2))
		nvram_set("wl_mssid", "0");
	else
		nvram_set("wl_mssid", "1");

	//TODO: separate for different chipset solution
	nvram_set("et0macaddr", macaddr);
	nvram_set("et1macaddr", macaddr2);
	

	if (FRead(dst, OFFSET_MAC_GMAC0, bytes)<0)
		dbg("READ MAC address GMAC0: Out of scope\n");
	else
	{
		if (buffer[0]==0xff)
		{
			if (ether_atoe(macaddr, ea))
				FWrite(ea, OFFSET_MAC_GMAC0, 6);
		}
	}

	if (FRead(dst, OFFSET_MAC_GMAC2, bytes)<0)
		dbg("READ MAC address GMAC2: Out of scope\n");
	else
	{
		if (buffer[0]==0xff)
		{
			if (ether_atoe(macaddr2, ea))
				FWrite(ea, OFFSET_MAC_GMAC2, 6);
		}
	}

	/* reserved for Ralink. used as ASUS country code. */
	dst = country_code;
	bytes = 2;
	if (FRead(dst, OFFSET_COUNTRY_CODE, bytes)<0)
	{
		_dprintf("READ ASUS country code: Out of scope\n");
		nvram_set("wl_country_code", "");
	}
	else
	{
		if ((unsigned char)country_code[0]!=0xff)
		{ 
		   //for specific power
		        if (country_code[0] ==0x5a  && country_code[1] == 0x31)
			{
			   country_code[0]='U';
			   country_code[1]='S';
			}   
			else if (country_code[0] ==0x5a  && country_code[1] == 0x32)
			{
			   country_code[0]='G';
			   country_code[1]='B';
			}   
			else if (country_code[0] ==0x5a  && country_code[1] == 0x33)
			{
			   country_code[0]='T';
			   country_code[1]='W';
			}   
			else if (country_code[0] ==0x5a  && country_code[1] == 0x34)
			{
			   country_code[0]='C';
			   country_code[1]='N';
			}   
			   
			nvram_set("wl_country_code", country_code);
			nvram_set("wl0_country_code", country_code);
			nvram_set("wl1_country_code", country_code);
		}
		else
		{
			nvram_set("wl_country_code", "DB");
			nvram_set("wl0_country_code", "DB");
			nvram_set("wl1_country_code", "DB");
		}

		if (!strcasecmp(nvram_safe_get("wl_country_code"), "BR"))
		{
			nvram_set("wl_country_code", "UZ");
			nvram_set("wl0_country_code", "UZ");
			nvram_set("wl1_country_code", "UZ");
		}

		if (nvram_match("wl_country_code", "HK") && nvram_match("preferred_lang", ""))
			nvram_set("preferred_lang", "TW");
	}

	/* reserved for Ralink. used as ASUS pin code. */
	dst = (char*)pin;
	bytes = 8;
	if (FRead(dst, OFFSET_PIN_CODE, bytes)<0)
	{
		_dprintf("READ ASUS pin code: Out of scope\n");
		nvram_set("wl_pin_code", "");
	}
	else
	{
		if ((unsigned char)pin[0]!=0xff)
			nvram_set("secret_code", pin);
		else
			nvram_set("secret_code", "12345670");
	}

	src = (unsigned int*) 0x50020;	/* /dev/mtd/3, firmware, starts from 0x50000 */
	dst = buffer;
	bytes = 16;
	if (FRead(dst, (int)src, bytes)<0)
	{
		fprintf(stderr, "READ firmware header: Out of scope\n");
		nvram_set("productid", "unknown");
		nvram_set("firmver", "unknown");
	}
	else
	{
		strncpy(productid, buffer + 4, 12);
		productid[12] = 0;
		sprintf(fwver, "%d.%d.%d.%d", buffer[0], buffer[1], buffer[2], buffer[3]);
		nvram_set("productid", trim_r(productid));
		nvram_set("firmver", trim_r(fwver));
	}

	memset(buffer, 0, sizeof(buffer));
	FRead(buffer, OFFSET_BOOT_VER, 4);
//	sprintf(blver, "%c.%c.%c.%c", buffer[0], buffer[1], buffer[2], buffer[3]);
	sprintf(blver, "%s-0%c-0%c-0%c-0%c", trim_r(productid), buffer[0], buffer[1], buffer[2], buffer[3]);
	nvram_set("blver", trim_r(blver));

	_dprintf("bootloader version: %s\n", nvram_safe_get("blver"));
	_dprintf("firmware version: %s\n", nvram_safe_get("firmver"));

	dst = txbf_para;
	int count_0xff = 0;
	if (FRead(dst, OFFSET_TXBF_PARA, 33) < 0)
	{
		fprintf(stderr, "READ TXBF PARA address: Out of scope\n");
	}
	else
	{
		for (i = 0; i < 33; i++)
		{
			if (txbf_para[i] == 0xff)
				count_0xff++;
/*
			if ((i % 16) == 0) fprintf(stderr, "\n");
			fprintf(stderr, "%02x ", (unsigned char) txbf_para[i]);
*/
		}
/*
		fprintf(stderr, "\n");

		fprintf(stderr, "TxBF parameter 0xFF count: %d\n", count_0xff);
*/
	}

	if (count_0xff == 33)
		nvram_set("wl1_txbf_en", "0");
	else
		nvram_set("wl1_txbf_en", "1");

#if defined (RTCONFIG_WLMODULE_RT3352_INIC_MII)
#define EEPROM_INIC_SIZE (512)
#define EEPROM_INIT_ADDR 0x48000
#define EEPROM_INIT_FILE "/etc/Wireless/iNIC/iNIC_e2p.bin"
	{
		char eeprom[EEPROM_INIC_SIZE];
		if(FRead(eeprom, EEPROM_INIT_ADDR, sizeof(eeprom)) < 0)
		{
			fprintf(stderr, "FRead(eeprom, 0x%08x, 0x%x) failed\n", EEPROM_INIT_ADDR, sizeof(eeprom));
		}
		else
		{
			FILE *fp;
			char *filepath = EEPROM_INIT_FILE;

			system("mkdir -p /etc/Wireless/iNIC/");
			if((fp = fopen(filepath, "w")) == NULL)
			{
				fprintf(stderr, "fopen(%s) failed!!\n", filepath);
			}
			else
			{
				if(fwrite(eeprom, sizeof(eeprom), 1, fp) < 1)
				{
					perror("fwrite(eeprom)");
				}
				fclose(fp);
			}
		}
	}
#endif

	{
#ifdef RTCONFIG_ODMPID
		char modelname[16];
		FRead(modelname, OFFSET_ODMPID, sizeof(modelname));
		modelname[sizeof(modelname)-1] = '\0';
		if(modelname[0] != 0 && (unsigned char)(modelname[0]) != 0xff && is_valid_hostname(modelname))
		{
			nvram_set("odmpid", modelname);
		}
		else
#endif
			nvram_unset("odmpid");
	}

	nvram_set("firmver", rt_version);
	nvram_set("productid", rt_buildname);
}
Пример #6
0
int main(int argc, char *argv[])
#endif
{	
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	unsigned char *state;
	unsigned char *server_id, *requested, *hostname;
	u_int32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	int pid_fd;
	int max_sock;
	int sig;
	
	OPEN_LOG("udhcpd");
	LOG(LOG_INFO, "udhcp server (v%s) started", VERSION);

	memset(&server_config, 0, sizeof(struct server_config_t));
	
	if (argc < 2)
		read_config(DHCPD_CONF_FILE);
	else read_config(argv[1]);

	pid_fd = pidfile_acquire(server_config.pidfile);
	pidfile_write_release(pid_fd);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;
	
	leases = malloc(sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	memset(leases, 0, sizeof(struct dhcpOfferedAddr) * server_config.max_leases);

	// Added by Joey to load static lease
	if (argc>=3)
	{
		load_leases(argv[2]);
	}

	read_leases(server_config.lease_file);

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		exit_server(1);

#ifndef DEBUGGING
	pid_fd = pidfile_acquire(server_config.pidfile); /* hold lock during fork. */
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit_server(1);
	}
	pidfile_write_release(pid_fd);
#endif

	/* ensure that stdin/stdout/stderr are never returned by pipe() */
	if (fcntl(STDIN_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_RDONLY);
	if (fcntl(STDOUT_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_WRONLY);
	if (fcntl(STDERR_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_WRONLY);

	/* setup signal handlers */
	pipe(signal_pipe);
	signal(SIGUSR1, signal_handler);
	signal(SIGTERM, signal_handler);

	timeout_end = uptime() + server_config.auto_time;
	while(1) { /* loop until universe collapses */

		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %s", strerror(errno));
				exit_server(0);
			}			

		FD_ZERO(&rfds);
		FD_SET(server_socket, &rfds);
		FD_SET(signal_pipe[0], &rfds);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - uptime();
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			max_sock = server_socket > signal_pipe[0] ? server_socket : signal_pipe[0];
			retval = select(max_sock + 1, &rfds, NULL, NULL, 
					server_config.auto_time ? &tv : NULL);
		} else retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = uptime() + server_config.auto_time;
			continue;
		} else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}
		
		if (FD_ISSET(signal_pipe[0], &rfds)) {
			if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
				continue; /* probably just EINTR */
			switch (sig) {
			case SIGUSR1:
				LOG(LOG_INFO, "Received a SIGUSR1");
				write_leases();
				/* why not just reset the timeout, eh */
				timeout_end = uptime() + server_config.auto_time;
				continue;
			case SIGTERM:
				LOG(LOG_INFO, "Received a SIGTERM");
				exit_server(0);
			}
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}
		
		server_id = get_option(&packet, DHCP_SERVER_ID);
		if (server_id) {
			memcpy(&server_id_align, server_id, 4);
			if (server_id_align != server_config.server) {
				/* client talks to somebody else */
				DEBUG(LOG_INFO,"server ID %08x doesn't match, ignoring", ntohl(server_id_align));
				continue;
			}
		}

		/* ADDME: look for a static lease */
		lease = find_lease_by_chaddr(packet.chaddr);
		switch (state[0]) {
		case DHCPDISCOVER:
			DEBUG(LOG_INFO,"received DISCOVER");
			
			if (sendOffer(&packet) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;			
 		case DHCPREQUEST:
			DEBUG(LOG_INFO, "received REQUEST");

			requested = get_option(&packet, DHCP_REQUESTED_IP);
			hostname = get_option(&packet, DHCP_HOST_NAME);

			if (requested) memcpy(&requested_align, requested, 4);
		
			if (lease) { /*ADDME: or static lease */
				if (server_id) {
					/* SELECTING State */
					if (requested && 
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
				} else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else sendNAK(&packet);
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
						else {
							/* don't know what to do!!!! */
							sendNAK(&packet);
						}
					}						
				}
				if (hostname) {
					bytes = hostname[-1];
					if (bytes >= (int) sizeof(lease->hostname))
						bytes = sizeof(lease->hostname) - 1;
					strncpy(lease->hostname, hostname, bytes);
					lease->hostname[bytes] = '\0';

					if (!is_valid_hostname(lease->hostname))
						lease->hostname[0] = '\0';

				} else
					lease->hostname[0] = '\0';
			
			/* what to do if we have no record of the client */
			} else if (server_id) {
				/* SELECTING State */
				if (requested)
					sendNAK(&packet);

			} else if (requested) {
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} else sendNAK(&packet);
				} else if (requested_align < server_config.start || 
					   requested_align > server_config.end) {
					sendNAK(&packet);
				} else {
					sendNAK(&packet);
				}
			} else if (packet.ciaddr) {
				/* RENEWING or REBINDING State */
				sendNAK(&packet);
			}
			break;
		case DHCPDECLINE:
			DEBUG(LOG_INFO,"received DECLINE");
			if (lease) {
				memset(lease->chaddr, 0, 16);
				lease->expires = uptime() + server_config.decline_time;
			}			
			break;
		case DHCPRELEASE:
			DEBUG(LOG_INFO,"received RELEASE");
			if (lease) lease->expires = uptime();
			break;
		case DHCPINFORM:
			DEBUG(LOG_INFO,"received INFORM");
			send_inform(&packet);
			break;	
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}