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

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

?? route.c

?? 內核是系統的心臟
?? C
字號:
/*
 * 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.
 *
 *		ROUTE - implementation of the IP router.
 *
 * Version:	@(#)route.c	1.0.14	05/31/93
 *
 * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
 *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *
 * Fixes:
 *		Alan Cox	:	Verify area fixes.
 *		Alan Cox	:	cli() protects routing changes
 *		Rui Oliveira	:	ICMP routing table updates
 *		(rco@di.uminho.pt)	Routing table insertion and update
 *		Linus Torvalds	:	Rewrote bits to be sensible
 *
 *		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 <asm/segment.h>
#include <asm/system.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/errno.h>
#include <linux/in.h>
#include "inet.h"
#include "dev.h"
#include "ip.h"
#include "protocol.h"
#include "route.h"
#include "tcp.h"
#include "skbuff.h"
#include "sock.h"
#include "arp.h"
#include "icmp.h"


static struct rtable *rt_base = NULL;
static struct rtable *rt_loopback = NULL;

/* Dump the contents of a routing table entry. */
static void
rt_print(struct rtable *rt)
{
  if (rt == NULL || inet_debug != DBG_RT) return;

  printk("RT: %06lx NXT=%06lx FLAGS=0x%02x\n",
		(long) rt, (long) rt->rt_next, rt->rt_flags);
  printk("    TARGET=%s ", in_ntoa(rt->rt_dst));
  printk("GW=%s ", in_ntoa(rt->rt_gateway));
  printk("    DEV=%s USE=%ld REF=%d\n",
	(rt->rt_dev == NULL) ? "NONE" : rt->rt_dev->name,
	rt->rt_use, rt->rt_refcnt);
}


/*
 * Remove a routing table entry.
 */
static void rt_del(unsigned long dst)
{
	struct rtable *r, **rp;
	unsigned long flags;

	DPRINTF((DBG_RT, "RT: flushing for dst %s\n", in_ntoa(dst)));
	rp = &rt_base;
	save_flags(flags);
	cli();
	while((r = *rp) != NULL) {
		if (r->rt_dst != dst) {
			rp = &r->rt_next;
			continue;
		}
		*rp = r->rt_next;
		if (rt_loopback == r)
			rt_loopback = NULL;
		kfree_s(r, sizeof(struct rtable));
	} 
	restore_flags(flags);
}


/*
 * Remove all routing table entries for a device.
 */
void rt_flush(struct device *dev)
{
	struct rtable *r;
	struct rtable **rp;
	unsigned long flags;

	DPRINTF((DBG_RT, "RT: flushing for dev 0x%08lx (%s)\n", (long)dev, dev->name));
	rp = &rt_base;
	cli();
	save_flags(flags);
	while ((r = *rp) != NULL) {
		if (r->rt_dev != dev) {
			rp = &r->rt_next;
			continue;
		}
		*rp = r->rt_next;
		if (rt_loopback == r)
			rt_loopback = NULL;
		kfree_s(r, sizeof(struct rtable));
	} 
	restore_flags(flags);
}

/*
 * Used by 'rt_add()' when we can't get the netmask any other way..
 *
 * If the lower byte or two are zero, we guess the mask based on the
 * number of zero 8-bit net numbers, otherwise we use the "default"
 * masks judging by the destination address and our device netmask.
 */
static inline unsigned long default_mask(unsigned long dst)
{
	dst = ntohl(dst);
	if (IN_CLASSA(dst))
		return htonl(IN_CLASSA_NET);
	if (IN_CLASSB(dst))
		return htonl(IN_CLASSB_NET);
	return htonl(IN_CLASSC_NET);
}

static unsigned long guess_mask(unsigned long dst, struct device * dev)
{
	unsigned long mask;

	if (!dst)
		return 0;
	mask = default_mask(dst);
	if ((dst ^ dev->pa_addr) & mask)
		return mask;
	return dev->pa_mask;
}

static inline struct device * get_gw_dev(unsigned long gw)
{
	struct rtable * rt;

	for (rt = rt_base ; ; rt = rt->rt_next) {
		if (!rt)
			return NULL;
		if ((gw ^ rt->rt_dst) & rt->rt_mask)
			continue;
		/* gateways behind gateways are a no-no */
		if (rt->rt_flags & RTF_GATEWAY)
			return NULL;
		return rt->rt_dev;
	}
}

/*
 * rewrote rt_add(), as the old one was weird. Linus
 */
void rt_add(short flags, unsigned long dst, unsigned long mask,
	unsigned long gw, struct device *dev)
{
	struct rtable *r, *rt;
	struct rtable **rp;
	unsigned long cpuflags;

	if (flags & RTF_HOST) {
		mask = 0xffffffff;
	} else if (!mask) {
		if (!((dst ^ dev->pa_addr) & dev->pa_mask)) {
			mask = dev->pa_mask;
			flags &= ~RTF_GATEWAY;
			if (flags & RTF_DYNAMIC) {
				/*printk("Dynamic route to my own net rejected\n");*/
				return;
			}
		} else
			mask = guess_mask(dst, dev);
		dst &= mask;
	}
	if (gw == dev->pa_addr)
		flags &= ~RTF_GATEWAY;
	if (flags & RTF_GATEWAY) {
		/* don't try to add a gateway we can't reach.. */
		if (dev != get_gw_dev(gw))
			return;
		flags |= RTF_GATEWAY;
	} else
		gw = 0;
	/* Allocate an entry. */
	rt = (struct rtable *) kmalloc(sizeof(struct rtable), GFP_ATOMIC);
	if (rt == NULL) {
		DPRINTF((DBG_RT, "RT: no memory for new route!\n"));
		return;
	}
	memset(rt, 0, sizeof(struct rtable));
	rt->rt_flags = flags | RTF_UP;
	rt->rt_dst = dst;
	rt->rt_dev = dev;
	rt->rt_gateway = gw;
	rt->rt_mask = mask;
	rt->rt_mtu = dev->mtu;
	rt_print(rt);
	/*
	 * What we have to do is loop though this until we have
	 * found the first address which has a higher generality than
	 * the one in rt.  Then we can put rt in right before it.
	 */
	save_flags(cpuflags);
	cli();
	/* remove old route if we are getting a duplicate. */
	rp = &rt_base;
	while ((r = *rp) != NULL) {
		if (r->rt_dst != dst) {
			rp = &r->rt_next;
			continue;
		}
		*rp = r->rt_next;
		if (rt_loopback == r)
			rt_loopback = NULL;
		kfree_s(r, sizeof(struct rtable));
	}
	/* add the new route */
	rp = &rt_base;
	while ((r = *rp) != NULL) {
		if ((r->rt_mask & mask) != mask)
			break;
		rp = &r->rt_next;
	}
	rt->rt_next = r;
	*rp = rt;
	if (rt->rt_dev->flags & IFF_LOOPBACK)
		rt_loopback = rt;
	restore_flags(cpuflags);
	return;
}

static inline int bad_mask(unsigned long mask, unsigned long addr)
{
	if (addr & (mask = ~mask))
		return 1;
	mask = ntohl(mask);
	if (mask & (mask+1))
		return 1;
	return 0;
}

