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