亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ip.c

?? 內核是系統的心臟
?? C
?? 第 1 頁 / 共 3 頁
字號:
 		offset += len;
/* 		printk("Queue frag\n");*/
 
 		/* Put this fragment into the sending queue. */
 		ip_queue_xmit(sk, dev, skb2, 1);
/* 		printk("Queued\n");*/
   	}
 }
 


#ifdef CONFIG_IP_FORWARD

/* Forward an IP datagram to its next destination. */
static void
ip_forward(struct sk_buff *skb, struct device *dev, int is_frag)
{
  struct device *dev2;
  struct iphdr *iph;
  struct sk_buff *skb2;
  struct rtable *rt;
  unsigned char *ptr;
  unsigned long raddr;

  /*
   * Only forward packets that were fired at us when we are in promiscuous
   * mode. In standard mode we rely on the driver to filter for us.
   */
   
  if(dev->flags&IFF_PROMISC)
  {
  	if(memcmp((char *)&skb[1],dev->dev_addr,dev->addr_len))
  		return;
  }
  
  /*
   * According to the RFC, we must first decrease the TTL field. If
   * that reaches zero, we must reply an ICMP control message telling
   * that the packet's lifetime expired.
   */
  iph = skb->h.iph;
  iph->ttl--;
  if (iph->ttl <= 0) {
	DPRINTF((DBG_IP, "\nIP: *** datagram expired: TTL=0 (ignored) ***\n"));
	DPRINTF((DBG_IP, "    SRC = %s   ", in_ntoa(iph->saddr)));
	DPRINTF((DBG_IP, "    DST = %s (ignored)\n", in_ntoa(iph->daddr)));

	/* Tell the sender its packet died... */
	icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, dev);
	return;
  }

  /* Re-compute the IP header checksum. */
  ip_send_check(iph);

  /*
   * OK, the packet is still valid.  Fetch its destination address,
   * and give it to the IP sender for further processing.
   */
  rt = rt_route(iph->daddr, NULL);
  if (rt == NULL) {
	DPRINTF((DBG_IP, "\nIP: *** routing (phase I) failed ***\n"));

	/* Tell the sender its packet cannot be delivered... */
	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, dev);
	return;
  }


  /*
   * Gosh.  Not only is the packet valid; we even know how to
   * forward it onto its final destination.  Can we say this
   * is being plain lucky?
   * If the router told us that there is no GW, use the dest.
   * IP address itself- we seem to be connected directly...
   */
  raddr = rt->rt_gateway;
  if (raddr != 0) {
	rt = rt_route(raddr, NULL);
	if (rt == NULL) {
		DPRINTF((DBG_IP, "\nIP: *** routing (phase II) failed ***\n"));

		/* Tell the sender its packet cannot be delivered... */
		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, dev);
		return;
	}
	if (rt->rt_gateway != 0) raddr = rt->rt_gateway;
  } else raddr = iph->daddr;
  dev2 = rt->rt_dev;


  if (dev == dev2)
	return;
  /*
   * We now allocate a new buffer, and copy the datagram into it.
   * If the indicated interface is up and running, kick it.
   */
  DPRINTF((DBG_IP, "\nIP: *** fwd %s -> ", in_ntoa(iph->saddr)));
  DPRINTF((DBG_IP, "%s (via %s), LEN=%d\n",
			in_ntoa(raddr), dev2->name, skb->len));

  if (dev2->flags & IFF_UP) {
	skb2 = (struct sk_buff *) alloc_skb(sizeof(struct sk_buff) +
		       dev2->hard_header_len + skb->len, GFP_ATOMIC);
	if (skb2 == NULL) {
		printk("\nIP: No memory available for IP forward\n");
		return;
	}
	ptr = skb2->data;
	skb2->sk = NULL;
	skb2->free = 1;
	skb2->len = skb->len + dev2->hard_header_len;
	skb2->mem_addr = skb2;
	skb2->mem_len = sizeof(struct sk_buff) + skb2->len;
	skb2->next = NULL;
	skb2->h.raw = ptr;

	/* Copy the packet data into the new buffer. */
	memcpy(ptr + dev2->hard_header_len, skb->h.raw, skb->len);
		
	/* Now build the MAC header. */
	(void) ip_send(skb2, raddr, skb->len, dev2, dev2->pa_addr);

	if(skb2->len > dev2->mtu)
	{
		ip_fragment(NULL,skb2,dev2, is_frag);
		kfree_skb(skb2,FREE_WRITE);
	}
	else
		dev2->queue_xmit(skb2, dev2, SOPRI_NORMAL);
  }
}


#endif

/* This function receives all incoming IP datagrams. */
int
ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
{
  struct iphdr *iph = skb->h.iph;
  unsigned char hash;
  unsigned char flag = 0;
  unsigned char opts_p = 0;	/* Set iff the packet has options. */
  struct inet_protocol *ipprot;
  static struct options opt; /* since we don't use these yet, and they
				take up stack space. */
  int brd;
  int is_frag=0;

  DPRINTF((DBG_IP, "<<\n"));

  skb->ip_hdr = iph;		/* Fragments can cause ICMP errors too! */
  /* Is the datagram acceptable? */
  if (skb->len<sizeof(struct iphdr) || iph->ihl<5 || iph->version != 4 || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0) {
	DPRINTF((DBG_IP, "\nIP: *** datagram error ***\n"));
	DPRINTF((DBG_IP, "    SRC = %s   ", in_ntoa(iph->saddr)));
	DPRINTF((DBG_IP, "    DST = %s (ignored)\n", in_ntoa(iph->daddr)));
	skb->sk = NULL;
	kfree_skb(skb, FREE_WRITE);
	return(0);
  }
  
  if (iph->ihl != 5) {  	/* Fast path for the typical optionless IP packet. */
      ip_print(iph);		/* Bogus, only for debugging. */
      memset((char *) &opt, 0, sizeof(opt));
      if (do_options(iph, &opt) != 0)
	  return 0;
      opts_p = 1;
  }

  if (iph->frag_off & 0x0020)
  	is_frag|=1;
  if (ntohs(iph->frag_off) & 0x1fff)
  	is_frag|=2;
  	
  /* Do any IP forwarding required.  chk_addr() is expensive -- avoid it someday. */
  if ((brd = chk_addr(iph->daddr)) == 0) {
#ifdef CONFIG_IP_FORWARD
	ip_forward(skb, dev, is_frag);
#else
	printk("Machine %x tried to use us as a forwarder to %x but we have forwarding disabled!\n",
			iph->saddr,iph->daddr);
#endif			
	skb->sk = NULL;
	kfree_skb(skb, FREE_WRITE);
	return(0);
  }

  /*
   * Reassemble IP fragments. 
   */

  if(is_frag)
  {
#ifdef CONFIG_IP_DEFRAG
        skb=ip_defrag(iph,skb,dev);
        if(skb==NULL)
        {
        	return 0;
        }
        iph=skb->h.iph;
#else
	printk("\nIP: *** datagram fragmentation not yet implemented ***\n");
	printk("    SRC = %s   ", in_ntoa(iph->saddr));
	printk("    DST = %s (ignored)\n", in_ntoa(iph->daddr));
	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
	skb->sk = NULL;
	kfree_skb(skb, FREE_WRITE);
	return(0);
#endif
  }



  if(brd==IS_INVBCAST)
  {
/*	printk("Invalid broadcast address from %x [target %x] (Probably they have a wrong netmask)\n",
		iph->saddr,iph->daddr);*/
  	skb->sk=NULL;
  	kfree_skb(skb,FREE_WRITE);
  	return(0);
  }
  
  /* Point into the IP datagram, just past the header. */

  skb->ip_hdr = iph;
  skb->h.raw += iph->ihl*4;
  hash = iph->protocol & (MAX_INET_PROTOS -1);
  for (ipprot = (struct inet_protocol *)inet_protos[hash];
       ipprot != NULL;
       ipprot=(struct inet_protocol *)ipprot->next)
    {
       struct sk_buff *skb2;

       if (ipprot->protocol != iph->protocol) continue;
       DPRINTF((DBG_IP, "Using protocol = %X:\n", ipprot));
       print_ipprot(ipprot);

       /*
	* See if we need to make a copy of it.  This will
	* only be set if more than one protocol wants it. 
	* and then not for the last one.
	*/
       if (ipprot->copy) {
		skb2 = alloc_skb(skb->mem_len, GFP_ATOMIC);
		if (skb2 == NULL) 
			continue;
		memcpy(skb2, skb, skb->mem_len);
		skb2->mem_addr = skb2;
		skb2->ip_hdr = (struct iphdr *)(
				(unsigned long)skb2 +
				(unsigned long) skb->ip_hdr -
				(unsigned long)skb);
		skb2->h.raw = (unsigned char *)(
				(unsigned long)skb2 +
				(unsigned long) skb->h.raw -
				(unsigned long)skb);
		skb2->free=1;
	} else {
		skb2 = skb;
	}
	flag = 1;

       /*
	* Pass on the datagram to each protocol that wants it,
	* based on the datagram protocol.  We should really
	* check the protocol handler's return values here...
	*/
	ipprot->handler(skb2, dev, opts_p ? &opt : 0, iph->daddr,
			(ntohs(iph->tot_len) - (iph->ihl * 4)),
			iph->saddr, 0, ipprot);

  }

  /*
   * All protocols checked.
   * If this packet was a broadcast, we may *not* reply to it, since that
   * causes (proven, grin) ARP storms and a leakage of memory (i.e. all
   * ICMP reply messages get queued up for transmission...)
   */
  if (!flag) {
	if (brd != IS_BROADCAST)
		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
	skb->sk = NULL;
	kfree_skb(skb, FREE_WRITE);
  }

  return(0);
}


