📄 uip_arp.s
字号:
.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 + -