?? arp
字號:
| ------------
| | 包分發 |
| ------------
| |
| V
| ----------------------------
| | | | |
| V -------------------------- IP_in過濾
| | V V V
| ARP ICMP(Ping) UDP TCP
| | | | |
| ----------------------------
| | 串行處理
| | (32bitMCU可設計成并發模式)
|---------<-------------
圖7 接收流程圖
我仔細檢查了幾遍,似乎比較完備了,各種情況下均可以正常工作。在超負荷流量下,只會拋包,不會死機。當然,由于本人接觸資料有限和個人局限性,肯定有錯誤和疏漏之處,希望大家提出意見和建議。
偽代碼清單:
ARP_init() //ARP緩存初始化
{
for(i=0;i<ARPTabSize;i++)
ARPTable[i].status=0;
}
ARP_request(目的IP地址) //ARP請求
{
//判斷IP地址是否屬于同一子網的任務交給上層軟件處理
//(由它決定請求網卡IP地址還是默認網關IP地址),
//這有利于減少代碼量。
//申請小號內存
pARP=OSMemGet();
//填以太網幀
以太網協議=0x0806;//ARP協議
目的MAC地址=0xffff;//廣播地址
源MAC地址=自己的MAC地址;
//填ARP表
硬件類型=0x0001;
協議類型=0x0800;
硬件地址長度=0x06;
協議長度=0x04;
操作=0x0001;//請求
發送方首部=自己的MAC地址;
發送方IP地址=源IP地址;
目標首部=0x0000;
目標IP地址=目的IP地址;
//填充PAD
沒有內容處填充0;
//發送ARP包至TxQFIFO緩存
OSQSend(QID,*pARP);
}
ARP_answer(*pARP) //ARP應答
{
學習/更新ARP緩存表;
//修改收到的ARP包,形成ARP應答
//填以太網幀
目的MAC地址=對方(網卡/網關)發來的源MAC地址;
源MAC地址=自己的MAC地址;
//填ARP表
目標首部=發送方首部;發送方首部=自己的MAC地址;
交換發送方IP地址和目標IP地址;
操作=0x0002;//ARP應答
//發送ARP包至TxQFIFO緩存
OSQSend(QID,*pARP);
}
ARP_process(*pARP) //ARP應答處理
{
//更新
for(i=0;i<ARPTabSize;i++){
if(ARPTab[i].status==1){
if(ARPTab[i].IPAdr==收到的ARP應答包源IP地址){
ARPTab[i].ttl=最大壽命;
ARPTab[i].IPAdr=收到的包的源IP地址;
ARPTab[i].MACAdr=收到的包的源MAC地址;
return;
}
}
}
//學習
for(i=0;i<ARPTabSize;i++){
if(ARPTab[i].status==0){
ARPTab[i].status=1;
ARPTab[i].ttl=最大壽命;
ARPTab[i].IPAdr=收到的包的源IP地址;
ARPTab[i].MACAdr=收到的包的源MAC地址;
return;
}
}
//表滿處理,有損性能的快速算法
ARPTab[index].status=1; //注:index為全局變量,保存ARP緩存表項索引。每次處理加1取模。
ARPTab[index].ttl=最大壽命;
index++;
if(index>=ARPTabSize) index=0;
}
IP_in(*pIP) //IP包過濾(ARP地址學習) 注:這里處理的是IP包,偽代碼與上面程序相似,但源代碼差別很大。
{
//更新
for(i=0;i<ARPTabSize;i++){
if(ARPTab[i].status==1){
if(ARPTab[i].IPAdr==收到的IP包源IP地址){
ARPTab[i].ttl=最大壽命;
ARPTab[i].IPAdr=收到的包的源IP地址;
ARPTab[i].MACAdr=收到的包的源MAC地址;
return;
}
}
}
//學習
for(i=0;i<ARPTabSize;i++){
if(ARPTab[i].status==0){
ARPTab[i].status=1;
ARPTab[i].ttl=最大壽命;
ARPTab[i].IPAdr=收到的包的源IP地址;
ARPTab[i].MACAdr=收到的包的源MAC地址;
return;
}
}
//表滿處理,有損性能的快速算法
ARPTab[index].status=1; //注:index為全局變量,保存ARP緩存表項索引。每次處理加1取模。
ARPTab[index].ttl=最大壽命;
index++;
if(index>=ARPTabSize) index=0;
}
timer() //軟定時器任務,用于ARP老化
{
for(;;){
taskDelay(1秒);
for(i=0;i<ARPTabSize;i++){
if(ARPTab[i].status==1){
if(ARPTab[i].ttl==0)
ARPTab[i].status=0;
else
ARPTab[i].ttl--;
}
}
}
主程序框架:
initNIC //初始化網卡
//創建資源
TxSem和RxSem信號量
TxQFIFO隊列
大中小內存設立
//創建任務
收
發
。
。
。
參考文獻:
1?!队肨CP/IP進行網際互連》(第3版)第一、二、三卷 DOUGLAS E.COMER著 電子工業出版社
2。www.laogu.com
3。www.sics.se/~adam/lwip/ 的uip6
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -