⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uip_arp.s

📁 uIP是免费的TCP/IP协议栈,我们将它移植到我们的AVR以太网开发板中
💻 S
📖 第 1 页 / 共 2 页
字号:
	.module uip_arp.c
	.area data(ram, con, rel)
_uip_ethaddr::
	.blkb 2
	.area idata
	.byte 'O,'F
	.area data(ram, con, rel)
	.blkb 2
	.area idata
	.byte 'F,'I
	.area data(ram, con, rel)
	.blkb 2
	.area idata
	.byte 'C,'E
	.area data(ram, con, rel)
	.dbfile D:\hexok项目\AVRNET项目\AVRNET光盘\AVRuIP\uip_arp.c
	.dbstruct 0 6 uip_eth_addr
	.dbfield 0 addr A[6:6]c
	.dbend
	.dbsym e uip_ethaddr _uip_ethaddr S[uip_eth_addr]
	.area text(rom, con, rel)
	.dbfile D:\hexok项目\AVRNET项目\AVRNET光盘\AVRuIP\uip_arp.c
	.dbfunc e uip_arp_init _uip_arp_init fV
	.even
_uip_arp_init::
	sbiw R28,2
	.dbline -1
	.dbline 129
; /**
;  * \addtogroup uip
;  * @{
;  */
; 
; /**
;  * \defgroup uiparp uIP Address Resolution Protocol
;  * @{
;  * 
;  * The Address Resolution Protocol ARP is used for mapping between IP
;  * addresses and link level addresses such as the Ethernet MAC
;  * addresses. ARP uses broadcast queries to ask for the link level
;  * address of a known IP address and the host which is configured with
;  * the IP address for which the query was meant, will respond with its
;  * link level address.
;  *
;  * \note This ARP implementation only supports Ethernet.
;  */
;  
; /**
;  * \file
;  * Implementation of the ARP Address Resolution Protocol.
;  * \author Adam Dunkels <adam@dunkels.com>
;  *
;  */
; 
; /*
;  * Copyright (c) 2001-2003, Adam Dunkels.
;  * All rights reserved. 
;  *
;  * Redistribution and use in source and binary forms, with or without 
;  * modification, are permitted provided that the following conditions 
;  * are met: 
;  * 1. Redistributions of source code must retain the above copyright 
;  *    notice, this list of conditions and the following disclaimer. 
;  * 2. Redistributions in binary form must reproduce the above copyright 
;  *    notice, this list of conditions and the following disclaimer in the 
;  *    documentation and/or other materials provided with the distribution. 
;  * 3. The name of the author may not be used to endorse or promote
;  *    products derived from this software without specific prior
;  *    written permission.  
;  *
;  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
;  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
;  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
;  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
;  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
;  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
;  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
;  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
;  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
;  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
;  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
;  *
;  * This file is part of the uIP TCP/IP stack.
;  *
;  * $Id: uip_arp.c,v 1.1 2004/05/09 00:24:48 Louis Exp $
;  *
;  */
; 
; 
; #include "uip_arp.h"
; 
; #include <string.h>
; 
; struct arp_hdr {
;   struct uip_eth_hdr ethhdr;
;   u16_t hwtype;
;   u16_t protocol;
;   u8_t hwlen;
;   u8_t protolen;
;   u16_t opcode;
;   struct uip_eth_addr shwaddr;
;   u16_t sipaddr[2];
;   struct uip_eth_addr dhwaddr;
;   u16_t dipaddr[2]; 
; };
; 
; struct ethip_hdr {
;   struct uip_eth_hdr ethhdr;
;   /* IP header. */
;   u8_t vhl,
;     tos,          
;     len[2],       
;     ipid[2],        
;     ipoffset[2],  
;     ttl,          
;     proto;     
;   u16_t ipchksum;
;   u16_t srcipaddr[2], 
;     destipaddr[2];
; };
; 
; #define ARP_REQUEST 1
; #define ARP_REPLY   2
; 
; #define ARP_HWTYPE_ETH 1
; 
; struct arp_entry {
;   u16_t ipaddr[2];
;   struct uip_eth_addr ethaddr;
;   u8_t time;
; };
; 
; struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0,
; 				    UIP_ETHADDR1,
; 				    UIP_ETHADDR2,
; 				    UIP_ETHADDR3,
; 				    UIP_ETHADDR4,
; 				    UIP_ETHADDR5}};
; 
; static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
; static u16_t ipaddr[2];
; static u8_t i, c;
; 
; static u8_t arptime;
; static u8_t tmpage;
; 
; #define BUF   ((struct arp_hdr *)&uip_buf[0])
; #define IPBUF ((struct ethip_hdr *)&uip_buf[0])
; /*-----------------------------------------------------------------------------------*/
; /**
;  * Initialize the ARP module.
;  *
;  */
; /*-----------------------------------------------------------------------------------*/
; void
; uip_arp_init(void)
; {
	.dbline 130
	clr R2
	sts _i,R2
	xjmp L11
L8:
	.dbline 130
	.dbline 131
	ldi R24,4
	ldi R25,0
	std y+1,R25
	std y+0,R24
	clr R18
	clr R19
	lds R2,_i
	ldi R24,11
	mul R24,R2
	movw R16,R0
	ldi R24,<_arp_table
	ldi R25,>_arp_table
	add R16,R24
	adc R17,R25
	xcall _memset
	.dbline 132
L9:
	.dbline 130
	lds R24,_i
	subi R24,255    ; addi 1
	sts _i,R24
L11:
	.dbline 130
;   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
	lds R24,_i
	cpi R24,8
	brlo L8
	.dbline -2
L7:
	adiw R28,2
	.dbline 0 ; func end
	ret
	.dbend
	.dbfunc e uip_arp_timer _uip_arp_timer fV
	.dbstruct 0 11 arp_entry
	.dbfield 0 ipaddr A[4:2]s
	.dbfield 4 ethaddr S[uip_eth_addr]
	.dbfield 10 time c
	.dbend
;         tabptr -> R10,R11
	.even
_uip_arp_timer::
	xcall push_gset3x
	sbiw R28,2
	.dbline -1
	.dbline 146
;     memset(arp_table[i].ipaddr, 0, 4);
;   }
; }
; /*-----------------------------------------------------------------------------------*/
; /**
;  * Periodic ARP processing function.
;  *
;  * This function performs periodic timer processing in the ARP module
;  * and should be called at regular intervals. The recommended interval
;  * is 10 seconds between the calls.
;  *
;  */
; /*-----------------------------------------------------------------------------------*/
; void
; uip_arp_timer(void)
; {
	.dbline 149
;   struct arp_entry *tabptr;
;   
;   ++arptime;
	lds R24,_arptime
	subi R24,255    ; addi 1
	sts _arptime,R24
	.dbline 150
	clr R2
	sts _i,R2
	xjmp L16
L13:
	.dbline 150
;   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
	.dbline 151
;     tabptr = &arp_table[i];
	lds R2,_i
	ldi R24,11
	mul R24,R2
	movw R10,R0
	ldi R24,<_arp_table
	ldi R25,>_arp_table
	add R10,R24
	adc R11,R25
	.dbline 152
;     if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
	movw R30,R10
	ldd R2,z+2
	ldd R3,z+3
	movw R30,R10
	ldd R4,z+0
	ldd R5,z+1
	or R4,R2
	or R5,R3
	tst R4
	brne X0
	tst R5
	breq L17
X0:
	movw R30,R10
	ldd R2,z+10
	lds R24,_arptime
	sub R24,R2
	cpi R24,120
	brlo L17
	.dbline 153
;        arptime - tabptr->time >= UIP_ARP_MAXAGE) {
	.dbline 154
;       memset(tabptr->ipaddr, 0, 4);
	ldi R24,4
	ldi R25,0
	std y+1,R25
	std y+0,R24
	clr R18
	clr R19
	movw R16,R10
	xcall _memset
	.dbline 155
;     }
L17:
	.dbline 156
