?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik /*! \file arp.c \brief ARP Protocol Library. */
2 //*****************************************************************************
3 //
4 // File Name : 'arp.c'
5 // Title : ARP Protocol Library
6 // Author : Pascal Stang
7 // Created : 9/7/2004
8 // Revised : 7/3/2005
9 // Version : 0.1
10 // Target MCU : Atmel AVR series
11 // Editor Tabs : 4
12 //
13 //*****************************************************************************
14  
15 #include "global.h"
16 #include "net.h"
17 #include "nic.h"
18 #include "arp.h"
19  
20 #include "rprintf.h"
21  
22 // global variables
23  
24 /// Single ARP table entry/record
25 struct ArpEntry
26 {
27 uint32_t ipaddr; ///< remote-note IP address
28 struct netEthAddr ethaddr; ///< remote-node ethernet (hardware/mac) address
29 uint8_t time; ///< time to live (in ARP table); this is decremented by arpTimer()
30 };
31  
32 struct ArpEntry ArpMyAddr; ///< my local interface information (IP and MAC address)
33 struct ArpEntry ArpTable[ARP_TABLE_SIZE]; ///< ARP table of matched IP<->MAC associations
34  
35  
36 void arpInit(void)
37 {
38 u08 i;
39 // initialize all ArpTable elements to unused
40 for(i=0; i<ARP_TABLE_SIZE; i++)
41 {
42 ArpTable[i].ipaddr = 0;
43 ArpTable[i].time = 0;
44 }
45 }
46  
47 void arpSetAddress(struct netEthAddr* myeth, uint32_t myip)
48 {
49 // set local address record
50 ArpMyAddr.ethaddr = *myeth;
51 ArpMyAddr.ipaddr = myip;
52 }
53  
54 void arpArpIn(unsigned int len, struct netEthArpHeader* packet)
55 {
56 #ifdef ARP_DEBUG
57 rprintfProgStrM("Received ARP Request\r\n");
58 arpPrintHeader( &packet->arp );
59 #endif
60  
61 // for now, we just reply to requests
62 // need to add ARP cache
63 if( (packet->arp.dipaddr == HTONL(ArpMyAddr.ipaddr)) &&
64 (packet->arp.opcode == htons(ARP_OPCODE_REQUEST)) )
65 {
66 // in ARP header
67 // copy sender's address info to dest. fields
68 packet->arp.dhwaddr = packet->arp.shwaddr;
69 packet->arp.dipaddr = packet->arp.sipaddr;
70 // fill in our information
71 packet->arp.shwaddr = ArpMyAddr.ethaddr;
72 packet->arp.sipaddr = HTONL(ArpMyAddr.ipaddr);
73 // change op to reply
74 packet->arp.opcode = htons(ARP_OPCODE_REPLY);
75  
76 // in ethernet header
77 packet->eth.dest = packet->eth.src;
78 packet->eth.src = ArpMyAddr.ethaddr;
79  
80 #ifdef ARP_DEBUG
81 rprintfProgStrM("Sending ARP Reply\r\n");
82 arpPrintHeader( &packet->arp );
83 #endif
84  
85 // send reply!
86 nicSend(len, (unsigned char*)packet);
87 }
88 }
89  
90 void arpIpIn(struct netEthIpHeader* packet)
91 {
92 int8_t index;
93  
94 // check if sender is already present in arp table
95 index = arpMatchIp(HTONL(packet->ip.srcipaddr));
96 if(index != -1)
97 {
98 // sender's IP address found, update ARP entry
99 ArpTable[index].ethaddr = packet->eth.src;
100 // and we're done
101 return;
102 }
103  
104 // sender was not present in table,
105 // must add in empty/expired slot
106 for(index=0; index<ARP_TABLE_SIZE; index++)
107 {
108 if(!ArpTable[index].time)
109 {
110 // write entry
111 ArpTable[index].ethaddr = packet->eth.src;
112 ArpTable[index].ipaddr = HTONL(packet->ip.srcipaddr);
113 ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE;
114 // and we're done
115 return;
116 }
117 }
118  
119 // no space in table, we give up
120 }
121  
122 void arpIpOut(struct netEthIpHeader* packet, uint32_t phyDstIp)
123 {
124 int index;
125 // check if destination is already present in arp table
126 // use the physical dstIp if it's provided, otherwise the dstIp in packet
127 if(phyDstIp)
128 index = arpMatchIp(phyDstIp);
129 else
130 index = arpMatchIp(HTONL(packet->ip.destipaddr));
131 // fill in ethernet info
132 if(index != -1)
133 {
134 // ARP entry present, fill eth address(es)
135 packet->eth.src = ArpMyAddr.ethaddr;
136 packet->eth.dest = ArpTable[index].ethaddr;
137 packet->eth.type = HTONS(ETHTYPE_IP);
138 }
139 else
140 {
141 // not in table, must send ARP request
142 packet->eth.src = ArpMyAddr.ethaddr;
143 // MUST CHANGE, but for now, send this one broadcast
144 packet->eth.dest.addr[0] = 0xFF;
145 packet->eth.dest.addr[1] = 0xFF;
146 packet->eth.dest.addr[2] = 0xFF;
147 packet->eth.dest.addr[3] = 0xFF;
148 packet->eth.dest.addr[4] = 0xFF;
149 packet->eth.dest.addr[5] = 0xFF;
150 packet->eth.type = HTONS(ETHTYPE_IP);
151 }
152 }
153  
154 void arpTimer(void)
155 {
156 int index;
157 // this function meant to be called on a regular time interval
158  
159 // decrement time-to-live for all entries
160 for(index=0; index<ARP_TABLE_SIZE; index++)
161 {
162 if(ArpTable[index].time)
163 ArpTable[index].time--;
164 }
165 }
166  
167 int arpMatchIp(uint32_t ipaddr)
168 {
169 uint8_t i;
170  
171 // check if IP address is present in arp table
172 for(i=0; i<ARP_TABLE_SIZE; i++)
173 {
174 if(ArpTable[i].ipaddr == ipaddr)
175 {
176 // IP address found
177 return i;
178 }
179 }
180  
181 // no match
182 return -1;
183 }
184  
185 #ifdef ARP_DEBUG_PRINT
186 void arpPrintHeader(struct netArpHeader* packet)
187 {
188 rprintfProgStrM("ARP Packet:\r\n");
189 //debugPrintHexTable(60, (unsigned char*)&packet);
190 // print operation type
191 rprintfProgStrM("Operation : ");
192 if(packet->opcode == htons(ARP_OPCODE_REQUEST))
193 rprintfProgStrM("REQUEST");
194 else if(packet->opcode == htons(ARP_OPCODE_REPLY))
195 rprintfProgStrM("REPLY");
196 else
197 rprintfProgStrM("UNKNOWN");
198 rprintfCRLF();
199 // print source hardware address
200 rprintfProgStrM("SrcHwAddr : "); netPrintEthAddr(&packet->shwaddr); rprintfCRLF();
201 // print source protocol address
202 rprintfProgStrM("SrcProtoAddr: "); netPrintIPAddr(HTONL(packet->sipaddr)); rprintfCRLF();
203 // print target hardware address
204 rprintfProgStrM("DstHwAddr : "); netPrintEthAddr(&packet->dhwaddr); rprintfCRLF();
205 // print target protocol address
206 rprintfProgStrM("DstProtoAddr: "); netPrintIPAddr(HTONL(packet->dipaddr)); rprintfCRLF();
207 }
208  
209  
210 void arpPrintTable(void)
211 {
212 uint8_t i;
213  
214 // print ARP table
215 rprintfProgStrM("Time Eth Address IP Address\r\n");
216 rprintfProgStrM("---------------------------------------\r\n");
217 for(i=0; i<ARP_TABLE_SIZE; i++)
218 {
219 rprintfu08(ArpTable[i].time);
220 rprintfProgStrM(" ");
221 netPrintEthAddr(&ArpTable[i].ethaddr);
222 rprintfProgStrM(" ");
223 netPrintIPAddr(ArpTable[i].ipaddr);
224 rprintfCRLF();
225 }
226 }
227 #endif
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3