/*
 * Queues a packet to be sent, and starts the transmitter
 * if necessary.  if free = 1 then we free the block after
 * transmit, otherwise we don't.
 * This routine also needs to put in the total length, and
 * compute the checksum.
 */
void
ip_queue_xmit(struct sock *sk, struct device *dev, 
	      struct sk_buff *skb, int free)
{
  struct iphdr *iph;
  unsigned char *ptr;

  if (sk == NULL) free = 1;
  if (dev == NULL) {
	printk("IP: ip_queue_xmit dev = NULL\n");
	return;
  }
  IS_SKB(skb);
  skb->free = free;
  skb->dev = dev;
  skb->when = jiffies;
  
  DPRINTF((DBG_IP, ">>\n"));
  ptr = skb->data;
  ptr += dev->hard_header_len;
  iph = (struct iphdr *)ptr;
  skb->ip_hdr = iph;
  iph->tot_len = ntohs(skb->len-dev->hard_header_len);

  if(skb->len > dev->mtu)
  {
/*  	printk("Fragment!\n");*/
  	ip_fragment(sk,skb,dev,0);
  	IS_SKB(skb);
  	kfree_skb(skb,FREE_WRITE);
  	return;
  }
  
  ip_send_check(iph);
  ip_print(iph);
  skb->next = NULL;

  /* See if this is the one trashing our queue. Ross? */
  skb->magic = 1;
  if (!free) {
	skb->link3 = NULL;
	sk->packets_out++;
	cli();
	if (sk->send_head == NULL) {
		sk->send_tail = skb;
		sk->send_head = skb;
	} else {
		/* See if we've got a problem. */
		if (sk->send_tail == NULL) {
			printk("IP: ***bug sk->send_tail == NULL != sk->send_head\n");
			sort_send(sk);
		} else {
			sk->send_tail->link3 = skb;
			sk->send_tail = skb;
		}
	}
	sti();
	reset_timer(sk, TIME_WRITE, sk->rto);
  } else {
	skb->sk = sk;
  }

  /* If the indicated interface is up and running, kick it. */
  if (dev->flags & IFF_UP) {
	if (sk != NULL) {
		dev->queue_xmit(skb, dev, sk->priority);
	} 
	else {
		dev->queue_xmit(skb, dev, SOPRI_NORMAL);
	}
  } else {
	if (free) kfree_skb(skb, FREE_WRITE);
  }
}


void
ip_do_retransmit(struct sock *sk, int all)
{
  struct sk_buff * skb;
  struct proto *prot;
  struct device *dev;
  int retransmits;

  prot = sk->prot;
  skb = sk->send_head;
  retransmits = sk->retransmits;
  while (skb != NULL) {
	dev = skb->dev;
	/* I know this can't happen but as it does.. */
	if(dev==NULL)
	{
		printk("ip_retransmit: NULL device bug!\n");
		goto oops;
	}

	IS_SKB(skb);
	
	/*
	 * The rebuild_header function sees if the ARP is done.
	 * If not it sends a new ARP request, and if so it builds
	 * the header.
	 */
        cli();	/* We might get interrupted by an arp reply here and fill
		   the frame in twice. Because of the technique used this
		   would be a little sad */
	if (!skb->arp) {
		if (dev->rebuild_header(skb->data, dev)) {
			sti();	/* Failed to rebuild - next */
			if (!all) break;
			skb = (struct sk_buff *)skb->link3;
			continue;
		}
	}
	skb->arp = 1;
	sti();
	skb->when = jiffies;

	/* If the interface is (still) up and running, kick it. */
	if (dev->flags & IFF_UP) {
		if (sk && !skb_device_locked(skb))
			dev->queue_xmit(skb, dev, sk->priority);
	/*	  else dev->queue_xmit(skb, dev, SOPRI_NORMAL ); CANNOT HAVE SK=NULL HERE */
	}

oops:	retransmits++;
	sk->prot->retransmits ++;
	if (!all) break;

	/* This should cut it off before we send too many packets. */
	if (sk->retransmits > sk->cong_window) break;
	skb = (struct sk_buff *)skb->link3;
  }
}

/*
 * This is the normal code called for timeouts.  It does the retransmission
 * and then does backoff.  ip_do_retransmit is separated out because
 * tcp_ack needs to send stuff from the retransmit queue without
 * initiating a backoff.
 */

void
ip_retransmit(struct sock *sk, int all)
{
  ip_do_retransmit(sk, all);

  /*
   * Increase the timeout each time we retransmit.  Note that
   * we do not increase the rtt estimate.  rto is initialized
   * from rtt, but increases here.  Jacobson (SIGCOMM 88) suggests
   * that doubling rto each time is the least we can get away with.
   * In KA9Q, Karns uses this for the first few times, and then
   * goes to quadratic.  netBSD doubles, but only goes up to *64,
   * and clamps at 1 to 64 sec afterwards.  Note that 120 sec is
   * defined in the protocol as the maximum possible RTT.  I guess
   * we'll have to use something other than TCP to talk to the
   * University of Mars.
   */

  sk->retransmits++;
  sk->backoff++;
  sk->rto = min(sk->rto << 1, 120*HZ);
  reset_timer(sk, TIME_WRITE, sk->rto);
}

/*
 *	Socket option code for IP. This is the end of the line after any TCP,UDP etc options on
 *	an IP socket.
 */
 
int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen)
{
	int val,err;
	
  	if (optval == NULL) 
  		return(-EINVAL);

  	err=verify_area(VERIFY_READ, optval, sizeof(int));
  	if(err)
  		return err;
  	
  	val = get_fs_long((unsigned long *)optval);

	if(level!=SOL_IP)
		return -EOPNOTSUPP;

	switch(optname)
	{
		case IP_TOS:
			if(val<0||val>255)
				return -EINVAL;
			sk->ip_tos=val;
			return 0;
		case IP_TTL:
			if(val<1||val>255)
				return -EINVAL;
			sk->ip_ttl=val;
			return 0;
		/* IP_OPTIONS and friends go here eventually */
		default:
			return(-ENOPROTOOPT);
	}
}

int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen)
{
	int val,err;
	
	if(level!=SOL_IP)
		return -EOPNOTSUPP;
		
	switch(optname)
	{
		case IP_TOS:
			val=sk->ip_tos;
			break;
		case IP_TTL:
			val=sk->ip_ttl;
			break;
		default:
			return(-ENOPROTOOPT);
	}
	err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
	if(err)
  		return err;
  	put_fs_long(sizeof(int),(unsigned long *) optlen);

  	err=verify_area(VERIFY_WRITE, optval, sizeof(int));
  	if(err)
  		return err;
  	put_fs_long(val,(unsigned long *)optval);

  	return(0);
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
www.亚洲色图| 亚洲天堂免费在线观看视频| 亚洲人成人一区二区在线观看| 国产suv精品一区二区6| 久久久久久久性| 成人开心网精品视频| 中文字幕在线播放不卡一区| 99r精品视频| 亚洲午夜精品网| 欧美一级黄色大片| 六月婷婷色综合| 国产a级毛片一区| 亚洲另类中文字| 欧美图片一区二区三区| 国产精品91xxx| 在线观看亚洲专区| 奇米影视一区二区三区| 国产日韩欧美高清| 在线不卡a资源高清| 粉嫩av亚洲一区二区图片| 一区二区三区精密机械公司| 久久精子c满五个校花| 91丨九色丨国产丨porny| 蜜臀av一级做a爰片久久| 国产精品久久久久aaaa樱花| 欧美一级黄色大片| 欧美日韩国产天堂| 不卡一区二区在线| 国产毛片精品国产一区二区三区| 亚洲一区免费观看| 色综合久久中文综合久久97| 精品一区二区日韩| 午夜私人影院久久久久| 国产精品毛片久久久久久久| 一区二区在线观看视频在线观看| 日韩欧美国产三级电影视频| 91丨porny丨中文| 国产夫妻精品视频| 精品中文av资源站在线观看| 午夜精品久久一牛影视| 亚洲天堂福利av| 97se亚洲国产综合自在线| 久草在线在线精品观看| 蜜乳av一区二区| 蓝色福利精品导航| 久久国产精品免费| 国内精品国产三级国产a久久 | 欧美性生活影院| 久久午夜羞羞影院免费观看| 国产成人午夜精品影院观看视频 | 6080亚洲精品一区二区| 欧美日韩一区不卡| 欧美美女喷水视频| 国内精品第一页| 国产精品99久久久| 91视频精品在这里| 欧美精品v日韩精品v韩国精品v| 欧美电影在线免费观看| 欧美成人精品福利| 国产精品久久久久久久久免费丝袜 | 天天综合色天天综合| 亚洲高清免费在线| 精品一区二区三区影院在线午夜| 国产福利一区在线| 男人的天堂亚洲一区| 国产毛片一区二区| 欧美性一区二区| 国产视频一区二区在线观看| 亚洲精品日日夜夜| 国产69精品久久久久毛片| 欧美中文字幕亚洲一区二区va在线| 日韩欧美色综合网站| 日本韩国欧美一区| 国产精品福利一区| 麻豆精品国产传媒mv男同 | 91欧美一区二区| 欧美成人乱码一区二区三区| 亚洲一区二区三区在线播放| 国产精品资源在线看| 欧美日韩mp4| 亚洲一区av在线| 91小视频在线| 日韩一区中文字幕| 99精品一区二区| 久久青草欧美一区二区三区| 亚洲va欧美va人人爽午夜| 色综合久久天天| 一区二区中文视频| 99精品视频在线播放观看| 久久蜜臀精品av| 国产剧情av麻豆香蕉精品| 久久嫩草精品久久久久| 男男gaygay亚洲| 91精品国产综合久久蜜臀| 香港成人在线视频| 欧美日韩成人激情| 一个色在线综合| 欧美在线观看一区| 一区二区三区四区高清精品免费观看 | 欧美国产综合色视频| 国产精品一区二区91| 日本一区二区三区免费乱视频 | 亚洲老妇xxxxxx| 欧美日韩一二区| 国产在线精品视频| 亚洲人成在线播放网站岛国| 欧美日韩在线播放| 麻豆精品久久精品色综合| 久久丝袜美腿综合| 亚洲自拍欧美精品| 久久夜色精品国产欧美乱极品| 成人永久aaa| 北岛玲一区二区三区四区| 亚洲精品中文在线影院| 日韩一级完整毛片| 91精品1区2区| 久久www免费人成看片高清| 国产精品二三区| 久久人人超碰精品| 在线播放亚洲一区| 99久久精品免费| 伦理电影国产精品| 一区二区三区四区中文字幕| 久久久久久久久一| 日韩免费福利电影在线观看| av不卡免费在线观看| 国产一区二区不卡| 蜜臀va亚洲va欧美va天堂| 亚洲人妖av一区二区| 日本一二三不卡| 2021中文字幕一区亚洲| 欧美精品色一区二区三区| 欧美在线观看你懂的| 成人一区二区三区在线观看| 精品在线你懂的| 久久se精品一区精品二区| 图片区小说区国产精品视频| 最新中文字幕一区二区三区| 久久久国际精品| 国产婷婷一区二区| 国产精品久久久久久亚洲伦| 精品播放一区二区| 成人一区二区在线观看| 九九热在线视频观看这里只有精品| 免费不卡在线视频| 青椒成人免费视频| 中文字幕不卡在线| 中文字幕一区二区三区不卡| 亚洲日本在线天堂| 亚洲夂夂婷婷色拍ww47 | 26uuu久久天堂性欧美| 精品国产乱码久久久久久夜甘婷婷| 欧美一级欧美三级| 久久久国产精品不卡| 国产精品久久久久久久久晋中| 国产精品久久久久久久久免费丝袜 | 成人小视频免费在线观看| 91蜜桃在线免费视频| 欧美麻豆精品久久久久久| 久久综合色综合88| 亚洲欧美激情视频在线观看一区二区三区 | 亚洲不卡av一区二区三区| 色综合久久综合网97色综合| 91精品国产免费| 国产精品天天摸av网| 亚洲综合久久久| 国产1区2区3区精品美女| 欧美色图天堂网| 国产日韩欧美一区二区三区综合| 一区二区三区自拍| 国内精品视频一区二区三区八戒| 91年精品国产| 国产午夜久久久久| 蜜桃免费网站一区二区三区| 在线观看日韩国产| 国产精品毛片无遮挡高清| 奇米色一区二区| 欧美老人xxxx18| 亚洲一区二区三区四区的| 成人午夜私人影院| 欧美成人三级电影在线| 舔着乳尖日韩一区| 欧美亚洲自拍偷拍| 一区二区欧美在线观看| 91婷婷韩国欧美一区二区| 国产欧美一区二区三区在线老狼| 久久国产尿小便嘘嘘| 日韩免费在线观看| 日日夜夜精品视频免费| 精品视频在线免费观看| 亚洲国产日日夜夜| 91精彩视频在线观看| 一区二区三区不卡视频在线观看 | 伊人婷婷欧美激情| 亚洲综合免费观看高清完整版 | 国产精品三级av在线播放| 国产精品一卡二卡| 久久精品欧美日韩精品| 国产一区二区三区观看| 日韩欧美三级在线|