// ----------------------------------------------------------------------------
// initialization of network settings
void artnet_netInit(void) {

	if (artnet_netConfig == 1) {
		if (*((unsigned long*)&myip[0]) == IP(127,127,127,127)) {
			#if USE_DHCP
				//ARTNET_DEBUG("Setting network address: Custom (DHCP)\r\n");
				dhcp_init();
				if (dhcp() != 0) {
					//ARTNET_DEBUG("DHCP fail\r\n");
					//use programmed value
					(*((unsigned long*)&myip[0])) = MYIP;
					(*((unsigned long*)&netmask[0])) = NETMASK;
				}
			#else
				//ARTNET_DEBUG("Setting network address: Custom\r\n");
				(*((unsigned long*)&myip[0])) = MYIP;
				(*((unsigned long*)&netmask[0])) = NETMASK;
			#endif //USE_DHCP
		} else {
			read_ip_addresses();
		}
	} 
	// calculate broadcast adress
	(*((unsigned long*)&broadcast_ip[0])) = (((*((unsigned long*)&myip[0])) & (*((unsigned long*)&netmask[0]))) | (~(*((unsigned long*)&netmask[0]))));

	// remove any existing app from port
	kill_udp_app(artnet_port);
	// add port to stack with callback
	add_udp_app(artnet_port, (void(*)(unsigned char))artnet_get);
}
Example #2
0
void
do_packet(struct interface_info *interface, struct dhcp_packet *packet,
    int len, unsigned int from_port, struct iaddr from, struct hardware *hfrom)
{
	struct packet tp;
	int i;

	if (packet->hlen > sizeof(packet->chaddr)) {
		note("Discarding packet with invalid hlen.");
		return;
	}

	memset(&tp, 0, sizeof(tp));
	tp.raw = packet;
	tp.packet_length = len;
	tp.client_port = from_port;
	tp.client_addr = from;
	tp.interface = interface;
	tp.haddr = hfrom;

	parse_options(&tp);
	if (tp.options_valid &&
	    tp.options[DHO_DHCP_MESSAGE_TYPE].data)
		tp.packet_type = tp.options[DHO_DHCP_MESSAGE_TYPE].data[0];
	if (tp.packet_type)
		dhcp(&tp);
	else
		bootp(&tp);

	/* Free the data associated with the options. */
	for (i = 0; i < 256; i++)
		if (tp.options[i].len && tp.options[i].data)
			free(tp.options[i].data);
}
Example #3
0
/*ARGSUSED*/
static int
cldhcp(cli_ent_t *cliptr, char *valstr, boolean_t out)
{
	static boolean_t	first_time = B_TRUE;
	static int		ret = CLI_CONT;

	if (first_time) {
		/*
		 * Set DHCP's idea of the client_id from our cached value.
		 */
		cliptr = find_cli_ent(BI_CLIENT_ID);
		if (CLF_ISMOD(cliptr)) {
			dhcp_set_client_id(cliptr->varptr, cliptr->varlen);
		}

		bootlog("wanboot", BOOTLOG_INFO, "Starting DHCP configuration");

		(void) ipv4_setpromiscuous(B_TRUE);
		if (dhcp() == 0) {
			bootlog("wanboot", BOOTLOG_INFO,
			    "DHCP configuration succeeded");
		} else {
			bootlog("wanboot", BOOTLOG_CRIT,
			    "DHCP configuration failed");
			ret = CLI_FAIL;
		}
		(void) ipv4_setpromiscuous(B_FALSE);

		first_time = B_FALSE;
	}

	return (ret);
}
Example #4
0
static void *am33xx_net_boot(void)
{
	void *buf = NULL;
	int err;
	int len;
	struct dhcp_req_param dhcp_param;
	const char *bootfile, *ip;
	char *file;

	am33xx_register_ethaddr(0, 0);

	memset(&dhcp_param, 0, sizeof(struct dhcp_req_param));
	dhcp_param.vendor_id = "am335x barebox-mlo";
	err = dhcp(20, &dhcp_param);
	if (err) {
		printf("dhcp failed\n");
		return NULL;
	}

	/*
	 * Older tftp server don't send the file size.
	 * Then tftpfs needs temporary place to store the file.
	 */
	err = mount("none", "ramfs", "/", NULL);
	if (err < 0) {
		printf("failed to mount ramfs\n");
		return NULL;
	}

	err = make_directory(TFTP_MOUNT);
	if (err)
		return NULL;

	ip = ip_to_string(net_get_serverip());
	err = mount(ip, "tftp", TFTP_MOUNT, NULL);
	if (err < 0) {
		printf("Unable to mount.\n");
		return NULL;
	}

	bootfile = getenv("bootfile");
	if (!bootfile) {
		printf("bootfile not found.\n");
		return NULL;
	}

	file = asprintf("%s/%s", TFTP_MOUNT, bootfile);

	buf = read_file(file, &len);
	if (!buf)
		printf("could not read %s.\n", bootfile);

	free(file);

	umount(TFTP_MOUNT);

	return buf;
}
Example #5
0
/**
 * Execute "dhcp" command for a network device
 *
 * @v netdev		Network device
 * @ret rc		Exit code
 */
static int dhcp_exec_netdev ( struct net_device *netdev ) {
	int rc;

	if ( ( rc = dhcp ( netdev ) ) != 0 ) {
		printf ( "Could not configure %s: %s\n",
			 netdev->name, strerror ( rc ) );

		/* Close device on failure, to avoid memory exhaustion */
		netdev_close ( netdev );

		return 1;
	}

	return 0;
}
Example #6
0
/**
 * The "dhcp" command
 *
 * @v argc		Argument count
 * @v argv		Argument list
 * @ret rc		Exit code
 */
static int dhcp_exec ( int argc, char **argv ) {
	static struct option longopts[] = {
		{ "help", 0, NULL, 'h' },
		{ NULL, 0, NULL, 0 },
	};
	const char *netdev_txt;
	struct net_device *netdev;
	int c;
	int rc;

	/* Parse options */
	while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
		switch ( c ) {
		case 'h':
			/* Display help text */
		default:
			/* Unrecognised/invalid option */
			dhcp_syntax ( argv );
			return 1;
		}
	}

	/* Need exactly one interface name remaining after the options */
	if ( optind != ( argc - 1 ) ) {
		dhcp_syntax ( argv );
		return 1;
	}
	netdev_txt = argv[optind];

	/* Parse arguments */
	netdev = find_netdev ( netdev_txt );
	if ( ! netdev ) {
		printf ( "No such interface: %s\n", netdev_txt );
		return 1;
	}

	/* Perform DHCP */
	if ( ( rc = dhcp ( netdev ) ) != 0 ) {
		printf ( "Could not configure %s: %s\n", netdev->name,
			 strerror ( rc ) );
		return 1;
	}

	return 0;
}
Example #7
0
/*
 * This routine will open a device as it is known by the V2 OBP. It
 * then goes thru the stuff necessary to initialize the network device,
 * get our network parameters, (using DHCP or rarp/bootparams), and
 * finally actually go and get the root filehandle. Sound like fun?
 * Suuurrrree. Take a look.
 *
 * Returns 0 if things worked. -1 if we crashed and burned.
 */
int
boot_nfs_mountroot(char *str)
{
	int		status;
	enum clnt_stat	rpc_stat;
	char		*root_path = &root_pathbuf[0];	/* to make XDR happy */
	struct timeval	wait;
	int		fd;
	int		bufsize;
	char		*opts, *val;
	int		nfs_version = 0;
	int		istcp = 1;
	int		nfs_port = 0;	/* Cause pmap to get port */
	struct sockaddr_in tmp_addr;	/* throw away */

	if (root_CLIENT != NULL) {
		AUTH_DESTROY(root_CLIENT->cl_auth);
		CLNT_DESTROY(root_CLIENT);
		root_CLIENT = NULL;
	}

	root_to.sin_family = AF_INET;
	root_to.sin_addr.s_addr = htonl(INADDR_ANY);
	root_to.sin_port = htons(0);

	mac_init(str);

	(void) ipv4_setpromiscuous(TRUE);

	if (get_netconfig_strategy() == NCT_BOOTP_DHCP) {
		if (boothowto & RB_VERBOSE)
			printf("Using BOOTP/DHCP...\n");
		if (dhcp() != 0 || setup_root_vars() != 0) {
			(void) ipv4_setpromiscuous(FALSE);
			if (boothowto & RB_VERBOSE)
				printf("BOOTP/DHCP configuration failed!\n");
			return (-1);
		}

		/* now that we have an IP address, turn off promiscuous mode */
		(void) ipv4_setpromiscuous(FALSE);
	} else {
		/* Use RARP/BOOTPARAMS. RARP will try forever... */
		if (boothowto & RB_VERBOSE)
			printf("Using RARP/BOOTPARAMS...\n");
		mac_call_rarp();

		/*
		 * Since there is no way to determine our netmask, and therefore
		 * figure out if the router we got is useful, we assume all
		 * services are local. Use DHCP if this bothers you.
		 */
		dontroute = TRUE;
		/*
		 * We are trying to keep the ARP response
		 * timeout on the lower side with BOOTP/RARP.
		 * We are doing this for BOOTP/RARP where policy
		 * doesn't allow to route the packets outside
		 * the subnet as it has no idea about the
		 * netmask. By doing so, we are reducing
		 * ARP response timeout for any packet destined
		 * for outside booting clients subnet. Client can
		 * not expect such ARP replies and will finally
		 * timeout after a long delay. This would cause
		 * booting client to get stalled for a longer
		 * time. We can not avoid accepting any outside
		 * subnet packets accidentally destined for the
		 * booting client.
		 */
		mac_set_arp_timeout(ARP_INETBOOT_TIMEOUT);

		/* now that we have an IP address, turn off promiscuous mode */
		(void) ipv4_setpromiscuous(FALSE);

		/* get our hostname */
		if (whoami() == FALSE)
			return (-1);

		/* get our bootparams. */
		if (getfile("root", root_hostname, &root_to.sin_addr,
		    root_pathbuf) == FALSE)
			return (-1);

		/* get our rootopts. */
		(void) getfile("rootopts", root_hostname, &tmp_addr.sin_addr,
		    rootopts);
	}

	/* mount root */
	if (boothowto & RB_VERBOSE) {
		printf("root server: %s (%s)\n", root_hostname,
		    inet_ntoa(root_to.sin_addr));
		printf("root directory: %s\n", root_pathbuf);
	}

	/*
	 * Assumes we've configured the stack and thus know our
	 * IP address/hostname, either by using DHCP or rarp/bootparams.
	 */
	gethostname(my_hostname, sizeof (my_hostname));

	wait.tv_sec = RPC_RCVWAIT_MSEC / 1000;
	wait.tv_usec = 0;

	/*
	 * Parse out the interesting root options, if an invalid
	 * or unknown option is provided, silently ignore it and
	 * use the defaults.
	 */
	opts = rootopts;
	while (*opts) {
		int ival;
		switch (getsubopt(&opts, optlist, &val)) {
		case OPT_RSIZE:
			if (val == NULL || !isdigit(*val))
				break;
			nfs_readsize = atoi(val);
			break;
		case OPT_TIMEO:
			if (val == NULL || !isdigit(*val))
				break;
			ival = atoi(val);
			wait.tv_sec = ival / 10;
			wait.tv_usec = (ival % 10) * 100000;
			break;
		case OPT_VERS:
			if (val == NULL || !isdigit(*val))
				break;
			nfs_version = atoi(val);
			break;
		case OPT_PROTO:
			if (val == NULL || isdigit(*val))
				break;
			if ((strncmp(val, "udp", 3) == 0))
				istcp = 0;
			else
				istcp = 1;	/* must be tcp */
			break;
		case OPT_PORT:
			if (val == NULL || !isdigit(*val))
				break;
			nfs_port = atoi(val);

			/*
			 * Currently nfs_dlinet.c doesn't support setting
			 * the root NFS port. Delete this when it does.
			 */
			nfs_port = 0;
			break;
		default:
			/*
			 * Unknown options are silently ignored
			 */
			break;
		}
	}

	/*
	 * If version is set, then try that version first.
	 */
	switch (nfs_version) {
	case NFS_VERSION:
		if (nfsmountroot(root_path, &roothandle) == 0)
			goto domount;
		break;
	case NFS_V3:
		if (nfs3mountroot(root_path, &roothandle) == 0)
			goto domount;
		break;
	case NFS_V4:
		/*
		 * With v4 we skip the mount and go straight to
		 * setting the root filehandle.  Because of this we
		 * do things slightly differently and obtain our
		 * client handle first.
		 */
		if (istcp && nfs4init(root_path, nfs_port) == 0) {
			/*
			 * If v4 init succeeded then we are done.  Just return.
			 */
			return (0);
		}
	}

	/*
	 * If there was no chosen version or the chosen version failed
	 * try all versions in order, this may still fail to boot
	 * at the kernel level if the options are not right, but be
	 * generous at this early stage.
	 */
	if (istcp && nfs4init(root_path, nfs_port) == 0) {
		/*
		 * If v4 init succeeded then we are done.  Just return.
		 */
		return (0);
	}

	if (nfs3mountroot(root_path, &roothandle) == 0)
		goto domount;

	if ((status = nfsmountroot(root_path, &roothandle)) != 0)
		return (status);

domount:
	/*
	 * Only v2 and v3 go on from here.
	 */
	roothandle.offset = (uint_t)0;		/* it's a directory! */
	root_to.sin_port = htons(nfs_port);	/* NFS is next after mount */

	/*
	 * Create the CLIENT handle for NFS operations
	 */
	if (roothandle.version == NFS_VERSION)
		bufsize = NFSBUF_SIZE;
	else
		bufsize = NFS3BUF_SIZE;

	/*
	 * First try TCP then UDP (unless UDP asked for explicitly), if mountd
	 * alows this version but neither transport is available we are stuck.
	 */
	if (istcp) {
		fd = -1;
		root_CLIENT = clntbtcp_create(&root_to, NFS_PROGRAM,
			roothandle.version, wait, &fd, bufsize, bufsize);
		if (root_CLIENT != NULL) {
			root_CLIENT->cl_auth =
			    authunix_create(my_hostname, 0, 1, 1, &fake_gids);
			/*
			 * Send NULL proc, check if the server really exists
			 */
			rpc_stat = CLNT_CALL(root_CLIENT, 0,
					xdr_void, NULL, xdr_void, NULL, wait);

			if (rpc_stat == RPC_SUCCESS)
				return (0);

			AUTH_DESTROY(root_CLIENT->cl_auth);
			CLNT_DESTROY(root_CLIENT);
			root_CLIENT = NULL;
		}
		/* Fall through to UDP case */
	}

	fd = -1;
	root_CLIENT = clntbudp_bufcreate(&root_to, NFS_PROGRAM,
			roothandle.version, wait, &fd, bufsize, bufsize);
	if (root_CLIENT == NULL)
		return (-1);

	root_CLIENT->cl_auth =
			    authunix_create(my_hostname, 0, 1, 1, &fake_gids);
	/*
	 * Send NULL proc, check if the server really exists
	 */
	rpc_stat = CLNT_CALL(root_CLIENT, 0,
				xdr_void, NULL, xdr_void, NULL, wait);

	if (rpc_stat == RPC_SUCCESS)
		return (0);

	AUTH_DESTROY(root_CLIENT->cl_auth);
	CLNT_DESTROY(root_CLIENT);
	root_CLIENT = NULL;
	return (-1);
}