// ---------------------------------------------------------------------------- // 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); }
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); }
/*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); }
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; }
/** * 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; }
/** * 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; }
/* * 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); }