00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <ubixos/types.h>
00038 #include <lib/kprintf.h>
00039
00040 #include "net/debug.h"
00041 #include "net/ipv4/inet.h"
00042 #include "netif/arp.h"
00043 #include "net/ipv4/ip.h"
00044
00045
00046 #define ARP_MAXAGE 2
00047
00048 #define HWTYPE_ETHERNET 1
00049
00050 #define ARP_REQUEST 1
00051 #define ARP_REPLY 2
00052
00053
00054 PACK_STRUCT_BEGIN
00055 struct arp_hdr {
00056 PACK_STRUCT_FIELD(struct eth_hdr ethhdr);
00057 PACK_STRUCT_FIELD(uInt16 hwtype);
00058 PACK_STRUCT_FIELD(uInt16 proto);
00059 PACK_STRUCT_FIELD(uInt16 _hwlen_protolen);
00060 PACK_STRUCT_FIELD(uInt16 opcode);
00061 PACK_STRUCT_FIELD(struct eth_addr shwaddr);
00062 PACK_STRUCT_FIELD(struct ip_addr sipaddr);
00063 PACK_STRUCT_FIELD(struct eth_addr dhwaddr);
00064 PACK_STRUCT_FIELD(struct ip_addr dipaddr);
00065 } PACK_STRUCT_STRUCT;
00066 PACK_STRUCT_END
00067
00068 #define ARPH_HWLEN(hdr) (NTOHS((hdr)->_hwlen_protolen) >> 8)
00069 #define ARPH_PROTOLEN(hdr) (NTOHS((hdr)->_hwlen_protolen) & 0xff)
00070
00071
00072 #define ARPH_HWLEN_SET(hdr, len) (hdr)->_hwlen_protolen = HTONS(ARPH_PROTOLEN(hdr) | ((len) << 8))
00073 #define ARPH_PROTOLEN_SET(hdr, len) (hdr)->_hwlen_protolen = HTONS((len) | (ARPH_HWLEN(hdr) << 8))
00074
00075 PACK_STRUCT_BEGIN
00076 struct ethip_hdr {
00077 PACK_STRUCT_FIELD(struct eth_hdr eth);
00078 PACK_STRUCT_FIELD(struct ip_hdr ip);
00079 };
00080 PACK_STRUCT_END
00081
00082 struct arp_entry {
00083 struct ip_addr ipaddr;
00084 struct eth_addr ethaddr;
00085 uInt8 ctime;
00086 };
00087
00088 static struct arp_entry arp_table[ARP_TABLE_SIZE];
00089 static uInt8 ctime;
00090
00091
00092 void
00093 arp_init(void)
00094 {
00095 uInt8 i;
00096
00097 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00098 ip_addr_set(&(arp_table[i].ipaddr),
00099 IP_ADDR_ANY);
00100 }
00101 }
00102
00103 void
00104 arp_tmr(void)
00105 {
00106 uInt8 i;
00107
00108 ++ctime;
00109 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00110 if(!ip_addr_isany(&arp_table[i].ipaddr) &&
00111 ctime - arp_table[i].ctime >= ARP_MAXAGE) {
00112 DEBUGF(ARP_DEBUG, ("arp_timer: expired entry %d.\n", i));
00113 ip_addr_set(&(arp_table[i].ipaddr),
00114 IP_ADDR_ANY);
00115 }
00116 }
00117 }
00118
00119 static void
00120 add_arp_entry(struct ip_addr *ipaddr, struct eth_addr *ethaddr)
00121 {
00122 uInt8 i, j, k;
00123 uInt8 maxtime;
00124
00125
00126
00127
00128 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00129
00130
00131 if(!ip_addr_isany(&arp_table[i].ipaddr)) {
00132
00133
00134 if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00135
00136 for(k = 0; k < 6; ++k) {
00137 arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
00138 }
00139 arp_table[i].ctime = ctime;
00140 return;
00141 }
00142 }
00143 }
00144
00145
00146
00147
00148
00149 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00150 if(ip_addr_isany(&arp_table[i].ipaddr)) {
00151 break;
00152 }
00153 }
00154
00155
00156
00157 if(i == ARP_TABLE_SIZE) {
00158 maxtime = 0;
00159 j = 0;
00160 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00161 if(ctime - arp_table[i].ctime > maxtime) {
00162 maxtime = ctime - arp_table[i].ctime;
00163 j = i;
00164 }
00165 }
00166 i = j;
00167 }
00168
00169
00170
00171 ip_addr_set(&arp_table[i].ipaddr, ipaddr);
00172 for(k = 0; k < 6; ++k) {
00173 arp_table[i].ethaddr.addr[k] = ethaddr->addr[k];
00174 }
00175 arp_table[i].ctime = ctime;
00176 return;
00177
00178 }
00179
00180 void
00181 arp_ip_input(struct netif *netif, struct pbuf *p)
00182 {
00183 struct ethip_hdr *hdr;
00184
00185 hdr = p->payload;
00186
00187
00188
00189 if(!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
00190 return;
00191 }
00192 DEBUGF(ARP_DEBUG, ("arp_ip_input: updating ARP table.\n"));
00193 add_arp_entry(&(hdr->ip.src), &(hdr->eth.src));
00194 }
00195
00196 struct pbuf *
00197 arp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
00198 {
00199 struct arp_hdr *hdr;
00200 uInt8 i;
00201
00202 if(p->tot_len < sizeof(struct arp_hdr)) {
00203 kprintf("arp_arp_input: packet too short (%d/%d)\n", p->tot_len, sizeof(struct arp_hdr));
00204 pbuf_free(p);
00205 return NULL;
00206 }
00207
00208 hdr = p->payload;
00209
00210 switch(htons(hdr->opcode)) {
00211 case ARP_REQUEST:
00212
00213
00214 if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
00215 hdr->opcode = htons(ARP_REPLY);
00216
00217 ip_addr_set(&(hdr->dipaddr), &(hdr->sipaddr));
00218 ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
00219
00220 for(i = 0; i < 6; ++i) {
00221 hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
00222 hdr->shwaddr.addr[i] = ethaddr->addr[i];
00223 hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
00224 hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
00225 }
00226
00227 hdr->hwtype = htons(HWTYPE_ETHERNET);
00228 ARPH_HWLEN_SET(hdr, 6);
00229
00230 hdr->proto = htons(ETHTYPE_IP);
00231 ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
00232
00233 hdr->ethhdr.type = htons(ETHTYPE_ARP);
00234 return p;
00235 }
00236 break;
00237 case ARP_REPLY:
00238
00239 if(ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
00240 add_arp_entry(&(hdr->sipaddr), &(hdr->shwaddr));
00241 }
00242 break;
00243 default:
00244 kprintf("arp_arp_input: unknown type %d\n", htons(hdr->opcode));
00245 break;
00246 }
00247
00248 pbuf_free(p);
00249 return NULL;
00250 }
00251
00252 struct eth_addr *
00253 arp_lookup(struct ip_addr *ipaddr)
00254 {
00255 uInt8 i;
00256
00257 for(i = 0; i < ARP_TABLE_SIZE; ++i) {
00258 if(ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
00259 return &arp_table[i].ethaddr;
00260 }
00261 }
00262 return NULL;
00263 }
00264
00265 struct pbuf *
00266 arp_query(struct netif *netif, struct eth_addr *ethaddr, struct ip_addr *ipaddr)
00267 {
00268 struct arp_hdr *hdr;
00269 struct pbuf *p;
00270 uInt8 i;
00271
00272 p = pbuf_alloc(PBUF_LINK, sizeof(struct arp_hdr), PBUF_RAM);
00273 if(p == NULL) {
00274 return NULL;
00275 }
00276
00277 hdr = p->payload;
00278
00279 hdr->opcode = htons(ARP_REQUEST);
00280
00281 for(i = 0; i < 6; ++i) {
00282 hdr->dhwaddr.addr[i] = 0x00;
00283 hdr->shwaddr.addr[i] = ethaddr->addr[i];
00284 }
00285
00286 ip_addr_set(&(hdr->dipaddr), ipaddr);
00287 ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));
00288
00289 hdr->hwtype = htons(HWTYPE_ETHERNET);
00290 ARPH_HWLEN_SET(hdr, 6);
00291
00292 hdr->proto = htons(ETHTYPE_IP);
00293 ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
00294
00295 for(i = 0; i < 6; ++i) {
00296 hdr->ethhdr.dest.addr[i] = 0xff;
00297 hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
00298 }
00299
00300 hdr->ethhdr.type = htons(ETHTYPE_ARP);
00301 return p;
00302 }
00303
00304
00305
00306
00307