bootConfig.c
上传用户:yuanda199
上传日期:2022-06-26
资源大小:412k
文件大小:169k
源码类别:

VxWorks

开发平台:

C/C++

  1. {
  2. printf ("nError loading file: errno = 0x%x.n", errno);
  3. return (ERROR);
  4. }
  5.     return (OK);
  6.     }
  7. #ifdef INCLUDE_END
  8. /*******************************************************************************
  9. *
  10. * findCookie - traverses the cookieTbl to return the right cookie
  11. *
  12. * Given the unit number and the device name this function traverses the cookieTbl
  13. * to return the right cookie. This is a local file.
  14. *
  15. * RETURNS: cookie or NULL
  16. *
  17. */
  18. LOCAL void* findCookie
  19.     (
  20.     int unitNo,
  21.     char* devName
  22.     )
  23.     {
  24.     int count;
  25.     for(count=0;count<32;count++)
  26. {
  27. if((cookieTbl[count].unitNo==unitNo) && 
  28.     (STREQ(cookieTbl[count].devName,devName)))
  29.         return(cookieTbl[count].pCookie);
  30. }
  31.     return (NULL);
  32.     }
  33. #endif    /* INCLUDE_END */
  34. #ifdef BROADCOM_BSP
  35. /*****************************************************************************
  36. * netLoadInit - Attach the network to the point where ftpXfer will work.
  37. */
  38. LOCAL BOOL netLoadInited = FALSE;
  39. LOCAL STATUS netLoadInit(char *bootString)
  40. {
  41.     BOOT_PARAMS params;
  42.     char nad [20]; /* host's network internet addr */
  43.     int netmask = 0; /* temporary storage */
  44.     int  result;  /* classification of address string */
  45.     unsigned long  leaseLen;  /* lease length field (optional) */
  46. #ifdef INCLUDE_DHCPC
  47.     DHCP_LEASE_DATA dhcpLease;
  48. #endif  /* INCLUDE_DHCPC */
  49.     char buf [30]; /* string of netmask and timestamps */
  50.     char  netDev [BOOT_DEV_LEN + 1];
  51.     char  bootDev [BOOT_DEV_LEN];
  52.     BOOL backplaneBoot;
  53.     char * pBootAddr;
  54. #ifdef INCLUDE_END
  55.     char       muxDevName[8];
  56. #endif /* INCLUDE_END */
  57.     if (netLoadInited)
  58. return OK;
  59.     netLoadInited = TRUE;
  60.     /* interpret boot command */
  61.     if (usrBootLineCrack (BOOT_LINE_ADRS, &params) != OK)
  62. return (ERROR);
  63.     /* set our processor number: may establish vme access, etc. */
  64.     sysFlags = params.flags;
  65.     sysProcNumSet (params.procNum);
  66.     /* start the network */
  67.     /* initialize the generic socket library */
  68.     if (sockLibInit (NUM_FILES) == ERROR)
  69.         return (ERROR);
  70. #if defined(INCLUDE_STREAMS) || defined(INCLUDE_STREAMS_ALL)
  71.     if (usrStrmInit() == ERROR)         /* init Streams subsystem */
  72.         return (ERROR);
  73. #endif   
  74. #if defined(INCLUDE_BSD) || defined(INCLUDE_BSD_SOCKET)
  75.     /* add the BSD socket library interface */
  76.     if (sockLibAdd ((FUNCPTR) bsdSockLibInit, AF_INET_BSD, AF_INET) == ERROR)
  77.         return (ERROR);
  78.     if (sockLibAdd ((FUNCPTR) bsdSockLibInit, AF_ROUTE, AF_ROUTE) == ERROR)
  79.         return (ERROR);
  80. #endif  /* INCLUDE_BSD || INCLUDE_BSD_SOCKET */
  81.     /* install default socket library interface */
  82. #ifndef DEFAULT_STREAMS_SOCKET
  83.     if (sockLibAdd ((FUNCPTR) bsdSockLibInit, AF_INET, AF_INET) == ERROR)
  84.         return (ERROR);
  85. #endif  /* DEFAULT_STREAMS_SOCKET */
  86.  
  87.     hostTblInit (); /* initialize host table */
  88.     usrNetProtoInit ();         /* initialize various protocols */
  89.     netLibInit ();
  90. #ifdef INCLUDE_PPP
  91. #ifdef INCLUDE_PPP_CRYPT 
  92.     cryptRtnInit (&pppCryptRtn); /* install crypt() routine */ 
  93. #endif /* INCLUDE_PPP_CRYPT */
  94. #endif /* INCLUDE_PPP */
  95.     /* attach and configure boot interface */
  96.     if (strncmp (params.bootDev, "ppp", 3) == 0)
  97.         {
  98.         /* booting via ppp */
  99.         if (usrPPPInit (params.bootDev, params.unitNum, params.ead, 
  100.                         ((params.gad[0] == EOS)? params.had : params.gad)) 
  101.                         == ERROR)
  102.             return (ERROR);
  103.         }
  104.     else if (strncmp (params.bootDev, "sl", 2) == 0)
  105. {
  106.    if (usrSlipInit (params.bootDev, params.unitNum, params.ead, 
  107.                          ((params.gad[0] == EOS)? params.had : params.gad)) 
  108.                          == ERROR)
  109.     return (ERROR);
  110.         }
  111.     else
  112. {
  113.         strncpy (bootDev, params.bootDev, sizeof (bootDev));
  114. if ((strncmp (params.bootDev, "bp", 2) != 0) &&
  115.             (strncmp (params.bootDev, "sm", 2) != 0))
  116.     {
  117.     pBootAddr = params.ead;
  118.     backplaneBoot = FALSE;
  119.     }
  120.         else
  121.     {
  122.     if (sysProcNumGet () == 0)
  123. {
  124.                 printf (
  125.                   "Error: processor number must be non-zero to boot from bpn");
  126.         return (ERROR);
  127.                 }
  128.     if (usrBpInit (bootDev, params.unitNum, 0) == ERROR)
  129. return (ERROR);
  130.     pBootAddr = params.bad;
  131.     backplaneBoot = TRUE;
  132.     }
  133.         /* Save requested lease length, if any. Ignore lease origin value. */
  134.         result = bootLeaseExtract (pBootAddr, &leaseLen, NULL);
  135.         if (result < 0)
  136.             {
  137.             printf ("Error reading target address information.n");
  138.             return (ERROR);
  139.             }
  140.         /* Handle any lease information attached to the address entry. */
  141.         if (result == 2)
  142.             {
  143.             /* 
  144.              * The current address contains both a duration value and a start
  145.              * time, indicating that it was assigned by a DHCP server.
  146.              */
  147.             if (leaseLen != ~0)
  148.                 {
  149.                 /* Handle a finite address assignment. */
  150.                 if (sysFlags & SYSFLG_AUTOCONFIG)
  151.                     *pBootAddr = EOS;    /* Remove for later replacement. */
  152.                 else
  153.                     {
  154.                     /* 
  155.                      * Technically, this address is invalid since it contains
  156.                      * a finite interval that requires DHCP for verification
  157.                      * and the automatic configuration flag is not set.
  158.                      * However, this situation can only occur if caused 
  159.                      * deliberately by the user. So, just ignore the timing
  160.                      * information and assign the address permanently.
  161.                      */
  162.                     result = 0;    /* Prevents restoration of time values. */
  163.                     }
  164.                 }
  165.             }
  166. #ifdef INCLUDE_DHCPC
  167.         /* Set the DHCP lease information, if needed. */
  168.         if (sysFlags & SYSFLG_AUTOCONFIG)
  169.             {
  170.             /* Save the requested lease length if entered by the user. */
  171.             if (result == 1)
  172.                 dhcpLease.lease_duration = leaseLen;
  173.             else
  174.                 {
  175.                 /* 
  176.                  * The lease length is either not present or left over from
  177.                  * an earlier lease. Use the default value.
  178.                  */
  179.                 dhcpLease.lease_duration = DHCPC_DEFAULT_LEASE;
  180.                 }
  181.             dhcpLease.lease_origin = 0;
  182.             }
  183. #endif  /* INCLUDE_DHCPC */
  184.         netmask = 0;
  185.         bootNetmaskExtract (pBootAddr, &netmask);
  186.         (void) sprintf (netDev, "%s%d", bootDev, params.unitNum);
  187. #ifdef INCLUDE_END
  188.         pCookie=findCookie(params.unitNum, bootDev);
  189.         if (muxDevStart (pCookie) != OK)
  190.             {
  191.             printf("Failed to start device %sn", bootDev);
  192.             return (ERROR);
  193.             }
  194.         /* Find the END_OBJ associated with it. */
  195.         pEnd = endFindByName (bootDev, params.unitNum);
  196. #if 0
  197.         if (muxIoctl (pEnd, EIOCGMIB2, (char *)&endM2Tbl)
  198.                 == ERROR)
  199.             return (ERROR);
  200. #endif
  201.         /* Add our default address resolution functions. */
  202.         muxAddrResFuncAdd (M2_ifType_ethernet_csmacd, 0x800, ipEtherResolvRtn);
  203.         if (ipAttach (params.unitNum, bootDev) != OK)
  204.             {
  205.             printf ("Failed to attach TCP/IP to device %s", muxDevName);
  206.             return (ERROR);
  207.             }
  208.         printf ("Attached TCP/IP interface to %s%d.n", bootDev,
  209.                  params.unitNum);
  210. #else
  211.         if (usrNetIfAttach (bootDev, params.unitNum, pBootAddr) != OK)
  212.             return (ERROR);
  213.             
  214. #endif /* INCLUDE_END */
  215.         if ( (sysFlags & SYSFLG_AUTOCONFIG) || (sysFlags & SYSFLG_PROXY) ||
  216.             (netmask == 0))
  217.             {
  218.             struct ifnet * pIf;
  219.                 
  220.             /* Initialize the boot device */
  221.                 
  222.             if ( (pIf = ifunit (netDev)) == NULL) 
  223.                 {
  224.                 printf ("invalid device "%s"n", netDev);
  225.                 return (ERROR); /* device not attached */
  226.                 }
  227.                 
  228.             if (pIf->if_init != NULL)
  229.                 {
  230.                 if ( (*pIf->if_init) (pIf->if_unit) != 0)
  231.                     {
  232.                     printf ("initialization failed for device "%s"n",netDev);
  233.                     return (ERROR);
  234.                     }
  235.                 }
  236.             }
  237. #ifdef INCLUDE_SM_NET
  238.   if (backplaneBoot)
  239.     {
  240.     if ((params.bad [0] == EOS) &&
  241.      (strncmp (bootDev, "sm", 2) == 0) &&
  242. (smNetInetGet (netDev, params.bad, NONE) == OK))
  243.      printf ("Backplane inet address: %sn", params.bad);
  244.     if (params.bad [0] == EOS) 
  245.      {
  246.      printf ("no backplane address specifiedn");
  247. return (ERROR);
  248. }
  249.     if ((sysFlags & SYSFLG_AUTOCONFIG) && !(sysFlags & SYSFLG_PROXY))
  250.         {
  251. #ifdef INCLUDE_DHCPC
  252.         printf ("DHCP over backplane only with proxy arpn");
  253. #else
  254.         printf ("BOOTP over backplane only with proxy arpn");
  255. #endif
  256.         return (ERROR);
  257.         }
  258.     if (sysFlags & SYSFLG_PROXY)
  259. {
  260. #ifdef INCLUDE_PROXY_CLIENT
  261.      printf ("registering proxy client: %s", params.bad);
  262.      if (proxyReg (netDev, params.bad) == ERROR)
  263.     {
  264.          printf ("client registered failed %xn", errno);
  265.     return (ERROR);
  266.     }
  267. printf ("done.n");
  268. #else /* INCLUDE_PROXY_CLIENT */
  269.           printf ("proxy client referenced but not included.n");
  270.           return (ERROR);
  271. #endif /* INCLUDE_PROXY_CLIENT */
  272. }
  273.     }
  274. #endif /* INCLUDE_SM_NET */
  275.         /* Get boot parameters over the network if requested. */
  276.         if (sysFlags & SYSFLG_AUTOCONFIG)
  277.             {
  278.             if (bootpGet (netDev, pBootAddr, params.bootFile, params.had,
  279.                           &netmask) == ERROR)
  280.                 return (ERROR);
  281. #ifdef INCLUDE_DHCPC
  282.             if (dhcpGet (netDev, pBootAddr, params.bootFile, params.had,
  283.                          &netmask, &dhcpLease) == ERROR)
  284.                 return (ERROR);
  285. #endif      /* INCLUDE_DHCPC */
  286.             }
  287.         /* configure the device */
  288.         if (usrNetIfConfig (bootDev, params.unitNum, pBootAddr, 
  289.                             (char *) NULL, netmask) != OK)
  290.             return (ERROR);
  291.         if (netmask == 0)
  292.             {
  293.             (void) icmpMaskGet (netDev, pBootAddr, backplaneBoot ?
  294.                                 NULL : params.had, &netmask);
  295.             if (netmask != 0)
  296.                 {
  297.                 sprintf (bootDev, "%s%d", bootDev, params.unitNum);
  298.                 ifMaskSet (bootDev, netmask);
  299.                 printf ("Subnet Mask: 0x%xn", netmask);
  300.                 }
  301.             }
  302.   /* get gateway address */
  303. #ifdef INCLUDE_SM_NET
  304. if (backplaneBoot && (params.gad [0] == EOS) && 
  305.     !(sysFlags & SYSFLG_PROXY))
  306.     {
  307.         struct in_addr host; /* Internet Address */
  308.         struct in_addr backpl; /* Internet Address */
  309.         host.s_addr = inet_addr (params.had);
  310.         backpl.s_addr = inet_addr (params.bad);
  311.         if ( in_netof(host) != in_netof(backpl) )
  312.         {
  313.         /* We can get the gateway address (assumed to be master)  */
  314.         if ((strncmp (bootDev, "sm", 2) == 0) && 
  315.             (smNetInetGet (netDev, params.gad, 0) == OK))
  316.     printf ("Gateway inet address: %sn", params.gad);
  317. }
  318.     }
  319. #endif /* INCLUDE_SM_NET */
  320.         if (netmask != 0) /* reconstruct address with mask */
  321.             {
  322.             sprintf (buf, ":%x", netmask);
  323.             strcat  (pBootAddr, buf);
  324.             }
  325.         /* 
  326.          * If a value was specified for the requested lease length and the 
  327.          * address information was not replaced by automatic configuration, 
  328.          * restore that value for use by later reboots.
  329.          */
  330.         if (!(sysFlags & SYSFLG_AUTOCONFIG) && result == 1)
  331.             {
  332.             /* 
  333.              * The value is ignored if <result> is 2, since that is only
  334.              * possible at this point for permanent DHCP assignments, 
  335.              * which need no special processing by later reboots.
  336.              */
  337.             if (netmask == 0)  /* Create empty netmask field. */
  338.                 sprintf (buf, "::%lx", leaseLen);
  339.             else  /* Append requested lease length to netmask. */
  340.                 sprintf(buf, ":%lx", leaseLen);
  341.             strcat (pBootAddr, buf);
  342.             }
  343. #ifdef INCLUDE_DHCPC
  344.         /* 
  345.          * If the target IP address was assigned by a DHCP server, append
  346.          * the lease times. The presence of those fields in the address string 
  347.          * will cause the runtime image to renew the corresponding lease.
  348.          */
  349.         if (sysFlags & SYSFLG_AUTOCONFIG)
  350.             {
  351.             /* Add lease origin and lease duration if needed. */
  352.             if (dhcpcBindType == DHCP_NATIVE)
  353.                 {
  354.                 if (netmask == 0)  /* Create empty netmask field. */
  355.                     sprintf (buf, "::%lx:%lx", dhcpLease.lease_duration, 
  356.                                                dhcpLease.lease_origin);
  357.                 else  /* Append lease timestamps to netmask. */
  358.                     sprintf(buf, ":%lx:%lx", dhcpLease.lease_duration, 
  359.                                              dhcpLease.lease_origin);
  360.                 strcat (pBootAddr, buf);
  361.                 }
  362.             }
  363. #endif    /* INCLUDE_DHCPC */
  364.         bootStructToString (BOOT_LINE_ADRS, &params);
  365.         }
  366.     usrNetIfAttach ("lo", 0, "127.0.0.1");
  367.     usrNetIfConfig ("lo", 0, "127.0.0.1", "localhost", 0);
  368.     /* if a gateway was specified, extract the network part of the host's
  369.      * address and add a route to this network
  370.      */
  371.     if (params.gad[0] != EOS)
  372.         {
  373. inet_netof_string (params.had, nad);
  374. #ifdef BROADCOM_BSP
  375. /* Make the gateway the default route */
  376. routeAdd ("0.0.0.0", params.gad);
  377. #else
  378. routeAdd (nad, params.gad);
  379. #endif
  380.         }
  381.     /* associate hostName with the specified host address */
  382.     hostAdd (params.hostName, params.had);
  383. #ifdef BROADCOM_BSP
  384.     {
  385. extern void sysBindFix(void);
  386. sysBindFix(); /* See sysLib.c */
  387.     }
  388. #endif
  389.     /* load specified file */
  390.     return OK;
  391. }
  392. #define FLASH_BUF_SIZE (512 * 1024)
  393. LOCAL STATUS netFlash(char *bootString)
  394. {
  395.     BOOT_PARAMS params;
  396.     int fd = -1;
  397.     int errFd = -1;
  398.     FILE *fp = 0;
  399.     char command [100];
  400.     BOOL bootFtp;
  401.     BOOL bootRsh = FALSE;
  402.     char *hostName;
  403.     char *fileName;
  404.     char *usr;
  405.     char *passwd;
  406.     char *flashBuf = 0;
  407.     char tmpc = 0;
  408.     int entry, i;
  409.     int sRecords;
  410.     /* Re-probe in case jumper moved */
  411.     if (flashDrvLibInit() == ERROR) {
  412.         return(ERROR);
  413.     }
  414.     if ((flashBuf = malloc(FLASH_BUF_SIZE)) == 0) {
  415. printf("nNot enough memoryn");
  416. goto fail;
  417.     }
  418.     /* copy bootString to low mem address, if specified */
  419.     if ((bootString != NULL) && (*bootString != EOS))
  420. strcpy (BOOT_LINE_ADRS, bootString);
  421.     /* interpret boot command */
  422.     if (usrBootLineCrack (BOOT_LINE_ADRS, &params) != OK)
  423. goto fail;
  424.     hostName = params.had;
  425.     fileName = params.bootFile;
  426.     usr = params.usr;
  427.     passwd = params.passwd;
  428.     bootFtp = (passwd[0] != EOS);
  429.     if (strlen(fileName) < 4) {
  430.     bad_fname:
  431. printf("Illegal file %s, must end in .img or .hexn", fileName);
  432. goto fail;
  433.     }
  434.     if (! strcmp(fileName + strlen(fileName) - 4, ".img"))
  435. sRecords = 0;
  436.     else if (! strcmp(fileName + strlen(fileName) - 4, ".hex"))
  437. sRecords = 1;
  438.     else
  439. goto bad_fname; /* Above */
  440.     if (netLoadInit(bootString) != OK) {
  441. printf("nError configuring networkn");
  442. goto fail;
  443.     }
  444.     printf ("Loading... ");
  445. #ifdef INCLUDE_TFTP_CLIENT
  446.     if (sysFlags & SYSFLG_TFTP) /* use tftp to get image */
  447.         {
  448. if (tftpXfer (hostName, 0, fileName, "get", "binary", &fd,
  449.       &errFd) == ERROR)
  450.     goto fail;
  451. }
  452.    else
  453. #endif
  454.        {
  455. if (bootFtp)
  456.     {
  457.     if (ftpXfer2 (hostName, usr, passwd, "", "RETR %s", "", fileName,
  458.          &errFd, &fd) == ERROR)
  459. goto fail;
  460.     }
  461. else
  462.     {
  463.     bootRsh = TRUE;
  464.     sprintf (command, "cat %s", fileName);
  465.     fd = rcmd (hostName, RSHD, usr, usr, command, &errFd);
  466.     if (fd == ERROR)
  467. goto fail;
  468.     }
  469. }
  470.     if ((fp = fdopen(fd, "r")) == 0) {
  471. printf("nCould not open fdn");
  472. goto readErr;
  473.     }
  474.     if (sRecords) {
  475. if ((i = srecLoad(fp, flashBuf, FLASH_BUF_SIZE, &entry)) < 0) {
  476.     printf("nError reading file: %sn", srecErrmsg(i));
  477.     goto readErr;
  478. }
  479.     } else if ((i = fread(flashBuf, 1, 512 * 1024, fp)) != 512 * 1024) {
  480. printf("nFailed reading 512 kB from binary file %sn",
  481.        fileName);
  482. goto readErr;
  483.     }
  484.     printf("%dn", i);
  485. #ifdef MBZ
  486.     for(i = 0; i < FLASH_BUF_SIZE; i += 4) {
  487.         tmpc = flashBuf[i];
  488.         flashBuf[i] = flashBuf[i + 3];
  489.         flashBuf[i + 3] = tmpc;
  490.         tmpc = flashBuf[i + 1];
  491.         flashBuf[i + 1] = flashBuf[i + 2];
  492.         flashBuf[i + 2] = tmpc;
  493.     }
  494. #endif
  495.     if (bootRsh == FALSE)
  496. {
  497. /* Empty the Data Socket before close. PC FTP server hangs otherwise */
  498. while ((read (fd, command, sizeof (command))) > 0);
  499. /* Close the data connection -- fixes timeout hang with wu-ftp */
  500. close(fd); 
  501. if (bootFtp)
  502.     {
  503.     if (ftpReplyGet(errFd, TRUE) != FTP_COMPLETE)
  504. printErr("No FTP completion replyn");
  505.     (void) ftpCommand (errFd, "QUIT",0,0,0,0,0,0);
  506.     }
  507. }
  508.     fclose (fp); /* closes fd */
  509.     close (errFd);
  510.     printf("%dnErasing boot area ...", i);
  511.     for (i = FLASH_BOOT_START_SECTOR;
  512.  i < FLASH_BOOT_START_SECTOR + FLASH_BOOT_SIZE_SECTORS;
  513.  i++) {
  514. if (flashEraseBank(i,1) != OK) {
  515.     printf("nflashBoot: failed erasing -- PROM DESTROYEDn");
  516.     return ERROR;
  517. }
  518. printf(".");
  519.     }
  520.     printf("donenWriting boot data ...");
  521.     if (flashBlkWrite(FLASH_BOOT_START_SECTOR, flashBuf, 0, 512*1024) != OK) {
  522. printf("nflashBoot: failed writing -- PROM DESTROYEDn");
  523. return ERROR;
  524.     }
  525.     printf("donen");
  526.     free(flashBuf);
  527.     return (OK);
  528. readErr:
  529.     /* check standard error on Unix */
  530.     if (bootRsh == FALSE)
  531. {
  532. /* Empty the Data Socket before close. PC FTP server hangs otherwise */
  533. while ((read (fd, command, sizeof (command))) > 0);
  534. /* Close the data connection -- fixes timeout hang with wu-ftp */
  535. close(fd); 
  536. if (bootFtp)
  537.     {
  538.     (void) ftpReplyGet (errFd, FALSE); /* error message on std. err */
  539.     (void) ftpCommand (errFd, "QUIT",0,0,0,0,0,0);
  540.     }
  541. }
  542.     else
  543. {
  544. char buf [100];
  545. int errBytesRecv = fioRead (errFd, buf, sizeof (buf));
  546. if (errBytesRecv > 0)
  547.     {
  548.     /* print error message on standard error fd */
  549.     buf [errBytesRecv] = EOS;
  550.     printf ("n%s:%s: %sn", hostName, fileName, buf);
  551.     }
  552. }
  553.  fail:
  554.     if (fp)
  555. fclose(fp); /* closes fd */
  556.     else if (fd >= 0)
  557. close (fd);
  558.     if (errFd >= 0)
  559. close (errFd);
  560.     if (flashBuf)
  561. free(flashBuf);
  562.     return (ERROR);
  563. }
  564. #endif /* BROADCOM_BSP */
  565. /*******************************************************************************
  566. *
  567. * netLoad - downLoad a file from a remote machine via the network.
  568. *
  569. * The remote shell daemon on the machine 'host' is used to download
  570. * the given file to the specified previously opened network file descriptor.
  571. * The remote userId should have been set previously by a call to iam().
  572. * If the file does not exist, the error message from the Unix 'host'
  573. * is printed to the VxWorks standard error fd and ERROR is returned.
  574. *
  575. * RETURNS: OK or ERROR
  576. */
  577. LOCAL STATUS netLoad 
  578.     (
  579.     char *hostName,
  580.     char *fileName,
  581.     char *usr,
  582.     char *passwd,
  583.     FUNCPTR *pEntry
  584.     )
  585.     {
  586.     int fd;
  587.     int errFd; /* for receiving standard error messages from Unix */
  588.     char command [100];
  589.     BOOL bootFtp = (passwd[0] != EOS);
  590.     BOOL bootRsh = FALSE;
  591.     printf ("Loading... ");
  592. #ifdef INCLUDE_TFTP_CLIENT
  593.     if (sysFlags & SYSFLG_TFTP) /* use tftp to get image */
  594.         {
  595. if (tftpXfer (hostName, 0, fileName, "get", "binary", &fd,
  596.       &errFd) == ERROR)
  597.     return (ERROR);
  598. }
  599.    else
  600. #endif
  601.        {
  602. if (bootFtp)
  603.     {
  604. #ifdef BROADCOM_BSP
  605. #if 0
  606. printf("ftpXfer2: %s %s %s %sn",hostName, fileName, usr, passwd);
  607. #endif
  608.             if (ftpXfer2 (hostName, usr, passwd, "", "RETR %s", "", fileName,
  609.                          &errFd, &fd) == ERROR)
  610. #else
  611.     if (ftpXfer (hostName, usr, passwd, "", "RETR %s", "", fileName,
  612.          &errFd, &fd) == ERROR)
  613. #endif
  614. return (ERROR);
  615.     }
  616. else
  617.     {
  618.     bootRsh = TRUE;
  619.     sprintf (command, "cat %s", fileName);
  620.     fd = rcmd (hostName, RSHD, usr, usr, command, &errFd);
  621.     if (fd == ERROR)
  622. return (ERROR);
  623.     }
  624. }
  625. #ifdef BROADCOM_BSP
  626.     /* Support loading deflated files.  */
  627. #if 0
  628. {
  629.     int compSize, r;
  630. char compBuf;
  631.     while ((r = read(fd, /* Read loop required to support network */
  632.      &compBuf,
  633.      1 )) > 0)
  634. {
  635. if (compBuf == 'n') sysSerialPutc('r');
  636. sysSerialPutc(compBuf);
  637. }
  638. }
  639. #endif
  640.     if (DEFLATED_FILE(fileName)) {
  641.         if (bootLoadModuleInflate(fd, pEntry) != OK)
  642.             goto readErr;
  643.     } else {
  644.         if (bootLoadModule (fd, pEntry) != OK)
  645.             goto readErr;
  646.     }
  647. #else
  648.     if (bootLoadModule (fd, pEntry) != OK)
  649. goto readErr;
  650. #endif
  651. #ifdef INCLUDE_TFTP_CLIENT
  652.     /*
  653.      * Successful TFTP transfers don't need any cleanup. The tftpXfer()
  654.      * routine closes all file descriptors once the data has been
  655.      * retrieved from the remote host.
  656.      */
  657.     if (sysFlags & SYSFLG_TFTP) /* used tftp to get image - just exit */
  658.         return (OK);
  659. #endif
  660.     if (bootRsh == FALSE)
  661. {
  662. /* Empty the Data Socket before close. PC FTP server hangs otherwise */
  663. while ((read (fd, command, sizeof (command))) > 0);
  664. if (bootFtp)
  665.     (void) ftpCommand (errFd, "QUIT",0,0,0,0,0,0);
  666. }
  667.     close (fd);
  668.     close (errFd);
  669.     return (OK);
  670. readErr:
  671.     /* check standard error on Unix */
  672.     if (bootRsh == FALSE)
  673. {
  674. /* Empty the Data Socket before close. PC FTP server hangs otherwise */
  675. while ((read (fd, command, sizeof (command))) > 0);
  676. if (bootFtp)
  677.     {
  678.     (void) ftpReplyGet (errFd, FALSE); /* error message on std. err */
  679.     (void) ftpCommand (errFd, "QUIT",0,0,0,0,0,0);
  680.     }
  681. }
  682.     else
  683. {
  684. char buf [100];
  685. int errBytesRecv = fioRead (errFd, buf, sizeof (buf));
  686. if (errBytesRecv > 0)
  687.     {
  688.     /* print error message on standard error fd */
  689.     buf [errBytesRecv] = EOS;
  690.     printf ("n%s:%s: %sn", hostName, fileName, buf);
  691.     }
  692. }
  693.     close (fd);
  694.     close (errFd);
  695.     return (ERROR);
  696.     }
  697. #endif  /* INCLUDE_NETWORK */
  698. #if     (defined (INCLUDE_SCSI_BOOT) || defined (INCLUDE_FD) || 
  699.  defined (INCLUDE_IDE) || defined (INCLUDE_ATA) || 
  700.  defined (INCLUDE_TFFS))
  701. #define SPIN_UP_TIMEOUT 45 /* max # of seconds to wait for spinup */
  702. /******************************************************************************
  703. *
  704. * devSplit - split the device name from a full path name
  705. *
  706. * This routine returns the device name from a valid UNIX-style path name
  707. * by copying until two slashes ("/") are detected.  The device name is
  708. * copied into <devName>.
  709. *
  710. * RETURNS: N/A
  711. *
  712. * NOMANUAL
  713. */
  714. void devSplit 
  715.     (
  716.     FAST char *fullFileName, /* full file name being parsed */
  717.     FAST char *devName /* result device name */
  718.     )
  719.     {
  720.     FAST int nChars = 0;
  721.     if (fullFileName != NULL)
  722. {
  723. char *p0 = fullFileName;
  724. char *p1 = devName;
  725. while ((nChars < 2) && (*p0 != EOS))
  726.     {
  727.     if (*p0 == '/')
  728. nChars++;
  729.     *p1++ = *p0++;
  730.     }
  731. *p1 = EOS;
  732. }
  733.     else
  734. {
  735. (void) strcpy (devName, "");
  736. }
  737.     }
  738. #endif  /* (defined (INCLUDE_SCSI_BOOT) || (INCLUDE_FD) || (INCLUDE_IDE)) */
  739. #ifdef  INCLUDE_SCSI_BOOT
  740. /******************************************************************************
  741. *
  742. * scsiLoad - load a vxWorks image from a local SCSI disk
  743. *
  744. * RETURNS: OK, or ERROR if file can not be loaded.
  745. */
  746. LOCAL STATUS scsiLoad 
  747.     (
  748.     int     bootDevId,
  749.     int     bootDevLUN,
  750.     char    *fileName,
  751.     FUNCPTR *pEntry
  752.     )
  753.     {
  754.     int fd;
  755.     SCSI_PHYS_DEV *pScsiPhysBootDev;
  756.     BLK_DEV       *pScsiBlkBootDev;
  757.     char bootDir  [BOOT_FILE_LEN];
  758.     int           ix;
  759. #ifdef INCLUDE_SCSI2
  760.     SCSI_OPTIONS  options;
  761.     UINT          which;
  762. #endif /* INCLUDE_SCSI2 */
  763.     if (!scsiInitialized) /* skip if this is a retry */
  764. {
  765. if (sysScsiInit () == ERROR)
  766.     {
  767.     printErr ("Could not initialize SCSI.n");
  768.     return (ERROR);
  769.     }
  770. scsiInitialized = TRUE;
  771. }
  772.     taskDelay (sysClkRateGet ()); /* delay 1 second after reset */
  773.     if ((bootDevId  < SCSI_MIN_BUS_ID) ||
  774. (bootDevId  > SCSI_MAX_BUS_ID) ||
  775. (bootDevLUN < SCSI_MIN_LUN)    ||
  776. (bootDevLUN > SCSI_MAX_LUN))
  777. {
  778. printErr ("SCSI device parameters < busId = %d, lun = %d > ",
  779.   bootDevId, bootDevLUN);
  780. printErr ("are out of range (0-7).n");
  781. printErr ("Check boot device format:n");
  782. printErr ("    scsi=<busId>,<lun>  e.g.  scsi=2,0n");
  783. return (ERROR);
  784. }
  785. #ifdef INCLUDE_SCSI2
  786.     /* Set all devices to asynchronous data transfer */
  787.     which = SCSI_SET_OPT_XFER_PARAMS;
  788.     options.maxOffset = 0;
  789.     options.minPeriod = SCSI_SYNC_XFER_MIN_PERIOD;
  790.     scsiTargetOptionsSet (pSysScsiCtrl, bootDevId, &options, which);
  791. #endif /* INCLUDE_SCSI2 */
  792.     /* create device handle for TEST UNIT READY commands */
  793.     if ((pScsiPhysBootDev = scsiPhysDevCreate (pSysScsiCtrl, bootDevId,
  794.        bootDevLUN, 128, 0, 0,
  795.        0xffff, 512))
  796. == NULL)
  797. {
  798. printErr ("scsiPhysDevCreate failed.n");
  799. return (ERROR);
  800. }
  801.     /* issue a couple fo TEST UNIT READY commands to clear reset execption */
  802.     scsiTestUnitRdy (pScsiPhysBootDev);
  803.     scsiTestUnitRdy (pScsiPhysBootDev);
  804.     /* issue a TEST UNIT READY every second for SPIN_UP_TIMEOUT seconds,
  805.      * or until device returns OK status.
  806.      */
  807.     if (scsiTestUnitRdy (pScsiPhysBootDev) != OK)
  808.         {
  809.         printf ("Waiting for disk to spin up...");
  810.         for (ix = 0; ix < SPIN_UP_TIMEOUT; ix++)
  811.             {
  812.             if (scsiTestUnitRdy (pScsiPhysBootDev) == OK)
  813.                 {
  814.                 printf (" done.n");
  815.                 break;
  816. }
  817.             else
  818. {
  819.                 if (ix != (SPIN_UP_TIMEOUT - 1))
  820.                     printf (".");
  821.                 else
  822.                     {
  823.                     printf (" timed out.n");
  824.                     return (ERROR);
  825.     }
  826.                 taskDelay (sysClkRateGet ());
  827. }
  828.     }
  829. }
  830.     /* delete temporary device handle */
  831.     scsiPhysDevDelete (pScsiPhysBootDev);
  832.     printf ("Attaching to scsi device... ");
  833.     /* recreate a device handle, with polling for actual device parameters */
  834.     taskDelay (sysClkRateGet ());
  835.     if ((pScsiPhysBootDev = scsiPhysDevCreate (pSysScsiCtrl, bootDevId,
  836.                                                bootDevLUN, 0, -1, 0, 0, 0))
  837.          == NULL)
  838. {
  839.         printErr ("scsiPhysDevCreate failed.n");
  840.         return (ERROR);
  841.         }
  842.     /*-------------------------------------------------------------------------
  843.      *
  844.      * Configuration of an OMTI3500
  845.      *
  846.      *-----------------------------------------------------------------------*/
  847.     if ((strncmp (pScsiPhysBootDev->devVendorID, "SMS", 3) == 0) &&
  848. (strncmp (pScsiPhysBootDev->devProductID, "OMTI3500", 8) == 0))
  849. {
  850. char modeData [4]; /* array for floppy MODE SELECT data */
  851. /* zero modeData array, then set byte 1 to "medium code" (0x1b).
  852.  * NOTE: MODE SELECT data is highly device-specific.  If your device
  853.  * requires configuration via MODE SELECT, please consult the device's
  854.  * Programmer's Reference for the relevant data format.
  855.  */
  856. bzero (modeData, sizeof (modeData));
  857. modeData [1] = 0x1b;
  858. /* issue a MODE SELECT cmd to correctly configure floppy controller */
  859. scsiModeSelect (pScsiPhysBootDev, 1, 0, modeData, sizeof (modeData));
  860. /* delete and re-create the SCSI_PHYS_DEV so that INQUIRY will return
  861.  * the new device parameters, i.e., correct number of blocks
  862.  */
  863. scsiPhysDevDelete (pScsiPhysBootDev);
  864. /* recreate a device handle, polling for actual device parameters */
  865. if ((pScsiPhysBootDev = scsiPhysDevCreate (pSysScsiCtrl, bootDevId,
  866.    bootDevLUN, 0, -1, 0, 0, 0))
  867.     == NULL)
  868.     {
  869.     printErr ("scsiPhysDevCreate failed.n");
  870.     return (ERROR);
  871.     }
  872. }
  873.     /*-------------------------------------------------------------------------
  874.      *
  875.      * END of OMTI3500 configuration
  876.      *
  877.      *-----------------------------------------------------------------------*/
  878.     /*-------------------------------------------------------------------------
  879.      *
  880.      * START OF CODE WHICH ASSUMES A DOS-FS PARTITION BEGINNING AT BLOCK 0
  881.      *
  882.      *-----------------------------------------------------------------------*/
  883.     /* create a block device spanning entire disk (non-distructive!) */
  884.     if ((pScsiBlkBootDev = scsiBlkDevCreate (pScsiPhysBootDev, 0, 0)) == NULL)
  885. {
  886.         printErr ("scsiBlkDevCreate failed.n");
  887.         return (ERROR);
  888. }
  889.     dosFsInit (NUM_DOSFS_FILES);        /* initialize DOS-FS */
  890.     /* split off boot device from boot file */
  891.     devSplit (fileName, bootDir);
  892.     /* initialize the boot block device as a dosFs device named <bootDir> */
  893.     if (dosFsDevInit (bootDir, pScsiBlkBootDev, NULL) == NULL)
  894. {
  895.         printErr ("dosFsDevInit failed.n");
  896.         return (ERROR);
  897. }
  898.     /*-------------------------------------------------------------------------
  899.      *
  900.      * END OF CODE WHICH ASSUMES A DOS-FS PARTITION BEGINNING AT BLOCK 0
  901.      *
  902.      *------------------------------------------------------------------------*/
  903.     printErr ("done.n");
  904.     /* load the boot file */
  905.     printErr ("Loading %s...", fileName);
  906.     fd = open (fileName, O_RDONLY, 0);
  907.     if (fd == ERROR)
  908. {
  909.         printErr ("nCannot open "%s".n", fileName);
  910.         return (ERROR);
  911. }
  912.     if (bootLoadModule (fd, pEntry) != OK)
  913.         goto readErr;
  914.     close (fd);
  915.     return (OK);
  916. readErr:
  917.     printErr ("nerror loading file: status = 0x%x.n", errnoGet ());
  918.     close (fd);
  919.     return (ERROR);
  920.     }
  921. #endif /* INCLUDE_SCSI_BOOT */
  922. #ifdef INCLUDE_FD
  923. #include "../../src/config/usrFd.c"
  924. /******************************************************************************
  925. *
  926. * fdLoad - load a vxWorks image from a local floppy disk
  927. *
  928. * RETURNS: OK, or ERROR if file can not be loaded.
  929. */
  930. LOCAL STATUS fdLoad 
  931.     (
  932.     int     drive,
  933.     int     type,
  934.     char    *fileName,
  935.     FUNCPTR *pEntry
  936.     )
  937.     {
  938.     int fd;
  939.     if (fdDrv (FD_INT_VEC, FD_INT_LVL) != OK)
  940. {
  941. printErr ("Could not initialize.n");
  942. return (ERROR);
  943. }
  944.     printf ("Attaching to floppy disk device... ");
  945.     dosFsInit (NUM_DOSFS_FILES);        /* initialize DOS-FS */
  946.     if (usrFdConfig (drive, type, fileName) == ERROR)
  947. {
  948.         printErr ("usrFdConfig failed.n");
  949.         return (ERROR);
  950. }
  951.     printErr ("done.n");
  952.     /* load the boot file */
  953.     printErr ("Loading %s...", fileName);
  954.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  955. {
  956.         printErr ("nCannot open "%s".n", fileName);
  957.         return (ERROR);
  958. }
  959.     if (bootLoadModule (fd, pEntry) != OK)
  960.         goto fdLoadErr;
  961.     close (fd);
  962.     return (OK);
  963. fdLoadErr:
  964.     printErr ("nerror loading file: status = 0x%x.n", errnoGet ());
  965.     close (fd);
  966.     return (ERROR);
  967.     }
  968. #endif /* INCLUDE_FD */
  969. #ifdef INCLUDE_IDE
  970. #define IDE_MEM_DOSFS 0x200000
  971. #include "../../src/config/usrIde.c"
  972. /******************************************************************************
  973. *
  974. * ideLoad - load a vxWorks image from a local IDE disk
  975. *
  976. * RETURNS: OK, or ERROR if file can not be loaded.
  977. */
  978. LOCAL STATUS ideLoad 
  979.     (
  980.     int     drive,
  981.     int     type,
  982.     char    *fileName,
  983.     FUNCPTR *pEntry
  984.     )
  985.     {
  986.     int fd;
  987.     if (ideDrv (IDE_INT_VEC, IDE_INT_LVL, type) == ERROR)
  988. {
  989. printErr ("Could not initialize.n");
  990. return (ERROR);
  991. }
  992.     printf ("Attaching to IDE disk device... ");
  993.     dosFsInit (NUM_DOSFS_FILES);        /* initialize DOS-FS */
  994.     if (usrIdeConfig (drive, fileName) == ERROR)
  995. {
  996.         printErr ("usrIdeConfig failed.n");
  997.         return (ERROR);
  998. }
  999.     printErr ("done.n");
  1000.     /* load the boot file */
  1001.     printErr ("Loading %s...", fileName);
  1002.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  1003. {
  1004.         printErr ("nCannot open "%s".n", fileName);
  1005.         return (ERROR);
  1006. }
  1007.     if (bootLoadModule (fd, pEntry) != OK)
  1008.         goto ideLoadErr;
  1009.     close (fd);
  1010.     return (OK);
  1011. ideLoadErr:
  1012.     printErr ("nerror loading file: status = 0x%x.n", errno);
  1013.     close (fd);
  1014.     return (ERROR);
  1015.     }
  1016. #endif /* INCLUDE_IDE */
  1017. #ifdef INCLUDE_ATA
  1018. #define ATA_MEM_DOSFS 0x200000
  1019. #include "../../src/config/usrAta.c"
  1020. /******************************************************************************
  1021. *
  1022. * ataLoad - load a vxWorks image from a local ATA disk
  1023. *
  1024. * RETURNS: OK, or ERROR if file can not be loaded.
  1025. */
  1026. LOCAL STATUS ataLoad 
  1027.     (
  1028.     int     ctrl,
  1029.     int     drive,
  1030.     char    *fileName,
  1031.     FUNCPTR *pEntry
  1032.     )
  1033.     {
  1034.     IMPORT ATA_RESOURCE ataResources[];
  1035.     ATA_RESOURCE *pAtaResource = &ataResources[ctrl];
  1036.     int fd;
  1037.     if (ataDrv (ctrl, pAtaResource->drives, pAtaResource->intVector,
  1038. pAtaResource->intLevel, pAtaResource->configType,
  1039. pAtaResource->semTimeout, pAtaResource->wdgTimeout) == ERROR)
  1040. {
  1041. printErr ("Could not initialize.n");
  1042. return (ERROR);
  1043. }
  1044.     printf ("Attaching to ATA disk device... ");
  1045.     dosFsInit (NUM_DOSFS_FILES);        /* initialize DOS-FS */
  1046.     if (usrAtaConfig (ctrl, drive, fileName) == ERROR)
  1047. {
  1048.         printErr ("usrAtaConfig failed.n");
  1049.         return (ERROR);
  1050. }
  1051.     printErr ("done.n");
  1052.     /* load the boot file */
  1053.     printErr ("Loading %s...", fileName);
  1054.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  1055. {
  1056.         printErr ("nCannot open "%s".n", fileName);
  1057.         return (ERROR);
  1058. }
  1059.     if (bootLoadModule (fd, pEntry) != OK)
  1060.         goto ataLoadErr;
  1061.     close (fd);
  1062.     return (OK);
  1063. ataLoadErr:
  1064.     printErr ("nerror loading file: status = 0x%x.n", errno);
  1065.     close (fd);
  1066.     return (ERROR);
  1067.     }
  1068. #endif /* INCLUDE_ATA */
  1069. #ifdef INCLUDE_PCMCIA
  1070. #define PCMCIA_MEM_DOSFS 0x200000
  1071. #include "../../src/config/usrPcmcia.c"
  1072. /******************************************************************************
  1073. *
  1074. * pcmciaLoad - load a vxWorks image from a PCMCIA disk device
  1075. *
  1076. * RETURNS: OK, or ERROR if file can not be loaded.
  1077. */
  1078. LOCAL STATUS pcmciaLoad 
  1079.     (
  1080.     int     sock,
  1081.     char    *fileName,
  1082.     FUNCPTR *pEntry
  1083.     )
  1084.     {
  1085.     int fd;
  1086.     printf ("Attaching to PCMCIA block device... ");
  1087.     dosFsInit (NUM_DOSFS_FILES);        /* initialize DOS-FS */
  1088.     if (usrPcmciaConfig (sock, fileName) != OK)
  1089.         return (ERROR);
  1090.     printErr ("done.n");
  1091.     /* load the boot file */
  1092.     printErr ("Loading %s...", fileName);
  1093.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  1094. {
  1095.         printErr ("nCannot open "%s".n", fileName);
  1096.         return (ERROR);
  1097. }
  1098.     if (bootLoadModule (fd, pEntry) != OK)
  1099.         goto pcmciaLoadErr;
  1100.     close (fd);
  1101.     return (OK);
  1102. pcmciaLoadErr:
  1103.     printErr ("nerror loading file: status = 0x%x.n", errno);
  1104.     close (fd);
  1105.     return (ERROR);
  1106.     }
  1107. #endif /* INCLUDE_PCMCIA */
  1108. #ifdef INCLUDE_TFFS
  1109. #ifndef BROADCOM_BSP
  1110. #define TFFS_MEM_DOSFS 0x200000
  1111. #include "../../src/config/usrTffs.c"
  1112. #endif
  1113. /******************************************************************************
  1114. *
  1115. * tffsLoad - load a vxWorks image from a TFFS Flash disk
  1116. *
  1117. * RETURNS: OK, or ERROR if file can not be loaded.
  1118. *
  1119. * NOMANUAL
  1120. */
  1121. LOCAL STATUS tffsLoad 
  1122.     (
  1123.     int     drive, /* TFFS drive number (0 - (noOfDrives-1)) */
  1124.     int     removable, /* 0 - nonremovable flash media */
  1125.     char    * fileName, /* file name to download */
  1126.     FUNCPTR * pEntry
  1127.     )
  1128.     {
  1129.     int fd;
  1130. #ifndef BROADCOM_BSP
  1131.     if (tffsDrv () != OK)
  1132. {
  1133. printErr ("Could not initialize.n");
  1134. return (ERROR);
  1135. }
  1136. #endif
  1137.     printf ("Attaching to TFFS... ");
  1138.     dosFsInit (NUM_DOSFS_FILES);        /* initialize DOS-FS */
  1139. #ifdef BROADCOM_BSP
  1140.     tffsBCM47xxInit(0);
  1141. #else
  1142.     if (usrTffsConfig (drive, removable, fileName) == ERROR)
  1143. {
  1144.         printErr ("usrTffsConfig failed.n");
  1145.         return (ERROR);
  1146. }
  1147. #endif
  1148.     printErr ("done.n");
  1149.     /* load the boot file */
  1150.     printErr ("Loading %s...", fileName);
  1151.     if ((fd = open (fileName, O_RDONLY, 0)) == ERROR)
  1152. {
  1153.         printErr ("nCannot open "%s".n", fileName);
  1154.         return (ERROR);
  1155. }
  1156. #ifdef BROADCOM_BSP
  1157.     if (DEFLATED_FILE(fileName)) {
  1158.         if (bootLoadModuleInflate(fd, pEntry) != OK) {
  1159.             /* Error message already printed */
  1160.             close(fd);
  1161.             return ERROR;
  1162.         }
  1163.     } else {
  1164.         printErr("Loading %s ... ", fileName);
  1165.         if (bootLoadModule(fd, pEntry) != OK) 
  1166.             goto tffsLoadErr;
  1167.     }
  1168. #else
  1169.     if (bootLoadModule (fd, pEntry) != OK)
  1170.         goto tffsLoadErr;
  1171. #endif
  1172.     close (fd);
  1173.     return (OK);
  1174. tffsLoadErr:
  1175.     printErr ("nerror loading file: status = 0x%x.n", errnoGet ());
  1176.     close (fd);
  1177.     return (ERROR);
  1178.     }
  1179. #endif /* INCLUDE_TFFS */
  1180. #ifdef INCLUDE_TSFS_BOOT
  1181. /******************************************************************************
  1182. *
  1183. * tsfsLoad - load a vxWorks image from a Target Server File System (TSFS).
  1184. *
  1185. * RETURNS: OK, or ERROR if file can not be loaded.
  1186. *
  1187. * NOMANUAL
  1188. */
  1189. LOCAL STATUS tsfsLoad 
  1190.     (
  1191.     char    * fileName, /* file name to download */
  1192.     FUNCPTR * pEntry
  1193.     )
  1194.     {
  1195.     int fd;
  1196.     WDB_EVT_NODE rebootEventNode;
  1197.     char corefile [strlen (fileName) + 8];
  1198.     /* add a leading slash if the filename is a relatif path */
  1199.     if (fileName[0] != '/' && fileName[0] != '\')
  1200. sprintf (corefile, "/tgtsvr/%s", fileName);
  1201.     else
  1202. sprintf (corefile, "/tgtsvr%s", fileName);
  1203.     printf ("Booting using TSFS...nMake sure that your");
  1204.     printf (" Target Server is started with -R[oot] option.n");
  1205. #ifndef INCLUDE_TSFS_BOOT_VIO_CONSOLE
  1206.     printf ("Waiting for Target Server connection...");
  1207.     /* wait for Target Server connection */
  1208.     while (!wdbTargetIsConnected())
  1209.      taskDelay (sysClkRateGet());
  1210.     printf (" Done.n");
  1211. #endif /* INCLUDE_TSFS_BOOT_VIO_CONSOLE */
  1212.     /* open the core file via tsfs */
  1213.     printErr ("nLoading %s...n", corefile);
  1214.     if ((fd = open (corefile, O_RDONLY, 0)) == ERROR)
  1215. {
  1216.         printErr ("nCannot open "%s".n", corefile);
  1217.         return (ERROR);
  1218. }
  1219.     /* load the the core file */
  1220.     if (bootLoadModule (fd, pEntry) != OK)
  1221.         goto tsfsLoadErr;
  1222.     close (fd);
  1223. #if (WDB_COMM_TYPE != WDB_COMM_SERIAL)
  1224.     /* Notify the host of the target reboot */
  1225.     wdbEventNodeInit (&rebootEventNode, wdbRebootEventGet, NULL, NULL);
  1226.     wdbEventPost (&rebootEventNode);
  1227.     /* let some time to WDB to post the event */
  1228.     taskDelay (sysClkRateGet() / 10);
  1229. #endif /* WDB_COMM_TYPE != WDB_COMM_SERIAL */
  1230.     return (OK);
  1231. tsfsLoadErr:
  1232.     printErr ("nerror loading file: status = 0x%x.n", errnoGet ());
  1233.     close (fd);
  1234.     return (ERROR);
  1235.     }
  1236. /******************************************************************************
  1237. *
  1238. * wdbRebootEventGet - dummy eventGet routine to force the Target Server restart
  1239. *
  1240. * suspend the WDB task, so the Target Server will get a RPC_SYSTEMERROR
  1241. * will trying to get an event, so it will restart and try to re-attach to
  1242. * the target.
  1243. */
  1244. LOCAL void wdbRebootEventGet
  1245.     (
  1246.     void * pNode,
  1247.     WDB_EVT_DATA * pEvtData
  1248.     )
  1249.     {
  1250.     taskSuspend (0);
  1251.     }
  1252. #endif /* INCLUDE_TSFS_BOOT */
  1253. #ifdef  INCLUDE_NETWORK
  1254. /******************************************************************************
  1255. *
  1256. * netifAdrsPrint - print MAC address of a network interface
  1257. */
  1258. LOCAL void netifAdrsPrint 
  1259.     (
  1260.     char *ifname /* interface name */
  1261.     )
  1262.     {
  1263.     IMPORT struct ifnet *ifunit ();
  1264.     struct ifnet *ifp;
  1265.     char *buf;
  1266.     char  devName [10];
  1267.     int i, value;
  1268.     if (ifname == NULL || *ifname == EOS)
  1269. {
  1270. printf ("Interface not specifiedn");
  1271. return;
  1272. }
  1273.     while (*ifname == ' ')
  1274. ifname++;       /* skip leading blanks */
  1275.     if (*ifname == EOS)
  1276. {
  1277. printf ("Interface not specifiedn");
  1278. return;
  1279. }
  1280.     /* Search for unit number of network device. */
  1281.     i = 0;
  1282.     while (!isdigit((int)ifname[i]) && !isspace((int)ifname[i]) && ifname[i] != EOS)
  1283.        i++;
  1284.     if (ifname[i] == EOS)          /* No unit number given - use 0. */
  1285.        value = 0;
  1286.  
  1287.     buf = &ifname[i];
  1288.     if (bootScanNum (&buf, &value, FALSE) != OK)  /* No unit number - use 0. */
  1289.        value = 0;
  1290.     ifname[i] = EOS;
  1291.     sprintf (devName, "%s%d", ifname, value);
  1292.     if (strncmp (devName, "bp", 2) == 0)
  1293. {
  1294. /* address for backplane is just processor number */
  1295. printf ("Address for device "%s" == 00:00:00:00:00:%02xn",
  1296. devName,  sysProcNumGet ());
  1297. return;
  1298. }
  1299.     /* start the network */
  1300.     hostTblInit (); /* initialize host table */
  1301.     netLibInit ();
  1302.     if ((ifp = ifunit (devName)) == NULL)
  1303. {
  1304. if ((usrNetIfAttach (ifname, value, "0") != OK) ||
  1305.     (usrNetIfConfig (ifname, value, "0", (char *) NULL, 0) != OK))
  1306.     {
  1307.     printf ("Cannot initialize interface named "%s"n", devName);
  1308.     return;
  1309.     }
  1310. if ((ifp = ifunit (devName)) == NULL)
  1311.     {
  1312.     printf ("Device named "%s" doesn't exist.n", devName);
  1313.     return;
  1314.     }
  1315. }
  1316.     if (!(ifp->if_flags & IFF_POINTOPOINT) &&
  1317. !(ifp->if_flags & IFF_LOOPBACK))
  1318. {
  1319.         printf ("Address for device "%s" == %02x:%02x:%02x:%02x:%02x:%02xn",
  1320. devName,
  1321. ((struct arpcom *)ifp)->ac_enaddr [0],
  1322. ((struct arpcom *)ifp)->ac_enaddr [1],
  1323. ((struct arpcom *)ifp)->ac_enaddr [2],
  1324. ((struct arpcom *)ifp)->ac_enaddr [3],
  1325. ((struct arpcom *)ifp)->ac_enaddr [4],
  1326. ((struct arpcom *)ifp)->ac_enaddr [5]);
  1327. }
  1328.     if_dettach (ifunit (devName)); /* dettach interface for fresh start */
  1329.     }
  1330. #endif  /* INCLUDE_NETWORK */
  1331. /*******************************************************************************
  1332. *
  1333. * go - start at specified address
  1334. */
  1335. LOCAL void go 
  1336.     (
  1337.     FUNCPTR entry
  1338.     )
  1339.     {
  1340.     printf ("Starting at 0x%x...nn", (int) entry);
  1341.     taskDelay (sysClkRateGet ()); /* give the network a moment to close */
  1342. #ifdef  INCLUDE_NETWORK
  1343.     ifreset (); /* reset network to avoid interrupts */
  1344. #ifdef INCLUDE_END
  1345.    
  1346.     /* Stop all ENDs to restore to known state for interrupts and DMA */
  1347.     (void) muxDevStopAll (0);      
  1348. #endif  /* INCLUDE_END */
  1349. #endif  /* INCLUDE_NETWORK */
  1350. #if (CPU_FAMILY == PPC)
  1351.     cacheTextUpdate ((void *) (LOCAL_MEM_LOCAL_ADRS), /* cache coherency */
  1352.      (size_t) (sysMemTop() - LOCAL_MEM_LOCAL_ADRS));
  1353. #else
  1354. #ifdef INCLUDE_CACHE_SUPPORT
  1355.     cacheClear (DATA_CACHE, NULL, ENTIRE_CACHE); /* push cache to mem */
  1356. #endif /* INCLUDE_CACHE_SUPPORT */
  1357. #endif /* (CPU_FAMILY == PPC) */
  1358. #if (CPU_FAMILY == I80X86)
  1359.     sysClkDisable (); /* no clock interrupts are necessary */
  1360. #endif /* (CPU_FAMILY == I80X86) */
  1361.     (entry) (); /* go to entry point - never to return */
  1362.     }
  1363. /*******************************************************************************
  1364. *
  1365. * m - modify memory
  1366. *
  1367. * This routine prompts the user for modifications to memory, starting at the
  1368. * specified address.  It prints each address, and the current contents of
  1369. * that address, in turn.  The user can respond in one of several ways:
  1370. *
  1371. * RETURN   - No change to that address, but continue
  1372. *    prompting at next address.
  1373. * <number> - Set the contents to <number>.
  1374. * . (dot)  - No change to that address, and quit.
  1375. * <EOF>  - No change to that address, and quit.
  1376. *
  1377. * All numbers entered and displayed are in hexadecimal.
  1378. * Memory is treated as 16-bit words.
  1379. */
  1380. LOCAL void m 
  1381.     (
  1382.     char *adrs /* address to change */
  1383.     )
  1384.     {
  1385.     char line [MAX_LINE + 1]; /* leave room for EOS */
  1386.     char *pLine; /* ptr to current position in line */
  1387.     int value; /* value found in line */
  1388.     char excess;
  1389.     /* round down to word boundary */
  1390.     for (adrs = (char *) ((int) adrs & 0xfffffffe); /* start on even addr */
  1391.          ; /* FOREVER */
  1392.  adrs = (char *) (((short *) adrs) + 1)) /* bump as short ptr */
  1393. {
  1394. /* prompt for substitution */
  1395. printf ("%06x:  %04x-", (int) adrs, (*(short *)adrs) & 0x0000ffff);
  1396. /* get substitution value:
  1397.  *   skip empty lines (CR only);
  1398.  *   quit on end of file or invalid input;
  1399.  *   otherwise put specified value at address */
  1400. if (fioRdString (STD_IN, line, MAX_LINE) == EOF)
  1401.     break;
  1402. line [MAX_LINE] = EOS; /* make sure input line has EOS */
  1403. /* skip leading spaces*/
  1404. for (pLine = line; isspace ((UINT) * pLine); ++pLine)
  1405.     ;
  1406. if (*pLine == EOS) /* skip field if just CR */
  1407.     continue;
  1408. if (sscanf (pLine, "%x%1s", &value, &excess) != 1)
  1409.     break; /* quit if not number */
  1410. * (short *) adrs = value; /* assign new value */
  1411. }
  1412.     printf ("n");
  1413.     }
  1414. /*******************************************************************************
  1415. *
  1416. * d - display memory
  1417. *
  1418. * Display contents of memory, starting at adrs.  Memory is displayed in
  1419. * words.  The number of words displayed defaults to 64.  If
  1420. * nwords is non-zero, that number of words is printed, rounded up to
  1421. * the nearest number of full lines.  That number then becomes the default.
  1422. */
  1423. LOCAL void d 
  1424.     (
  1425.     FAST char *adrs, /* address to display */
  1426.     int        nwords /* number of words to print. */
  1427.     ) /* If 0, print 64 or last specified. */
  1428.     {
  1429.     static char *last_adrs;
  1430.     static int dNbytes = 128;
  1431.     char ascii [17];
  1432.     FAST int nbytes;
  1433.     FAST int byte;
  1434.     ascii [16] = EOS; /* put an EOS on the string */
  1435.     nbytes = 2 * nwords;
  1436.     if (nbytes == 0)
  1437. nbytes = dNbytes; /* no count specified: use current byte count */
  1438.     else
  1439. dNbytes = nbytes; /* change current byte count */
  1440.     if (adrs == 0)
  1441. adrs = last_adrs; /* no address specified: use last address */
  1442.     adrs = (char *) ((int) adrs & ~1); /* round adrs down to word boundary */
  1443.     /* print leading spaces on first line */
  1444.     bfill ((char *) ascii, 16, '.');
  1445.     printf ("%06x:  ", (int) adrs & ~0xf);
  1446.     for (byte = 0; byte < ((int) adrs & 0xf); byte++)
  1447. {
  1448. printf ("  ");
  1449. if (byte & 1)
  1450.     printf (" "); /* space between words */
  1451. if (byte == 7)
  1452.     printf (" "); /* extra space between words 3 and 4 */
  1453. ascii [byte] = ' ';
  1454. }
  1455.     /* print out all the words */
  1456.     while (nbytes-- > 0)
  1457. {
  1458. if (byte == 16)
  1459.     {
  1460.     /* end of line:
  1461.      *   print out ascii format values and address of next line */
  1462.     printf ("  *%16s*n%06x:  ", ascii, (int) adrs);
  1463.     bfill ((char *) ascii, 16, '.'); /* clear out ascii buffer */
  1464.     byte = 0; /* reset word count */
  1465.     }
  1466. printf ("%02x", *adrs & 0x000000ff);
  1467. if (byte & 1)
  1468.     printf (" "); /* space between words */
  1469. if (byte == 7)
  1470.     printf (" "); /* extra space between words 3 and 4 */
  1471. if (* adrs == ' ' ||
  1472. (isascii ((UINT) * adrs) && isprint ((UINT) * adrs)))
  1473.     ascii [byte] = (UINT) * adrs;
  1474. adrs++;
  1475. byte++;
  1476. }
  1477.     /* print remainder of last line */
  1478.     for (; byte < 16; byte++)
  1479. {
  1480. printf ("  ");
  1481. if (byte & 1)
  1482.     printf (" "); /* space between words */
  1483. if (byte == 7)
  1484.     printf (" "); /* extra space between words 3 and 4 */
  1485. ascii [byte] = ' ';
  1486. }
  1487.     printf ("  *%16s*n", ascii); /* print out ascii format values */
  1488.     last_adrs = adrs;
  1489.     }
  1490. /*******************************************************************************
  1491. *
  1492. * bootExcHandler - bootrom exception handling routine
  1493. */
  1494. LOCAL void bootExcHandler 
  1495.     (
  1496.     int tid /* task ID */
  1497.     )
  1498.     {
  1499.     REG_SET regSet;       /* task's registers */
  1500.     /* get registers of task to be traced */
  1501.     if (taskRegsGet (tid, &regSet) != ERROR)
  1502.         {
  1503.         trcStack (&regSet, (FUNCPTR) NULL, tid);
  1504.         taskRegsShow (tid);
  1505.         }
  1506.     else
  1507.         printf ("bootExcHandler: exception caught but no valid task.n");
  1508.     taskDelay (sysClkRateGet ());       /* pause a second */
  1509.     reboot (BOOT_NO_AUTOBOOT);
  1510.     }
  1511. /*******************************************************************************
  1512. *
  1513. * skipSpace - advance pointer past white space
  1514. *
  1515. * Increments the string pointer passed as a parameter to the next
  1516. * non-white-space character in the string.
  1517. */
  1518. LOCAL void skipSpace 
  1519.     (
  1520.     FAST char **strptr /* pointer to pointer to string */
  1521.     )
  1522.     {
  1523.     while (isspace ((UINT) ** strptr))
  1524. ++ * strptr;
  1525.     }
  1526. /*******************************************************************************
  1527. *
  1528. * printExcMsg - print exception message
  1529. *
  1530. * Avoid printing possible control characters in exception message area.
  1531. */
  1532. LOCAL void printExcMsg 
  1533.     (
  1534.     char *string
  1535.     )
  1536.     {
  1537.     printf ("n");
  1538.     while (isascii ((UINT) * string) && (isprint ((UINT) * string) ||
  1539. isspace ((UINT) * string)))
  1540. printf ("%c", * string++);
  1541.     printf ("n");
  1542.     }
  1543. /******************************************************************************
  1544. *
  1545. * getArg - get argument from command line
  1546. *
  1547. * This routine gets the next numerical argument from the command line.
  1548. * If the argument is not optional, then an error is reported if no argument
  1549. * is found.  <ppString> will be updated to point to the new position in the
  1550. * command line.
  1551. *
  1552. * RETURNS: OK or ERROR
  1553. */
  1554. LOCAL STATUS getArg 
  1555.     (
  1556.     FAST char **ppString, /* ptr to ptr to current position in line */
  1557.     int * pValue, /* ptr where to return value */
  1558.     BOOL defaultHex, /* TRUE = arg is hex (even w/o 0x) */
  1559.     BOOL optional /* TRUE = ok if end of line */
  1560.     )
  1561.     {
  1562.     skipSpace (ppString);
  1563.     /* if nothing left, complain if arg is not optional */
  1564.     if (**ppString == EOS)
  1565. {
  1566. if (!optional)
  1567.     {
  1568.     printf ("missing parametern");
  1569.     return (ERROR);
  1570.     }
  1571. else
  1572.     return (OK);
  1573. }
  1574.     /* scan arg */
  1575.     if (bootScanNum (ppString, pValue, defaultHex) != OK)
  1576. {
  1577. printf ("invalid parametern");
  1578. return (ERROR);
  1579. }
  1580.     skipSpace (ppString);
  1581.     /* if we encountered ',' delimiter, step over it */
  1582.     if (**ppString == ',')
  1583. {
  1584. ++*ppString;
  1585. return (OK);
  1586. }
  1587.     /* if end of line, scan is ok */
  1588.     if (**ppString == EOS)
  1589. return (OK);
  1590.     /* we got stopped by something else */
  1591.     printf ("invalid parametern");
  1592.     return (ERROR);
  1593.     }
  1594. /* The following routines are common to bootConfig and usrConfig and will
  1595.  * eventually be merged
  1596.  */
  1597. /******************************************************************************
  1598. *
  1599. * usrBootLineInit - initialize system boot line
  1600. *
  1601. * Initializes system boot line as per specified start type.
  1602. * If this is a COLD boot, i.e., with CLEAR option to clear memory,
  1603. * then the boot line is initialized from non-volatile RAM, if any,
  1604. * otherwise from the compiled in default boot line.
  1605. */
  1606. LOCAL void usrBootLineInit 
  1607.     (
  1608.     int startType
  1609.     )
  1610.     {
  1611.     if (startType & BOOT_CLEAR)
  1612. {
  1613. /* this is a cold boot so get the default boot line */
  1614. if ((sysNvRamGet (BOOT_LINE_ADRS, 
  1615.                           BOOT_LINE_SIZE, 
  1616.                           bootActiveStringNVOFF()) == ERROR) ||
  1617.     (*BOOT_LINE_ADRS == EOS))
  1618.     {
  1619.     /* either no non-volatile RAM or empty boot line */
  1620.     strcpy (BOOT_LINE_ADRS, DEFAULT_BOOT_LINE);
  1621.     }
  1622. }
  1623.     }
  1624. /******************************************************************************
  1625. *
  1626. * usrBootLineCrack - interpret and verify boot line
  1627. *
  1628. * This routine interprets the specified boot line and checks the validity
  1629. * of certain parameters.  If there are errors, a diagnostic message is
  1630. * printed.
  1631. *
  1632. * RETURNS: OK or ERROR
  1633. */
  1634. LOCAL STATUS usrBootLineCrack 
  1635.     (
  1636.     char *  bootString,
  1637.     BOOT_PARAMS *pParams
  1638.     )
  1639.     {
  1640.     FAST char * pS;
  1641.     pS = bootStringToStruct (bootString, pParams);
  1642.     if (*pS != EOS)
  1643. {
  1644. bootParamsErrorPrint (bootString, pS);
  1645. return (ERROR);
  1646. }
  1647. #ifdef  INCLUDE_NETWORK
  1648.     /* check inet addresses */
  1649.     if ((checkInetAddrField (pParams->ead, TRUE) != OK) ||
  1650. (checkInetAddrField (pParams->bad, TRUE) != OK) ||
  1651. (checkInetAddrField (pParams->had, FALSE) != OK) ||
  1652. (checkInetAddrField (pParams->gad, FALSE) != OK))
  1653. {
  1654. return (ERROR);
  1655. }
  1656. #endif  /* INCLUDE_NETWORK */
  1657.     return (OK);
  1658.     }
  1659. #ifdef  INCLUDE_NETWORK
  1660. /******************************************************************************
  1661. *
  1662. * checkInetAddrField - check for valid inet address in boot field
  1663. */
  1664. LOCAL STATUS checkInetAddrField 
  1665.     (
  1666.     char *pInetAddr,
  1667.     BOOL subnetMaskOK
  1668.     )
  1669.     {
  1670.     char inetAddr [30];
  1671.     int netmask;
  1672.     /* 
  1673.      * The bzero() call corrects SPR 6326. The calls to bootNetmaskExtract()
  1674.      * and inet_addr() did not delimit the input string with a ''. When
  1675.      * inet_addr attempted to print the invalid address, the system would
  1676.      * crash or hang.
  1677.      */
  1678.     bzero (inetAddr, sizeof(inetAddr));
  1679.     if (*pInetAddr == EOS)
  1680. return (OK);
  1681.     strncpy (inetAddr, pInetAddr, sizeof (inetAddr) - 1);
  1682.     if (subnetMaskOK)
  1683. {
  1684. if (bootNetmaskExtract (inetAddr, &netmask) < 0)
  1685.     {
  1686.     printf ("Error: invalid netmask in boot field "%s".n", inetAddr);
  1687.     return (ERROR);
  1688.     }
  1689. }
  1690.     if (inet_addr (inetAddr) == (ULONG) ERROR)
  1691. {
  1692. printf ("Error: invalid inet address in boot field "%s".n",inetAddr);
  1693. return (ERROR);
  1694. }
  1695.     return (OK);
  1696.     }
  1697. /******************************************************************************
  1698. *
  1699. * usrNetIfAttach - attach a network interface
  1700. *
  1701. * This routine attaches the specified network interface.
  1702. *
  1703. * - interface is attached
  1704. * - interface name is constructed as "<devName><unitNum>"
  1705. *
  1706. * RETURNS: OK or ERROR
  1707. */
  1708. LOCAL STATUS usrNetIfAttach 
  1709.     (
  1710.     char *devName,
  1711.     int  unitNum,
  1712.     char *inetAdrs
  1713.     )
  1714.     {
  1715.     FAST NETIF * pNif;
  1716.     STATUS  status;
  1717.     char                buf [BOOT_DEV_LEN];     /* network device */
  1718. #ifdef  INCLUDE_PCMCIA
  1719.     int sock;
  1720.     if (strncmp (devName, "pcmcia", 6) == 0)
  1721. {
  1722. if (strlen (devName) == 6)
  1723.     return (ERROR);
  1724. else
  1725.     sscanf (devName, "%*6s%*c%d", &sock);
  1726. *(devName + 6) = '';
  1727. }
  1728. #endif  /* INCLUDE_PCMCIA */
  1729.     /* find interface in table */
  1730.     sprintf(buf, "%s%d", devName, unitNum);
  1731.     for (pNif = netIf; pNif->ifName != 0; pNif++)
  1732. {
  1733. if (strcmp (buf, pNif->ifName) == 0)
  1734.     break;
  1735. }
  1736.     /*
  1737.      * For backward compatibility, the device name only is acceptable for
  1738.      * unit numbers of 0.
  1739.      */
  1740.     if (pNif->ifName == 0 && unitNum == 0)
  1741.         {
  1742.         for (pNif = netIf; pNif->ifName != 0; pNif++)
  1743.             {
  1744.             if (strcmp (devName, pNif->ifName) == 0)
  1745.                 break;
  1746.             }
  1747.         }
  1748.     if (pNif->ifName == 0)
  1749. {
  1750. printf ("Network interface %s unknown.n", devName);
  1751. return (ERROR);
  1752. }
  1753.     if (pNif->attachRtn == NULL)
  1754.         {
  1755. printf ("Network interface %s has no attach routine.n", devName);
  1756. return (OK);
  1757. }
  1758.     printf ("Attaching network interface %s... ", buf);
  1759. #ifdef INCLUDE_PCMCIA
  1760.     if (strncmp (devName, "pcmcia", 6) == 0)
  1761. pNif->arg1 = (char *)sock;
  1762. #endif /* INCLUDE_PCMCIA */
  1763. #if defined (TARGET_VIP10)
  1764.         /* SGI VIP10 boards are supposed to come with the ethernet address
  1765.          * in SGI formated non volatile ram.  We can not be sure where this
  1766.          * is so we default the upper 4 bytes of the address to SGI standard
  1767.          * and use the bottom two bytes of the internet address for the rest.
  1768.          */
  1769.         if (strcmp (devName, "lnsgi") == 0)
  1770.             {
  1771.             IMPORT char lnsgiEnetAddr [];      /* ethernet addr for lance */
  1772.             u_long inet = inet_addr (inetAdrs);
  1773.             lnsgiEnetAddr [4] = (inet >> 8) & 0xff;
  1774.             lnsgiEnetAddr [5] = inet & 0xff;
  1775.             }
  1776. #endif  /* TARGET_VIP10 */
  1777.     status = pNif->attachRtn (unitNum, pNif->arg1, pNif->arg2, pNif->arg3,
  1778.       pNif->arg4, pNif->arg5, pNif->arg6, pNif->arg7, 
  1779.                               pNif->arg8);
  1780.     if (status != OK)
  1781. {
  1782.         if (errno == S_iosLib_CONTROLLER_NOT_PRESENT)
  1783.             printf ("failed.nError: S_iosLib_CONTROLLER_NOT_PRESENT.n");
  1784.         else if (errno == S_iosLib_INVALID_ETHERNET_ADDRESS)
  1785.     printf ("failed: S_iosLib_INVALID_ETHERNET_ADDRESS, use N commandn");
  1786. else
  1787.     printf ("failed: errno = %#x.n", errno);
  1788. return (ERROR);
  1789. }
  1790.     printf ("done.n");
  1791.     return (OK);
  1792.     }
  1793. /******************************************************************************
  1794. *
  1795. * usrNetIfConfig - configure a network interface
  1796. * - subnetmask is extracted from inetAdrs and, if present,
  1797. *   set for interface
  1798. * - inet address is set for interface
  1799. * - if present, inet name for interface is added to host table
  1800. */
  1801. LOCAL STATUS usrNetIfConfig 
  1802.     (
  1803.     char * devName, /* device name */
  1804.     int         unitNum,                /* unit number */
  1805.     char * inetAdrs, /* inet address */
  1806.     char * inetName, /* host name */
  1807.     int  netmask /* subnet mask */
  1808.     )
  1809.     {
  1810.     char  ifname [20];
  1811. #ifdef INCLUDE_PCMCIA
  1812.     if (strncmp (devName, "pcmcia", 6) == 0)
  1813. devName = "pcmcia";
  1814. #endif /* INCLUDE_PCMCIA */
  1815.     /* check for empty inet address */
  1816.     if (inetAdrs[0] == EOS)
  1817. {
  1818. printf ("No inet address specified for interface %s.n", devName);
  1819. return (ERROR);
  1820. }
  1821.     /* build interface name */
  1822.     sprintf (ifname, "%s%d", devName, unitNum);
  1823.     /* set subnet mask, if any specified */
  1824.     if (netmask != 0)
  1825. ifMaskSet (ifname, netmask);
  1826.     /* set inet address */
  1827.     if (ifAddrSet (ifname, inetAdrs) != OK)
  1828.         {
  1829.         printf ("Error setting inet address of %s to %s, errno = %#xn",
  1830.                 ifname, inetAdrs, errno);
  1831.         return (ERROR);
  1832.         }
  1833.     /* add host name to host table */
  1834.     if ((inetName != NULL) && (*inetName != EOS))
  1835. hostAdd (inetName, inetAdrs);
  1836.     return (OK);
  1837.     }
  1838. /******************************************************************************
  1839. *
  1840. * usrBpInit - initialize backplane driver
  1841. *
  1842. * usrBpInit initializes the backplane driver shared memory region
  1843. * and sets up the backplane parameters to attach.
  1844. *
  1845. * RETURNS: OK if successful otherwise ERROR
  1846. */
  1847. LOCAL STATUS usrBpInit 
  1848.     (
  1849.     char * devName, /* device name */
  1850.     int         unitNum,        /* unit number */
  1851.     u_long startAddr /* inet address */
  1852.     )
  1853.     {
  1854. #ifdef INCLUDE_SM_NET
  1855.     char * bpAnchor; /* anchor address */
  1856.     FAST NETIF * pNif; /* netif struct */
  1857.     STATUS  status; /* status */
  1858.     int procNum; /* proc num */
  1859.     char                buf [BOOT_DEV_LEN];     /* network device */
  1860.     /*
  1861.      * Pick off optional "=<anchorAdrs>" from backplane
  1862.      * device.  Also truncates devName to just "bp" or "sm"
  1863.      */
  1864.     if ((strncmp (devName, "bp=", 3) == 0) ||
  1865.         (strncmp (devName, "sm=", 3) == 0))
  1866. {
  1867. if (bootBpAnchorExtract (devName, &bpAnchor) < 0)
  1868.     {
  1869.     printf ("Invalid anchor address specified: "%s"n", devName);
  1870.     return (ERROR);
  1871.     }
  1872. }
  1873.     else
  1874. bpAnchor = SM_ANCHOR_ADRS; /* default anchor */
  1875.     procNum = sysProcNumGet ();
  1876.     /* if we are master, initialize backplane net */
  1877.     if (procNum == 0)
  1878. {
  1879. printf ("Initializing backplane net with anchor at %#x... ",
  1880. (int) bpAnchor);
  1881. status = smNetInit ((SM_ANCHOR *) bpAnchor, (char *) SM_MEM_ADRS,
  1882.    (int) SM_MEM_SIZE, SM_TAS_TYPE, 0, 0, startAddr);
  1883. if (status == ERROR)
  1884.        {
  1885.     printf ("Error: backplane device %s not initializedn", devName);
  1886.     return (ERROR);
  1887.     }
  1888. printf ("done.n");
  1889. }
  1890.     /* Locate NETIF structure for backplane */
  1891.     sprintf(buf, "%s%d", devName, unitNum);
  1892.     for (pNif = netIf; pNif->ifName != 0; pNif++)
  1893.     {
  1894. if (strcmp (buf, pNif->ifName) == 0)
  1895.     break;
  1896. }
  1897.     /*
  1898.      * For backward compatibility, the device name only is acceptable for
  1899.      * unit numbers of 0.
  1900.      */
  1901.     if (pNif->ifName == 0 && unitNum == 0)
  1902.         {
  1903.         for (pNif = netIf; pNif->ifName != 0; pNif++)
  1904.             {
  1905.             if (strcmp (devName, pNif->ifName) == 0)
  1906.                 break;
  1907.             }
  1908.         }
  1909.     if (pNif->ifName == 0)
  1910. return (ERROR);
  1911.     printf ("Backplane anchor at %#x... ", (int) bpAnchor);
  1912.     /* configure backplane parameters (most set in NETIF struct) */
  1913.     pNif->arg1 = bpAnchor; /* anchor address */
  1914.     pNif->arg3 = SM_INT_NONE;
  1915.     pNif->arg4 = 0;
  1916.     pNif->arg5 = 0;
  1917.     pNif->arg6 = 0;
  1918.     return (OK);
  1919. #else /* INCLUDE_SM_NET */
  1920.     printf ("nError: backplane driver referenced but not included.n");
  1921.     return (ERROR);
  1922. #endif /* INCLUDE_SM_NET */
  1923.     }
  1924. /*******************************************************************************
  1925. *
  1926. * usrSlipInit - initialize the slip device
  1927. *
  1928. * RETURNS: OK if successful, otherwise ERROR.
  1929. */
  1930. LOCAL STATUS usrSlipInit 
  1931.     (
  1932.     char *pBootDev, /* boot device */
  1933.     int  unitNum,               /* unit number */
  1934.     char *localAddr, /* local address */
  1935.     char *peerAddr /* peer address */
  1936.     )
  1937.     {
  1938. #ifdef INCLUDE_SLIP
  1939.     char  slTyDev [20]; /* slip device */
  1940.     int netmask; /* netmask */
  1941. #ifndef SLIP_BAUDRATE
  1942. #define SLIP_BAUDRATE 0 /* uses previously selected baudrate */
  1943. #endif
  1944. #ifdef CSLIP_ENABLE
  1945. #undef CSLIP_ENABLE
  1946. #define CSLIP_ENABLE TRUE /* force CSLIP header compression */
  1947. #else /* CSLIP_ENABLE */
  1948. #undef CSLIP_ENABLE
  1949. #define CSLIP_ENABLE FALSE
  1950. #endif /* CSLIP_ENABLE */
  1951. #ifdef CSLIP_ALLOW
  1952. #undef CSLIP_ALLOW
  1953. #define CSLIP_ALLOW TRUE /* enable CSLIP compression on Rx */
  1954. #else /* CSLIP_ALLOW */
  1955. #undef CSLIP_ALLOW
  1956. #define CSLIP_ALLOW FALSE
  1957. #endif /* CSLIP_ALLOW */
  1958. #ifndef SLIP_MTU
  1959. #define SLIP_MTU 576
  1960. #endif
  1961.     if (pBootDev [2] == '=')
  1962. {
  1963. /* get the tty device used for SLIP interface e.g. "sl=/tyCo/1" */
  1964. strcpy (slTyDev, &pBootDev [3]);
  1965. pBootDev [2] = '';
  1966. }
  1967.     else
  1968. {
  1969. /* construct the default SLIP tty device */
  1970. sprintf (slTyDev, "%s%d", "/tyCo/", SLIP_TTY);
  1971. }
  1972.     printf ("Attaching network interface sl%d... ", unitNum);
  1973.     bootNetmaskExtract (localAddr, &netmask); /* remove and ignore mask */
  1974.     if (slipInit (unitNum, slTyDev, localAddr, peerAddr, SLIP_BAUDRATE,
  1975.         CSLIP_ENABLE, CSLIP_ALLOW, SLIP_MTU) == ERROR)
  1976. {
  1977. printf ("nslipInit failed 0x%xn", errno);
  1978. return (ERROR);
  1979. }
  1980.     printf ("done.n");
  1981.     return (OK);
  1982. #else /* INCLUDE_SLIP */
  1983.     printf ("nError: slip not included.n");
  1984.     return (ERROR);
  1985. #endif /* INCLUDE_SLIP */
  1986.     }
  1987. /*******************************************************************************
  1988. *
  1989. * usrPPPInit - initialize a ppp channel
  1990. *
  1991. * RETURNS: OK if successful, otherwise ERROR.
  1992. */
  1993. LOCAL STATUS usrPPPInit (pBootDev, unitNum, localAddr, peerAddr)
  1994.     char *      pBootDev;               /* boot device */
  1995.     int         unitNum;                /* unit number */
  1996.     char *      localAddr;              /* local address */
  1997.     char *      peerAddr;               /* peer address */
  1998.     {
  1999. #ifdef INCLUDE_PPP
  2000.     PPP_INFO    pppInfo;
  2001.     PPP_OPTIONS *pOptions = NULL;
  2002.     char        pppTyDev [20];          /* ppp device */
  2003. #ifdef PPP_BAUDRATE
  2004.     int pppBaudRate = PPP_BAUDRATE; /* ppp baud rate */
  2005. #else
  2006.     int pppBaudRate = 0; /* ppp baud rate */
  2007. #endif /* PPP_BAUDRATE */
  2008.     char * pBaudStr; /* ppp boot string */
  2009.     int         netmask;                /* netmask */
  2010.     int sysRate = sysClkRateGet();
  2011.     int ix;
  2012. #ifdef  PPP_OPTIONS_STRUCT  
  2013.     pOptions = &pppOptions;
  2014. #endif  /* PPP_OPTIONS_STRUCT */
  2015.      
  2016.     if ((pBaudStr = strpbrk (pBootDev, ",")) != NULL)
  2017.         {
  2018. *pBaudStr++ = '';
  2019. pppBaudRate = atoi (pBaudStr);
  2020. }
  2021.     if (pBootDev [3] == '=')
  2022.         {
  2023.         /* get the tty device used for PPP interface e.g. "ppp=/tyCo/1" */
  2024.         strcpy (pppTyDev, &pBootDev [4]);
  2025.         pBootDev [3] = '';
  2026.         }
  2027.     else 
  2028.         {
  2029.         /* construct the default PPP tty device */
  2030.         sprintf (pppTyDev, "%s%d", "/tyCo/", PPP_TTY);
  2031.         }
  2032.     printf ("Attaching network interface ppp%d...n", unitNum);
  2033.     bootNetmaskExtract (localAddr, &netmask); /* remove and ignore mask */
  2034.     if (pppInit (unitNum, pppTyDev, localAddr, peerAddr, pppBaudRate,
  2035.  pOptions, PPP_OPTIONS_FILE) == ERROR)
  2036.         {
  2037.         printf ("npppInit failed 0x%xn", errno);
  2038.         return (ERROR);
  2039.         }
  2040.     /* wait for PPP link to be established */
  2041.     for (ix = 0; ix < PPP_CONNECT_DELAY; ix++)
  2042. {
  2043. taskDelay (sysRate);
  2044.         if ((pppInfoGet (unitNum, &pppInfo) == OK) &&
  2045.     (pppInfo.ipcp_fsm.state == OPENED))
  2046.            break;
  2047. }
  2048.     if (ix == PPP_CONNECT_DELAY) 
  2049.         {
  2050.         pppDelete (unitNum);                   /* kill the interface */ 
  2051. printf ("ppp0: timeout: could not establish link with peer.n");
  2052. return (ERROR);
  2053. }
  2054.     printf ("done.n");
  2055.     return (OK);
  2056. #else /* INCLUDE_PPP */
  2057.     printf ("nError: ppp not included.n");
  2058.     return (ERROR);
  2059. #endif  /* INCLUDE_PPP */
  2060.     }
  2061. #if defined(INCLUDE_STREAMS) || defined(INCLUDE_STREAMS_ALL)
  2062. /*******************************************************************************
  2063. *
  2064. * usrStrmInit - Streams subsystem initialization
  2065. *
  2066. * This routine is called at system startup time to create the Streams task
  2067. * and install relevant Streams services.
  2068. *
  2069. * RETURNS: OK, or ERROR if the Streams initialization fails.
  2070. */
  2071.  
  2072. LOCAL STATUS usrStrmInit (void)
  2073.     {
  2074.     int strmMemSize = STREAMS_MEM_PART_SIZE;
  2075.     if ((strmMemSize == NULL) || (strmMemSize > STREAMS_MEM_MAX))
  2076.         strmMemSize = STREAMS_MEM_MAX;
  2077.  
  2078.     if (strmInit (strmMemSize,
  2079.                      STREAMS_MEM_PART_ADDR,
  2080.                      STREAMS_MSGSZ_MAX,
  2081.                      STREAMS_CTLSZ_MAX,
  2082.                      STREAMS_PUSH_MAX) == ERROR)
  2083.         {
  2084.         printf ("Streams initialization failuren");
  2085.         return (ERROR);
  2086.         }
  2087.  
  2088. #if defined(INCLUDE_STREAMS_SOCKET) || defined(INCLUDE_STREAMS_ALL)
  2089.     strmSockInit ();            /* initialize sockmod module */
  2090.     if (sockLibAdd ((FUNCPTR) strmSockLibInit, AF_INET_STREAMS, AF_INET) ==
  2091.         ERROR)
  2092.         return (ERROR);
  2093.  
  2094. #ifdef  DEFAULT_STREAMS_SOCKET
  2095.     if (sockLibAdd ((FUNCPTR) strmSockLibInit, AF_INET, AF_INET) == ERROR)
  2096.         return (ERROR);
  2097. #endif  /* DEFAULT_STREAMS_SOCKET */
  2098. #endif  /* INCLUDE_STREAMS_SOCKET */
  2099.  
  2100. #if defined(INCLUDE_STREAMS_TLI) || defined(INCLUDE_STREAMS_ALL)
  2101.     tliInit ();                 /* initialize timod and tirdwr modules */
  2102. #endif  /* INCLUDE_STREAMS_TLI */
  2103.  
  2104. #if defined(INCLUDE_STREAMS_AUTOPUSH) || defined(INCLUDE_STREAMS_ALL)
  2105.     autopushInit ();                 /* Include Autopush facility */
  2106. #endif  /* INCLUDE_STREAMS_AUTOPUSH */
  2107.  
  2108. #if defined(INCLUDE_STREAMS_DLPI) || defined(INCLUDE_STREAMS_ALL)
  2109.     dlpiInit ();                /* initialize the /dev/dlb devices */
  2110. #endif  /* INCLUDE_STREAMS_DLPI */
  2111.  
  2112. #if defined(INCLUDE_STREAMS_STRACE) || defined(INCLUDE_STREAMS_ALL)
  2113.     strmStraceInit (STREAMS_STRACE_OUTPUT_DIR);  /* init strace utility */
  2114. #endif  /* INCLUDE_STREAMS_STRACE */
  2115.  
  2116. #if defined(INCLUDE_STREAMS_STRERR) || defined(INCLUDE_STREAMS_ALL)
  2117.     strmStrerrInit (STREAMS_STRERR_OUTPUT_DIR);  /* init strerr utility */
  2118. #endif  /* INCLUDE_STREAMS_STRERR */
  2119.                      
  2120. #ifdef INCLUDE_STREAMS_DEBUG
  2121.     strmDebugInit ();           /* initialize the Streams debug facility */
  2122. #endif  /* INCLUDE_STREAMS_DEBUG */
  2123.  
  2124.     /* call user-provided protocol initialization hook routine */
  2125.  
  2126.     if ((strmProtoInitRtn != NULL) && ((*strmProtoInitRtn) () == ERROR))
  2127.         return (ERROR);
  2128.  
  2129.     return (OK);                /* Streams initialization complete */
  2130.     }
  2131. #endif /* INCLUDE_STREAMS */
  2132. /******************************************************************************
  2133. *
  2134. * bootpGet - get boot parameters via BOOTP.
  2135. *
  2136. * This routine retrieves a boot file name, host and target IP addresses, and 
  2137. * subnet mask from a BOOTP server, using the bootstrap protocol defined in
  2138. * RFC 1542. The IP address and subnet mask values will only be stored in the 
  2139. * boot parameters if not already specified. In order to use BOOTP, the boot 
  2140. * device indicated by <pNetDev> must be capable of sending broadcast messages. 
  2141. * Currently, only Ethernet devices and the shared-memory network drivers are 
  2142. * supported. To use the shared-memory drivers, the target IP address must 
  2143. * already be specified.
  2144. * .IP
  2145. * The routine is called when the SYSFLG_AUTOCONFIG boot flag is set and the 
  2146. * BOOTP client is included in the boot program. If the DHCP client is also
  2147. * included, that protocol is used instead.
  2148. *
  2149. * RETURNS: OK if successful, or ERROR otherwise.
  2150. *
  2151. * ERRNO: N/A
  2152. *
  2153. * SEE ALSO: bootpLib, RFC 1542, RFC 951
  2154. */
  2155. LOCAL STATUS bootpGet 
  2156.     (
  2157.     char *pNetDev, /* boot device */
  2158.     char *pBootDevAddr, /* device address */
  2159.     char *pBootFile, /* file name */
  2160.     char *pHostAddr, /* host address */
  2161.     int  *pMask  /* mask */
  2162.     )
  2163.     {
  2164. #ifndef INCLUDE_DHCPC
  2165. #ifdef INCLUDE_BOOTP
  2166.     struct bootpParams  bootParams;     /* parameter descriptor */
  2167.     struct in_addr  clntAddr;  /* client address */
  2168.     struct in_addr  hostAddr;  /* server address */
  2169.     int  subnetMask; /* subnet mask */
  2170.     char bootServer [INET_ADDR_LEN];/* boot server */
  2171.     subnetMask        = 0;
  2172.     bzero ( (char *)&clntAddr, sizeof (struct in_addr));
  2173.     bzero ( (char *)&hostAddr, sizeof (struct in_addr));
  2174.     bzero (bootServer, INET_ADDR_LEN);
  2175.     bzero ((char *)&bootParams, sizeof (struct bootpParams));
  2176.     /* Need inet address to boot over the backplane */
  2177.     if ( (strncmp (pNetDev, "bp", 2) == 0) || 
  2178.             (strncmp (pNetDev, "sm", 2) == 0))
  2179. {
  2180. if (pBootDevAddr [0] == EOS)
  2181.     return (ERROR);
  2182.         clntAddr.s_addr = inet_addr (pBootDevAddr);
  2183.         if (clntAddr.s_addr == (ULONG)ERROR)
  2184.             return (ERROR);
  2185. }
  2186.     /* Set pointers to retrieve needed boot parameters. */
  2187.     bootParams.clientAddr = &clntAddr;    /* pBootDevAddr */
  2188.     bootParams.bootHostAddr = &hostAddr;     /* pHostAddr */
  2189.     bootParams.bootfile = pBootFile;
  2190.     bootParams.netmask = (struct in_addr *)&subnetMask;
  2191.     printf ("Getting boot parameters via network interface %s", pNetDev);
  2192.     if (bootpParamsGet (pNetDev, 0, 0, &bootParams) == ERROR)
  2193.         return (ERROR);
  2194.     inet_ntoa_b (*bootParams.bootHostAddr, bootServer);
  2195.     printf ("nBootp Server:%sn", bootServer);
  2196.     if (pBootFile [0] == EOS)
  2197. return (ERROR); /* no bootfile */
  2198.     printf ("    Boot file: %sn", pBootFile);
  2199.     /* copies to params.had */
  2200.     if (pHostAddr [0] == EOS) /* fill in host address */
  2201. {
  2202. strncpy (pHostAddr, bootServer, INET_ADDR_LEN);
  2203. printf ("    Boot host: %sn", pHostAddr);
  2204. }
  2205.     /*
  2206.      * copies to pBootDevAddr (params.ead or params.bad) if not using bp or sm 
  2207.      * drivers and address is not already present.
  2208.      */
  2209.     if (pBootDevAddr [0] == EOS) /* fill in inet address */
  2210. {
  2211.         inet_ntoa_b (*bootParams.clientAddr, pBootDevAddr);
  2212. printf ("    Boot device Addr (%s): %sn", pNetDev, pBootDevAddr);
  2213. }
  2214.     /* copies to netmask */
  2215.     if ((*pMask == 0) && (subnetMask != 0))
  2216. {
  2217.         *pMask = ntohl (subnetMask);
  2218. printf ("    Subnet mask: 0x%xn", *pMask);
  2219. }
  2220.     return (OK);
  2221. #else
  2222.     printf ("automatic address assignment requested but not included.n");
  2223.     return (ERROR);
  2224. #endif
  2225. #else
  2226.     return (OK);            /* DHCP client used instead. */
  2227. #endif
  2228.     }
  2229. #ifdef INCLUDE_DHCPC
  2230. /******************************************************************************
  2231. *
  2232. * dhcpGet - get boot parameters with DHCP 
  2233. *
  2234. * This routine retrieves a boot file name, host and target IP addresses, and 
  2235. * subnet mask from a DHCP or BOOTP server, using the lease negotation process
  2236. * defined in RFC 1541. The IP address and subnet mask values will only be 
  2237. * stored in the boot parameters if not already specified. The DHCP client will 
  2238. * select the longest offered lease which exceeds the DHCPC_MIN_LEASE value. 
  2239. * Any DHCP lease will be given preference over BOOTP replies. Unless a 
  2240. * specific lease duration is provided in the target IP address entry, the 
  2241. * client requests the lease length defined by DHCPC_DEFAULT_LEASE. The client 
  2242. * will collect additional DHCP offers until the interval specified by 
  2243. * DHCPC_OFFER_TIMEOUT expires.
  2244. * .IP
  2245. * The <pNetDev> argument indicates the network device which will be used to
  2246. * send and receive DHCP messages. The DHCP client only supports devices
  2247. * attached to the IP protocol with the MUX/END interface. The MTU size of the
  2248. * network interface must be large enough to receive an IP datagram of 576
  2249. * bytes and the device also must be capable of sending broadcast messages.
  2250. * Finally, the target IP address must already be specified to use the
  2251. * shared-memory driver.
  2252. * .IP
  2253. * This routine executes when the SYSFLG_AUTOCONFIG boot flag is set and the
  2254. * DHCP client is included in the boot program, whether or not the BOOTP client
  2255. * is also available.
  2256. *
  2257. * NOTE
  2258. * The boot file to be loaded must also contain the DHCP client library in 
  2259. * order to continue using the assigned target IP address. In addition, the 
  2260. * DHCP server included with Windows NT does not supply boot file names. If 
  2261. * that server is used to supply the boot parameters, the boot file name must 
  2262. * be entered manually.
  2263. *
  2264. * RETURNS: OK if successful, or ERROR otherwise.
  2265. *
  2266. * ERRNO: N/A
  2267. *
  2268. * SEE ALSO: dhcpcBootLib, RFC 1541
  2269. */
  2270. LOCAL STATUS dhcpGet
  2271.     (
  2272.     char *  pNetDev,  /* boot device */
  2273.     char *  pBootDevAddr,  /* device IP address */
  2274.     char *  pBootFile,  /* boot file name */
  2275.     char *  pHostAddr,  /* host IP address */
  2276.     int *  pMask,  /* target subnet mask */
  2277.     DHCP_LEASE_DATA *  pDhcpLease  /* lease times and addresses */
  2278.     )
  2279.     {
  2280.     STATUS  result;
  2281.     struct ifnet *  pIf;  /* pointer to network interface data */
  2282.     char  serverAddr [INET_ADDR_LEN];   /* DHCP server address */
  2283.     char  bootFile [BOOT_FILE_LEN];  /* name of boot file */
  2284.     int  subnetMask;  /* subnet mask */
  2285.     void *              pCookie;
  2286.     struct dhcp_param  bootParams;
  2287.     bzero (serverAddr, INET_ADDR_LEN);
  2288.     bzero ( (char *)&bootParams, sizeof (struct dhcp_param));
  2289.  
  2290.     /* 
  2291.      * Using pBootFile directly only works if all the DHCP servers supply a 
  2292.      * bootfile. The Windows NT server does not, so we can't do this.  
  2293.      */
  2294.     /* bootParams.file = pBootFile;  - Desired assignment to save memory. */
  2295.     bootParams.file = bootFile;
  2296.     bootParams.subnet_mask = (struct in_addr *)&subnetMask;
  2297.     /* Need target IP address to boot over the backplane */
  2298.     if ( (strncmp (pNetDev, "bp", 2) == 0) || 
  2299.             (strncmp (pNetDev, "sm", 2) == 0))
  2300.         {
  2301.         if (pBootDevAddr [0] == EOS)
  2302.             return (ERROR);
  2303.         }
  2304.     pIf = ifunit (pNetDev);
  2305.     if (pIf == NULL)
  2306.         return (ERROR);
  2307.     printf ("Getting boot parameters via network interface %s.n", pNetDev);
  2308.     /* Setup client to retrieve address information from a DHCP server. */
  2309.     pCookie = dhcpcBootInit (pIf, DHCPC_SPORT, DHCPC_CPORT, DHCPC_MAX_MSGSIZE,
  2310.    DHCPC_OFFER_TIMEOUT,DHCPC_DEFAULT_LEASE,DHCPC_MIN_LEASE );
  2311.     if (pCookie == NULL)
  2312.         {
  2313.         printf ("Error initializing DHCP client.n");
  2314.         return (ERROR);
  2315.         }
  2316.     /* Set requested lease length to value from bootline. */
  2317.  
  2318.     dhcpcOptionAdd (pCookie, _DHCP_LEASE_TIME_TAG, sizeof (int),
  2319.                     (UCHAR *)&pDhcpLease->lease_duration);
  2320.     if (pBootDevAddr[0] == EOS)
  2321.         {
  2322.         /* Attempt to retrieve address information from a DHCP server. */
  2323.  
  2324.         result = dhcpcBootBind ();
  2325.         if (result != OK)
  2326.             return (ERROR);
  2327.         }
  2328.     else
  2329.         {
  2330.         /*
  2331.          * Externally configured address. Get any additional parameters.
  2332.          * Ignore any failure (since the network device can be configured)
  2333.          * as long as a boot file is available.
  2334.          */
  2335.  
  2336.         result = dhcpcBootInformGet (pBootDevAddr);
  2337.  
  2338.         if (result != OK)
  2339.             {
  2340.             if (pBootFile[0] == EOS)
  2341.                 return (ERROR);
  2342.             else
  2343.                 return (OK);
  2344.             }
  2345.         }
  2346.     result = dhcpcBootParamsGet (&bootParams);
  2347.     if (result == ERROR)
  2348.       return (ERROR);
  2349.     /* Fill in configuration parameters for storage in bootline. */
  2350.     if (pBootDevAddr[0] == EOS)
  2351.         {
  2352.         /*
  2353.          * If the DHCP process established a lease (which includes an IP
  2354.          * address assignment), get the assigned address and timestamp
  2355.          * values. This information is not available if an address is
  2356.          * assigned externally. (A DHCP inform message is sent in that case).
  2357.          */
  2358.  
  2359.         bcopy ( (char *)&bootParams.yiaddr, (char *)&pDhcpLease->yiaddr,
  2360.                sizeof (struct in_addr));
  2361.         pDhcpLease->lease_duration = bootParams.lease_duration;
  2362.         pDhcpLease->lease_origin = bootParams.lease_origin;
  2363.         }
  2364.     inet_ntoa_b (bootParams.server_id, serverAddr);
  2365.     printf ("nDHCP Server:%sn", serverAddr);
  2366.     if (pBootFile [0] == EOS && bootFile[0] == EOS)
  2367.         return (ERROR);                         /* no bootfile */
  2368.     if (bootFile[0] != EOS)                     /* Save new bootfile */
  2369.         {
  2370.         bcopy (bootFile, pBootFile, BOOT_FILE_LEN);
  2371.         printf ("    Boot file: %sn", pBootFile);
  2372.         }
  2373.     if (pHostAddr [0] == EOS)                   /* fill in host address */
  2374.         {
  2375.         inet_ntoa_b (bootParams.siaddr, pHostAddr);
  2376.         printf ("    Boot host: %sn", pHostAddr);
  2377.         }
  2378.     /* 
  2379.      * Fill in the target's IP address, if needed. The status 
  2380.      * variable indicates the source of the IP address as follows:
  2381.      *    DHCP_NATIVE - assigned by a DHCP server
  2382.      *    DHCP_BOOTP - issued by a BOOTP server
  2383.      *    DHCP_MANUAL - entered in boot parameters
  2384.      */
  2385.     if (pBootDevAddr [0] == EOS)                /* fill in inet address */
  2386.         {
  2387.         /*
  2388.          * Use the IP address from the DHCP protocol.
  2389.          * The status variable has already been set.
  2390.          */
  2391.         inet_ntoa_b (bootParams.yiaddr, pBootDevAddr);
  2392.         printf ("    Boot device Addr (%s): %sn", pNetDev, pBootDevAddr);
  2393.         }
  2394.     if ( (*pMask == 0) && (subnetMask != 0))
  2395.         {
  2396.         *pMask = ntohl (subnetMask);
  2397.         printf ("    Subnet mask: 0x%xn", *pMask);
  2398.         }
  2399.     return (OK);
  2400.     }
  2401. #endif             /* INCLUDE_DHCPC */
  2402. #ifdef ETHERNET_ADR_SET
  2403. /*******************************************************************************
  2404. *
  2405. * mEnet - modify the last three bytes of the ethernet address
  2406. *
  2407. * RETURNS: void
  2408. *
  2409. * NOMANUAL
  2410. */
  2411. void mEnet 
  2412.     (
  2413.     char *  pNum   /* Boot line, including unit number. */
  2414.     )
  2415.     {
  2416.     uchar_t byte [MAX_ADR_SIZE]; /* array to hold new Enet addr */
  2417.     uchar_t curArr [MAX_ADR_SIZE]; /* array to hold current Enet addr */
  2418.     char line [MAX_LINE + 1];
  2419.     char *pLine; /* ptr to current position in line */
  2420.     int value; /* value found in line */
  2421.     char excess;
  2422.     char *buf;
  2423.     int unitNum;
  2424.     int ix;
  2425.     /* Search for unit number of network device. */
  2426.     buf = pNum;
  2427.     if (bootScanNum (&buf, &unitNum, FALSE) != OK)  /* Use 0 if no unit #. */
  2428.        unitNum = 0;
  2429.     sysEnetAddrGet (unitNum, curArr);
  2430.     printf ("Current Ethernet Address is: ");
  2431. #if _BYTE_ORDER == _BIG_ENDIAN
  2432.     printf ("%02x:%02x:%02x:%02x:%02x:%02xn", curArr[5], 
  2433.     curArr[4], curArr[3], curArr[2], 
  2434.     curArr[1], curArr[0]);
  2435.     byte[5] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
  2436.     byte[4] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
  2437.     byte[3] = ((ENET_DEFAULT & 0xff000000) >> 24);
  2438.     byte[2] = curArr[2];
  2439.     byte[1] = curArr[1];
  2440.     byte[0] = curArr[0];
  2441. #else  /* _BYTE_ORDER == _LITTLE_ENDIAN  */
  2442.     printf ("%02x:%02x:%02x:%02x:%02x:%02xn", curArr[0], 
  2443.     curArr[1], curArr[2], curArr[3], 
  2444.     curArr[4], curArr[5]);
  2445.     byte[5] = ((ENET_DEFAULT & 0x00ff0000) >> 16);
  2446.     byte[4] = ((ENET_DEFAULT & 0x0000ff00) >> 8);
  2447.     byte[3] = (ENET_DEFAULT & 0x000000ff);
  2448.     byte[2] = curArr[3];
  2449.     byte[1] = curArr[4];
  2450.     byte[0] = curArr[5];
  2451. #endif /* _BYTE_ORDER == _BIG_ENDIAN */
  2452.     printf ("Modify only the last 3 bytes (board unique portion) of Ethernet Address.n");
  2453.     printf ("The first 3 bytes are fixed at manufacturer's default address block.n");
  2454.     for (ix = 5; ix > 2; ix--)
  2455.         printf ("%02x- %02xn", byte[ix], byte[ix]);
  2456.     /* start on fourth byte of enet addr */
  2457.     for (ix = 2; ix >= 0; ix --)
  2458. {
  2459. /* prompt for substitution */
  2460. printf ("%02x- ", byte[ix]);
  2461. /* get substitution value:
  2462.  *   skip empty lines (CR only);
  2463.  *   quit on end of file or invalid input;
  2464.  *   otherwise put specified value at address */
  2465. if (fioRdString (STD_IN, line, MAX_LINE) == EOF)
  2466.     break;
  2467. line [MAX_ADR_SIZE] = EOS; /* make sure input line has EOS */
  2468. for (pLine = line; isspace ((int) *pLine); ++pLine) /* skip leading spaces*/
  2469.     ;
  2470. if (*pLine == EOS) /* skip field if just CR */
  2471.     continue;
  2472. if (sscanf (pLine, "%x%1s", &value, &excess) != 1)
  2473.     break; /* quit if not number */
  2474. byte[ix]  = (uchar_t)value; /* assign new value */
  2475. }
  2476.     printf ("n");
  2477.     sysEnetAddrSet (byte[5], byte[4], byte[3], byte[2], byte[1], byte[0]);
  2478.     printf ("New Ethernet Address is: ");
  2479. #if _BYTE_ORDER == _BIG_ENDIAN
  2480.     for (ix = 5; ix > 0; ix--)
  2481.         printf ("%02x:", byte[ix]);
  2482.     printf ("%02xn", byte[0]);
  2483. #else  /* _BYTE_ORDER == _LITTLE_ENDIAN */
  2484.     for (ix = 5; ix > 0; ix--)
  2485.         printf ("%02x:", byte[ix]);
  2486.     printf ("%02xn", byte[0]);
  2487. #endif /* _BYTE_ODER == _BIG_ENDIAN */
  2488.     }
  2489. #endif  /* ETHERNET_ADR_SET */
  2490. /*******************************************************************************
  2491. *
  2492. * usrNetProtoInit - configure the various protocols
  2493. *
  2494. * This routine configures various protocols of the network system.
  2495. * This function should be called before netLibInit() at the initialization
  2496. * time.
  2497. *
  2498. * RETURNS: OK, or ERROR if the protocol initialization fails
  2499. *
  2500. * NOMANUAL
  2501. */
  2502. LOCAL STATUS usrNetProtoInit (void)
  2503.     {
  2504.     ipLibInit (&ipCfgParams);           /* has to included by default */
  2505.     rawIpLibInit ();                    /* has to included by default */
  2506.     rawLibInit ();
  2507. #ifdef INCLUDE_UDP
  2508.     udpLibInit (&udpCfgParams);         /* udp protocol initialization */
  2509. #endif
  2510. #ifdef INCLUDE_TCP
  2511.     tcpLibInit (&tcpCfgParams);         /* tcp protocol initialization */
  2512. #endif
  2513. #ifdef INCLUDE_ICMP
  2514.     icmpLibInit (&icmpCfgParams);       /* icmp protocol initialization */
  2515. #endif
  2516. #ifdef INCLUDE_IGMP
  2517.     igmpLibInit ();                     /* igmp protocol initialization */
  2518. #endif
  2519. #ifdef INCLUDE_OSPF
  2520.     ospfLibInit ();
  2521. #endif
  2522.     return (OK);
  2523.     }
  2524. #endif  /* INCLUDE_NETWORK */