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

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

?? arp.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 2 頁
字號:
/*
 * INET		An implementation of the TCP/IP protocol suite for the LINUX
 *		operating system.  INET is implemented using the  BSD Socket
 *		interface as the means of communication with the user level.
 *
 *		This file implements the Address Resolution Protocol (ARP),
 *		which is used by TCP/IP to map the IP addresses from a host
 *		to a low-level hardware address (like an Ethernet address)
 *		which it can use to talk to that host.
 *
 * NOTE:	This module will be rewritten completely in the near future,
 *		because I want it to become a multi-address-family address
 *		resolver, like it should be.  It will be put in a separate
 *		directory under 'net', being a protocol of its own. -FvK
 *
 * Version:	@(#)arp.c	1.0.15	05/25/93
 *
 * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *		Arnt Gulbrandsen, <agulbra@pvv.unit.no>
 *
 * Fixes:
 *		Stephen A. Wood	:	arp problems
 *		'Mr Linux'	:	arp problems.
 *		Alan Cox	:	arp_ioctl now checks memory areas with verify_area.
 *		Alan Cox	:	Non IP arp message now only appears with debugging on.
 *		Alan Cox	: 	arp queue is volatile (may be altered by arp messages while doing sends) 
 *					Generic queue code is urgently needed!
 *		Alan Cox	:	Deleting your own ip addr now gives EINVAL not a printk message.
 *		Alan Cox	:	Fix to arp linked list error
 *		Alan Cox	:	Ignore broadcast arp (Linus' idea 8-))
 *		Alan Cox	:	arp_send memory leak removed
 *		Alan Cox	:	generic skbuff code fixes.
 *		Alan Cox	:	'Bad Packet' only reported on debugging
 *		Alan Cox	:	Proxy arp.
 *		Alan Cox	:	skb->link3 maintained by letting the other xmit queue kill the packet.
 *		Alan Cox	:	Knows about type 3 devices (AX.25) using an AX.25 protocol ID not the ethernet
 *					one.
 *		Dominik Kubla	:	Better checking
 *		Tegge		:	Assorted corrections on cross port stuff
 *		Alan Cox	:	ATF_PERM was backwards! - might be useful now (sigh)
 *		Alan Cox	:	Arp timer added.
 *
 * To Fix:
 *				:	arp response allocates an skbuff to send. However there is a perfectly
 *					good spare skbuff the right size about to be freed (the query). Use the
 *					query for the reply. This avoids an out of memory case _and_ speeds arp
 *					up.
 *				:	FREE_READ v FREE_WRITE errors. Not critical as loopback arps don't occur
 *
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 */
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/config.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/if_arp.h>
#include <linux/in.h>
#include <asm/system.h>
#include <asm/segment.h>
#include <stdarg.h>
#include "inet.h"
#include "dev.h"
#include "eth.h"
#include "ip.h"
#include "route.h"
#include "protocol.h"
#include "tcp.h"
#include "skbuff.h"
#include "sock.h"
#include "arp.h"


#define ARP_MAX_TRIES	3


static char *unk_print(unsigned char *, int);
static char *eth_aprint(unsigned char *, int);


static char *arp_cmds[] = {
  "0x%04X",
  "REQUEST",
  "REPLY",
  "REVERSE REQUEST",
  "REVERSE REPLY",
  NULL
};
#define	ARP_MAX_CMDS	(sizeof(arp_cmds) / sizeof(arp_cmds[0]))

static struct {
  char	*name;
  char	*(*print)(unsigned char *ptr, int len);
} arp_types[] = {
  { "0x%04X",			unk_print	},
  { "10 Mbps Ethernet", 	eth_aprint	},
  { "3 Mbps Ethernet",		eth_aprint	},
  { "AX.25",			unk_print	},
  { "Pronet",			unk_print	},
  { "Chaos",			unk_print	},
  { "IEEE 802.2 Ethernet (?)",	eth_aprint	},
  { "Arcnet",			unk_print	},
  { "AppleTalk",		unk_print	},
  { NULL,			NULL		}
};
#define	ARP_MAX_TYPE	(sizeof(arp_types) / sizeof(arp_types[0]))


struct arp_table *arp_tables[ARP_TABLE_SIZE] = {
  NULL,
};

static int arp_proxies=0;	/* So we can avoid the proxy arp 
				   overhead with the usual case of
				   no proxy arps */

struct sk_buff * volatile arp_q = NULL;

static struct arp_table *arp_lookup(unsigned long addr);
static struct arp_table *arp_lookup_proxy(unsigned long addr);

/* Dump the ADDRESS bytes of an unknown hardware type. */
static char *
unk_print(unsigned char *ptr, int len)
{
  static char buff[32];
  char *bufp = buff;
  int i;

  for (i = 0; i < len; i++)
	bufp += sprintf(bufp, "%02X ", (*ptr++ & 0377));
  return(buff);
}


/* Dump the ADDRESS bytes of an Ethernet hardware type. */
static char *
eth_aprint(unsigned char *ptr, int len)
{
  if (len != ETH_ALEN) return("");
  return(eth_print(ptr));
}


/* Dump an ARP packet. Not complete yet for non-Ethernet packets. */
static void
arp_print(struct arphdr *arp)
{
  int len, idx;
  unsigned char *ptr;

  if (inet_debug != DBG_ARP) return;

  printk("ARP: ");
  if (arp == NULL) {
	printk("(null)\n");
	return;
  }

  /* Print the opcode name. */
  len = htons(arp->ar_op);
  if (len < ARP_MAX_CMDS) idx = len;
    else idx = 0;
  printk("op ");
  printk(arp_cmds[idx], len);

  /* Print the ARP header. */
  len = htons(arp->ar_hrd);
  if (len < ARP_MAX_TYPE) idx = len;
    else idx = 0;
  printk("   hrd = "); printk(arp_types[idx].name, len);
  printk("   pro = 0x%04X\n", htons(arp->ar_pro));
  printk("   hlen = %d plen = %d\n", arp->ar_hln, arp->ar_pln);

  /*
   * Print the variable data.
   * When ARP gets redone (after the formal introduction of NET-2),
   * this part will be redone.  ARP will then be a multi-family address
   * resolver, and the code below will be made more general. -FvK
   */
  ptr = ((unsigned char *) &arp->ar_op) + sizeof(u_short);
  printk("   sender HA = %s ", arp_types[idx].print(ptr, arp->ar_hln));
  ptr += arp->ar_hln;
  printk("  PA = %s\n", in_ntoa(*(unsigned long *) ptr));
  ptr += arp->ar_pln;
  printk("   target HA = %s ", arp_types[idx].print(ptr, arp->ar_hln));
  ptr += arp->ar_hln;
  printk("  PA = %s\n", in_ntoa(*(unsigned long *) ptr));
}


/* This will try to retransmit everything on the queue. */
static void
arp_send_q(void)
{
  struct sk_buff *skb;
  struct sk_buff *volatile work_q;
  cli();
  work_q = arp_q;
  skb_new_list_head(&work_q);
  arp_q = NULL;
  sti();
  while((skb=skb_dequeue(&work_q))!=NULL)
  {
  	IS_SKB(skb);
	skb->magic = 0;
	skb->next = NULL;
	skb->prev = NULL;

	/* Decrement the 'tries' counter. */
	cli();
	skb->tries--;
	if (skb->tries == 0) {
		/*
		 * Grmpf.
		 * We have tried ARP_MAX_TRIES to resolve the IP address
		 * from this datagram.  This means that the machine does
		 * not listen to our ARP requests.  Perhaps someone tur-
		 * ned off the thing?
		 * In any case, trying further is useless.  So, we kill
		 * this packet from the queue.  (grinnik) -FvK
		 */
		skb->sk = NULL;
		if(skb->free)
			kfree_skb(skb, FREE_WRITE);
			/* If free was 0, magic is now 0, next is 0 and 
			   the write queue will notice and kill */
		sti();
		continue;
	}

	/* Can we now complete this packet? */
	sti();
	if (skb->arp || !skb->dev->rebuild_header(skb->data, skb->dev)) {
		skb->arp  = 1;
		skb->dev->queue_xmit(skb, skb->dev, 0);
	} else {
		/* Alas.  Re-queue it... */
		skb->magic = ARP_QUEUE_MAGIC;      
		skb_queue_head(&arp_q,skb);
	}
  }
}


static struct timer_list arp_timer;

static void arp_queue_ticker(unsigned long data);

static void arp_queue_kick(void)
{
	arp_timer.expires = 500;	/* 5 seconds */
	arp_timer.data = 0;
	arp_timer.function = arp_queue_ticker;
	del_timer(&arp_timer);
	add_timer(&arp_timer);
}

static void arp_queue_ticker(unsigned long data/*UNUSED*/)
{
	arp_send_q();
	if (skb_peek(&arp_q))
		arp_queue_kick();
}



/* Create and send our response to an ARP request. */
static int
arp_response(struct arphdr *arp1, struct device *dev,  int addrtype)
{
  struct arphdr *arp2;
  struct sk_buff *skb;
  unsigned long src, dst;
  unsigned char *ptr1, *ptr2;
  int hlen;
  struct arp_table *apt = NULL;/* =NULL otherwise the compiler gives warnings */

  /* Decode the source (REQUEST) message. */
  ptr1 = ((unsigned char *) &arp1->ar_op) + sizeof(u_short);
  src = *((unsigned long *) (ptr1 + arp1->ar_hln));
  dst = *((unsigned long *) (ptr1 + (arp1->ar_hln * 2) + arp1->ar_pln));
  
  if(addrtype!=IS_MYADDR)
  {
  	apt=arp_lookup_proxy(dst);
  	if(apt==NULL)
  		return(1);
  }

  /* Get some mem and initialize it for the return trip. */
  skb = alloc_skb(sizeof(struct sk_buff) +
  		sizeof(struct arphdr) +
		(2 * arp1->ar_hln) + (2 * arp1->ar_pln) +
		dev->hard_header_len, GFP_ATOMIC);
  if (skb == NULL) {
	printk("ARP: no memory available for ARP REPLY!\n");
	return(1);
  }

  skb->mem_addr = skb;
  skb->len      = sizeof(struct arphdr) + (2 * arp1->ar_hln) + 
		  (2 * arp1->ar_pln) + dev->hard_header_len;
  skb->mem_len  = sizeof(struct sk_buff) + skb->len;
  hlen = dev->hard_header(skb->data, dev, ETH_P_ARP, src, dst, skb->len);
  if (hlen < 0) {
	printk("ARP: cannot create HW frame header for REPLY !\n");
	kfree_skb(skb, FREE_WRITE);
	return(1);
  }

  /*
   * Fill in the ARP REPLY packet.
   * This looks ugly, but we have to deal with the variable-length
   * ARP packets and such.  It is not as bad as it looks- FvK
   */
  arp2 = (struct arphdr *) (skb->data + hlen);
  ptr2 = ((unsigned char *) &arp2->ar_op) + sizeof(u_short);
  arp2->ar_hrd = arp1->ar_hrd;
  arp2->ar_pro = arp1->ar_pro;
  arp2->ar_hln = arp1->ar_hln;
  arp2->ar_pln = arp1->ar_pln;
  arp2->ar_op = htons(ARPOP_REPLY);
  if(addrtype==IS_MYADDR)
	  memcpy(ptr2, dev->dev_addr, arp2->ar_hln);
  else		/* Proxy arp, so pull from the table */
  	  memcpy(ptr2, apt->ha, arp2->ar_hln);
  ptr2 += arp2->ar_hln;
  memcpy(ptr2, ptr1 + (arp1->ar_hln * 2) + arp1->ar_pln, arp2->ar_pln);
  ptr2 += arp2->ar_pln;
  memcpy(ptr2, ptr1, arp2->ar_hln);
  ptr2 += arp2->ar_hln;
  memcpy(ptr2, ptr1 + arp1->ar_hln, arp2->ar_pln);

  skb->free = 1;
  skb->arp = 1;
  skb->sk = NULL;
  skb->next = NULL;

  DPRINTF((DBG_ARP, ">>"));
  arp_print(arp2);

  /* Queue the packet for transmission. */
  dev->queue_xmit(skb, dev, 0);
  return(0);
}


/* This will find an entry in the ARP table by looking at the IP address. */
static struct arp_table *
arp_lookup(unsigned long paddr)
{
  struct arp_table *apt;
  unsigned long hash;

  DPRINTF((DBG_ARP, "ARP: lookup(%s)\n", in_ntoa(paddr)));

  /* We don't want to ARP ourselves. */
  if (chk_addr(paddr) == IS_MYADDR) {
	printk("ARP: ARPing my own IP address %s !\n", in_ntoa(paddr));
	return(NULL);
  }

  /* Loop through the table for the desired address. */
  hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
  cli();
  apt = arp_tables[hash];
  while(apt != NULL) {
	if (apt->ip == paddr) {
		sti();
		return(apt);
	}
	apt = apt->next;
  }
  sti();
  return(NULL);
}


/* This will find a proxy in the ARP table by looking at the IP address. */
static struct arp_table *arp_lookup_proxy(unsigned long paddr)
{
  struct arp_table *apt;
  unsigned long hash;

  DPRINTF((DBG_ARP, "ARP: lookup proxy(%s)\n", in_ntoa(paddr)));

  /* Loop through the table for the desired address. */
  hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
  cli();
  apt = arp_tables[hash];
  while(apt != NULL) {
	if (apt->ip == paddr && (apt->flags & ATF_PUBL) ) {
		sti();
		return(apt);
	}
	apt = apt->next;
  }
  sti();
  return(NULL);
}


/* Delete an ARP mapping entry in the cache. */
void
arp_destructor(unsigned long paddr, int force)
{
  struct arp_table *apt;
  struct arp_table **lapt;
  unsigned long hash;

  DPRINTF((DBG_ARP, "ARP: destroy(%s)\n", in_ntoa(paddr)));

  /* We cannot destroy our own ARP entry. */
  if (chk_addr(paddr) == IS_MYADDR) {
	DPRINTF((DBG_ARP, "ARP: Destroying my own IP address %s !\n",
							in_ntoa(paddr)));
	return;
  }
  hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);

  cli();
  lapt = &arp_tables[hash];
  while ((apt = *lapt) != NULL) {
	if (apt->ip == paddr) {
		if((apt->flags&ATF_PERM) && !force)
			return;
		*lapt = apt->next;
		if(apt->flags&ATF_PUBL)
			arp_proxies--;			
		kfree_s(apt, sizeof(struct arp_table));
		sti();
		return;
	}
	lapt = &apt->next;
  }
  sti();
}

/*
 *	Kill an entry - eg for ioctl()
 */

void arp_destroy(unsigned long paddr)
{	
	arp_destructor(paddr,1);
}

/*
 *	Delete a possibly invalid entry (see timer.c)
 */

void arp_destroy_maybe(unsigned long paddr)
{
	arp_destructor(paddr,0);
}

/* Create an ARP entry.  The caller should check for duplicates! */
static struct arp_table *
arp_create(unsigned long paddr, unsigned char *addr, int hlen, int htype)
{
  struct arp_table *apt;
  unsigned long hash;

  DPRINTF((DBG_ARP, "ARP: create(%s, ", in_ntoa(paddr)));
  DPRINTF((DBG_ARP, "%s, ", eth_print(addr)));
  DPRINTF((DBG_ARP, "%d, %d)\n", hlen, htype));

  apt = (struct arp_table *) kmalloc(sizeof(struct arp_table), GFP_ATOMIC);
  if (apt == NULL) {
	printk("ARP: no memory available for new ARP entry!\n");
	return(NULL);
  }

  /* Fill in the allocated ARP cache entry. */
  hash = htonl(paddr) & (ARP_TABLE_SIZE - 1);
  apt->ip = paddr;
  apt->hlen = hlen;
  apt->htype = htype;
  apt->flags = (ATF_INUSE | ATF_COM);		/* USED and COMPLETED entry */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人精品一区二区三区四区| 国产午夜亚洲精品午夜鲁丝片| 日韩欧美一区在线观看| 欧美经典一区二区三区| 亚洲高清视频中文字幕| 国产一区二区福利视频| 欧美肥大bbwbbw高潮| 中文字幕巨乱亚洲| 精品一区二区三区香蕉蜜桃| 欧美最新大片在线看| 国产校园另类小说区| 日本aⅴ精品一区二区三区| 色诱视频网站一区| 国产欧美中文在线| 精品在线免费观看| 制服丝袜av成人在线看| 亚洲一区二区欧美激情| 成人高清av在线| 久久免费看少妇高潮| 国产成人在线看| 91精品在线观看入口| 一区二区在线观看视频| 成人国产一区二区三区精品| 国产亚洲成年网址在线观看| 久久国产精品无码网站| 91精品国产91久久久久久最新毛片 | 欧美亚洲愉拍一区二区| 国产日产精品一区| 国产麻豆精品theporn| 精品福利一区二区三区免费视频| 日韩精品五月天| 91精品国产欧美日韩| 天天综合色天天综合色h| 欧美日韩中文国产| 亚洲国产中文字幕| 欧美精品在线一区二区| 日韩激情一区二区| 日韩欧美一二三四区| 国内成人自拍视频| 久久久久久久久99精品| 国产乱子轮精品视频| 久久久久久久综合色一本| 国产成人在线视频播放| 国产精品成人网| 色综合 综合色| 午夜精品福利久久久| 日韩一区二区在线免费观看| 久久99这里只有精品| 国产午夜亚洲精品不卡| 91啪亚洲精品| 丝袜亚洲精品中文字幕一区| 91麻豆精品91久久久久久清纯| 久久9热精品视频| 中文字幕国产一区| 欧洲av在线精品| 麻豆成人久久精品二区三区小说| 国产欧美日韩亚州综合| 91网站黄www| 日韩福利电影在线| 国产欧美一区二区精品秋霞影院| 91视频在线观看免费| 国产成人av电影免费在线观看| 亚洲三级在线看| 91精品国产91久久久久久最新毛片| 国内成+人亚洲+欧美+综合在线| 国产欧美一区二区三区网站| 色哟哟国产精品| 久久精品国产一区二区| 亚洲三级在线免费| 精品国一区二区三区| 99国产精品久| 日韩高清不卡一区二区三区| 国产欧美日韩在线观看| 欧美群妇大交群中文字幕| 国产福利一区二区三区视频| 亚洲国产va精品久久久不卡综合| 久久久99精品免费观看不卡| 欧美伊人精品成人久久综合97| 国产传媒日韩欧美成人| 奇米一区二区三区| 亚洲裸体xxx| 国产人伦精品一区二区| 4438亚洲最大| 一本色道久久综合精品竹菊| 国产一区二区三区综合| 婷婷国产在线综合| 亚洲欧美电影院| 中文字幕成人av| 日韩视频一区二区三区在线播放 | 国产精品美日韩| 91麻豆精品国产自产在线观看一区 | 成人中文字幕在线| 免费成人你懂的| 亚洲国产一区二区在线播放| 中文字幕高清一区| 国产性做久久久久久| 日韩女优电影在线观看| 欧美日韩免费不卡视频一区二区三区| av爱爱亚洲一区| 国产成人精品影视| 国产精品69久久久久水密桃 | 国内精品伊人久久久久av一坑| 亚洲精品国产品国语在线app| 久久久777精品电影网影网| 欧美一级高清片在线观看| 欧美亚洲愉拍一区二区| 91在线云播放| 91视频免费播放| 91丨九色丨蝌蚪丨老版| 成人午夜精品在线| 国产精品一级片| 国产一区二区在线免费观看| 韩国三级电影一区二区| 九九热在线视频观看这里只有精品| 首页国产丝袜综合| 日本视频在线一区| 强制捆绑调教一区二区| 麻豆国产91在线播放| 久久精品噜噜噜成人av农村| 久久国产尿小便嘘嘘| 国产一区二区三区国产| 国产精品一区二区在线看| 国产在线播放一区| 国产成人一级电影| av电影天堂一区二区在线 | 激情综合网天天干| 久久国产精品无码网站| 狠狠色2019综合网| 国产伦精品一区二区三区免费 | 色94色欧美sute亚洲13| 91久久人澡人人添人人爽欧美| 欧美性受xxxx黑人xyx| 欧美日韩精品一区视频| 日韩欧美一卡二卡| 久久久精品影视| 亚洲日本乱码在线观看| 一区二区在线观看视频| 奇米888四色在线精品| 国产一区二区伦理| 99久久夜色精品国产网站| 欧美性videosxxxxx| 日韩欧美高清dvd碟片| 欧美经典一区二区| 亚洲午夜免费视频| 久久se精品一区精品二区| 成人妖精视频yjsp地址| 欧洲精品一区二区| 久久久久久夜精品精品免费| 国产中文字幕一区| 91小视频免费看| 日韩欧美一级在线播放| 国产精品美女久久久久久2018| 一区二区久久久久| 韩国精品主播一区二区在线观看| 不卡免费追剧大全电视剧网站| 欧美日韩中文精品| 欧美国产成人精品| 免费成人在线观看| 91欧美一区二区| 久久丝袜美腿综合| 午夜精品在线看| 成人免费av资源| 日韩精品一区二区三区中文精品| 1000部国产精品成人观看| 日韩电影一区二区三区四区| 成人性生交大片| 欧美一级黄色录像| 亚洲一二三四在线| 成人中文字幕电影| 日韩精品综合一本久道在线视频| 亚洲私人影院在线观看| 国产专区综合网| 欧美一级日韩免费不卡| 一区二区欧美精品| 国产成人av电影在线观看| 91精品国产综合久久久蜜臀粉嫩 | 亚洲欧洲一区二区在线播放| 喷白浆一区二区| 在线视频一区二区三| 日本一二三不卡| 国产精品一区专区| 精品久久久网站| 日本aⅴ亚洲精品中文乱码| 91福利资源站| 亚洲精品免费电影| 99精品视频在线播放观看| 中文字幕不卡在线观看| 国模冰冰炮一区二区| 欧美成人官网二区| 青青青伊人色综合久久| 在线播放国产精品二区一二区四区 | 日韩精品久久久久久| 欧美性受xxxx黑人xyx性爽| 亚洲精品亚洲人成人网| 99天天综合性| 亚洲啪啪综合av一区二区三区| www.日韩精品| 国产在线不卡一区| 欧美精品一区二区在线播放 | 日韩视频在线一区二区|