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