xref: /haiku/src/add-ons/kernel/network/stack/link.cpp (revision 41f05b86075aaec56018e9b6ffe277e48d560f54)
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  */
8 
9 
10 //! The net_protocol one talks to when using the AF_LINK protocol
11 
12 
13 #include "link.h"
14 
15 #include <net/if_types.h>
16 #include <new>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/sockio.h>
20 
21 #include <KernelExport.h>
22 
23 #include <lock.h>
24 #include <net_datalink.h>
25 #include <net_device.h>
26 #include <ProtocolUtilities.h>
27 #include <util/AutoLock.h>
28 
29 #include "device_interfaces.h"
30 #include "domains.h"
31 #include "stack_private.h"
32 #include "utility.h"
33 
34 
35 class LocalStackBundle {
36 public:
37 	static net_stack_module_info* Stack() { return &gNetStackModule; }
38 	static net_buffer_module_info* Buffer() { return &gNetBufferModule; }
39 };
40 
41 typedef DatagramSocket<MutexLocking, LocalStackBundle> LocalDatagramSocket;
42 
43 class LinkProtocol : public net_protocol, public LocalDatagramSocket {
44 public:
45 								LinkProtocol(net_socket* socket);
46 	virtual						~LinkProtocol();
47 
48 			status_t			StartMonitoring(const char* deviceName);
49 			status_t			StopMonitoring();
50 
51 protected:
52 			status_t			SocketStatus(bool peek) const;
53 
54 private:
55 			status_t			_Unregister();
56 
57 	static	status_t			_MonitorData(net_device_monitor* monitor,
58 									net_buffer* buffer);
59 	static	void				_MonitorEvent(net_device_monitor* monitor,
60 									int32 event);
61 
62 private:
63 			net_device_monitor	fMonitor;
64 			net_device_interface* fMonitoredDevice;
65 };
66 
67 
68 struct net_domain* sDomain;
69 
70 
71 LinkProtocol::LinkProtocol(net_socket* socket)
72 	: LocalDatagramSocket("packet capture", socket)
73 {
74 	fMonitor.cookie = this;
75 	fMonitor.receive = _MonitorData;
76 	fMonitor.event = _MonitorEvent;
77 	fMonitoredDevice = NULL;
78 }
79 
80 
81 LinkProtocol::~LinkProtocol()
82 {
83 	if (fMonitoredDevice) {
84 		unregister_device_monitor(fMonitoredDevice->device, &fMonitor);
85 		put_device_interface(fMonitoredDevice);
86 	}
87 }
88 
89 
90 status_t
91 LinkProtocol::StartMonitoring(const char* deviceName)
92 {
93 	MutexLocker _(fLock);
94 
95 	if (fMonitoredDevice)
96 		return B_BUSY;
97 
98 	net_device_interface* interface = get_device_interface(deviceName);
99 	if (interface == NULL)
100 		return B_DEVICE_NOT_FOUND;
101 
102 	status_t status = register_device_monitor(interface->device, &fMonitor);
103 	if (status < B_OK) {
104 		put_device_interface(interface);
105 		return status;
106 	}
107 
108 	fMonitoredDevice = interface;
109 	return B_OK;
110 }
111 
112 
113 status_t
114 LinkProtocol::StopMonitoring()
115 {
116 	MutexLocker _(fLock);
117 
118 	// TODO compare our device with the supplied device name?
119 	return _Unregister();
120 }
121 
122 
123 status_t
124 LinkProtocol::SocketStatus(bool peek) const
125 {
126 	if (fMonitoredDevice == NULL)
127 		return B_DEVICE_NOT_FOUND;
128 
129 	return LocalDatagramSocket::SocketStatus(peek);
130 }
131 
132 
133 status_t
134 LinkProtocol::_Unregister()
135 {
136 	if (fMonitoredDevice == NULL)
137 		return B_BAD_VALUE;
138 
139 	status_t status = unregister_device_monitor(fMonitoredDevice->device,
140 		&fMonitor);
141 	put_device_interface(fMonitoredDevice);
142 	fMonitoredDevice = NULL;
143 
144 	return status;
145 }
146 
147 
148 status_t
149 LinkProtocol::_MonitorData(net_device_monitor* monitor, net_buffer* packet)
150 {
151 	return ((LinkProtocol*)monitor->cookie)->SocketEnqueue(packet);
152 }
153 
154 
155 void
156 LinkProtocol::_MonitorEvent(net_device_monitor* monitor, int32 event)
157 {
158 	LinkProtocol* protocol = (LinkProtocol*)monitor->cookie;
159 
160 	if (event == B_DEVICE_GOING_DOWN) {
161 		MutexLocker _(protocol->fLock);
162 
163 		protocol->_Unregister();
164 		if (protocol->IsEmpty()) {
165 			protocol->WakeAll();
166 			notify_socket(protocol->socket, B_SELECT_READ, B_DEVICE_NOT_FOUND);
167 		}
168 	}
169 }
170 
171 
172 //	#pragma mark -
173 
174 
175 static bool
176 user_request_get_device_interface(void* value, struct ifreq& request,
177 	net_device_interface*& interface)
178 {
179 	if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK)
180 		return false;
181 
182 	interface = get_device_interface(request.ifr_name);
183 	return true;
184 }
185 
186 
187 //	#pragma mark -
188 
189 
190 net_protocol*
191 link_init_protocol(net_socket* socket)
192 {
193 	LinkProtocol* protocol = new (std::nothrow) LinkProtocol(socket);
194 	if (protocol != NULL && protocol->InitCheck() < B_OK) {
195 		delete protocol;
196 		return NULL;
197 	}
198 
199 	return protocol;
200 }
201 
202 
203 status_t
204 link_uninit_protocol(net_protocol* protocol)
205 {
206 	delete (LinkProtocol*)protocol;
207 	return B_OK;
208 }
209 
210 
211 status_t
212 link_open(net_protocol* protocol)
213 {
214 	return B_OK;
215 }
216 
217 
218 status_t
219 link_close(net_protocol* protocol)
220 {
221 	return B_OK;
222 }
223 
224 
225 status_t
226 link_free(net_protocol* protocol)
227 {
228 	return B_OK;
229 }
230 
231 
232 status_t
233 link_connect(net_protocol* protocol, const struct sockaddr* address)
234 {
235 	return EOPNOTSUPP;
236 }
237 
238 
239 status_t
240 link_accept(net_protocol* protocol, struct net_socket** _acceptedSocket)
241 {
242 	return EOPNOTSUPP;
243 }
244 
245 
246 status_t
247 link_control(net_protocol* _protocol, int level, int option, void* value,
248 	size_t* _length)
249 {
250 	LinkProtocol* protocol = (LinkProtocol*)_protocol;
251 
252 	switch (option) {
253 		case SIOCGIFINDEX:
254 		{
255 			// get index of interface
256 			net_device_interface* interface;
257 			struct ifreq request;
258 			if (!user_request_get_device_interface(value, request, interface))
259 				return B_BAD_ADDRESS;
260 
261 			if (interface != NULL) {
262 				request.ifr_index = interface->device->index;
263 				put_device_interface(interface);
264 			} else
265 				request.ifr_index = 0;
266 
267 			return user_memcpy(value, &request, sizeof(struct ifreq));
268 		}
269 		case SIOCGIFNAME:
270 		{
271 			// get name of interface via index
272 			struct ifreq request;
273 			if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK)
274 				return B_BAD_ADDRESS;
275 
276 			net_device_interface* interface
277 				= get_device_interface(request.ifr_index);
278 			if (interface == NULL)
279 				return B_DEVICE_NOT_FOUND;
280 
281 			strlcpy(request.ifr_name, interface->device->name, IF_NAMESIZE);
282 			put_device_interface(interface);
283 
284 			return user_memcpy(value, &request, sizeof(struct ifreq));
285 		}
286 
287 		case SIOCGIFCOUNT:
288 		{
289 			// count number of interfaces
290 			struct ifconf config;
291 			config.ifc_value = count_device_interfaces();
292 
293 			return user_memcpy(value, &config, sizeof(struct ifconf));
294 		}
295 
296 		case SIOCGIFCONF:
297 		{
298 			// retrieve available interfaces
299 			struct ifconf config;
300 			if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK)
301 				return B_BAD_ADDRESS;
302 
303 			status_t result = list_device_interfaces(config.ifc_buf,
304 				(size_t*)&config.ifc_len);
305 			if (result != B_OK)
306 				return result;
307 
308 			return user_memcpy(value, &config, sizeof(struct ifconf));
309 		}
310 
311 		case SIOCGIFADDR:
312 		{
313 			// get address of interface
314 			net_device_interface* interface;
315 			struct ifreq request;
316 			if (!user_request_get_device_interface(value, request, interface))
317 				return B_BAD_ADDRESS;
318 
319 			if (interface == NULL)
320 				return B_DEVICE_NOT_FOUND;
321 
322 			get_device_interface_address(interface, &request.ifr_addr);
323 			put_device_interface(interface);
324 
325 			return user_memcpy(&((struct ifreq*)value)->ifr_addr,
326 				&request.ifr_addr, request.ifr_addr.sa_len);
327 		}
328 
329 		case SIOCGIFFLAGS:
330 		{
331 			// get flags of interface
332 			net_device_interface* interface;
333 			struct ifreq request;
334 			if (!user_request_get_device_interface(value, request, interface))
335 				return B_BAD_ADDRESS;
336 
337 			if (interface == NULL)
338 				return B_DEVICE_NOT_FOUND;
339 
340 			request.ifr_flags = interface->device->flags;
341 			put_device_interface(interface);
342 
343 			return user_memcpy(&((struct ifreq*)value)->ifr_flags,
344 				&request.ifr_flags, sizeof(request.ifr_flags));
345 		}
346 
347 		case SIOCSPACKETCAP:
348 		{
349 			// Only root is allowed to capture packets
350 			if (geteuid() != 0)
351 				return B_NOT_ALLOWED;
352 
353 			struct ifreq request;
354 			if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK)
355 				return B_BAD_ADDRESS;
356 
357 			return protocol->StartMonitoring(request.ifr_name);
358 		}
359 
360 		case SIOCCPACKETCAP:
361 			return protocol->StopMonitoring();
362 	}
363 
364 	return gNetDatalinkModule.control(sDomain, option, value, _length);
365 }
366 
367 
368 status_t
369 link_getsockopt(net_protocol* protocol, int level, int option, void* value,
370 	int* length)
371 {
372 	if (protocol->next != NULL) {
373 		return protocol->next->module->getsockopt(protocol, level, option,
374 			value, length);
375 	}
376 
377 	return gNetSocketModule.get_option(protocol->socket, level, option, value,
378 		length);
379 }
380 
381 
382 status_t
383 link_setsockopt(net_protocol* protocol, int level, int option,
384 	const void* value, int length)
385 {
386 	if (protocol->next != NULL) {
387 		return protocol->next->module->setsockopt(protocol, level, option,
388 			value, length);
389 	}
390 
391 	return gNetSocketModule.set_option(protocol->socket, level, option,
392 		value, length);
393 }
394 
395 
396 status_t
397 link_bind(net_protocol* protocol, const struct sockaddr* address)
398 {
399 	// TODO: bind to a specific interface and ethernet type
400 	return B_ERROR;
401 }
402 
403 
404 status_t
405 link_unbind(net_protocol* protocol, struct sockaddr* address)
406 {
407 	return B_ERROR;
408 }
409 
410 
411 status_t
412 link_listen(net_protocol* protocol, int count)
413 {
414 	return EOPNOTSUPP;
415 }
416 
417 
418 status_t
419 link_shutdown(net_protocol* protocol, int direction)
420 {
421 	return EOPNOTSUPP;
422 }
423 
424 
425 status_t
426 link_send_data(net_protocol* protocol, net_buffer* buffer)
427 {
428 	// Only root is allowed to send link protocol packets
429 	if (geteuid() != 0)
430 		return B_NOT_ALLOWED;
431 
432 	return B_NOT_SUPPORTED;
433 }
434 
435 
436 status_t
437 link_send_routed_data(net_protocol* protocol, struct net_route* route,
438 	net_buffer* buffer)
439 {
440 	return B_NOT_SUPPORTED;
441 }
442 
443 
444 ssize_t
445 link_send_avail(net_protocol* protocol)
446 {
447 	return B_ERROR;
448 }
449 
450 
451 status_t
452 link_read_data(net_protocol* protocol, size_t numBytes, uint32 flags,
453 	net_buffer** _buffer)
454 {
455 	return ((LinkProtocol*)protocol)->SocketDequeue(flags, _buffer);
456 }
457 
458 
459 ssize_t
460 link_read_avail(net_protocol* protocol)
461 {
462 	return ((LinkProtocol*)protocol)->AvailableData();
463 }
464 
465 
466 struct net_domain*
467 link_get_domain(net_protocol* protocol)
468 {
469 	return sDomain;
470 }
471 
472 
473 size_t
474 link_get_mtu(net_protocol* protocol, const struct sockaddr* address)
475 {
476 	// TODO: for now
477 	return 0;
478 }
479 
480 
481 status_t
482 link_receive_data(net_buffer* buffer)
483 {
484 	return B_ERROR;
485 }
486 
487 
488 status_t
489 link_error(uint32 code, net_buffer* data)
490 {
491 	return B_ERROR;
492 }
493 
494 
495 status_t
496 link_error_reply(net_protocol* protocol, net_buffer* causedError, uint32 code,
497 	void* errorData)
498 {
499 	return B_ERROR;
500 }
501 
502 
503 static status_t
504 link_std_ops(int32 op, ...)
505 {
506 	switch (op) {
507 		case B_MODULE_INIT:
508 			return register_domain(AF_LINK, "link", NULL, NULL, &sDomain);
509 
510 		case B_MODULE_UNINIT:
511 			unregister_domain(sDomain);
512 			return B_OK;
513 
514 		default:
515 			return B_ERROR;
516 	}
517 }
518 
519 
520 //	#pragma mark -
521 
522 
523 void
524 link_init()
525 {
526 	register_domain_protocols(AF_LINK, SOCK_DGRAM, 0, "network/stack/link/v1",
527 		NULL);
528 
529 	register_domain_datalink_protocols(AF_LINK, IFT_ETHER,
530 		"network/datalink_protocols/ethernet_frame/v1",
531 		NULL);
532 }
533 
534 
535 net_protocol_module_info gLinkModule = {
536 	{
537 		"network/stack/link/v1",
538 		0,
539 		link_std_ops
540 	},
541 	NET_PROTOCOL_ATOMIC_MESSAGES,
542 
543 	link_init_protocol,
544 	link_uninit_protocol,
545 	link_open,
546 	link_close,
547 	link_free,
548 	link_connect,
549 	link_accept,
550 	link_control,
551 	link_getsockopt,
552 	link_setsockopt,
553 	link_bind,
554 	link_unbind,
555 	link_listen,
556 	link_shutdown,
557 	link_send_data,
558 	link_send_routed_data,
559 	link_send_avail,
560 	link_read_data,
561 	link_read_avail,
562 	link_get_domain,
563 	link_get_mtu,
564 	link_receive_data,
565 	NULL,
566 	link_error,
567 	link_error_reply,
568 };
569