OpenCores
URL https://opencores.org/ocsvn/openarty/openarty/trunk

Subversion Repositories openarty

[/] [openarty/] [trunk/] [sw/] [board/] [arp.c] - Blame information for rev 59

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 52 dgisselq
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Filename:    arp.c
4
//
5
// Project:     OpenArty, an entirely open SoC based upon the Arty platform
6
//
7
// Purpose:     To encapsulate common functions associated with the ARP protocol
8
//              and hardware (ethernet MAC) address resolution.
9
//
10
//
11
// Creator:     Dan Gisselquist, Ph.D.
12
//              Gisselquist Technology, LLC
13
//
14
////////////////////////////////////////////////////////////////////////////////
15
//
16
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
17
//
18
// This program is free software (firmware): you can redistribute it and/or
19
// modify it under the terms of  the GNU General Public License as published
20
// by the Free Software Foundation, either version 3 of the License, or (at
21
// your option) any later version.
22
//
23
// This program is distributed in the hope that it will be useful, but WITHOUT
24
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
25
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26
// for more details.
27
//
28
// You should have received a copy of the GNU General Public License along
29
// with this program.  (It's in the $(ROOT)/doc directory, run make with no
30
// target there if the PDF file isn't present.)  If not, see
31
// <http://www.gnu.org/licenses/> for a copy.
32
//
33
// License:     GPL, v3, as defined and found on www.gnu.org,
34
//              http://www.gnu.org/licenses/gpl.html
35
//
36
//
37
////////////////////////////////////////////////////////////////////////////////
38
//
39
//
40
#include "zipcpu.h"
41
#include "zipsys.h"
42
#define KTRAPID_SENDPKT 0
43
#include "artyboard.h"
44
#include "etcnet.h"
45
#include "protoconst.h"
46
#include "ipcksum.h"
47
 
48
///////////
49
//
50
//
51
// Simplified ARP table and ARP requester
52
//
53
//
54
///////////
55
 
56
typedef struct  {
57
        int             valid;
58
        unsigned        age, ipaddr;
59
        unsigned long   mac;
60
} ARP_TABLE_ENTRY;
61
 
62
#define NUM_ARP_ENTRIES 8
63
ARP_TABLE_ENTRY arp_table[NUM_ARP_ENTRIES];
64
 
65
void    init_arp_table(void) {
66
        for(int k=0; k<NUM_ARP_ENTRIES; k++)
67
                arp_table[k].valid = 0;
68
}
69
 
70
int     get_next_arp_index(void) {
71
        int     eid, eldest = 0, unused_id = -1, oldage = 0, found=-1;
72
        for(eid=0; eid<NUM_ARP_ENTRIES; eid++) {
73
                if (!arp_table[eid].valid) {
74
                        unused_id = eid;
75
                        break;
76
                } else if (arp_table[eid].age > oldage) {
77
                        oldage = arp_table[eid].age;
78
                        eldest = eid;
79
                }
80
        }
81
 
82
        if (unused_id >= 0)
83
                return unused_id;
84
        return eldest;
85
}
86
 
87
void    send_arp_request(int ipaddr) {
88
        unsigned        pkt[9];
89
 
90
        pkt[0] = 0xffffffff;
91
        pkt[1] = 0xffff0000 | ETHERTYPE_ARP;
92
        pkt[2] = 0x010800;      // hardware type (enet), proto type (inet)
93
        pkt[3] = 0x06040001;    // 6 octets in enet addr, 4 in inet addr,request
94
        pkt[4] = (unsigned)(my_mac_addr>>16);
95
        pkt[5] = ((unsigned)(my_mac_addr<<16))|(my_ip_addr>>16);
96
        pkt[6] = (my_ip_addr<<16);
97
        pkt[7] = 0;
98
        pkt[8] = ipaddr;
99
 
100
        // Send our packet
101
        syscall(KTRAPID_SENDPKT,0,(unsigned)pkt, 9*4);
102
}
103
 
104
int     arp_lookup(unsigned ipaddr, unsigned long *mac) {
105
        int     eid, eldest = 0, unused_id = -1, oldage = 0, found=-1;
106
 
107
        if (((((ipaddr ^ my_ip_addr) & my_ip_mask) != 0)
108
                || (ipaddr == my_ip_router))
109
                        &&(router_mac_addr)) {
110
                *mac = router_mac_addr;
111
                return 0;
112
        }
113
 
114
        for(eid=0; eid<NUM_ARP_ENTRIES; eid++) {
115
                if (arp_table[eid].valid) {
116
                        if (arp_table[eid].ipaddr == ipaddr) {
117
                                arp_table[eid].age = 0;
118
                                *mac = arp_table[eid].mac;
119
                                return 0;
120
                        } else if (arp_table[eid].age > oldage) {
121
                                oldage = arp_table[eid].age++;
122
                                eldest = eid;
123
                                if (oldage >= 0x010000)
124
                                        arp_table[eid].valid = 0;
125
                        } else
126
                                arp_table[eid].age++;
127
                }
128
        }
129
 
130
        send_arp_request(ipaddr);
131
        return 1;
132
}
133
 
134
typedef struct  {
135
        unsigned ipaddr;
136
        unsigned long   mac;
137
} ARP_TABLE_LOG_ENTRY;
138
 
139
int     arp_logid = 0;
140
ARP_TABLE_LOG_ENTRY     arp_table_log[32];
141
 
142
void    arp_table_add(unsigned ipaddr, unsigned long mac) {
143
        unsigned long   lclmac;
144
        int             eid;
145
 
146
        arp_table_log[arp_logid].ipaddr = ipaddr;
147
        arp_table_log[arp_logid].mac = mac;
148
        arp_logid++;
149
        arp_logid&= 31;
150
 
151
 
152
        if (ipaddr == my_ip_addr)
153
                return;
154
        // Missing the 'if'??
155
        else if (ipaddr == my_ip_router) {
156
                router_mac_addr = mac;
157
        } else if (arp_lookup(ipaddr, &lclmac)==0) {
158
                if (mac != lclmac) {
159
                        for(eid=0; eid<NUM_ARP_ENTRIES; eid++) {
160
                                if ((arp_table[eid].valid)&&
161
                                        (arp_table[eid].ipaddr == ipaddr)) {
162
                                        volatile int *ev = &arp_table[eid].valid;
163
                                        // Prevent anyone from using an invalid
164
                                        // entry while we are updating it
165
                                        *ev = 0;
166
                                        arp_table[eid].age = 0;
167
                                        arp_table[eid].mac = mac;
168
                                        *ev = 1;
169
                                        break;
170
                                }
171
                        }
172
                }
173
        } else {
174
                volatile int *ev = &arp_table[eid].valid;
175
                eid = get_next_arp_index();
176
 
177
                // Prevent anyone from using an invalid entry while we are
178
                // updating it
179
                *ev = 0;
180
                arp_table[eid].age = 0;
181
                arp_table[eid].ipaddr = ipaddr;
182
                arp_table[eid].mac = mac;
183
                *ev = 1;
184
        }
185
}
186
 
187
void    send_arp_reply(unsigned machi, unsigned maclo, unsigned ipaddr) {
188
        unsigned pkt[9];
189
        pkt[0] = (machi<<16)|(maclo>>16);
190
        pkt[1] = (maclo<<16)|ETHERTYPE_ARP;
191
        pkt[2] = 0x010800;      // hardware type (enet), proto type (inet)
192
        pkt[3] = 0x06040002;
193
        pkt[4] = (unsigned)(my_mac_addr>>16);
194
        pkt[5] = ((unsigned)(my_mac_addr<<16))|(my_ip_addr>>16);
195
        pkt[6] = (my_ip_addr<<16)|(machi);
196
        pkt[7] = maclo;
197
        pkt[8] = ipaddr;
198
 
199
        syscall(KTRAPID_SENDPKT, 0, (int)pkt, 9*4);
200
}
201
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.