L14:
	.dbline 150
	lds R24,_i
	subi R24,255    ; addi 1
	sts _i,R24
L16:
	.dbline 150
	lds R24,_i
	cpi R24,8
	brlo L13
	.dbline -2
L12:
	adiw R28,2
	xcall pop_gset3x
	.dbline 0 ; func end
	ret
	.dbsym r tabptr 10 pS[arp_entry]
	.dbend
	.dbfunc s uip_arp_update _uip_arp_update fV
;         tabptr -> R10,R11
;        ethaddr -> R12,R13
;         ipaddr -> R14,R15
	.even
_uip_arp_update:
	xcall push_gset5x
	movw R12,R18
	movw R14,R16
	sbiw R28,2
	.dbline -1
	.dbline 162
;   }
; 
; }
; /*-----------------------------------------------------------------------------------*/
; static void
; uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
; {
	.dbline 167
	clr R2
	sts _i,R2
	xjmp L23
L20:
	.dbline 167
;   register struct arp_entry *tabptr;
;   /* Walk through the ARP mapping table and try to find an entry to
;      update. If none is found, the IP -> MAC address mapping is
;      inserted in the ARP table. */
;   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
	.dbline 169
; 
;     tabptr = &arp_table[i];
	lds R2,_i
	ldi R24,11
	mul R24,R2
	movw R10,R0
	ldi R24,<_arp_table
	ldi R25,>_arp_table
	add R10,R24
	adc R11,R25
	.dbline 171
;     /* Only check those entries that are actually in use. */
;     if(tabptr->ipaddr[0] != 0 &&
	movw R30,R10
	ldd R2,z+0
	ldd R3,z+1
	tst R2
	brne X1
	tst R3
	brne X5
	xjmp L24
X5:
X1:
	movw R30,R10
	ldd R2,z+2
	ldd R3,z+3
	tst R2
	brne X2
	tst R3
	breq L24
X2:
	.dbline 172
;        tabptr->ipaddr[1] != 0) {
	.dbline 176
; 
;       /* Check if the source IP address of the incoming packet matches
;          the IP address in this ARP table entry. */
;       if(ipaddr[0] == tabptr->ipaddr[0] &&
	movw R30,R10
	ldd R2,z+0
	ldd R3,z+1
	movw R30,R14
	ldd R4,z+0
	ldd R5,z+1
	cp R4,R2
	cpc R5,R3
	brne L26
	movw R30,R10
	ldd R2,z+2
	ldd R3,z+3
	movw R30,R14
	ldd R4,z+2
	ldd R5,z+3
	cp R4,R2
	cpc R5,R3
	brne L26
	.dbline 177
; 	 ipaddr[1] == tabptr->ipaddr[1]) {
	.dbline 180
; 	 
; 	/* An old entry found, update this and return. */
; 	memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
	ldi R24,6
	ldi R25,0
	std y+1,R25
	std y+0,R24
	movw R18,R12
	movw R16,R10
	subi R16,252  ; offset = 4
	sbci R17,255
	xcall _memcpy
	.dbline 181
; 	tabptr->time = arptime;
	lds R2,_arptime
	movw R30,R10
	std z+10,R2
	.dbline 183
; 
; 	return;
	xjmp L19
L26:
	.dbline 185
;       }
;     }
L24:
	.dbline 186
L21:
	.dbline 167
	lds R24,_i
	subi R24,255    ; addi 1
	sts _i,R24
L23:
	.dbline 167
	lds R24,_i
	cpi R24,8
	brsh X6
	xjmp L20
X6:
	.dbline 192
	clr R2
	sts _i,R2
	xjmp L31
L28:
	.dbline 192
;   }
; 
;   /* If we get here, no existing ARP table entry was found, so we
;      create one. */
; 
;   /* First, we try to find an unused entry in the ARP table. */
;   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
	.dbline 193
;     tabptr = &arp_table[i];
	lds R2,_i
	ldi R24,11
	mul R24,R2
	movw R10,R0
	ldi R24,<_arp_table
	ldi R25,>_arp_table
	add R10,R24
	adc R11,R25
	.dbline 194
;     if(tabptr->ipaddr[0] == 0 &&
	movw R30,R10
	ldd R2,z+0
	ldd R3,z+1
	tst R2
	brne L32
	tst R3
	brne L32
X3:
	movw R30,R10
	ldd R2,z+2
	ldd R3,z+3
	tst R2
	brne L32
	tst R3
	brne L32
X4:
	.dbline 195
;        tabptr->ipaddr[1] == 0) {
	.dbline 196
;       break;
	xjmp L30
L32:
	.dbline 198
L29:
	.dbline 192
	lds R24,_i
	subi R24,255    ; addi 1
	sts _i,R24
L31:
	.dbline 192
	lds R24,_i
	cpi R24,8
	brlo L28
L30:
	.dbline 202
;     }
;   }
; 
;   /* If no unused entry is found, we try to find the oldest entry and
;      throw it away. */
;   if(i == UIP_ARPTAB_SIZE) {
	lds R24,_i
	cpi R24,8
	brne L34
	.dbline 202
	.dbline 203
;     tmpage = 0;
	clr R2
	sts _tmpage,R2
	.dbline 204
;     c = 0;
	sts _c,R2
	.dbline 205
	sts _i,R2
	xjmp L39
L36:
	.dbline 205
;     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
	.dbline 206
;       tabptr = &arp_table[i];
	lds R2,_i
	ldi R24,11
	mul R24,R2
	movw R10,R0
	ldi R24,<_arp_table
	ldi R25,>_arp_table
	add R10,R24
	adc R11,R25
	.dbline 207
;       if(arptime - tabptr->time > tmpage) {
	movw R30,R10
	ldd R2,z+10
	lds R3,_arptime
	sub R3,R2
	lds R2,_tmpage
	cp R2,R3
	brsh L40
	.dbline 207
	.dbline 208
; 	tmpage = arptime - tabptr->time;
	movw R30,R10
	ldd R2,z+10
	lds R3,_arptime
	sub R3,R2
	sts _tmpage,R3
	.dbline 209
; 	c = i;
	lds R2,_i
	sts _c,R2
	.dbline 210
;       }
L40:
	.dbline 211
L37:
	.dbline 205
	lds R24,_i
	subi R24,255    ; addi 1
	sts _i,R24
L39:
	.dbline 205
	lds R24,_i
	cpi R24,8
	brlo L36
	.dbline 212
;     }
;     i = c;
	lds R2,_c
	sts _i,R2
	.dbline 213