static int rt_new(struct rtentry *r)
{
	int err;
	char * devname;
	struct device * dev = NULL;
	unsigned long flags, daddr, mask, gw;

	if ((devname = r->rt_dev) != NULL) {
		err = getname(devname, &devname);
		if (err)
			return err;
		dev = dev_get(devname);
		putname(devname);
		if (!dev)
			return -EINVAL;
	}

	if (r->rt_dst.sa_family != AF_INET)
		return -EAFNOSUPPORT;

	flags = r->rt_flags;
	daddr = ((struct sockaddr_in *) &r->rt_dst)->sin_addr.s_addr;
	mask = ((struct sockaddr_in *) &r->rt_genmask)->sin_addr.s_addr;
	gw = ((struct sockaddr_in *) &r->rt_gateway)->sin_addr.s_addr;

/* BSD emulation: Permits route add someroute gw one-of-my-addresses
   to indicate which iface. Not as clean as the nice Linux dev technique
   but people keep using it... */
	if (!dev && (flags & RTF_GATEWAY)) {
		struct device *dev2;
		for (dev2 = dev_base ; dev2 != NULL ; dev2 = dev2->next) {
			if ((dev2->flags & IFF_UP) && dev2->pa_addr == gw) {
				flags &= ~RTF_GATEWAY;
				dev = dev2;
				break;
			}
		}
	}

	if (bad_mask(mask, daddr))
		mask = 0;

	if (flags & RTF_HOST)
		mask = 0xffffffff;
	else if (mask && r->rt_genmask.sa_family != AF_INET)
		return -EAFNOSUPPORT;

	if (flags & RTF_GATEWAY) {
		if (r->rt_gateway.sa_family != AF_INET)
			return -EAFNOSUPPORT;
		if (!dev)
			dev = get_gw_dev(gw);
	} else if (!dev)
		dev = dev_check(daddr);

	if (dev == NULL)
		return -ENETUNREACH;

	rt_add(flags, daddr, mask, gw, dev);
	return 0;
}


static int rt_kill(struct rtentry *r)
{
	struct sockaddr_in *trg;

	trg = (struct sockaddr_in *) &r->rt_dst;
	rt_del(trg->sin_addr.s_addr);
	return 0;
}


/* Called from the PROCfs module. */
int
rt_get_info(char *buffer)
{
  struct rtable *r;
  char *pos;

  pos = buffer;

  pos += sprintf(pos,
		 "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tMask\n");
  
  /* This isn't quite right -- r->rt_dst is a struct! */
  for (r = rt_base; r != NULL; r = r->rt_next) {
        pos += sprintf(pos, "%s\t%08lX\t%08lX\t%02X\t%d\t%lu\t%d\t%08lX\n",
		r->rt_dev->name, r->rt_dst, r->rt_gateway,
		r->rt_flags, r->rt_refcnt, r->rt_use, r->rt_metric,
		r->rt_mask);
  }
  return(pos - buffer);
}

/*
 * This is hackish, but results in better code. Use "-S" to see why.
 */
#define early_out ({ goto no_route; 1; })

struct rtable * rt_route(unsigned long daddr, struct options *opt)
{
	struct rtable *rt;

	for (rt = rt_base; rt != NULL || early_out ; rt = rt->rt_next) {
		if (!((rt->rt_dst ^ daddr) & rt->rt_mask))
			break;
		/* broadcast addresses can be special cases.. */
		if ((rt->rt_dev->flags & IFF_BROADCAST) &&
		     rt->rt_dev->pa_brdaddr == daddr)
			break;
	}
	if (daddr == rt->rt_dev->pa_addr) {
		if ((rt = rt_loopback) == NULL)
			goto no_route;
	}
	rt->rt_use++;
	return rt;
no_route:
	return NULL;
}

