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

📄 main.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 3 页
字号:
		{		  grub_memmove ((char *) arptable[ival].node,				arpreply->shwaddr,				ETH_ALEN);		  return 1;		}	      	      grub_memmove ((char *) &tmp, arpreply->tipaddr,			    sizeof (in_addr));	      	      if (arpreply->opcode == htons (ARP_REQUEST)		  && tmp == arptable[ARP_CLIENT].ipaddr.s_addr)		{		  arpreply->opcode = htons (ARP_REPLY);		  grub_memmove (arpreply->tipaddr, arpreply->sipaddr,				sizeof (in_addr));		  grub_memmove (arpreply->thwaddr, (char *) arpreply->shwaddr,				ETH_ALEN);		  grub_memmove (arpreply->sipaddr,				(char *) &arptable[ARP_CLIENT].ipaddr,				sizeof (in_addr));		  grub_memmove (arpreply->shwaddr,				arptable[ARP_CLIENT].node,				ETH_ALEN);		  eth_transmit (arpreply->thwaddr, ARP,				sizeof (struct arprequest),				arpreply);#ifdef MDEBUG		  grub_memmove (&tmp, arpreply->tipaddr, sizeof (in_addr));		  etherboot_printf ("Sent ARP reply to: %@\n", tmp);#endif	/* MDEBUG */		}	      	      continue;	    }	  if (type == AWAIT_QDRAIN)	    continue;	  	  /* Check for RARP - No IP hdr.  */	  if (type == AWAIT_RARP	      && nic.packetlen >= ETH_HLEN + sizeof (struct arprequest)	      && ptype == RARP)	    {	      arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];	      	      if (arpreply->opcode == htons (RARP_REPLY)		  && ! grub_memcmp (arpreply->thwaddr, ptr, ETH_ALEN))		{		  grub_memmove ((char *) arptable[ARP_SERVER].node,				arpreply->shwaddr, ETH_ALEN);		  grub_memmove ((char *) &arptable[ARP_SERVER].ipaddr,				arpreply->sipaddr, sizeof (in_addr));		  grub_memmove ((char *) &arptable[ARP_CLIENT].ipaddr,				arpreply->tipaddr, sizeof (in_addr));		  return 1;		}	      	      continue;	    }	  /* Anything else has IP header.  */	  if (nic.packetlen < protohdrlen || ptype != IP)	    continue;	  	  ip = (struct iphdr *) &nic.packet[ETH_HLEN];	  if (ip->verhdrlen != 0x45	      || ipchksum ((unsigned short *) ip, sizeof (struct iphdr))	      || ip->protocol != IP_UDP)	    continue;	  	  /*	    - Till Straumann <Till.Straumann@TU-Berlin.de>	    added udp checksum (safer on a wireless link)	    added fragmentation check: I had a corrupted image	    in memory due to fragmented TFTP packets - took me	    3 days to find the cause for this :-(	  */	  	  /* If More Fragments bit and Fragment Offset field	     are non-zero then packet is fragmented */	  if (ip->frags & htons(0x3FFF))	    {	      grub_printf ("ALERT: got a fragmented packet - reconfigure your server\n");	      continue;	    }	  	  udp = (struct udphdr *) &nic.packet[(ETH_HLEN					       + sizeof (struct iphdr))];	  if (udp->chksum && udpchksum (ip))	    {	      grub_printf ("UDP checksum error\n");	      continue;	    }	  	  /* BOOTP ?  */	  bootpreply = (struct bootp_t *)	    &nic.packet[(ETH_HLEN + sizeof (struct iphdr)			 + sizeof (struct udphdr))];	  if (type == AWAIT_BOOTP#ifdef NO_DHCP_SUPPORT	      && (nic.packetlen		  >= (ETH_HLEN + sizeof (struct bootp_t) - BOOTP_VENDOR_LEN))#else	      && (nic.packetlen		  >= (ETH_HLEN + sizeof (struct bootp_t) - DHCP_OPT_LEN))#endif /* ! NO_DHCP_SUPPORT */	      && udp->dest == htons (BOOTP_CLIENT)	      && bootpreply->bp_op == BOOTP_REPLY	      && bootpreply->bp_xid == xid	      && (! grub_memcmp (broadcast, bootpreply->bp_hwaddr, ETH_ALEN)		  || ! grub_memcmp (arptable[ARP_CLIENT].node,				    bootpreply->bp_hwaddr, ETH_ALEN)))	    {#ifdef DEBUG	      grub_printf ("BOOTP packet was received.\n");#endif	      arptable[ARP_CLIENT].ipaddr.s_addr		= bootpreply->bp_yiaddr.s_addr;#ifndef	NO_DHCP_SUPPORT	      dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;#ifdef DEBUG	      etherboot_printf ("dhcp_addr = %@\n", dhcp_addr.s_addr);#endif#endif /* ! NO_DHCP_SUPPORT */	      netmask = default_netmask ();	      arptable[ARP_SERVER].ipaddr.s_addr		= bootpreply->bp_siaddr.s_addr;	      /* Kill arp.  */	      grub_memset (arptable[ARP_SERVER].node, 0, ETH_ALEN);	      arptable[ARP_GATEWAY].ipaddr.s_addr		= bootpreply->bp_giaddr.s_addr;	      /* Kill arp.  */	      grub_memset (arptable[ARP_GATEWAY].node, 0, ETH_ALEN);	      grub_memmove ((char *) BOOTP_DATA_ADDR, (char *) bootpreply,			    sizeof (struct bootpd_t));#ifdef NO_DHCP_SUPPORT	      decode_rfc1533 (BOOTP_DATA_ADDR->bootp_reply.bp_vend,			      0, BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 1);#else	      decode_rfc1533 (BOOTP_DATA_ADDR->bootp_reply.bp_vend,			      0, DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 1);#endif /* ! NO_DHCP_SUPPORT */	      	      return 1;	    }	  	  /* TFTP ? */	  if (type == AWAIT_TFTP && ntohs (udp->dest) == ival)	    return 1;	}      else	{	  /* Check for abort key only if the Rx queue is empty -	   * as long as we have something to process, don't	   * assume that something failed.  It is unlikely that	   * we have no processing time left between packets.  */	  if (checkkey () != -1 && ASCII_CHAR (getkey ()) == CTRL_C)	    {	      ip_abort = 1;	      return 0;	    }	  	  /* Do the timeout after at least a full queue walk.  */	  if ((timeout == 0) || (currticks() > time))	    {	      break;	    }	}    }    return 0;}/**************************************************************************DECODE_RFC1533 - Decodes RFC1533 header**************************************************************************/intdecode_rfc1533 (unsigned char *p, int block, int len, int eof){  static unsigned char *extdata = NULL, *extend = NULL;  unsigned char *extpath = NULL;  unsigned char *endp;    if (block == 0)    {      end_of_rfc1533 = NULL;      vendorext_isvalid = 0;            if (grub_memcmp (p, rfc1533_cookie, 4))	/* no RFC 1533 header found */	return 0;            p += 4;      endp = p + len;    }  else    {      if (block == 1)	{	  if (grub_memcmp (p, rfc1533_cookie, 4))	    /* no RFC 1533 header found */	    return 0;	  	  p += 4;	  len -= 4;	}            if (extend + len	  <= ((unsigned char *)	      &(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])))	{	  grub_memmove (extend, p, len);	  extend += len;	}      else	{	  grub_printf ("Overflow in vendor data buffer! Aborting...\n");	  *extdata = RFC1533_END;	  return 0;	}            p = extdata;      endp = extend;    }  if (! eof)    return -1;    while (p < endp)    {      unsigned char c = *p;            if (c == RFC1533_PAD)	{	  p++;	  continue;	}      else if (c == RFC1533_END)	{	  end_of_rfc1533 = endp = p;	  continue;	}      else if (c == RFC1533_NETMASK)	{	  grub_memmove ((char *) &netmask, p + 2, sizeof (in_addr));	}      else if (c == RFC1533_GATEWAY)	{	  /* This is a little simplistic, but it will	     usually be sufficient.	     Take only the first entry.  */	  if (TAG_LEN (p) >= sizeof (in_addr))	    grub_memmove ((char *) &arptable[ARP_GATEWAY].ipaddr, p + 2,			  sizeof (in_addr));	}      else if (c == RFC1533_EXTENSIONPATH)	extpath = p;#ifndef	NO_DHCP_SUPPORT      else if (c == RFC2132_MSG_TYPE)	{	  dhcp_reply = *(p + 2);	}      else if (c == RFC2132_SRV_ID)	{	  grub_memmove ((char *) &dhcp_server, p + 2, sizeof (in_addr));#ifdef DEBUG	  etherboot_printf ("dhcp_server = %@\n", dhcp_server.s_addr);#endif	}#endif /* ! NO_DHCP_SUPPORT */      else if (c == RFC1533_VENDOR_MAGIC	       && TAG_LEN(p) >= 6	       && ! grub_memcmp (p + 2, vendorext_magic, 4)	       && p[6] == RFC1533_VENDOR_MAJOR)	vendorext_isvalid++;      /* GRUB now handles its own tag. Get the name of a configuration	 file from the network. Cool...  */      else if (c == RFC1533_VENDOR_CONFIGFILE)	{	  int l = TAG_LEN (p);	  	  /* Eliminate the trailing NULs according to RFC 2132.  */	  while (*(p + 2 + l - 1) == '\000' && l > 0)	    l--;	  	  /* XXX: Should check if LEN is less than the maximum length	     of CONFIG_FILE. This kind of robustness will be a goal	     in GRUB 1.0.  */	  grub_memmove (config_file, p + 2, l);	  config_file[l] = 0;	}            p += TAG_LEN (p) + 2;    }    extdata = extend = endp;    /* Perhaps we can eliminate this because we doesn't require so     much information, but I leave this alone.  */  if (block == 0 && extpath != NULL)    {      char fname[64];      int fnamelen = TAG_LEN (extpath);            while (*(extpath + 2 + fnamelen - 1) == '\000' && fnamelen > 0)	fnamelen--;            if (fnamelen + 1 > sizeof (fname))	{	  grub_printf ("Too long file name for Extensions Path\n");	  return 0;	}      else if (! fnamelen)	{	  grub_printf ("Empty file name for Extensions Path\n");	  return 0;	}            grub_memmove (fname, extpath + 2, fnamelen);      fname[fnamelen] = '\000';      grub_printf ("Loading BOOTP-extension file: %s\n", fname);      tftp (fname, decode_rfc1533);    }    /* Proceed with next block.  */  return -1;}/**************************************************************************IPCHKSUM - Checksum IP Header**************************************************************************/static unsigned short ipchksum (unsigned short *ip, int len){  unsigned long sum = 0;  len >>= 1;  while (len--)    {      sum += *(ip++);      if (sum > 0xFFFF)	sum -= 0xFFFF;    }  return (~sum) & 0x0000FFFF;}#define TWO_SECOND_DIVISOR (2147483647l/TICKS_PER_SEC)/**************************************************************************RFC2131_SLEEP_INTERVAL - sleep for expotentially longer times**************************************************************************/longrfc2131_sleep_interval (int base, int exp){  static long seed = 0;  long q;  unsigned long tmo;  #ifdef BACKOFF_LIMIT  if (exp > BACKOFF_LIMIT)    exp = BACKOFF_LIMIT;#endif  if (!seed)    /* Initialize linear congruential generator */    seed = (currticks () + *((long *) &arptable[ARP_CLIENT].node)	    + ((short *) arptable[ARP_CLIENT].node)[2]);  /* simplified version of the LCG given in Bruce Schneier's     "Applied Cryptography" */  q = seed / 53668;  if ((seed = 40014 * (seed - 53668 * q) - 12211 *q ) < 0)    seed += 2147483563L;  tmo = (base << exp) + (TICKS_PER_SEC - (seed / TWO_SECOND_DIVISOR));  return tmo;}/**************************************************************************CLEANUP - shut down networking**************************************************************************/voidcleanup_net (void){  if (network_ready)    {      /* Stop receiving packets.  */      eth_disable ();      network_ready = 0;    }}

⌨️ 快捷键说明

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