1 /*
2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 * Hugo Santos, hugosantos@gmail.com
8 */
9
10
11 //! Ethernet Address Resolution Protocol, see RFC 826.
12
13
14 #include <arp_control.h>
15 #include <net_datalink_protocol.h>
16 #include <net_device.h>
17 #include <net_datalink.h>
18 #include <net_stack.h>
19 #include <NetBufferUtilities.h>
20
21 #include <generic_syscall.h>
22 #include <util/atomic.h>
23 #include <util/AutoLock.h>
24 #include <util/DoublyLinkedList.h>
25 #include <util/OpenHashTable.h>
26
27 #include <ByteOrder.h>
28 #include <KernelExport.h>
29
30 #include <net/if.h>
31 #include <net/if_dl.h>
32 #include <net/if_types.h>
33 #include <new>
34 #include <stdio.h>
35 #include <string.h>
36 #include <sys/sockio.h>
37
38
39 //#define TRACE_ARP
40 #ifdef TRACE_ARP
41 # define TRACE(x) dprintf x
42 #else
43 # define TRACE(x) ;
44 #endif
45
46
47 struct arp_header {
48 uint16 hardware_type;
49 uint16 protocol_type;
50 uint8 hardware_length;
51 uint8 protocol_length;
52 uint16 opcode;
53
54 // TODO: this should be a variable length header, but for our current
55 // usage (Ethernet/IPv4), this should work fine.
56 uint8 hardware_sender[6];
57 in_addr_t protocol_sender;
58 uint8 hardware_target[6];
59 in_addr_t protocol_target;
60 } _PACKED;
61
62 #define ARP_OPCODE_REQUEST 1
63 #define ARP_OPCODE_REPLY 2
64
65 #define ARP_HARDWARE_TYPE_ETHER 1
66
67 struct arp_entry {
68 arp_entry *next;
69 in_addr_t protocol_address;
70 sockaddr_dl hardware_address;
71 uint32 flags;
72 net_buffer *request_buffer;
73 net_timer timer;
74 uint32 timer_state;
75 bigtime_t timestamp;
76 net_datalink_protocol *protocol;
77
78 typedef DoublyLinkedListCLink<net_buffer> NetBufferLink;
79 typedef DoublyLinkedList<net_buffer, NetBufferLink> BufferList;
80
81 BufferList queue;
82
83 static arp_entry *Lookup(in_addr_t protocolAddress);
84 static arp_entry *Add(in_addr_t protocolAddress,
85 sockaddr_dl *hardwareAddress, uint32 flags);
86
87 ~arp_entry();
88
89 void ClearQueue();
90 void MarkFailed();
91 void MarkValid();
92 void ScheduleRemoval();
93 };
94
95 // see arp_control.h for more flags
96 #define ARP_FLAG_REMOVED 0x00010000
97 #define ARP_PUBLIC_FLAG_MASK 0x0000ffff
98
99 #define ARP_NO_STATE 0
100 #define ARP_STATE_REQUEST 1
101 #define ARP_STATE_LAST_REQUEST 5
102 #define ARP_STATE_REQUEST_FAILED 6
103 #define ARP_STATE_REMOVE_FAILED 7
104 #define ARP_STATE_STALE 8
105
106 #define ARP_STALE_TIMEOUT 30 * 60000000LL // 30 minutes
107 #define ARP_REJECT_TIMEOUT 20000000LL // 20 seconds
108 #define ARP_REQUEST_TIMEOUT 1000000LL // 1 second
109
110 struct arp_protocol : net_datalink_protocol {
111 sockaddr_dl hardware_address;
112 in_addr_t local_address;
113 };
114
115
116 static const net_buffer* kDeletedBuffer = (net_buffer*)~0;
117
118 static void arp_timer(struct net_timer *timer, void *data);
119
120 net_buffer_module_info* gBufferModule;
121 static net_stack_module_info* sStackModule;
122 static net_datalink_module_info* sDatalinkModule;
123 static bool sIgnoreReplies;
124
125
126 struct arpHash {
127 typedef in_addr_t KeyType;
128 typedef arp_entry ValueType;
129
HashKeyarpHash130 size_t HashKey(KeyType key) const
131 {
132 return key;
133 }
134
HasharpHash135 size_t Hash(ValueType* value) const
136 {
137 return HashKey(value->protocol_address);
138 }
139
ComparearpHash140 bool Compare(KeyType key, ValueType* value) const
141 {
142 return value->protocol_address == key;
143 }
144
GetLinkarpHash145 ValueType*& GetLink(ValueType* value) const
146 {
147 return value->next;
148 }
149 };
150
151
152 typedef BOpenHashTable<arpHash> AddressCache;
153 static AddressCache* sCache;
154 static mutex sCacheLock;
155
156
157 #ifdef TRACE_ARP
158
159
160 const char*
mac_to_string(uint8 * address)161 mac_to_string(uint8* address)
162 {
163 static char buffer[20];
164 snprintf(buffer, sizeof(buffer), "%02x:%02x:%02x:%02x:%02x:%02x",
165 address[0], address[1], address[2], address[3], address[4], address[5]);
166 return buffer;
167 }
168
169
170 const char*
inet_to_string(in_addr_t address)171 inet_to_string(in_addr_t address)
172 {
173 static char buffer[20];
174
175 unsigned int hostAddress = ntohl(address);
176 snprintf(buffer, sizeof(buffer), "%d.%d.%d.%d",
177 hostAddress >> 24, (hostAddress >> 16) & 0xff,
178 (hostAddress >> 8) & 0xff, hostAddress & 0xff);
179 return buffer;
180 }
181
182
183 #endif // TRACE_ARP
184
185
186 static net_buffer*
get_request_buffer(arp_entry * entry)187 get_request_buffer(arp_entry* entry)
188 {
189 net_buffer* buffer = entry->request_buffer;
190 if (buffer == NULL || buffer == kDeletedBuffer)
191 return NULL;
192
193 buffer = atomic_pointer_test_and_set(&entry->request_buffer,
194 (net_buffer*)NULL, buffer);
195 if (buffer == kDeletedBuffer)
196 return NULL;
197
198 return buffer;
199 }
200
201
202 static void
put_request_buffer(arp_entry * entry,net_buffer * buffer)203 put_request_buffer(arp_entry* entry, net_buffer* buffer)
204 {
205 net_buffer* requestBuffer = atomic_pointer_test_and_set(
206 &entry->request_buffer, buffer, (net_buffer*)NULL);
207 if (requestBuffer != NULL) {
208 // someone else took over ownership of the request buffer
209 gBufferModule->free(buffer);
210 }
211 }
212
213
214 static void
delete_request_buffer(arp_entry * entry)215 delete_request_buffer(arp_entry* entry)
216 {
217 net_buffer* buffer = atomic_pointer_get_and_set(&entry->request_buffer,
218 kDeletedBuffer);
219 if (buffer != NULL && buffer != kDeletedBuffer)
220 gBufferModule->free(buffer);
221 }
222
223
224 static void
ipv4_to_ether_multicast(sockaddr_dl * destination,const sockaddr_in * source)225 ipv4_to_ether_multicast(sockaddr_dl *destination, const sockaddr_in *source)
226 {
227 // RFC 1112 - Host extensions for IP multicasting
228 //
229 // ``An IP host group address is mapped to an Ethernet multicast
230 // address by placing the low-order 23-bits of the IP address into
231 // the low-order 23 bits of the Ethernet multicast address
232 // 01-00-5E-00-00-00 (hex).''
233
234 destination->sdl_len = sizeof(sockaddr_dl);
235 destination->sdl_family = AF_LINK;
236 destination->sdl_index = 0;
237 destination->sdl_type = IFT_ETHER;
238 destination->sdl_e_type = htons(ETHER_TYPE_IP);
239 destination->sdl_nlen = destination->sdl_slen = 0;
240 destination->sdl_alen = ETHER_ADDRESS_LENGTH;
241
242 memcpy(LLADDR(destination) + 2, &source->sin_addr, sizeof(in_addr));
243 uint32 *data = (uint32 *)LLADDR(destination);
244 data[0] = (data[0] & htonl(0x7f)) | htonl(0x01005e00);
245 }
246
247
248 // #pragma mark -
249
250
251 /*static*/ arp_entry *
Lookup(in_addr_t address)252 arp_entry::Lookup(in_addr_t address)
253 {
254 return sCache->Lookup(address);
255 }
256
257
258 /*static*/ arp_entry *
Add(in_addr_t protocolAddress,sockaddr_dl * hardwareAddress,uint32 flags)259 arp_entry::Add(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress,
260 uint32 flags)
261 {
262 ASSERT_LOCKED_MUTEX(&sCacheLock);
263
264 arp_entry *entry = new (std::nothrow) arp_entry;
265 if (entry == NULL)
266 return NULL;
267
268 entry->protocol_address = protocolAddress;
269 entry->flags = flags;
270 entry->timestamp = system_time();
271 entry->protocol = NULL;
272 entry->request_buffer = NULL;
273 entry->timer_state = ARP_NO_STATE;
274 sStackModule->init_timer(&entry->timer, arp_timer, entry);
275
276 if (hardwareAddress != NULL) {
277 // this entry is already resolved
278 entry->hardware_address = *hardwareAddress;
279 entry->hardware_address.sdl_e_type = htons(ETHER_TYPE_IP);
280 } else {
281 // this entry still needs to be resolved
282 entry->hardware_address.sdl_alen = 0;
283 }
284 if (entry->hardware_address.sdl_len != sizeof(sockaddr_dl)) {
285 // explicitly set correct length in case our caller hasn't...
286 entry->hardware_address.sdl_len = sizeof(sockaddr_dl);
287 }
288
289 if (sCache->Insert(entry) != B_OK) {
290 // We can delete the entry here with the sCacheLock held, since it's
291 // guaranteed there are no timers pending.
292 delete entry;
293 return NULL;
294 }
295
296 return entry;
297 }
298
299
~arp_entry()300 arp_entry::~arp_entry()
301 {
302 // make sure there is no active timer left for us
303 sStackModule->cancel_timer(&timer);
304 sStackModule->wait_for_timer(&timer);
305
306 ClearQueue();
307 }
308
309
310 void
ClearQueue()311 arp_entry::ClearQueue()
312 {
313 BufferList::Iterator iterator = queue.GetIterator();
314 while (iterator.HasNext()) {
315 net_buffer *buffer = iterator.Next();
316 iterator.Remove();
317 gBufferModule->free(buffer);
318 }
319 }
320
321
322 void
MarkFailed()323 arp_entry::MarkFailed()
324 {
325 TRACE(("ARP entry %p Marked as FAILED\n", this));
326
327 flags = (flags & ~ARP_FLAG_VALID) | ARP_FLAG_REJECT;
328 ClearQueue();
329 }
330
331
332 void
MarkValid()333 arp_entry::MarkValid()
334 {
335 TRACE(("ARP entry %p Marked as VALID, have %li packets queued.\n", this,
336 queue.Count()));
337
338 flags = (flags & ~ARP_FLAG_REJECT) | ARP_FLAG_VALID;
339
340 BufferList::Iterator iterator = queue.GetIterator();
341 while (iterator.HasNext()) {
342 net_buffer *buffer = iterator.Next();
343 iterator.Remove();
344
345 TRACE((" ARP Dequeing packet %p...\n", buffer));
346
347 memcpy(buffer->destination, &hardware_address,
348 hardware_address.sdl_len);
349 protocol->next->module->send_data(protocol->next, buffer);
350 }
351 }
352
353
354 void
ScheduleRemoval()355 arp_entry::ScheduleRemoval()
356 {
357 // schedule a timer to remove this entry
358 timer_state = ARP_STATE_REMOVE_FAILED;
359 sStackModule->set_timer(&timer, 0);
360 }
361
362
363 // #pragma mark -
364
365
366 /*! Updates the entry determined by \a protocolAddress with the specified
367 \a hardwareAddress.
368 If such an entry does not exist yet, a new entry is added. If you try
369 to update a local existing entry but didn't ask for it (by setting
370 \a flags to ARP_FLAG_LOCAL), an error is returned.
371
372 This function does not lock the cache - you have to do it yourself
373 before calling it.
374 */
375 static status_t
arp_update_entry(in_addr_t protocolAddress,sockaddr_dl * hardwareAddress,uint32 flags,arp_entry ** _entry=NULL)376 arp_update_entry(in_addr_t protocolAddress, sockaddr_dl *hardwareAddress,
377 uint32 flags, arp_entry **_entry = NULL)
378 {
379 ASSERT_LOCKED_MUTEX(&sCacheLock);
380 TRACE(("%s(%s, %s, flags 0x%" B_PRIx32 ")\n", __FUNCTION__,
381 inet_to_string(protocolAddress), mac_to_string(LLADDR(hardwareAddress)),
382 flags));
383
384 arp_entry *entry = arp_entry::Lookup(protocolAddress);
385 if (entry != NULL) {
386 // We disallow updating of entries that had been resolved before,
387 // but to a different address (only for those that belong to a
388 // specific address - redefining INADDR_ANY is always allowed).
389 // Right now, you have to manually purge the ARP entries (or wait some
390 // time) to let us switch to the new address.
391 if (protocolAddress != INADDR_ANY
392 && entry->hardware_address.sdl_alen != 0
393 && memcmp(LLADDR(&entry->hardware_address),
394 LLADDR(hardwareAddress), ETHER_ADDRESS_LENGTH)) {
395 uint8* data = LLADDR(hardwareAddress);
396 dprintf("ARP host %08x updated with different hardware address "
397 "%02x:%02x:%02x:%02x:%02x:%02x.\n", protocolAddress,
398 data[0], data[1], data[2], data[3], data[4], data[5]);
399 return B_ERROR;
400 }
401
402 entry->hardware_address = *hardwareAddress;
403 entry->timestamp = system_time();
404 } else {
405 entry = arp_entry::Add(protocolAddress, hardwareAddress, flags);
406 if (entry == NULL)
407 return B_NO_MEMORY;
408 }
409
410 delete_request_buffer(entry);
411
412 if ((entry->flags & ARP_FLAG_PERMANENT) == 0) {
413 // (re)start the stale timer
414 entry->timer_state = ARP_STATE_STALE;
415 sStackModule->set_timer(&entry->timer, ARP_STALE_TIMEOUT);
416 }
417
418 if ((entry->flags & ARP_FLAG_REJECT) != 0)
419 entry->MarkFailed();
420 else
421 entry->MarkValid();
422
423 if (_entry)
424 *_entry = entry;
425
426 return B_OK;
427 }
428
429
430 static status_t
arp_set_local_entry(arp_protocol * protocol,const sockaddr * local)431 arp_set_local_entry(arp_protocol* protocol, const sockaddr* local)
432 {
433 MutexLocker locker(sCacheLock);
434
435 net_interface* interface = protocol->interface;
436 in_addr_t inetAddress;
437
438 if (local == NULL) {
439 // interface has not yet been set
440 inetAddress = INADDR_ANY;
441 } else
442 inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr;
443
444 TRACE(("%s(): address %s\n", __FUNCTION__, inet_to_string(inetAddress)));
445
446 if (protocol->local_address == 0)
447 protocol->local_address = inetAddress;
448
449 sockaddr_dl address;
450 address.sdl_len = sizeof(sockaddr_dl);
451 address.sdl_family = AF_LINK;
452 address.sdl_type = IFT_ETHER;
453 address.sdl_e_type = htons(ETHER_TYPE_IP);
454 address.sdl_nlen = 0;
455 address.sdl_slen = 0;
456 address.sdl_alen = interface->device->address.length;
457 memcpy(LLADDR(&address), interface->device->address.data, address.sdl_alen);
458
459 memcpy(&protocol->hardware_address, &address, sizeof(sockaddr_dl));
460 // cache the address in our protocol
461
462 arp_entry* entry;
463 status_t status = arp_update_entry(inetAddress, &address,
464 ARP_FLAG_LOCAL | ARP_FLAG_PERMANENT, &entry);
465 if (status == B_OK)
466 entry->protocol = protocol;
467
468 return status;
469 }
470
471
472 static void
arp_remove_local_entry(arp_protocol * protocol,const sockaddr * local,net_interface_address * updateLocalAddress=NULL)473 arp_remove_local_entry(arp_protocol* protocol, const sockaddr* local,
474 net_interface_address* updateLocalAddress = NULL)
475 {
476 in_addr_t inetAddress;
477
478 if (local == NULL) {
479 // interface has not yet been set
480 inetAddress = INADDR_ANY;
481 } else
482 inetAddress = ((sockaddr_in*)local)->sin_addr.s_addr;
483
484 TRACE(("%s(): address %s\n", __FUNCTION__, inet_to_string(inetAddress)));
485
486 MutexLocker locker(sCacheLock);
487
488 arp_entry* entry = arp_entry::Lookup(inetAddress);
489 if (entry != NULL) {
490 sCache->Remove(entry);
491 entry->flags |= ARP_FLAG_REMOVED;
492 }
493
494 if (updateLocalAddress != NULL && protocol->local_address == inetAddress) {
495 // find new local sender address
496 protocol->local_address = 0;
497
498 net_interface_address* address = NULL;
499 while (sDatalinkModule->get_next_interface_address(protocol->interface,
500 &address)) {
501 if (address == updateLocalAddress || address->local == NULL
502 || address->local->sa_family != AF_INET)
503 continue;
504
505 protocol->local_address
506 = ((sockaddr_in*)address->local)->sin_addr.s_addr;
507 }
508 }
509
510 locker.Unlock();
511 delete entry;
512
513 if (protocol->local_address == 0 && updateLocalAddress) {
514 // Try to keep the interface operational
515 arp_set_local_entry(protocol, NULL);
516 }
517 }
518
519
520 /*! Removes all entries belonging to the local interface of the \a procotol
521 given.
522 */
523 static void
arp_remove_local(arp_protocol * protocol)524 arp_remove_local(arp_protocol* protocol)
525 {
526 net_interface_address* address = NULL;
527 while (sDatalinkModule->get_next_interface_address(protocol->interface,
528 &address)) {
529 if (address->local == NULL || address->local->sa_family != AF_INET)
530 continue;
531
532 arp_remove_local_entry(protocol, address->local);
533 }
534 }
535
536
537 /*! Creates permanent local entries for all addresses of the interface belonging
538 to this protocol.
539 Returns an error if no entry could be added.
540 */
541 static status_t
arp_update_local(arp_protocol * protocol)542 arp_update_local(arp_protocol* protocol)
543 {
544 protocol->local_address = 0;
545 // TODO: test if this actually works - maybe we should use
546 // INADDR_BROADCAST instead
547
548 ssize_t count = 0;
549
550 net_interface_address* address = NULL;
551 while (sDatalinkModule->get_next_interface_address(protocol->interface,
552 &address)) {
553 if (address->local == NULL || address->local->sa_family != AF_INET)
554 continue;
555
556 if (arp_set_local_entry(protocol, address->local) == B_OK) {
557 count++;
558 }
559 }
560
561 if (count == 0)
562 return arp_set_local_entry(protocol, NULL);
563
564 return B_OK;
565 }
566
567
568 static status_t
handle_arp_request(net_buffer * buffer,arp_header & header)569 handle_arp_request(net_buffer *buffer, arp_header &header)
570 {
571 MutexLocker locker(sCacheLock);
572
573 if (!sIgnoreReplies) {
574 arp_update_entry(header.protocol_sender,
575 (sockaddr_dl *)buffer->source, 0);
576 // remember the address of the sender as we might need it later
577 }
578
579 // check if this request is for us
580
581 arp_entry *entry = arp_entry::Lookup(header.protocol_target);
582 if (entry == NULL || entry->protocol == NULL
583 || (entry->flags & (ARP_FLAG_LOCAL | ARP_FLAG_PUBLISH)) == 0) {
584 // We're not the one to answer this request
585 // TODO: instead of letting the other's request time-out, can we reply
586 // failure somehow?
587 TRACE((" not for us\n"));
588 return B_ERROR;
589 }
590
591 // send a reply (by reusing the buffer we got)
592
593 TRACE((" send reply!\n"));
594 header.opcode = htons(ARP_OPCODE_REPLY);
595
596 memcpy(header.hardware_target, header.hardware_sender, ETHER_ADDRESS_LENGTH);
597 header.protocol_target = header.protocol_sender;
598 memcpy(header.hardware_sender, LLADDR(&entry->hardware_address),
599 ETHER_ADDRESS_LENGTH);
600 header.protocol_sender = entry->protocol_address;
601
602 // exchange source and destination address
603 memcpy(LLADDR((sockaddr_dl *)buffer->source), header.hardware_sender,
604 ETHER_ADDRESS_LENGTH);
605 memcpy(LLADDR((sockaddr_dl *)buffer->destination), header.hardware_target,
606 ETHER_ADDRESS_LENGTH);
607
608 buffer->msg_flags = 0;
609 // make sure this won't be a broadcast message
610
611 gBufferModule->trim(buffer, sizeof(arp_header));
612 return entry->protocol->next->module->send_data(entry->protocol->next,
613 buffer);
614 }
615
616
617 static void
handle_arp_reply(net_buffer * buffer,arp_header & header)618 handle_arp_reply(net_buffer *buffer, arp_header &header)
619 {
620 if (sIgnoreReplies)
621 return;
622
623 MutexLocker locker(sCacheLock);
624 arp_update_entry(header.protocol_sender, (sockaddr_dl *)buffer->source, 0);
625 }
626
627
628 static status_t
arp_receive(void * cookie,net_device * device,net_buffer * buffer)629 arp_receive(void *cookie, net_device *device, net_buffer *buffer)
630 {
631 TRACE(("ARP receive\n"));
632
633 NetBufferHeaderReader<arp_header> bufferHeader(buffer);
634 if (bufferHeader.Status() < B_OK)
635 return bufferHeader.Status();
636
637 arp_header &header = bufferHeader.Data();
638 uint16 opcode = ntohs(header.opcode);
639
640 #ifdef TRACE_ARP
641 dprintf(" hw sender: %s\n", mac_to_string(header.hardware_sender));
642 dprintf(" proto sender: %s\n", inet_to_string(header.protocol_sender));
643 dprintf(" hw target: %s\n", mac_to_string(header.hardware_target));;
644 dprintf(" proto target: %s\n", inet_to_string(header.protocol_target));
645 #endif // TRACE_ARP
646
647 if (ntohs(header.protocol_type) != ETHER_TYPE_IP
648 || ntohs(header.hardware_type) != ARP_HARDWARE_TYPE_ETHER)
649 return B_BAD_TYPE;
650
651 // check if the packet is okay
652
653 if (header.hardware_length != ETHER_ADDRESS_LENGTH
654 || header.protocol_length != sizeof(in_addr_t))
655 return B_BAD_DATA;
656
657 // handle packet
658
659 switch (opcode) {
660 case ARP_OPCODE_REQUEST:
661 TRACE((" got ARP request\n"));
662 if (handle_arp_request(buffer, header) == B_OK) {
663 // the function will take care of the buffer if everything
664 // went well
665 return B_OK;
666 }
667 break;
668 case ARP_OPCODE_REPLY:
669 TRACE((" got ARP reply\n"));
670 handle_arp_reply(buffer, header);
671 break;
672
673 default:
674 dprintf("unknown ARP opcode %d\n", opcode);
675 return B_ERROR;
676 }
677
678 gBufferModule->free(buffer);
679 return B_OK;
680 }
681
682
683 static void
arp_timer(struct net_timer * timer,void * data)684 arp_timer(struct net_timer *timer, void *data)
685 {
686 arp_entry *entry = (arp_entry *)data;
687 TRACE(("ARP timer %ld, entry %p!\n", entry->timer_state, entry));
688
689 switch (entry->timer_state) {
690 case ARP_NO_STATE:
691 // who are you kidding?
692 break;
693
694 case ARP_STATE_REQUEST_FAILED:
695 // Requesting the ARP entry failed, we keep it around for a while,
696 // though, so that we won't try to request the same address again
697 // too soon.
698 TRACE((" requesting ARP entry %p failed!\n", entry));
699 entry->timer_state = ARP_STATE_REMOVE_FAILED;
700 entry->MarkFailed();
701 sStackModule->set_timer(&entry->timer, ARP_REJECT_TIMEOUT);
702 break;
703
704 case ARP_STATE_REMOVE_FAILED:
705 case ARP_STATE_STALE:
706 {
707 // the entry has aged so much that we're going to remove it
708 TRACE((" remove ARP entry %p!\n", entry));
709
710 MutexLocker locker(sCacheLock);
711 if ((entry->flags & ARP_FLAG_REMOVED) != 0) {
712 // The entry has already been removed, and is about to be
713 // deleted
714 break;
715 }
716
717 sCache->Remove(entry);
718 locker.Unlock();
719
720 delete entry;
721 break;
722 }
723
724 default:
725 {
726 if (entry->timer_state > ARP_STATE_LAST_REQUEST
727 || entry->protocol == NULL)
728 break;
729
730 TRACE((" send request for ARP entry %p!\n", entry));
731
732 net_buffer *request = get_request_buffer(entry);
733 if (request == NULL)
734 break;
735
736 if (entry->timer_state < ARP_STATE_LAST_REQUEST) {
737 // we'll still need our buffer, so in order to prevent it being
738 // freed by a successful send, we need to clone it
739 net_buffer* clone = gBufferModule->clone(request, true);
740 if (clone == NULL) {
741 // cloning failed - that means we won't be able to send as
742 // many requests as originally planned
743 entry->timer_state = ARP_STATE_LAST_REQUEST;
744 } else {
745 put_request_buffer(entry, request);
746 request = clone;
747 }
748 }
749
750 // we're trying to resolve the address, so keep sending requests
751 status_t status = entry->protocol->next->module->send_data(
752 entry->protocol->next, request);
753 if (status < B_OK)
754 gBufferModule->free(request);
755
756 entry->timer_state++;
757 sStackModule->set_timer(&entry->timer, ARP_REQUEST_TIMEOUT);
758 break;
759 }
760 }
761 }
762
763
764 /*! Address resolver function: prepares and triggers the ARP request necessary
765 to retrieve the hardware address for \a address.
766
767 You need to have the sCacheLock held when calling this function.
768 */
769 static status_t
arp_start_resolve(arp_protocol * protocol,in_addr_t address,arp_entry ** _entry)770 arp_start_resolve(arp_protocol* protocol, in_addr_t address, arp_entry** _entry)
771 {
772 ASSERT_LOCKED_MUTEX(&sCacheLock);
773
774 // create an unresolved ARP entry as a placeholder
775 arp_entry *entry = arp_entry::Add(address, NULL, 0);
776 if (entry == NULL)
777 return B_NO_MEMORY;
778
779 // prepare ARP request
780
781 entry->request_buffer = gBufferModule->create(256);
782 if (entry->request_buffer == NULL) {
783 entry->ScheduleRemoval();
784 return B_NO_MEMORY;
785 }
786
787 NetBufferPrepend<arp_header> bufferHeader(entry->request_buffer);
788 status_t status = bufferHeader.Status();
789 if (status < B_OK) {
790 entry->ScheduleRemoval();
791 return status;
792 }
793
794 // prepare ARP header
795
796 net_device *device = protocol->interface->device;
797 arp_header &header = bufferHeader.Data();
798
799 header.hardware_type = htons(ARP_HARDWARE_TYPE_ETHER);
800 header.protocol_type = htons(ETHER_TYPE_IP);
801 header.hardware_length = ETHER_ADDRESS_LENGTH;
802 header.protocol_length = sizeof(in_addr_t);
803 header.opcode = htons(ARP_OPCODE_REQUEST);
804
805 memcpy(header.hardware_sender, device->address.data, ETHER_ADDRESS_LENGTH);
806 memset(header.hardware_target, 0, ETHER_ADDRESS_LENGTH);
807 header.protocol_sender = protocol->local_address;
808 header.protocol_target = address;
809
810 // prepare source and target addresses
811
812 struct sockaddr_dl &source = *(struct sockaddr_dl *)
813 entry->request_buffer->source;
814 source.sdl_len = sizeof(sockaddr_dl);
815 source.sdl_family = AF_LINK;
816 source.sdl_index = device->index;
817 source.sdl_type = IFT_ETHER;
818 source.sdl_e_type = htons(ETHER_TYPE_ARP);
819 source.sdl_nlen = source.sdl_slen = 0;
820 source.sdl_alen = ETHER_ADDRESS_LENGTH;
821 memcpy(source.sdl_data, device->address.data, ETHER_ADDRESS_LENGTH);
822
823 entry->request_buffer->msg_flags = MSG_BCAST;
824 // this is a broadcast packet, we don't need to fill in the destination
825
826 entry->protocol = protocol;
827 entry->timer_state = ARP_STATE_REQUEST;
828 sStackModule->set_timer(&entry->timer, 0);
829 // start request timer
830
831 *_entry = entry;
832 return B_OK;
833 }
834
835
836 static status_t
arp_control(const char * subsystem,uint32 function,void * buffer,size_t bufferSize)837 arp_control(const char *subsystem, uint32 function, void *buffer,
838 size_t bufferSize)
839 {
840 struct arp_control control;
841 if (bufferSize != sizeof(struct arp_control))
842 return B_BAD_VALUE;
843 if (user_memcpy(&control, buffer, sizeof(struct arp_control)) < B_OK)
844 return B_BAD_ADDRESS;
845
846 MutexLocker locker(sCacheLock);
847
848 switch (function) {
849 case ARP_SET_ENTRY:
850 {
851 sockaddr_dl hardwareAddress;
852
853 hardwareAddress.sdl_len = sizeof(sockaddr_dl);
854 hardwareAddress.sdl_family = AF_LINK;
855 hardwareAddress.sdl_index = 0;
856 hardwareAddress.sdl_type = IFT_ETHER;
857 hardwareAddress.sdl_e_type = htons(ETHER_TYPE_IP);
858 hardwareAddress.sdl_nlen = hardwareAddress.sdl_slen = 0;
859 hardwareAddress.sdl_alen = ETHER_ADDRESS_LENGTH;
860 memcpy(hardwareAddress.sdl_data, control.ethernet_address,
861 ETHER_ADDRESS_LENGTH);
862
863 return arp_update_entry(control.address, &hardwareAddress,
864 control.flags & (ARP_FLAG_PUBLISH | ARP_FLAG_PERMANENT
865 | ARP_FLAG_REJECT));
866 }
867
868 case ARP_GET_ENTRY:
869 {
870 arp_entry *entry = arp_entry::Lookup(control.address);
871 if (entry == NULL || !(entry->flags & ARP_FLAG_VALID))
872 return B_ENTRY_NOT_FOUND;
873
874 if (entry->hardware_address.sdl_alen == ETHER_ADDRESS_LENGTH) {
875 memcpy(control.ethernet_address,
876 entry->hardware_address.sdl_data, ETHER_ADDRESS_LENGTH);
877 } else
878 memset(control.ethernet_address, 0, ETHER_ADDRESS_LENGTH);
879
880 control.flags = entry->flags & ARP_PUBLIC_FLAG_MASK;
881 return user_memcpy(buffer, &control, sizeof(struct arp_control));
882 }
883
884 case ARP_GET_ENTRIES:
885 {
886 AddressCache::Iterator iterator(sCache);
887
888 arp_entry *entry = NULL;
889 for (uint32 i = 0; i <= control.cookie; i++) {
890 if (!iterator.HasNext())
891 return B_ENTRY_NOT_FOUND;
892 entry = iterator.Next();
893 }
894
895 control.cookie++;
896 control.address = entry->protocol_address;
897 if (entry->hardware_address.sdl_alen == ETHER_ADDRESS_LENGTH) {
898 memcpy(control.ethernet_address,
899 entry->hardware_address.sdl_data, ETHER_ADDRESS_LENGTH);
900 } else
901 memset(control.ethernet_address, 0, ETHER_ADDRESS_LENGTH);
902 control.flags = entry->flags & ARP_PUBLIC_FLAG_MASK;
903
904 return user_memcpy(buffer, &control, sizeof(struct arp_control));
905 }
906
907 case ARP_DELETE_ENTRY:
908 {
909 arp_entry *entry = arp_entry::Lookup(control.address);
910 if (entry == NULL)
911 return B_ENTRY_NOT_FOUND;
912 if ((entry->flags & ARP_FLAG_LOCAL) != 0)
913 return B_BAD_VALUE;
914
915 entry->ScheduleRemoval();
916 return B_OK;
917 }
918
919 case ARP_FLUSH_ENTRIES:
920 {
921 AddressCache::Iterator iterator(sCache);
922
923 arp_entry *entry;
924 while (iterator.HasNext()) {
925 entry = iterator.Next();
926 // we never flush local ARP entries
927 if ((entry->flags & ARP_FLAG_LOCAL) != 0)
928 continue;
929
930 entry->ScheduleRemoval();
931 }
932 return B_OK;
933 }
934
935 case ARP_IGNORE_REPLIES:
936 sIgnoreReplies = control.flags != 0;
937 return B_OK;
938 }
939
940 return B_BAD_VALUE;
941 }
942
943
944 static status_t
arp_init()945 arp_init()
946 {
947 mutex_init(&sCacheLock, "arp cache");
948
949 sCache = new(std::nothrow) AddressCache();
950 if (sCache == NULL || sCache->Init(64) != B_OK) {
951 mutex_destroy(&sCacheLock);
952 return B_NO_MEMORY;
953 }
954
955 register_generic_syscall(ARP_SYSCALLS, arp_control, 1, 0);
956 return B_OK;
957 }
958
959
960 static status_t
arp_uninit()961 arp_uninit()
962 {
963 ASSERT(sCache->IsEmpty());
964 unregister_generic_syscall(ARP_SYSCALLS, 1);
965 return B_OK;
966 }
967
968
969 // #pragma mark - net_datalink_protocol
970
971
972 status_t
arp_init_protocol(net_interface * interface,net_domain * domain,net_datalink_protocol ** _protocol)973 arp_init_protocol(net_interface* interface, net_domain* domain,
974 net_datalink_protocol** _protocol)
975 {
976 // We currently only support a single family and type!
977 if (interface->device->type != IFT_ETHER
978 || domain->family != AF_INET)
979 return B_BAD_TYPE;
980
981 status_t status = sStackModule->register_device_handler(interface->device,
982 B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_ARP), &arp_receive, NULL);
983 if (status != B_OK)
984 return status;
985
986 status = sStackModule->register_domain_device_handler(
987 interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_IP), domain);
988 if (status != B_OK)
989 return status;
990
991 arp_protocol* protocol = new(std::nothrow) arp_protocol;
992 if (protocol == NULL)
993 return B_NO_MEMORY;
994
995 memset(&protocol->hardware_address, 0, sizeof(sockaddr_dl));
996 protocol->local_address = 0;
997
998 *_protocol = protocol;
999 return B_OK;
1000 }
1001
1002
1003 status_t
arp_uninit_protocol(net_datalink_protocol * protocol)1004 arp_uninit_protocol(net_datalink_protocol *protocol)
1005 {
1006 sStackModule->unregister_device_handler(protocol->interface->device,
1007 B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_ARP));
1008 sStackModule->unregister_device_handler(protocol->interface->device,
1009 B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_IP));
1010
1011 delete protocol;
1012 return B_OK;
1013 }
1014
1015
1016 status_t
arp_send_data(net_datalink_protocol * _protocol,net_buffer * buffer)1017 arp_send_data(net_datalink_protocol *_protocol, net_buffer *buffer)
1018 {
1019 arp_protocol *protocol = (arp_protocol *)_protocol;
1020 {
1021 MutexLocker locker(sCacheLock);
1022
1023 // Set buffer target and destination address
1024
1025 memcpy(buffer->source, &protocol->hardware_address,
1026 protocol->hardware_address.sdl_len);
1027
1028 if ((buffer->msg_flags & MSG_MCAST) != 0) {
1029 sockaddr_dl multicastDestination;
1030 ipv4_to_ether_multicast(&multicastDestination,
1031 (sockaddr_in *)buffer->destination);
1032 memcpy(buffer->destination, &multicastDestination,
1033 sizeof(multicastDestination));
1034 } else if ((buffer->msg_flags & MSG_BCAST) == 0) {
1035 // Lookup destination (we may need to wait for this)
1036 arp_entry *entry = arp_entry::Lookup(
1037 ((struct sockaddr_in *)buffer->destination)->sin_addr.s_addr);
1038 if (entry == NULL) {
1039 status_t status = arp_start_resolve(protocol,
1040 ((struct sockaddr_in*)buffer->destination)->sin_addr.s_addr,
1041 &entry);
1042 if (status != B_OK)
1043 return status;
1044 }
1045
1046 if ((entry->flags & ARP_FLAG_REJECT) != 0)
1047 return EHOSTUNREACH;
1048
1049 if ((entry->flags & ARP_FLAG_VALID) == 0) {
1050 // entry is still being resolved.
1051 TRACE(("ARP Queuing packet %p, entry still being resolved.\n",
1052 buffer));
1053 entry->queue.Add(buffer);
1054 return B_OK;
1055 }
1056
1057 memcpy(buffer->destination, &entry->hardware_address,
1058 entry->hardware_address.sdl_len);
1059 }
1060 // the broadcast address is set in the ethernet frame module
1061 }
1062 TRACE(("%s(%p): from %s\n", __FUNCTION__, buffer,
1063 mac_to_string(LLADDR((sockaddr_dl*)buffer->source))));
1064 TRACE((" to %s\n",
1065 mac_to_string(LLADDR((sockaddr_dl*)buffer->destination))));
1066
1067 return protocol->next->module->send_data(protocol->next, buffer);
1068 }
1069
1070
1071 status_t
arp_up(net_datalink_protocol * _protocol)1072 arp_up(net_datalink_protocol* _protocol)
1073 {
1074 arp_protocol* protocol = (arp_protocol*)_protocol;
1075 status_t status = protocol->next->module->interface_up(protocol->next);
1076 if (status != B_OK)
1077 return status;
1078
1079 // cache this device's address for later use
1080
1081 status = arp_update_local(protocol);
1082 if (status != B_OK) {
1083 protocol->next->module->interface_down(protocol->next);
1084 return status;
1085 }
1086
1087 return B_OK;
1088 }
1089
1090
1091 void
arp_down(net_datalink_protocol * protocol)1092 arp_down(net_datalink_protocol *protocol)
1093 {
1094 // remove local ARP entries from the cache
1095 arp_remove_local((arp_protocol*)protocol);
1096
1097 protocol->next->module->interface_down(protocol->next);
1098 }
1099
1100
1101 status_t
arp_change_address(net_datalink_protocol * _protocol,net_interface_address * address,int32 option,const struct sockaddr * oldAddress,const struct sockaddr * newAddress)1102 arp_change_address(net_datalink_protocol* _protocol,
1103 net_interface_address* address, int32 option,
1104 const struct sockaddr* oldAddress, const struct sockaddr* newAddress)
1105 {
1106 arp_protocol* protocol = (arp_protocol*)_protocol;
1107 TRACE(("%s(option %" B_PRId32 ")\n", __FUNCTION__, option));
1108
1109 switch (option) {
1110 case SIOCSIFADDR:
1111 case SIOCAIFADDR:
1112 case SIOCDIFADDR:
1113 // Those are the options we handle
1114 if ((protocol->interface->flags & IFF_UP) != 0) {
1115 // Update ARP entry for the local address
1116
1117 if (newAddress != NULL && newAddress->sa_family == AF_INET) {
1118 status_t status = arp_set_local_entry(protocol, newAddress);
1119 if (status != B_OK)
1120 return status;
1121 }
1122
1123 if (option != SIOCAIFADDR
1124 && (oldAddress == NULL || oldAddress->sa_family == AF_INET))
1125 arp_remove_local_entry(protocol, oldAddress, address);
1126 }
1127 break;
1128
1129 default:
1130 break;
1131 }
1132
1133 return protocol->next->module->change_address(protocol->next, address,
1134 option, oldAddress, newAddress);
1135 }
1136
1137
1138 status_t
arp_control(net_datalink_protocol * _protocol,int32 op,void * argument,size_t length)1139 arp_control(net_datalink_protocol *_protocol, int32 op, void *argument,
1140 size_t length)
1141 {
1142 arp_protocol* protocol = (arp_protocol*)_protocol;
1143 return protocol->next->module->control(protocol->next, op, argument,
1144 length);
1145 }
1146
1147
1148 static status_t
arp_join_multicast(net_datalink_protocol * protocol,const sockaddr * address)1149 arp_join_multicast(net_datalink_protocol *protocol, const sockaddr *address)
1150 {
1151 if (address->sa_family != AF_INET)
1152 return EINVAL;
1153
1154 sockaddr_dl multicastAddress;
1155 ipv4_to_ether_multicast(&multicastAddress, (const sockaddr_in *)address);
1156
1157 return protocol->next->module->join_multicast(protocol->next,
1158 (sockaddr *)&multicastAddress);
1159 }
1160
1161
1162 static status_t
arp_leave_multicast(net_datalink_protocol * protocol,const sockaddr * address)1163 arp_leave_multicast(net_datalink_protocol *protocol, const sockaddr *address)
1164 {
1165 if (address->sa_family != AF_INET)
1166 return EINVAL;
1167
1168 sockaddr_dl multicastAddress;
1169 ipv4_to_ether_multicast(&multicastAddress, (const sockaddr_in *)address);
1170
1171 return protocol->next->module->leave_multicast(protocol->next,
1172 (sockaddr *)&multicastAddress);
1173 }
1174
1175
1176 static status_t
arp_std_ops(int32 op,...)1177 arp_std_ops(int32 op, ...)
1178 {
1179 switch (op) {
1180 case B_MODULE_INIT:
1181 return arp_init();
1182 case B_MODULE_UNINIT:
1183 return arp_uninit();
1184
1185 default:
1186 return B_ERROR;
1187 }
1188 }
1189
1190
1191 static net_datalink_protocol_module_info sARPModule = {
1192 {
1193 "network/datalink_protocols/arp/v1",
1194 0,
1195 arp_std_ops
1196 },
1197 arp_init_protocol,
1198 arp_uninit_protocol,
1199 arp_send_data,
1200 arp_up,
1201 arp_down,
1202 arp_change_address,
1203 arp_control,
1204 arp_join_multicast,
1205 arp_leave_multicast,
1206 };
1207
1208
1209 module_dependency module_dependencies[] = {
1210 {NET_STACK_MODULE_NAME, (module_info**)&sStackModule},
1211 {NET_DATALINK_MODULE_NAME, (module_info**)&sDatalinkModule},
1212 {NET_BUFFER_MODULE_NAME, (module_info**)&gBufferModule},
1213 {}
1214 };
1215
1216 module_info* modules[] = {
1217 (module_info*)&sARPModule,
1218 NULL
1219 };
1220