static int get_old_rtent(struct old_rtentry * src, struct rtentry * rt)
{
	int err;
	struct old_rtentry tmp;

	err=verify_area(VERIFY_READ, src, sizeof(*src));
	if (err)
		return err;
	memcpy_fromfs(&tmp, src, sizeof(*src));
	memset(rt, 0, sizeof(*rt));
	rt->rt_dst = tmp.rt_dst;
	rt->rt_gateway = tmp.rt_gateway;
	rt->rt_genmask.sa_family = AF_INET;
	((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr = tmp.rt_genmask;
	rt->rt_flags = tmp.rt_flags;
	rt->rt_dev = tmp.rt_dev;
	return 0;
}

int rt_ioctl(unsigned int cmd, void *arg)
{
	int err;
	struct rtentry rt;

	switch(cmd) {
	case DDIOCSDBG:
		return dbg_ioctl(arg, DBG_RT);
	case SIOCADDRTOLD:
	case SIOCDELRTOLD:
		if (!suser())
			return -EPERM;
		err = get_old_rtent((struct old_rtentry *) arg, &rt);
		if (err)
			return err;
		return (cmd == SIOCDELRTOLD) ? rt_kill(&rt) : rt_new(&rt);
	case SIOCADDRT:
	case SIOCDELRT:
		if (!suser())
			return -EPERM;
		err=verify_area(VERIFY_READ, arg, sizeof(struct rtentry));
		if (err)
			return err;
		memcpy_fromfs(&rt, arg, sizeof(struct rtentry));
		return (cmd == SIOCDELRT) ? rt_kill(&rt) : rt_new(&rt);
	}

	return -EINVAL;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
久久精品国产久精国产爱| 久久精品人人做人人爽人人| 欧美亚洲国产一卡| 9191成人精品久久| 久久久九九九九| 国产精品激情偷乱一区二区∴| 综合色天天鬼久久鬼色| 日本女人一区二区三区| 国产精品一区二区在线观看网站| 色综合咪咪久久| 欧美电影精品一区二区| 国产精品国产三级国产| 性做久久久久久久免费看| 国产经典欧美精品| 欧美区视频在线观看| 中文字幕不卡的av| 亚洲欧美日韩综合aⅴ视频| 麻豆传媒一区二区三区| 精品系列免费在线观看| 欧洲一区在线电影| 国产精品三级av在线播放| 青青草91视频| 在线亚洲免费视频| 国产欧美日韩中文久久| 蜜臀久久久久久久| 色噜噜狠狠一区二区三区果冻| 精品av久久707| 三级精品在线观看| 在线影院国内精品| 欧美一区二区在线视频| 亚洲午夜久久久久久久久久久| 国产一区二区导航在线播放| 欧美日韩三级视频| 一区二区三区四区视频精品免费| 国内一区二区视频| 日韩美一区二区三区| 日精品一区二区| 欧美伦理电影网| 亚洲一区二区三区四区在线免费观看 | 91色乱码一区二区三区| 欧美精选午夜久久久乱码6080| 亚洲区小说区图片区qvod| 成人av电影在线观看| 久久婷婷国产综合国色天香| 麻豆精品一区二区三区| 欧美一区二区在线免费观看| 亚洲综合成人在线视频| 日本电影欧美片| 亚洲欧美国产毛片在线| 99久久婷婷国产| 亚洲精品日产精品乱码不卡| 99国产精品99久久久久久| 椎名由奈av一区二区三区| caoporm超碰国产精品| 国产精品天天看| 免费的成人av| 日韩视频永久免费| 国内精品视频666| 国产女人18毛片水真多成人如厕| 激情欧美日韩一区二区| 国产日韩欧美精品一区| 北条麻妃国产九九精品视频| 国产精品天干天干在观线| 国产剧情一区二区| 国产精品久久久久久久蜜臀| 国产成人免费视频网站 | 日韩成人免费看| 欧美性一级生活| 亚洲成人精品影院| 欧美一区二区三区系列电影| 国内精品伊人久久久久av一坑| 国产亚洲1区2区3区| 99r国产精品| 肉色丝袜一区二区| 欧美一区在线视频| 国产成人在线观看| 一区二区三区在线观看国产| 欧美日韩电影在线| 国产成人综合视频| 日本一区二区在线不卡| 色域天天综合网| 亚洲二区视频在线| 久久久久久久久久看片| 欧美日韩国产在线播放网站| gogo大胆日本视频一区| 国产伦精一区二区三区| 日韩高清欧美激情| 中文字幕在线观看一区| 久久亚洲综合av| 欧美婷婷六月丁香综合色| 激情综合五月婷婷| 亚洲国产精品久久一线不卡| 国产女人18水真多18精品一级做| 欧美精品xxxxbbbb| 99久久精品情趣| 国产盗摄一区二区三区| 蜜桃视频第一区免费观看| 亚洲国产日韩综合久久精品| 自拍偷拍欧美激情| 亚洲欧洲色图综合| 国产女同性恋一区二区| 久久精品男人的天堂| 欧美精品一区二区三区一线天视频 | 在线国产亚洲欧美| av男人天堂一区| 成人午夜视频免费看| 国产黑丝在线一区二区三区| 极品瑜伽女神91| 国产一区二区h| 国产自产2019最新不卡| 韩国精品一区二区| 狠狠色狠狠色综合系列| 国产在线视频一区二区| 九九在线精品视频| 国产一区二区导航在线播放| 国产一区二区福利视频| 国产精品一二三四五| 国产精品一区二区视频| 成人性生交大片免费看视频在线| 懂色一区二区三区免费观看| 成人av在线影院| 色婷婷av一区二区三区软件| 在线观看网站黄不卡| 欧美美女一区二区三区| 91精品国产色综合久久ai换脸| 91精品国产色综合久久不卡蜜臀 | 久久综合九色综合97_久久久| 精品91自产拍在线观看一区| 亚洲一卡二卡三卡四卡| 久久久久久麻豆| 国产日韩欧美亚洲| 中文字幕日本不卡| 亚洲国产成人tv| 免费成人在线观看视频| 国产成人精品免费看| 日本韩国精品在线| 欧美精品高清视频| 久久久久久久久久久久久久久99| 国产精品国产三级国产aⅴ原创| 亚洲欧美另类综合偷拍| 肉色丝袜一区二区| 国产成人精品免费| 欧美亚洲国产一区二区三区va| 欧美一区二区黄| 中文字幕乱码一区二区免费| 一区二区三区日韩欧美精品| 免费成人深夜小野草| 99精品久久只有精品| 欧美精品第1页| 国产精品视频一二三区 | 老司机精品视频线观看86| 成人性生交大片免费看在线播放| 在线观看中文字幕不卡| 精品福利av导航| 一区二区三区蜜桃| 国内外成人在线视频| 在线观看日韩高清av| 久久精品欧美一区二区三区麻豆| 亚洲欧美成aⅴ人在线观看| 欧美bbbbb| 99re视频这里只有精品| 精品美女在线观看| 亚洲一二三区不卡| av在线这里只有精品| 精品日产卡一卡二卡麻豆| 国产乱人伦精品一区二区在线观看| 久久99最新地址| 日韩三级伦理片妻子的秘密按摩| 欧美性猛交xxxxxx富婆| 国产日韩欧美精品电影三级在线| 天天色 色综合| 91行情网站电视在线观看高清版| 久久理论电影网| 蜜臀av性久久久久蜜臀av麻豆 | 国产在线精品视频| 色婷婷精品久久二区二区蜜臂av| 久久免费的精品国产v∧| 日韩av二区在线播放| 在线一区二区三区四区五区| 国产精品久久精品日日| 国产精品一区二区不卡| 91精品国产手机| 亚洲国产一区二区三区| 不卡的av在线| 中文字幕乱码亚洲精品一区| 免费人成在线不卡| 欧美电影一区二区| 亚洲国产成人91porn| 在线国产亚洲欧美| 亚洲欧美日韩成人高清在线一区| 国产精品亚洲专一区二区三区| 欧美大片一区二区| 日本sm残虐另类| 欧美一级生活片| 日本sm残虐另类| 日韩一级片在线观看| 美日韩一区二区三区| 欧美刺激午夜性久久久久久久 | 国产精品18久久久久久久久 | 国产精品久久久久久久久快鸭|