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); }
int net_mountroot(void) { #ifdef DEBUG printf("net_mountroot\n"); #endif /* * Get info for NFS boot: our IP address, our hostname, * server IP address, and our root path on the server. * There are two ways to do this: The old, Sun way, * and the more modern, BOOTP way. (RFC951, RFC1048) */ #ifdef SUN_BOOTPARAMS /* Get boot info using RARP and Sun bootparams. */ /* Get our IP address. (rarp.c) */ if (rarp_getipaddress(netdev_sock) == -1) return errno; printf("boot: client IP address: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address. */ if (bp_whoami(netdev_sock)) return (errno); printf("boot: client name: %s\n", hostname); /* Get the root pathname. */ if (bp_getfile(netdev_sock, "root", &rootip, rootpath)) return (errno); #else /* Get boot info using BOOTP way. (RFC951, RFC1048) */ bootp(netdev_sock); printf("Using IP address: %s\n", inet_ntoa(myip)); printf("myip: %s (%s)", hostname, inet_ntoa(myip)); if (gateip) printf(", gateip: %s", inet_ntoa(gateip)); if (netmask) printf(", netmask: %s", intoa(netmask)); printf("\n"); #endif printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); /* Get the NFS file handle (mount). */ if (nfs_mount(netdev_sock, rootip, rootpath) != 0) return (errno); return 0; }
int net_open(struct open_file *f, ...) { char *fname; char **file; struct iodesc *s; va_list ap; va_start(ap, f); fname = va_arg(ap, char *); file = va_arg(ap, char **); va_end(ap); f->f_devdata = &netdev_sock; netdev_sock = netif_open(NULL); bootfile[0] = '\0'; if (bootopts.b_flags & B_F_USE_BOOTP) { s = socktodesc(netdev_sock); bootp(netdev_sock); if (fname[0] != '\0') strlcpy(bootfile, fname, sizeof bootfile); } else { s = socktodesc(netdev_sock); servip = s->destip = bootopts.b_remote_ip; myip = s->myip = bootopts.b_local_ip; netmask = bootopts.b_netmask; gateip = bootopts.b_gate_ip; if (fname[0] == '\0') { printf("no boot filename\n"); netif_close(netdev_sock); return EIO; } strlcpy(bootfile, fname, sizeof bootfile); } *file = bootfile; return 0; }
/* * non-standard control messages. * called with c locked. */ static char *ipifcctl(struct conv *c, char **argv, int argc) { struct Ipifc *ifc; int i; ifc = (struct Ipifc *)c->ptcl; if (strcmp(argv[0], "add") == 0) return ipifcadd(ifc, argv, argc, 0, NULL); else if (strcmp(argv[0], "bootp") == 0) return bootp(ifc); else if (strcmp(argv[0], "try") == 0) return ipifcadd(ifc, argv, argc, 1, NULL); else if (strcmp(argv[0], "remove") == 0) return ipifcrem(ifc, argv, argc); else if (strcmp(argv[0], "unbind") == 0) return ipifcunbind(ifc); else if (strcmp(argv[0], "joinmulti") == 0) return ipifcjoinmulti(ifc, argv, argc); else if (strcmp(argv[0], "leavemulti") == 0) return ipifcleavemulti(ifc, argv, argc); else if (strcmp(argv[0], "mtu") == 0) return ipifcsetmtu(ifc, argv, argc); else if (strcmp(argv[0], "reassemble") == 0) { ifc->reassemble = 1; return NULL; } else if (strcmp(argv[0], "iprouting") == 0) { i = 1; if (argc > 1) i = atoi(argv[1]); iprouting(c->p->f, i); return NULL; } else if (strcmp(argv[0], "addpref6") == 0) return ipifcaddpref6(ifc, argv, argc); else if (strcmp(argv[0], "setpar6") == 0) return ipifcsetpar6(ifc, argv, argc); else if (strcmp(argv[0], "sendra6") == 0) return ipifcsendra6(ifc, argv, argc); else if (strcmp(argv[0], "recvra6") == 0) return ipifcrecvra6(ifc, argv, argc); return "unsupported ctl"; }
int net_mountroot_bootp(void) { bootp(netdev_sock); if (myip.s_addr == 0) return(ENOENT); printf("Using BOOTP protocol: "); printf("ip address: %s", inet_ntoa(myip)); if (hostname[0]) printf(", hostname: %s", hostname); if (netmask) printf(", netmask: %s", intoa(netmask)); if (gateip.s_addr) printf(", gateway: %s", inet_ntoa(gateip)); printf("\n"); return (0); }
int net_mountroot() { #ifdef DEBUG printf("net_mountroot\n"); #endif /* * Get info for NFS boot: our IP address, out hostname, * server IP address, and our root path on the server. * We use BOOTP (RFC951, RFC1532) exclusively as mandated * by PowerPC Reference Platform Specification I.4.2 */ bootp(netdev_sock); if (myip.s_addr == 0) return ETIMEDOUT; printf("Using IP address: %s\n", inet_ntoa(myip)); #ifdef DEBUG printf("myip: %s (%s)", hostname, inet_ntoa(myip)); if (gateip.s_addr) printf(", gateip: %s", inet_ntoa(gateip)); if (netmask) printf(", netmask: %s", intoa(netmask)); printf("\n"); #endif printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); /* * Get the NFS file handle (mount). */ if (nfs_mount(netdev_sock, rootip, rootpath) < 0) return errno; return 0; }
static int net_getparams(int sock) { char buf[MAXHOSTNAMELEN]; n_long rootaddr, smask; #ifdef SUPPORT_BOOTP /* * Try to get boot info using BOOTP. If we succeed, then * the server IP address, gateway, and root path will all * be initialized. If any remain uninitialized, we will * use RARP and RPC/bootparam (the Sun way) to get them. */ if (try_bootp) bootp(sock, BOOTP_NONE); if (myip.s_addr != 0) goto exit; #ifdef NETIF_DEBUG if (debug) printf("net_open: BOOTP failed, trying RARP/RPC...\n"); #endif #endif /* * Use RARP to get our IP address. This also sets our * netmask to the "natural" default for our address. */ if (rarp_getipaddress(sock)) { printf("net_open: RARP failed\n"); return (EIO); } printf("net_open: client addr: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address, gateway. */ if (bp_whoami(sock)) { printf("net_open: bootparam/whoami RPC failed\n"); return (EIO); } #ifdef NETIF_DEBUG if (debug) printf("net_open: client name: %s\n", hostname); #endif /* * Ignore the gateway from whoami (unreliable). * Use the "gateway" parameter instead. */ smask = 0; gateip.s_addr = 0; if (bp_getfile(sock, "gateway", &gateip, buf) == 0) { /* Got it! Parse the netmask. */ smask = ip_convertaddr(buf); } if (smask) { netmask = smask; #ifdef NETIF_DEBUG if (debug) printf("net_open: subnet mask: %s\n", intoa(netmask)); #endif } #ifdef NETIF_DEBUG if (gateip.s_addr && debug) printf("net_open: net gateway: %s\n", inet_ntoa(gateip)); #endif /* Get the root server and pathname. */ if (bp_getfile(sock, "root", &rootip, rootpath)) { printf("net_open: bootparam/getfile RPC failed\n"); return (EIO); } exit: if ((rootaddr = net_parse_rootpath()) != INADDR_NONE) rootip.s_addr = rootaddr; #ifdef NETIF_DEBUG if (debug) { printf("net_open: server addr: %s\n", inet_ntoa(rootip)); printf("net_open: server path: %s\n", rootpath); } #endif return (0); }
int netmountroot(struct open_file *f, char *devname) { int error; struct iodesc *d; #ifdef DEBUG printf("netmountroot: %s\n", devname); #endif if (netio_ask) { get_my_ip: printf("My IP address? "); bzero(input_line, sizeof(input_line)); gets(input_line); if ((myip.s_addr = inet_addr(input_line)) == htonl(INADDR_NONE)) { printf("invalid IP address: %s\n", input_line); goto get_my_ip; } get_my_netmask: printf("My netmask? "); bzero(input_line, sizeof(input_line)); gets(input_line); if ((netmask = inet_addr(input_line)) == htonl(INADDR_NONE)) { printf("invalid netmask: %s\n", input_line); goto get_my_netmask; } get_my_gateway: printf("My gateway? "); bzero(input_line, sizeof(input_line)); gets(input_line); if ((gateip.s_addr = inet_addr(input_line)) == htonl(INADDR_NONE)) { printf("invalid IP address: %s\n", input_line); goto get_my_gateway; } get_server_ip: printf("Server IP address? "); bzero(input_line, sizeof(input_line)); gets(input_line); if ((rootip.s_addr = inet_addr(input_line)) == htonl(INADDR_NONE)) { printf("invalid IP address: %s\n", input_line); goto get_server_ip; } get_server_path: printf("Server path? "); bzero(rootpath, sizeof(rootpath)); gets(rootpath); if (rootpath[0] == '\0' || rootpath[0] == '\n') goto get_server_path; if ((d = socktodesc(netdev_sock)) == NULL) return (EMFILE); d->myip = myip; goto do_nfs_mount; } /* * Get info for NFS boot: our IP address, our hostname, * server IP address, and our root path on the server. * There are two ways to do this: The old, Sun way, * and the more modern, BOOTP way. (RFC951, RFC1048) */ #ifdef SUN_BOOTPARAMS /* Get boot info using RARP and Sun bootparams. */ /* Get our IP address. (rarp.c) */ if (rarp_getipaddress(netdev_sock) == -1) return (errno); printf("boot: client IP address: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address. */ if (bp_whoami(netdev_sock)) return (errno); printf("boot: client name: %s\n", hostname); /* Get the root pathname. */ if (bp_getfile(netdev_sock, "root", &rootip, rootpath)) return (errno); #else /* Get boot info using BOOTP way. (RFC951, RFC1048) */ bootp(netdev_sock); printf("Using IP address: %s\n", inet_ntoa(myip)); printf("myip: %s (%s)", hostname, inet_ntoa(myip)); if (gateip) printf(", gateip: %s", inet_ntoa(gateip)); if (mask) printf(", mask: %s", intoa(netmask)); printf("\n"); #endif /* SUN_BOOTPARAMS */ printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); do_nfs_mount: /* Get the NFS file handle (mount). */ error = nfs_mount(netdev_sock, rootip, rootpath); return (error); }
void if_simple_setup(ifnet *interface, int addr, int netmask, int bcast, int net, int router, int def_router) { ifaddr *address; //addr = htonl(addr); //netmask = htonl(netmask); //bcast = htonl(bcast); // 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) = htonl(addr); NETADDR_TO_IPV4(address->addr) = addr; address->netmask.len = 4; address->netmask.type = ADDR_TYPE_IP; //NETADDR_TO_IPV4(address->netmask) = htonl(netmask); NETADDR_TO_IPV4(address->netmask) = netmask; address->broadcast.len = 4; address->broadcast.type = ADDR_TYPE_IP; //NETADDR_TO_IPV4(address->broadcast) = htonl(bcast); NETADDR_TO_IPV4(address->broadcast) = bcast; if_bind_address(interface, address); #if 1 printf("if a "); dump_ipv4_addr(addr); printf(" mask "); dump_ipv4_addr(netmask); printf(" broad "); dump_ipv4_addr(bcast); printf("\n"); #endif // set up an initial routing table int rc; if( (rc = ipv4_route_add( net, netmask, router, interface->id) ) ) { SHOW_ERROR( 1, "Adding route - failed, rc = %d", rc); } else { SHOW_INFO0( 2, "Adding route - ok"); } SHOW_INFO0( 2, "Adding default route..."); if( (rc = ipv4_route_add_default( router, interface->id, def_router ) ) ) { SHOW_ERROR( 1, "Adding route - failed, rc = %d", rc); } else { SHOW_INFO0( 2, "Adding route - ok"); } #if 0 hal_start_kernel_thread_arg( bootp_thread, interface ); #else // Now try to get something real :) bootp(interface); #endif }
/* * Initialize networkiness. * * Empty comments in column 1 indicate things that need to be undone upon * failure or in net_shutdown. * * Returns zero on success, an error code from <oskit/error.h> otherwise. */ oskit_error_t net_init(void) { #define BUFSIZE 128 struct bootp_net_info bpi; struct in_addr gw, ns; char hn[64], dn[64]; static char buf[BUFSIZE]; oskit_etherdev_t **alldevs; int ndev; int i, ix; unsigned required_flags; int interactive = 0; oskit_socket_factory_t *fsc; #ifdef FREEBSD_NET oskit_error_t err; #endif /* * Find all the Ethernet device nodes. */ retry: ndev = osenv_device_lookup(&oskit_etherdev_iid, (void***)&alldevs); #ifdef BOOTP_IF if (ndev < BOOTP_IF) panic("BOOTP Ethernet adaptor %d not found!", BOOTP_IF); #else if (ndev <= 0) panic("no Ethernet adaptors found!"); #endif dev = NULL; memset(&bpi, 0, sizeof bpi); /* * Prompt user for info */ if (interactive) { char *cp; do { printf("Enter ethernet IF to use [%d-%d]: ", 0, ndev-1); fgets(buf, BUFSIZE, stdin); ix = atoi(buf); if (ix < 0) goto gotinfo; } while (ix >= ndev); do { printf("Enter IP address: "); fgets(buf, BUFSIZE, stdin); } while (inet_aton(buf, &bpi.ip) == 0); do { printf("Enter netmask: "); fgets(buf, BUFSIZE, stdin); } while (inet_aton(buf, &bpi.netmask) == 0); do { printf("Enter gateway IP address: "); fgets(buf, BUFSIZE, stdin); } while (inet_aton(buf, &gw) == 0); bpi.gateway.addr = &gw; bpi.gateway.len = 1; printf("Enter hostname: "); fgets(buf, BUFSIZE, stdin); if ((cp = strchr(buf, '\n')) != 0) *cp = '\0'; memcpy(hn, buf, sizeof hn); bpi.hostname = hn; printf("Enter domainname: "); fgets(buf, BUFSIZE, stdin); if ((cp = strchr(buf, '\n')) != 0) *cp = '\0'; memcpy(dn, buf, sizeof dn); bpi.domainname = dn; do { printf("Enter nameserver IP address: "); fgets(buf, BUFSIZE, stdin); } while (inet_aton(buf, &ns) == 0); bpi.dns_server.addr = &ns; bpi.dns_server.len = 1; dev = alldevs[ix]; goto gotinfo; } /* * Try bootp on each dev and use the first one that succeeds. */ ix = ndev; for (i = 0; i < ndev; i++) { #ifdef BOOTP_IF if (i != BOOTP_IF) { oskit_etherdev_release(alldevs[i]); continue; } #else if (dev) { /* Have choice, but must release the others anyway. */ oskit_etherdev_release(alldevs[i]); continue; } #endif if (bootp(alldevs[i], &bpi) != 0) { oskit_etherdev_release(alldevs[i]); continue; } required_flags = (BOOTP_NET_IP | BOOTP_NET_NETMASK | BOOTP_NET_GATEWAY | BOOTP_NET_DNS_SERVER | BOOTP_NET_DOMAINNAME | BOOTP_NET_HOSTNAME); if ((bpi.flags & required_flags) != required_flags) { #define MISSING(flag, name) if ((bpi.flags & flag) == 0) \ printf("bootp did not supply %s\n", name) MISSING(BOOTP_NET_IP, "my IP address"); MISSING(BOOTP_NET_NETMASK, "my netmask"); MISSING(BOOTP_NET_GATEWAY, "gateway address"); MISSING(BOOTP_NET_DNS_SERVER, "DNS servers"); MISSING(BOOTP_NET_DOMAINNAME, "domainname"); MISSING(BOOTP_NET_HOSTNAME, "my hostname"); #undef MISSING oskit_etherdev_release(alldevs[i]); continue; } /**/ dev = alldevs[i]; ix = i; } gotinfo: if (dev == NULL) { #ifdef UTAHTESTBED /* * XXX fer now hack */ static int tried; if (tried++ < 5) goto retry; #endif #ifdef BOOTP_IF printf("No bootp server found for eth%d!", BOOTP_IF); #else printf("No bootp server found for any interface!"); #endif printf(" Try again? [n] "); fgets(buf, BUFSIZE, stdin); if (buf[0] == 'y' || buf[0] == 'Y') goto retry; printf("Enter bootp information manually? [y] "); fgets(buf, BUFSIZE, stdin); if (buf[0] != 'n' && buf[0] != 'N') { interactive = 1; goto retry; } return OSKIT_E_FAIL; } /* * Now we know our bootp struct has all we need, * so we copy the info out. */ ipaddr = strdup(inet_ntoa(bpi.ip)); netmask = strdup(inet_ntoa(bpi.netmask)); gateway = strdup(inet_ntoa(bpi.gateway.addr[0])); domain = strdup(bpi.domainname); { struct bootp_addr_array ns; int x; ns = bpi.dns_server; nameservers = mustcalloc(1, (sizeof(char*) * ns.len) + 1); for (x = 0; x < ns.len; x++) nameservers[x] = strdup(inet_ntoa(ns.addr[x])); nameservers[ns.len] = NULL; } /* Hostnamelen needs to be word aligned for RPC code. */ hostname = (char *)mustcalloc(strlen(bpi.hostname) + 3, 1); strcpy(hostname, bpi.hostname); hostnamelen = (strlen(hostname) + 3) & ~3; #ifdef DEBUG bootp_dump(&bpi); #endif printf("I am %s.%s (IP: %s, GW: %s, mask: %s)\n", hostname, domain, ipaddr, gateway, netmask); #ifdef FREEBSD_NET err = start_conf_network_init(start_osenv(), &fsc); assert(!err); err = start_conf_network_eifstart(i, ipaddr, netmask); assert(!err); start_conf_network_host(hostname, gateway, domain, nameservers); #else /* Now init the fudp module. It will open the device */ udplib_init(dev, hostname, ipaddr, netmask, gateway, &fsc); /* * This writes out the DNS files. We need the freebsd stub * function below since it thinks its dealing with the freebsd * network stack. */ start_conf_network_host(hostname, gateway, domain, nameservers); #endif /* * Register to socket factory so that UDP might be useful for others. * Its a long shot! */ #ifdef PTHREADS pthread_init_socketfactory(fsc); #else oskit_register(&oskit_socket_factory_iid, (void *) fsc); #endif return 0; }
static int net_getparams(int sock) { char buf[MAXHOSTNAMELEN]; char temp[FNAME_SIZE]; struct iodesc *d; int i; n_long smask; #ifdef SUPPORT_BOOTP /* * Try to get boot info using BOOTP. If we succeed, then * the server IP address, gateway, and root path will all * be initialized. If any remain uninitialized, we will * use RARP and RPC/bootparam (the Sun way) to get them. */ if (try_bootp) bootp(sock, BOOTP_NONE); if (myip.s_addr != 0) goto exit; if (debug) printf("net_open: BOOTP failed, trying RARP/RPC...\n"); #endif /* * Use RARP to get our IP address. This also sets our * netmask to the "natural" default for our address. */ if (rarp_getipaddress(sock)) { printf("net_open: RARP failed\n"); return (EIO); } printf("net_open: client addr: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address, gateway. */ if (bp_whoami(sock)) { printf("net_open: bootparam/whoami RPC failed\n"); return (EIO); } printf("net_open: client name: %s\n", hostname); /* * Ignore the gateway from whoami (unreliable). * Use the "gateway" parameter instead. */ smask = 0; gateip.s_addr = 0; if (bp_getfile(sock, "gateway", &gateip, buf) == 0) { /* Got it! Parse the netmask. */ smask = ip_convertaddr(buf); } if (smask) { netmask = smask; printf("net_open: subnet mask: %s\n", intoa(netmask)); } if (gateip.s_addr) printf("net_open: net gateway: %s\n", inet_ntoa(gateip)); /* Get the root server and pathname. */ if (bp_getfile(sock, "root", &rootip, rootpath)) { printf("net_open: bootparam/getfile RPC failed\n"); return (EIO); } exit: /* * If present, strip the server's address off of the rootpath * before passing it along. This allows us to be compatible with * the kernel's diskless (BOOTP_NFSROOT) booting conventions */ for (i = 0; i < FNAME_SIZE && rootpath[i] != '\0'; i++) if (rootpath[i] == ':') break; if (i && i != FNAME_SIZE && rootpath[i] == ':') { rootpath[i++] = '\0'; if (inet_addr(&rootpath[0]) != INADDR_NONE) rootip.s_addr = inet_addr(&rootpath[0]); memcpy(&temp[0], &rootpath[i], strlen(&rootpath[i])+1); memcpy(&rootpath[0], &temp[0], strlen(&rootpath[i])+1); } printf("net_open: server addr: %s\n", inet_ntoa(rootip)); printf("net_open: server path: %s\n", rootpath); d = socktodesc(sock); snprintf(temp, sizeof(temp), "%6D", d->myea, ":"); setenv("boot.netif.ip", inet_ntoa(myip), 1); setenv("boot.netif.netmask", intoa(netmask), 1); setenv("boot.netif.gateway", inet_ntoa(gateip), 1); setenv("boot.netif.hwaddr", temp, 1); setenv("boot.nfsroot.server", inet_ntoa(rootip), 1); setenv("boot.nfsroot.path", rootpath, 1); return (0); }
/************************************************************************** LOAD - Try to get booted **************************************************************************/ load() { char *p,*q; char cfg[64]; int root_mount_port; int swap_nfs_port; int swap_mount_port; char cmd_line[80]; int err, read_size, i; long addr, broadcast; int swsize; unsigned long pad; config_buffer[0]='\0'; /* clear; bootp might fill this up */ /* Initialize this early on */ nfsdiskless.root_args.rsize = 8192; nfsdiskless.root_args.wsize = 8192; nfsdiskless.swap_args.rsize = 8192; nfsdiskless.swap_args.wsize = 8192; nfsdiskless.root_args.sotype = SOCK_DGRAM; nfsdiskless.root_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE | NFSMNT_RESVPORT); nfsdiskless.swap_args.sotype = SOCK_DGRAM; nfsdiskless.swap_args.flags = (NFSMNT_WSIZE | NFSMNT_RSIZE | NFSMNT_RESVPORT); /* Find a server to get BOOTP reply from */ if (!arptable[ARP_CLIENT].ipaddr || !arptable[ARP_SERVER].ipaddr) { printf("\nSearching for server...\n"); if (!bootp()) { printf("No Server found.\n"); longjmp(jmp_bootmenu,1); } } printf("My IP %I, Server IP %I, GW IP %I\n", arptable[ARP_CLIENT].ipaddr, arptable[ARP_SERVER].ipaddr, arptable[ARP_GATEWAY].ipaddr); #ifdef MDEBUG printf("\n=>>"); getchar(); #endif /*** check if have got info from bootp ***/ if (config_buffer[0]) goto cfg_done; #ifndef NO_TFTP /* Now use TFTP to load configuration file */ sprintf(cfg,"/tftpboot/freebsd.%I",arptable[ARP_CLIENT].ipaddr); if (tftp(cfg) || tftp(cfg+10)) goto cfg_done; cfg[17]='\0'; if (tftp(cfg) || tftp(cfg+10)) goto cfg_done; sprintf(cfg,"/tftpboot/cfg.%I",arptable[ARP_CLIENT].ipaddr); if (tftp(cfg) || tftp(cfg+10)) goto cfg_done; #endif /* not found; using default values... */ sprintf(config_buffer,"rootfs %I:/usr/diskless_root", arptable[ARP_SERVER].ipaddr); printf("Unable to load config file, guessing:\n\t%s\n", config_buffer); cfg_done: #ifdef MDEBUG printf("\n=>>"); getchar(); #endif p = config_buffer; while(*p) { q = cmd_line; while ((*p != '\n') && (*p)) *(q++) = *(p++); *q = 0; printf("%s\n",cmd_line); execute(cmd_line); if (*p) p++; } #ifdef MDEBUG printf("\n=>>"); getchar(); #endif /* Check to make sure we've got a rootfs */ if (!arptable[ARP_ROOTSERVER].ipaddr) { printf("No ROOT filesystem server!\n"); longjmp(jmp_bootmenu,1); } /* Fill in nfsdiskless.myif */ sprintf(&nfsdiskless.myif.ifra_name,eth_driver); nfsdiskless.myif.ifra_addr.sa_len = sizeof(struct sockaddr); nfsdiskless.myif.ifra_addr.sa_family = AF_INET; addr = htonl(arptable[ARP_CLIENT].ipaddr); bcopy(&addr, &nfsdiskless.myif.ifra_addr.sa_data[2], 4); broadcast = (addr & netmask) | ~netmask; nfsdiskless.myif.ifra_broadaddr.sa_len = sizeof(struct sockaddr); nfsdiskless.myif.ifra_broadaddr.sa_family = AF_INET; bcopy(&broadcast, &nfsdiskless.myif.ifra_broadaddr.sa_data[2], 4); addr = htonl(arptable[ARP_GATEWAY].ipaddr); if (addr) { nfsdiskless.mygateway.sin_len = sizeof(struct sockaddr); nfsdiskless.mygateway.sin_family = AF_INET; bcopy(&addr, &nfsdiskless.mygateway.sin_addr, 4); } else { nfsdiskless.mygateway.sin_len = 0; } nfsdiskless.myif.ifra_mask.sa_len = sizeof(struct sockaddr); nfsdiskless.myif.ifra_mask.sa_family = AF_UNSPEC; bcopy(&netmask, &nfsdiskless.myif.ifra_mask.sa_data[2], 4); rpc_id = currticks(); /* Lookup NFS/MOUNTD ports for SWAP using PORTMAP */ if (arptable[ARP_SWAPSERVER].ipaddr) { char swapfs_fh[32], swapfile[32]; swap_nfs_port = rpclookup(ARP_SWAPSERVER, PROG_NFS, 2); swap_mount_port = rpclookup(ARP_SWAPSERVER, PROG_MOUNT, 1); if ((swap_nfs_port == -1) || (swap_mount_port == -1)) { printf("Unable to get SWAP NFS/MOUNT ports\n"); longjmp(jmp_bootmenu,1); } if (err = nfs_mount(ARP_SWAPSERVER, swap_mount_port, nfsdiskless.swap_hostnam, &swapfs_fh)) { printf("Unable to mount SWAP filesystem: "); nfs_err(err); longjmp(jmp_bootmenu,1); } sprintf(swapfile,"swap.%I",arptable[ARP_CLIENT].ipaddr); if (err = nfs_lookup(ARP_SWAPSERVER, swap_nfs_port, &swapfs_fh, swapfile, &nfsdiskless.swap_fh, &swsize)) { printf("Unable to open %s: ",swapfile); nfs_err(err); longjmp(jmp_bootmenu,1); } if (!nfsdiskless.swap_nblks) { nfsdiskless.swap_nblks = swsize / 1024; printf("Swap size is: %d blocks\n",nfsdiskless.swap_nblks); } nfsdiskless.swap_saddr.sin_len = sizeof(struct sockaddr_in); nfsdiskless.swap_saddr.sin_family = AF_INET; nfsdiskless.swap_saddr.sin_port = htons(swap_nfs_port); nfsdiskless.swap_saddr.sin_addr.s_addr = htonl(arptable[ARP_SWAPSERVER].ipaddr); nfsdiskless.swap_args.timeo = 10; nfsdiskless.swap_args.retrans = 100; } /* Lookup NFS/MOUNTD ports for ROOT using PORTMAP */ root_nfs_port = rpclookup(ARP_ROOTSERVER, PROG_NFS, 2); root_mount_port = rpclookup(ARP_ROOTSERVER, PROG_MOUNT, 1); if ((root_nfs_port == -1) || (root_mount_port == -1)) { printf("Unable to get ROOT NFS/MOUNT ports\n"); longjmp(jmp_bootmenu,1); } if (err = nfs_mount(ARP_ROOTSERVER, root_mount_port, nfsdiskless.root_hostnam, &nfsdiskless.root_fh)) { printf("Unable to mount ROOT filesystem: "); nfs_err(err); longjmp(jmp_bootmenu,1); } nfsdiskless.root_saddr.sin_len = sizeof(struct sockaddr_in); nfsdiskless.root_saddr.sin_family = AF_INET; nfsdiskless.root_saddr.sin_port = htons(root_nfs_port); nfsdiskless.root_saddr.sin_addr.s_addr = htonl(arptable[ARP_ROOTSERVER].ipaddr); nfsdiskless.root_args.timeo = 10; nfsdiskless.root_args.retrans = 100; nfsdiskless.root_time = 0; if (err = nfs_lookup(ARP_ROOTSERVER, root_nfs_port, &nfsdiskless.root_fh, *kernel == '/' ? kernel+1 : kernel, &kernel_handle, NULL)) { printf("Unable to open %s: ",kernel); nfs_err(err); longjmp(jmp_bootmenu,1); } /* Load the kernel using NFS */ printf("Loading %s...\n",kernel); if ((err = nfs_read(ARP_ROOTSERVER, root_nfs_port, &kernel_handle, 0, sizeof(struct exec), &head)) < 0) { printf("Unable to read %s: ",kernel); nfs_err(err); longjmp(jmp_bootmenu,1); } if (N_BADMAG(head)) { printf("Bad executable format!\n"); longjmp(jmp_bootmenu, 1); } loadpoint = (char *)(head.a_entry & 0x00FFFFFF); offset = N_TXTOFF(head); printf("text=0x%X, ",head.a_text); #ifdef PC98 set_twiddle_max(8); #endif nfsload(head.a_text); while (((int)loadpoint) & PAGE_MASK) *(loadpoint++) = 0; printf("data=0x%X, ",head.a_data); nfsload(head.a_data); printf("bss=0x%X, ",head.a_bss); while(head.a_bss--) *(loadpoint++) = 0; while (((int)loadpoint) & PAGE_MASK) *(loadpoint++) = 0; bootinfo.bi_symtab = (int) loadpoint; p = (char*)&head.a_syms; for (i=0;i<sizeof(head.a_syms);i++) *loadpoint++ = *p++; printf("symbols=[+0x%x+0x%x", sizeof(head.a_syms), head.a_syms); nfsload(head.a_syms); i = sizeof(int); p = loadpoint; nfsload(i); i = *(int*)p; printf("+0x%x]\n", i); i -= sizeof(int); nfsload(i); bootinfo.bi_esymtab = (int) loadpoint; printf("entry=0x%X.\n",head.a_entry); /* Jump to kernel */ bootinfo.bi_version = BOOTINFO_VERSION; bootinfo.bi_kernelname = kernel; bootinfo.bi_nfs_diskless = &nfsdiskless; bootinfo.bi_size = sizeof bootinfo; kernelentry = (void *)(head.a_entry & 0x00FFFFFF); (*kernelentry)(howto|RB_BOOTINFO,NODEV,0,0,0,&bootinfo,0,0,0); printf("*** %s execute failure ***\n",kernel); }
int net_devinit(struct open_file *f, struct netif_driver *drv, u_char *eaddr) { static struct netif best_if; struct iodesc *s; int r; if (inited) return 0; /* find a free socket */ s = &desc; memset(s, 0, sizeof(*s)); best_if.nif_driver = drv; s->io_netif = &best_if; memcpy(s->myea, eaddr, 6); /* * Get info for NFS boot: our IP address, our hostname, * server IP address, and our root path on the server. * There are two ways to do this: The old, Sun way, * and the more modern, BOOTP way. (RFC951, RFC1048) */ #ifdef SUPPORT_BOOTP /* Get boot info using BOOTP way. (RFC951, RFC1048) */ printf("Trying BOOTP\n"); bootp(0); if (myip.s_addr) { printf("Using IP address: %s\n", inet_ntoa(myip)); printf("myip: %s (%s)\n", hostname, inet_ntoa(myip)); } else #endif /* SUPPORT_BOOTP */ { #ifdef SUPPORT_BOOTPARAMS /* Get boot info using RARP and Sun bootparams. */ printf("Trying BOOTPARAMS\n"); /* Get our IP address. (rarp.c) */ if (rarp_getipaddress(0) == -1) return (errno); printf("boot: client IP address: %s\n", inet_ntoa(myip)); /* Get our hostname, server IP address. */ if (bp_whoami(0)) return (errno); printf("boot: client name: %s\n", hostname); /* Get the root pathname. */ if (bp_getfile(0, "root", &rootip, rootpath)) return (errno); #endif } printf("root addr=%s path=%s\n", inet_ntoa(rootip), rootpath); f->f_devdata = s; /* Get the NFS file handle (mount). */ r = nfs_mount(0, rootip, rootpath); if (r) return r; inited = 1; return 0; }
/* * Called by devopen after it sets f->f_dev to our devsw entry. * This opens the low-level device and sets f->f_devdata. */ int net_open(struct open_file *f, ...) { int error = 0; #ifdef NET_DEBUG if (netdev_sock != -1) panic("net_open"); #endif /* Find network interface. */ if ((netdev_sock = netif_open()) < 0) return (ENXIO); #ifdef SUPPORT_BOOTP printf("configure network...trying bootp\n"); /* Get boot info using BOOTP way. (RFC951, RFC1048) */ bootp(netdev_sock); #endif if (myip.s_addr != INADDR_ANY) { /* got bootp reply or * manually set */ #ifdef TFTP_HACK int num, i; /* XXX (some) tftp servers don't like leading "/" */ for (num = 0; bootfile[num] == '/'; num++); for (i = 0; (bootfile[i] = bootfile[i + num]) != 0; i++); #endif printf("boot: client IP address: %s\n", inet_ntoa(myip)); printf("boot: client name: %s\n", hostname); } else { #ifdef SUPPORT_RARP /* * no answer, Get boot info using RARP and Sun * bootparams. */ printf("configure network...trying rarp\n"); /* Get our IP address. (rarp.c) */ if (rarp_getipaddress(netdev_sock)) { error = EIO; goto bad; } printf("boot: client IP address: %s\n", inet_ntoa(myip)); #ifdef SUPPORT_BOOTPARAM /* Get our hostname, server IP address. */ if (!bp_whoami(netdev_sock)) { printf("boot: client name: %s\n", hostname); /* Get the root pathname. */ bp_getfile(netdev_sock, "root", &rootip, rootpath); } #else /* * else fallback: use rarp server address */ #endif #else /* no SUPPORT_RARP */ error = EIO; goto bad; #endif } printf("boot: server: %s, rootpath: %s, bootfile: %s\n", inet_ntoa(rootip), rootpath, bootfile); f->f_devdata = &netdev_sock; return (error); bad: printf("net_open failed\n"); netif_close(netdev_sock); return (error); }