;   }
L34:
	.dbline 217
; 
;   /* Now, i is the ARP table entry which we will fill with the new
;      information. */
;   memcpy(tabptr->ipaddr, ipaddr, 4);
	ldi R24,4
	ldi R25,0
	std y+1,R25
	std y+0,R24
	movw R18,R14
	movw R16,R10
	xcall _memcpy
	.dbline 218
;   memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
	ldi R24,6
	ldi R25,0
	std y+1,R25
	std y+0,R24
	movw R18,R12
	movw R16,R10
	subi R16,252  ; offset = 4
	sbci R17,255
	xcall _memcpy
	.dbline 219
;   tabptr->time = arptime;
	lds R2,_arptime
	movw R30,R10
	std z+10,R2
	.dbline -2
L19:
	adiw R28,2
	xcall pop_gset5x
	.dbline 0 ; func end
	ret
	.dbsym r tabptr 10 pS[arp_entry]
	.dbsym r ethaddr 12 pS[uip_eth_addr]
	.dbsym r ipaddr 14 ps
	.dbend
	.dbfunc e uip_arp_ipin _uip_arp_ipin fV
	.even
_uip_arp_ipin::
	.dbline -1
	.dbline 237
; }
; /*-----------------------------------------------------------------------------------*/
; /**
;  * ARP processing for incoming IP packets
;  *
;  * This function should be called by the device driver when an IP
;  * packet has been received. The function will check if the address is
;  * in the ARP cache, and if so the ARP cache entry will be
;  * refreshed. If no ARP cache entry was found, a new one is created.
;  *
;  * This function expects an IP packet with a prepended Ethernet header
;  * in the uip_buf[] buffer, and the length of the packet in the global
;  * variable uip_len.
;  */
; /*-----------------------------------------------------------------------------------*/
; void
; uip_arp_ipin(void)
; {
	.dbline 238
;   uip_len -= sizeof(struct uip_eth_hdr);
	lds R24,_uip_len
	lds R25,_uip_len+1
	sbiw R24,14
	sts _uip_len+1,R25
	sts _uip_len,R24
	.dbline 242
; 	
;   /* Only insert/update an entry if the source IP address of the
;      incoming IP packet comes from a host on the local network. */
;   if((IPBUF->srcipaddr[0] & uip_arp_netmask[0]) !=
	ldi R30,<_uip_arp_netmask
	ldi R31,>_uip_arp_netmask
	lpm R0,Z+
	lpm R1,Z
	movw R30,R0
	ldi R26,<_uip_hostaddr
	ldi R27,>_uip_hostaddr
	st -y,R31
	st -y,R30
	movw R30,R26
	lpm R26,Z+
	lpm R27,Z
	ld R30,y+
	ld R31,y+
	and R26,R30
	and R27,R31
	ldi R30,<_uip_arp_netmask
	ldi R31,>_uip_arp_netmask
	lpm R0,Z+
	lpm R1,Z
	movw R30,R0
	lds R2,_uip_buf+26
	lds R3,_uip_buf+26+1
	and R2,R30
	and R3,R31
	cp R2,R26
	cpc R3,R27
	breq L43
	.dbline 243
;      (uip_hostaddr[0] & uip_arp_netmask[0])) {
	.dbline 244
;     return;
	xjmp L42
L43:
	.dbline 246
;   }
;   if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
	ldi R30,<_uip_arp_netmask+2
	ldi R31,>_uip_arp_netmask+2
	lpm R0,Z+
	lpm R1,Z
	movw R30,R0
	ldi R26,<_uip_hostaddr+2
	ldi R27,>_uip_hostaddr+2
	st -y,R31
	st -y,R30
	movw R30,R26
	lpm R26,Z+
	lpm R27,Z
	ld R30,y+
	ld R31,y+
	and R26,R30
	and R27,R31
	ldi R30,<_uip_arp_netmask+2
	ldi R31,>_uip_arp_netmask+2
	lpm R0,Z+
	lpm R1,Z
	movw R30,R0
	lds R2,_uip_buf+26+2
	lds R3,_uip_buf+26+2+1
	and R2,R30
	and R3,R31
	cp R2,R26
	cpc R3,R27

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -