/* if the bootloader loaded a different file * than what the BOOTP/DHCP server says we have * then we want to forge the respective system * variables. */ static void my_bootp_intercept(void) { int media; /* Interfaces are attached; now see if we should set the media * Note that we treat the case of an empty media string and * 'auto' differently. In the former case, we simply leave the * IF alone, otherwise we enforce autoconfig. */ if ( boot_my_media && *boot_my_media ) { /* Only do something if the string is not empty */ media = rtems_str2ifmedia(boot_my_media, 0/* only 1 phy supported here */); if ( !media ) { fprintf(stderr,"Unable to configure IF media - invalid parameter '%s'\n",boot_my_media); } else { /* network port has already been selected and the IF name fixed */ struct rtems_bsdnet_ifconfig *ifc; ifc = find_first_real_if(); if ( !ifc ) { fprintf(stderr,"Unable to set IF media - no interface found\n"); } else { if ( rtems_bsdnet_ifconfig(ifc->name, SIOCSIFMEDIA, &media )) { fprintf(stderr, "Setting IF media on %s (SIOCSIFMEDIA) failed: %s\n", ifc->name, strerror(errno)); } } } } /* now check if we should do real bootp */ if ( 'N' != do_bootp() ) { /* Do bootp first */ if (the_apps_bootp) { the_apps_bootp(); } else { rtems_bsdnet_do_bootp(); } } if ( 'Y' != do_bootp() ) { /* override the server/filename parameters */ fillin_srvrandfile(); } }
errno_t bootp(ifnet *iface) { struct bootp_state _bstate; void * udp_sock; struct bootp_state *bstate = &_bstate; memset( &_bstate, 0, sizeof(struct bootp_state) ); _bstate.expected_dhcpmsgtype = -1; int err = iface->dev->dops.get_address(iface->dev, &_bstate.mac_addr, sizeof(_bstate.mac_addr)); if(err < 0) { SHOW_ERROR0( 0, "can't get interface MAC address"); return ENXIO; } if( xid == 0 ) xid = (int)time(0) ^ 0x1E0A4F; // Some strange number :) int tries = 3; errno_t e; do { if( udp_open(&udp_sock) ) { SHOW_ERROR0( 0, "UDP - can't prepare endpoint"); return ENOTSOCK; } e = do_bootp( bstate, udp_sock, 0); udp_close(udp_sock); } while( e && (tries-- > 0) ); if(e) SHOW_ERROR( 0, "error %d", e); else { SHOW_FLOW( 1, "DHCP netmask: 0x%08X", bstate->smask); SHOW_FLOW( 1, "DHCP ip: %s", inet_ntoa(bstate->myip) ); SHOW_FLOW( 2, "gateway ip: %s", inet_ntoa(bstate->gateip) ); SHOW_FLOW( 2, "root ip: %s", inet_ntoa(bstate->rootip) ); SHOW_FLOW( 2, "server ip: %s", inet_ntoa(bstate->servip) ); SHOW_FLOW( 2, "rootpath: '%s'", bstate->rootpath ); SHOW_FLOW( 2, "hostname: '%s'", bstate->hostname ); SHOW_FLOW( 2, "bootfile: '%s'", bstate->bootfile ); // Now apply it to interface ifaddr *address; // set the ip address for this net interface address = malloc(sizeof(ifaddr)); address->addr.len = 4; address->addr.type = ADDR_TYPE_IP; NETADDR_TO_IPV4(address->addr) = bstate->myip.s_addr; address->netmask.len = 4; address->netmask.type = ADDR_TYPE_IP; NETADDR_TO_IPV4(address->netmask) = bstate->smask; u_int32_t bcast = (bstate->myip.s_addr) | bstate->smask; address->broadcast.len = 4; address->broadcast.type = ADDR_TYPE_IP; NETADDR_TO_IPV4(address->broadcast) = bcast; if_bind_address(iface, address); u_int32_t net = (bstate->myip.s_addr) & ~(bstate->smask); int rc; if( (rc = ipv4_route_add( net, ~(bstate->smask), bstate->myip.s_addr, iface->id) ) ) { SHOW_ERROR( 1, "Adding route - failed, rc = %d", rc); } else { SHOW_INFO0( 1, "Adding route - ok"); } if( (rc = ipv4_route_add_default( bstate->myip.s_addr, iface->id, bstate->gateip.s_addr ) ) ) { SHOW_ERROR( 1, "Adding default route - failed, rc = %d", rc); } else { SHOW_INFO0( 1, "Adding default route - ok"); } // At least one char! if(*bstate->hostname) strlcpy( phantom_uname.nodename, bstate->hostname, _UTSNAME_NODENAME_LENGTH ); } return e; }
// // Initialize network interface[s] using BOOTP/DHCP // void init_all_network_interfaces(void) { static volatile int in_init_all_network_interfaces = 0; #ifdef CYGPKG_IO_PCMCIA cyg_netdevtab_entry_t *t; #endif // CYGPKG_IO_PCMCIA #ifdef CYGOPT_NET_IPV6_ROUTING_THREAD int rs_wait = 40; #endif cyg_scheduler_lock(); while ( in_init_all_network_interfaces ) { // Another thread is doing this... cyg_scheduler_unlock(); cyg_thread_delay( 10 ); cyg_scheduler_lock(); } in_init_all_network_interfaces = 1; cyg_scheduler_unlock(); #ifdef CYGHWR_NET_DRIVER_ETH0 if ( ! eth0_up ) { // Make this call idempotent #ifdef CYGPKG_IO_PCMCIA if ((t = eth_drv_netdev("eth0")) != (cyg_netdevtab_entry_t *)NULL) { int tries = 0; while (t->status != CYG_NETDEVTAB_STATUS_AVAIL) { if (tries == 0) { diag_printf("... Waiting for PCMCIA device 'eth0'\n"); } if (++tries == 5) { diag_printf("... Giving up on PCMCIA device 'eth0'\n"); goto bail_eth0; } cyg_thread_delay(100); } } #endif // CYGPKG_IO_PCMCIA #ifdef CYGHWR_NET_DRIVER_ETH0_BOOTP // Perform a complete initialization, using BOOTP/DHCP eth0_up = true; #ifdef CYGHWR_NET_DRIVER_ETH0_DHCP eth0_dhcpstate = 0; // Says that initialization is external to dhcp if (do_dhcp(eth0_name, ð0_bootp_data, ð0_dhcpstate, ð0_lease)) #else #ifdef CYGPKG_NET_DHCP eth0_dhcpstate = DHCPSTATE_BOOTP_FALLBACK; // so the dhcp machine does no harm if called #endif if (do_bootp(eth0_name, ð0_bootp_data)) #endif { #ifdef CYGHWR_NET_DRIVER_ETH0_BOOTP_SHOW show_bootp(eth0_name, ð0_bootp_data); #endif } else { diag_printf("BOOTP/DHCP failed on eth0\n"); eth0_up = false; } #elif defined(CYGHWR_NET_DRIVER_ETH0_ADDRS_IP) eth0_up = true; build_bootp_record(ð0_bootp_data, eth0_name, string(CYGHWR_NET_DRIVER_ETH0_ADDRS_IP), string(CYGHWR_NET_DRIVER_ETH0_ADDRS_NETMASK), string(CYGHWR_NET_DRIVER_ETH0_ADDRS_BROADCAST), string(CYGHWR_NET_DRIVER_ETH0_ADDRS_GATEWAY), string(CYGHWR_NET_DRIVER_ETH0_ADDRS_SERVER)); show_bootp(eth0_name, ð0_bootp_data); #endif #ifdef CYGPKG_IO_PCMCIA bail_eth0: #endif } #endif // CYGHWR_NET_DRIVER_ETH0 #ifdef CYGHWR_NET_DRIVER_ETH1 if ( ! eth1_up ) { // Make this call idempotent #ifdef CYGPKG_IO_PCMCIA if ((t = eth_drv_netdev("eth1")) != (cyg_netdevtab_entry_t *)NULL) { int tries = 0; while (t->status != CYG_NETDEVTAB_STATUS_AVAIL) { if (tries == 0) { diag_printf("... Waiting for PCMCIA device 'eth1'\n"); } if (++tries == 5) { diag_printf("... Giving up on PCMCIA device 'eth1'\n"); goto bail_eth1; } cyg_thread_delay(100); } } #endif // CYGPKG_IO_PCMCIA #ifdef CYGHWR_NET_DRIVER_ETH1_BOOTP // Perform a complete initialization, using BOOTP/DHCP eth1_up = true; #ifdef CYGHWR_NET_DRIVER_ETH1_DHCP eth1_dhcpstate = 0; // Says that initialization is external to dhcp if (do_dhcp(eth1_name, ð1_bootp_data, ð1_dhcpstate, ð1_lease)) #else #ifdef CYGPKG_NET_DHCP eth1_dhcpstate = DHCPSTATE_BOOTP_FALLBACK; // so the dhcp machine does no harm if called #endif if (do_bootp(eth1_name, ð1_bootp_data)) #endif { #ifdef CYGHWR_NET_DRIVER_ETH1_BOOTP_SHOW show_bootp(eth1_name, ð1_bootp_data); #endif } else { diag_printf("BOOTP/DHCP failed on eth1\n"); eth1_up = false; } #elif defined(CYGHWR_NET_DRIVER_ETH1_ADDRS_IP) eth1_up = true; build_bootp_record(ð1_bootp_data, eth1_name, string(CYGHWR_NET_DRIVER_ETH1_ADDRS_IP), string(CYGHWR_NET_DRIVER_ETH1_ADDRS_NETMASK), string(CYGHWR_NET_DRIVER_ETH1_ADDRS_BROADCAST), string(CYGHWR_NET_DRIVER_ETH1_ADDRS_GATEWAY), string(CYGHWR_NET_DRIVER_ETH1_ADDRS_SERVER)); show_bootp(eth1_name, ð1_bootp_data); #endif #ifdef CYGPKG_IO_PCMCIA bail_eth1: #endif } #endif // CYGHWR_NET_DRIVER_ETH1 #ifdef CYGHWR_NET_DRIVER_ETH0 #ifndef CYGHWR_NET_DRIVER_ETH0_MANUAL if (eth0_up) { if (!init_net(eth0_name, ð0_bootp_data)) { diag_printf("Network initialization failed for eth0\n"); eth0_up = false; } #ifdef CYGHWR_NET_DRIVER_ETH0_IPV6_PREFIX if (!init_net_IPv6(eth0_name, ð0_bootp_data, string(CYGHWR_NET_DRIVER_ETH0_IPV6_PREFIX))) { diag_printf("Static IPv6 network initialization failed for eth0\n"); eth0_up = false; // ??? } #endif } #endif #endif #ifdef CYGHWR_NET_DRIVER_ETH1 #ifndef CYGHWR_NET_DRIVER_ETH1_MANUAL if (eth1_up) { if (!init_net(eth1_name, ð1_bootp_data)) { diag_printf("Network initialization failed for eth1\n"); eth1_up = false; } #ifdef CYGHWR_NET_DRIVER_ETH1_IPV6_PREFIX if (!init_net_IPv6(eth1_name, ð1_bootp_data, string(CYGHWR_NET_DRIVER_ETH1_IPV6_PREFIX))) { diag_printf("Static IPv6 network initialization failed for eth1\n"); eth1_up = false; // ??? } #endif } #endif #endif #ifdef CYGPKG_NET_NLOOP #if 0 < CYGPKG_NET_NLOOP { static int loop_init = 0; int i; if ( 0 == loop_init++ ) for ( i = 0; i < CYGPKG_NET_NLOOP; i++ ) init_loopback_interface( i ); } #endif #endif #ifdef CYGOPT_NET_DHCP_DHCP_THREAD dhcp_start_dhcp_mgt_thread(); #endif #ifdef CYGOPT_NET_IPV6_ROUTING_THREAD ipv6_start_routing_thread(); // Wait for router solicit process to happen. while (rs_wait-- && !cyg_net_get_ipv6_advrouter(NULL)) { cyg_thread_delay(10); } if (rs_wait == 0 ) { diag_printf("No router solicit received\n"); } else { // Give Duplicate Address Detection time to work cyg_thread_delay(200); } #endif #ifdef CYGDAT_NS_DNS_DEFAULT_SERVER cyg_dns_res_start(string(CYGDAT_NS_DNS_DEFAULT_SERVER)); #endif #ifdef CYGDAT_NS_DNS_DOMAINNAME_NAME #define _NAME string(CYGDAT_NS_DNS_DOMAINNAME_NAME) { const char buf[] = _NAME; int len = strlen(_NAME); setdomainname(buf,len); } #endif // Open the monitor to other threads. in_init_all_network_interfaces = 0; }
void nvramFixupBsdnetConfig(int readNvram, char *argline) { Parm p; struct rtems_bsdnet_ifconfig *ifc; /* now hack into the network configuration... */ /* extract_boot_params() modifies the commandline string (part of the fixup) */ if ( readNvram ) { NetConfigCtxtRec ctx; lock(); netConfigCtxtInitialize(&ctx,stdout,0); readNVRAM(&ctx); netConfigCtxtFinalize(&ctx); unlock(); } #ifndef HAVE_BSP_COMMANDLINE_STRING if ( !argline ) #ifdef HAVE_BSP_CMDLINE argline = bsp_cmdline(); #else argline = cmdlinebuf; #endif #endif if ( argline ) cmdlinePairExtract(argline, putparm, 1); if ( boot_my_if ) { if ( (boot_my_media = strchr(boot_my_if,':')) ) { *boot_my_media++ = 0; if ( 0 == *boot_my_if ) boot_my_if = 0; } else { boot_my_media = boot_my_if; boot_my_if = 0; } #ifndef BSP_HAS_MULTIPLE_NETIFS /* just drop the interface name */ boot_my_if = 0; #endif } ifc = find_first_real_if(); assert(ifc && "NO INTERFACE CONFIGURATION STRUCTURE FOUND"); if ( boot_my_if ) ifc->name = boot_my_if; if ( 'N' == do_bootp() ) { /* no bootp */ /* get pointers to the first interface's configuration */ ifc->ip_address = boot_my_ip; boot_my_ip=0; ifc->ip_netmask = boot_my_netmask; boot_my_netmask = 0; } else { the_apps_bootp=net_config.bootp; /* release the strings that will be set up by * bootp - bootpc relies on them being NULL */ for (p=parmList; p->name; p++) { if (!p->pval) continue; if (p->flags & FLAG_CLRBP) { free(*p->pval); *p->pval=0; } } } /* Always intercept; this gives us a chance do to things * after the interfaces are attached */ net_config.bootp=my_bootp_intercept; }