Linux的硬體位址解析過程

2021-03-31 18:59:57 字數 3906 閱讀 4107

linux的硬體位址解析過程

1) 在網路介面裝置的硬體層之間能夠直接進行包交換的裝置構成了乙個區域網,

區域網中的每一裝置

具有唯一的硬體位址. 對tcpip協議來說, 區域網中的每一裝置又具有唯一的ip位址.

當ip包要從某一

裝置發向區域網中具有另一ip位址的裝置時, 信源裝置必須獲得信宿裝置的硬體位址,

這就需要硬體

位址解析.arp協議是根據裝置的ip位址獲取其硬體位址的方法.

信源裝置向區域網廣播自已位址解析

請求, 區域網中其餘裝置都收到該請求, 具有所請求ip位址的裝置向信源裝置作出應答,

提供它的硬

件位址. 由於arp請求的廣播特性, 某一裝置可以對不是自已ip位址的請求作出應答,

這就是arp**.

2) 在linux核心中, 將能與自已在硬體層直接通訊的其他網路介面裝置稱為"鄰居",

用neighbour結構描述, 它包含裝置的硬體位址資訊.系統中所有的ip包都通過路由所繫結的鄰居傳送到介面裝置上.

鄰居由鄰居表(arp_tbl)來索引, 用鄰居的ip位址可查詢鄰居表中裝置的某個鄰居.

3) 當要傳送的ip包時, 如果鄰居的硬體位址(mac)還未解析,則將傳送包暫時緩衝在arp_queue隊

列中,然後傳送【位址解析】請求, 這時鄰居的狀態為未完成狀態(nud_in***plete).

如果1秒內沒收到arp應答, 將重發arp請求, 如果重發達到3次, 則解析失敗,

鄰居為失敗狀態(nud_failed).

當收到正確應答, 鄰居進入連線狀態(nud_reachable),這時arp_queue中傳送包將被建立幀頭後傳送到裝置上.

4) 鄰居的ip位址與硬體位址的關係並不是固定的, 系統在接收來自鄰居的ip包時,

會及時地證實(confirm)鄰居的ip位址與硬體位址的對映關係. 同時,

鄰居表每60秒周期性地掃瞄鄰居(neigh_periodic_timer),

一方面從表中清除那些解析失敗和長時間(60秒)未被使用的鄰居,

另一方面識別那些證實時間已超時的鄰居,將它們從連線狀態變為過期狀態(nud_stale).

; ***/ipv4/arp.c, core/neighbour.c:

;while ((n = *np) != null)

if ((long)(n->used - n->confirmed) < 0)

n->used = n->confirmed;

if (atomic_read(&n->ref**t) == 1 &&

(state == nud_failed || now - n->used > n->parms->gc_staletime))

if (n->nud_state&nud_reachable &&

now - n->confirmed > n->parms->reachable_time)

write_unlock(&n->lock);

next_elt:

np = &n->next;}}

mod_timer(&tbl->gc_timer, now + tbl->gc_interval);

write_unlock(&tbl->lock);

}int arp_bind_neighbour(struct dst_entry *dst) 將鄰居繫結給指定路由

return 0;

}static inline struct neighbour *

__neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,

struct ***_device *dev)

struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,

struct ***_device *dev)

}read_unlock_bh(&tbl->lock);

return n;

}static u32 arp_hash(const void *pkey, const struct ***_device *dev)

struct neighbour * neigh_create(struct neigh_table *tbl, const void *pkey,

struct ***_device *dev)

/* device specific setup. */

if (n->parms && n->parms->neigh_setup &&

(error = n->parms->neigh_setup(n)) < 0)

n->confirmed = jiffies - (n->parms->base_reachable_time<<1);

hash_val = tbl->hash(pkey, dev);

write_lock_bh(&tbl->lock);

for (n1 = tbl->hash_buckets[hash_val]; n1; n1 = n1->next)

}n->next = tbl->hash_buckets[hash_val];

tbl->hash_buckets[hash_val] = n; 插入索引鏈

n->dead = 0;

neigh_hold(n);

write_unlock_bh(&tbl->lock);

neigh_printk2("neigh %p is created./n", n);

return n;

}static struct neighbour *neigh_alloc(struct neigh_table *tbl) 分配鄰居結構

n = kmem_cache_alloc(tbl->kmem_cachep, slab_atomic);

if (n == null)

return null;

memset(n, 0, tbl->entry_size);

skb_queue_head_init(&n->arp_queue); 當鄰居的位址尚未解析時,

發向該鄰居的包緩衝在該佇列中

n->lock = rw_lock_unlocked;

n->updated = n->used = now;

n->nud_state = nud_none;

n->output = neigh_blackhole; 鄰居的ip包注入口

n->parms = &tbl->parms; 繼承鄰居表的引數

init_timer(&n->timer);

n->timer.function = neigh_timer_handler; 接收超時臨視器

n->timer.data = (unsigned long)n;

tbl->stats.allocs++;

neigh_glbl_allocs++;

tbl->entries++;

n->tbl = tbl;

atomic_set(&n->ref**t, 1);

n->dead = 1;

return n;

}static int neigh_blackhole(struct sk_buff *skb)

static int neigh_forced_gc(struct neigh_table *tbl) 強制釋放鄰居

{int shrunk = 0;

int i;

for (i=0; i<=neigh_hashmask; i++) {

struct neighbour *n, **np;

np = &tbl->hash_buckets

Linux的硬體位址解析過程

while n np null if long n used n confirmed 0 n used n confirmed if atomic read n ref t 1 state nud failed now n used n parms gc staletime if n nud sta...

ARP位址解析過程

arp位址解析過程 1 主機a首先檢視自己的arp表,確定其中是否包含有主機b對應的arp表項。如果找到了對應的mac位址,則主機a直接利用arp表中的mac位址,對ip資料報進行幀封裝,並將資料報傳送給主機b。2 如果主機a在arp表中找不到對應的mac位址,則將快取該資料報文,然後以廣播方式傳送...

開源硬體的幾個參考位址

各種派pi raspberry pi電腦板,中文譯名 樹莓派 banana pi 香蕉派是 raspberry pi 樹莓派的 轉殖 www.banana pi.com 最新開源硬體專案,相容樹莓派 banana pi m1是為了配合elastos.org開源os推廣而推出開源硬體平台 楊梅派 wa...