⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootp_subr.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
    bzero((caddr_t) &oldmask, sizeof(oldmask));  oldmask.sin_len=sizeof(oldmask);  oldmask.sin_family=AF_INET;  oldmask.sin_addr.s_addr = INADDR_ANY;    error = rtrequest(RTM_DELETE, 		    (struct sockaddr *) &olddst,		    (struct sockaddr *) &oldgw,		    (struct sockaddr *) &oldmask, 		    (RTF_UP | RTF_STATIC), NULL);  if (error) {    printf("nfs_boot: del default route, error=%d\n", error);    return error;  }  /*   * Do enough of ifconfig(8) so that the chosen interface   * can talk to the servers.  (just set the address)   */  bcopy(netmask,&ireq->ifr_addr,sizeof(*netmask));  error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)ireq, procp);  if (error)    panic("nfs_boot: set if netmask, error=%d", error);  /* Broadcast is with host part of IP address all 1's */    sin = (struct sockaddr_in *)&ireq->ifr_addr;  bzero((caddr_t)sin, sizeof(*sin));  sin->sin_len = sizeof(*sin);  sin->sin_family = AF_INET;  sin->sin_addr.s_addr = myaddr->sin_addr.s_addr | ~ netmask->sin_addr.s_addr;  error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, procp);  if (error)    panic("bootpc_call: set if broadcast addr, error=%d", error);    bcopy(myaddr,&ireq->ifr_addr,sizeof(*myaddr));  error = ifioctl(so, SIOCSIFADDR, (caddr_t)ireq, procp);  if (error)    panic("nfs_boot: set if addr, error=%d", error);  /* Add new default route */  error = rtrequest(RTM_ADD, 		    (struct sockaddr *) &olddst,		    (struct sockaddr *) gw,		    (struct sockaddr *) &oldmask,		    (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL);  if (error) {    printf("nfs_boot: add net route, error=%d\n", error);    return error;  }  return 0;}#if !defined(__rtems__)static int setfs(addr, path, p)	struct sockaddr_in *addr;	char *path;	char *p;{	unsigned ip = 0;	int val;	if (((val = getdec(&p)) < 0) || (val > 255)) return(0);	ip = val << 24;	if (*p != '.') return(0);	p++;	if (((val = getdec(&p)) < 0) || (val > 255)) return(0);	ip |= (val << 16);	if (*p != '.') return(0);	p++;	if (((val = getdec(&p)) < 0) || (val > 255)) return(0);	ip |= (val << 8);	if (*p != '.') return(0);	p++;	if (((val = getdec(&p)) < 0) || (val > 255)) return(0);	ip |= val;	if (*p != ':') return(0);	p++;	addr->sin_addr.s_addr = htonl(ip);	addr->sin_len = sizeof(struct sockaddr_in);	addr->sin_family = AF_INET;	strncpy(path,p,MNAMELEN-1);	return(1);}#endif#if !defined(__rtems__)static int getdec(ptr)	char **ptr;{	char *p = *ptr;	int ret=0;	if ((*p < '0') || (*p > '9')) return(-1);	while ((*p >= '0') && (*p <= '9')) {		ret = ret*10 + (*p - '0');		p++;	}	*ptr = p;	return(ret);}#endif#if !defined(__rtems__)static char *substr(a,b)	char *a,*b;{	char *loc1;	char *loc2;        while (*a != '\0') {                loc1 = a;                loc2 = b;                while (*loc1 == *loc2++) {                        if (*loc1 == '\0') return (0);                        loc1++;                        if (*loc2 == '\0') return (loc1);                }        a++;        }        return (0);}#endifstatic void printip(char *prefix,struct in_addr addr){  unsigned int ip;  ip = ntohl(addr.s_addr);  printf("%s is %d.%d.%d.%d\n",prefix,	 ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );}static int dhcpOptionOverload = 0;static char dhcp_gotgw = 0;static char dhcp_gotnetmask = 0;static char dhcp_gotserver = 0;static char dhcp_gotlogserver = 0;static struct sockaddr_in dhcp_netmask;static struct sockaddr_in dhcp_gw;static char *dhcp_hostname = NULL;static voidprocessOptions (unsigned char *optbuf, int optbufSize){  int j = 0;  int len;  int code, ncode;  char *p;  ncode = optbuf[0];  while (j < optbufSize) {    code = optbuf[j] = ncode;    if (code == 255)      return;    if (code == 0) {      j++;      continue;    }    len = optbuf[j+1];    j += 2;    if ((len + j) >= optbufSize) {      printf ("Truncated field for code %d", code);      return;    }    ncode = optbuf[j+len];    optbuf[j+len] = '\0';    p = &optbuf[j];    j += len;    /*     * Process the option     */    switch (code) {    case 1:      /* Subnet mask */      if (len!=4)         panic("bootpc: subnet mask len is %d",len);      bcopy (p, &dhcp_netmask.sin_addr, 4);      dhcp_gotnetmask = 1;      break;    case 2:      /* Time offset */      if (len!=4)         panic("bootpc: time offset len is %d",len);      bcopy (p, &rtems_bsdnet_timeoffset, 4);      rtems_bsdnet_timeoffset = ntohl (rtems_bsdnet_timeoffset);      break;    case 3:      /* Routers */      if (len % 4)         panic ("bootpc: Router Len is %d", len);      if (len > 0) {        bcopy(p, &dhcp_gw.sin_addr, 4);	dhcp_gotgw = 1;      }      break;    case 42:      /* NTP servers */      if (len % 4)         panic ("bootpc: time server Len is %d", len);      {      int tlen = 0;      while ((tlen < len) &&             (rtems_bsdnet_ntpserver_count < sizeof rtems_bsdnet_config.ntp_server /             sizeof rtems_bsdnet_config.ntp_server[0])) {        bcopy (p+tlen,		&rtems_bsdnet_ntpserver[rtems_bsdnet_ntpserver_count],		4);        printip("Time Server",          rtems_bsdnet_ntpserver[rtems_bsdnet_ntpserver_count]);        rtems_bsdnet_ntpserver_count++;        tlen += 4;      }      }      break;    case 6:      /* Domain Name servers */      if (len % 4)         panic ("bootpc: DNS Len is %d", len);      {      int dlen = 0;      while ((dlen < len) &&             (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /        sizeof rtems_bsdnet_config.name_server[0])) {        bcopy (p+dlen,        &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],        4);        printip("Domain Name Server",          rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);        rtems_bsdnet_nameserver_count++;        dlen += 4;      }      }      break;    case 12:      /* Host name */      if (len>=MAXHOSTNAMELEN)        panic ("bootpc: hostname >=%d bytes", MAXHOSTNAMELEN);      if (sethostname (p, len) < 0)        panic("Can't set host name");      printf("Hostname is %s\n", p);      dhcp_hostname = bootp_strdup_realloc(dhcp_hostname,p);      break;    case 7:      /* Log servers */      if (len % 4)         panic ("bootpc: Log server Len is %d", len);      if (len > 0) {        bcopy(p, &rtems_bsdnet_log_host_address, 4);	dhcp_gotlogserver = 1;      }      break;    case 15:      /* Domain name */      if (p[0]) {        rtems_bsdnet_domain_name = 	  bootp_strdup_realloc(rtems_bsdnet_domain_name,p);        printf("Domain name is %s\n", rtems_bsdnet_domain_name);      }      break;    case 16:  /* Swap server IP address. unused */      break;    case 52:      /* DHCP option override */      if (len != 1)         panic ("bootpc: DHCP option overload len is %d", len);      dhcpOptionOverload = p[0];      break;    case 128: /* Site-specific option for DHCP servers that                *   a) don't supply tag 54               * and               *   b) don't supply the server address in siaddr               * For example, on Solaris 2.6 in.dhcpd, include in the dhcptab:               *    Bootsrv s Site,128,IP,1,1               * and use that symbol in the macro that defines the client:               *    Bootsrv=<tftp-server-ip-address>               */    case 54:      /* DHCP server */      if (len != 4)         panic ("bootpc: DHCP server len is %d", len);      bcopy(p, &rtems_bsdnet_bootp_server_address, 4);      dhcp_gotserver = 1;      break;    case 66:      /* DHCP server name option */      if (p[0])        rtems_bsdnet_bootp_server_name = 	  bootp_strdup_realloc(rtems_bsdnet_bootp_server_name,p);      break;    case 67:      /* DHCP bootfile option */      if (p[0])        rtems_bsdnet_bootp_boot_file_name = 	  bootp_strdup_realloc(rtems_bsdnet_bootp_boot_file_name,p);      break;	case 129:	  /* Site specific option; we use this to get 	   * a 'command line string'	   */	  if (p[0])	  	rtems_bsdnet_bootp_cmdline = strdup(p);	  break;    default:      printf ("Ignoring BOOTP/DHCP option code %d\n", code);      break;    }  }}#define EALEN 6voidbootpc_init(int update_files){  struct bootp_packet call;  struct bootp_packet reply;  static u_int32_t xid = ~0xFF;    struct ifreq ireq;  struct ifnet *ifp;  struct socket *so;  int j;  int error;  struct sockaddr_in myaddr;  struct ifaddr *ifa;  struct sockaddr_dl *sdl = NULL;  char *delim;  struct proc *procp = NULL;  /*   * If already filled in, don't touch it here    */  if (nfs_diskless_valid)    return;  /*   * If we are to update the files create the root   * file structure.   */  if (update_files)    if (rtems_create_root_fs () < 0) {      printf("Error creating the root filesystem.\nFile not created.\n");      update_files = 0;    }  if (dhcp_hostname != NULL) {	/* free it */    dhcp_hostname=bootp_strdup_realloc(dhcp_hostname,0);  }  /*   * Find a network interface.   */  for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)    if ((ifp->if_flags &      (IFF_LOOPBACK|IFF_POINTOPOINT)) == 0)	break;  if (ifp == NULL)    panic("bootpc_init: no suitable interface");  bzero(&ireq,sizeof(ireq));  sprintf(ireq.ifr_name, "%s%d", ifp->if_name,ifp->if_unit);  printf("bootpc_init: using network interface '%s'\n",	 ireq.ifr_name);  if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)) != 0)    panic("nfs_boot: socreate, error=%d", error);	    bootpc_fakeup_interface(&ireq,so,procp);  printf("Bootpc testing starting\n");    /* Get HW address */  for (ifa = ifp->if_addrlist;ifa; ifa = ifa->ifa_next)    if (ifa->ifa_addr->sa_family == AF_LINK &&	(sdl = ((struct sockaddr_dl *) ifa->ifa_addr)) &&	sdl->sdl_type == IFT_ETHER)      break;    if (!sdl)    panic("bootpc: Unable to find HW address");  if (sdl->sdl_alen != EALEN )     panic("bootpc: HW address len is %d, expected value is %d",	  sdl->sdl_alen,EALEN);  printf("bootpc hw address is ");  delim="";  for (j=0;j<sdl->sdl_alen;j++) {    printf("%s%x",delim,((unsigned char *)LLADDR(sdl))[j]);    delim=":";  }  printf("\n");#if 0  bootpboot_p_iflist();  bootpboot_p_rtlist();#endif    bzero((caddr_t) &call, sizeof(call));  /* bootpc part */  call.op = 1; 			/* BOOTREQUEST */  call.htype= 1;		/* 10mb ethernet */  call.hlen=sdl->sdl_alen;	/* Hardware address length */  call.hops=0;	  xid++;  call.xid = txdr_unsigned(xid);  bcopy(LLADDR(sdl),&call.chaddr,sdl->sdl_alen);    call.vend[0]=99;  call.vend[1]=130;  call.vend[2]=83;  call.vend[3]=99;  call.vend[4]=255;    call.secs = 0;  call.flags = htons(0x8000); /* We need an broadcast answer */    error = bootpc_call(&call,&reply,procp);    if (error)    panic("BOOTP call failed -- error %d", error);    /*   * Initialize network address structures   */  bzero(&myaddr,sizeof(myaddr));  bzero(&dhcp_netmask,sizeof(dhcp_netmask));  bzero(&dhcp_gw,sizeof(dhcp_gw));  myaddr.sin_len = sizeof(myaddr);  myaddr.sin_family = AF_INET;  dhcp_netmask.sin_len = sizeof(dhcp_netmask);  dhcp_netmask.sin_family = AF_INET;  dhcp_gw.sin_len = sizeof(dhcp_gw);  dhcp_gw.sin_family= AF_INET;  /*   * Set our address   */  myaddr.sin_addr = reply.yiaddr;  printip("My ip address",myaddr.sin_addr);  /*   * Process BOOTP/DHCP options   */  if (reply.vend[0]==99 && reply.vend[1]==130 &&      reply.vend[2]==83 && reply.vend[3]==99) {    processOptions (&reply.vend[4], sizeof(reply.vend) - 4);  }  if (dhcpOptionOverload & 1) {    processOptions (reply.file, sizeof reply.file);  }  else {    if (reply.file[0])      rtems_bsdnet_bootp_boot_file_name = 	bootp_strdup_realloc(rtems_bsdnet_bootp_boot_file_name,reply.file);  }  if (dhcpOptionOverload & 2) {    processOptions (reply.sname, sizeof reply.sname);  }  else {    if (reply.sname[0])      rtems_bsdnet_bootp_server_name = 	bootp_strdup_realloc(rtems_bsdnet_bootp_server_name,reply.sname);  }  if (rtems_bsdnet_bootp_server_name)    printf ("Server name is %s\n", rtems_bsdnet_bootp_server_name);  if (rtems_bsdnet_bootp_boot_file_name)    printf ("Boot file is %s\n", rtems_bsdnet_bootp_boot_file_name);  if (rtems_bsdnet_bootp_cmdline)    printf ("Command line is %s\n", rtems_bsdnet_bootp_cmdline);  /*   * Use defaults if values were not supplied by BOOTP/DHCP options   */  if (!dhcp_gotnetmask) {    if (IN_CLASSA(ntohl(myaddr.sin_addr.s_addr)))      dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);    else if (IN_CLASSB(ntohl(myaddr.sin_addr.s_addr)))      dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);    else       dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);  }  printip ("Subnet mask", dhcp_netmask.sin_addr);  if (!dhcp_gotserver)   rtems_bsdnet_bootp_server_address = reply.siaddr;  printip ("Server ip address" ,rtems_bsdnet_bootp_server_address);  if (!dhcp_gotgw)    dhcp_gw.sin_addr = reply.giaddr;  printip ("Gateway ip address", dhcp_gw.sin_addr);  if (!dhcp_gotlogserver)    rtems_bsdnet_log_host_address = rtems_bsdnet_bootp_server_address;  printip ("Log server ip address", rtems_bsdnet_log_host_address);  /*   * Update the files if we are asked too.   */  if (update_files) {    char *dn = rtems_bsdnet_domain_name;    char *hn = dhcp_hostname;    if (!dn)      dn = "mydomain";    if (!hn)      hn = "me";    rtems_rootfs_append_host_rec(*((unsigned long*) &myaddr.sin_addr), hn, dn);    /*     * Should the given domainname be used here ?     */    if (dhcp_gotserver) {      if (rtems_bsdnet_bootp_server_name)        hn = rtems_bsdnet_bootp_server_name;      else        hn = "bootps";      rtems_rootfs_append_host_rec(*((unsigned long *) &rtems_bsdnet_bootp_server_address),                                   hn, dn);    }    if (dhcp_gotlogserver) {      rtems_rootfs_append_host_rec(*((unsigned long *) &rtems_bsdnet_log_host_address),                                   "logs", dn);    }    /*     * Setup the DNS configuration file /etc/resolv.conf.     */    if (rtems_bsdnet_nameserver_count) {      int        i;      char       buf[64];      const char *bufl[1];      bufl[0] = buf;      #define MKFILE_MODE (S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH)            if (rtems_bsdnet_domain_name &&          (strlen(rtems_bsdnet_domain_name) < (sizeof(buf) - 1))) {        strcpy(buf, "search ");        strcat(buf, rtems_bsdnet_domain_name);        strcat(buf, "\n");        rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl);      }      for (i = 0; i < rtems_bsdnet_nameserver_count; i++) {        strcpy(buf, "nameserver ");        strcat(buf, inet_ntoa(rtems_bsdnet_nameserver[i]));        strcat(buf, "\n");        if (rtems_rootfs_file_append ("/etc/resolv.conf", MKFILE_MODE, 1, bufl))          break;      }    }  }  /*   * Configure the interface with the new settings   */  error = bootpc_adjust_interface(&ireq,so,				  &myaddr,&dhcp_netmask,&dhcp_gw,procp);  soclose(so);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -