xref: /haiku/src/add-ons/kernel/network/devices/loopback/loopback.cpp (revision 4c07199d8201fcf267e90be0d24b76799d03cea6)
1 /*
2  * Copyright 2006-2007, 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 #include <net_buffer.h>
11 #include <net_device.h>
12 #include <net_stack.h>
13 
14 #include <KernelExport.h>
15 
16 #include <net/if.h>
17 #include <net/if_types.h>
18 #include <net/if_media.h>
19 #include <new>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 
24 struct loopback_device : net_device {
25 };
26 
27 
28 struct net_buffer_module_info *gBufferModule;
29 static struct net_stack_module_info *sStackModule;
30 
31 
32 //	#pragma mark -
33 
34 
35 status_t
36 loopback_init(const char *name, net_device **_device)
37 {
38 	loopback_device *device;
39 
40 	if (strncmp(name, "loop", 4))
41 		return B_BAD_VALUE;
42 
43 	status_t status = get_module(NET_STACK_MODULE_NAME, (module_info **)&sStackModule);
44 	if (status < B_OK)
45 		return status;
46 
47 	status = get_module(NET_BUFFER_MODULE_NAME, (module_info **)&gBufferModule);
48 	if (status < B_OK)
49 		goto err1;
50 
51 	device = new (std::nothrow) loopback_device;
52 	if (device == NULL) {
53 		status = B_NO_MEMORY;
54 		goto err2;
55 	}
56 
57 	memset(device, 0, sizeof(loopback_device));
58 
59 	strcpy(device->name, name);
60 	device->flags = IFF_LOOPBACK | IFF_LINK;
61 	device->type = IFT_LOOP;
62 	device->mtu = 65536;
63 	device->media = IFM_ACTIVE;
64 
65 	*_device = device;
66 	return B_OK;
67 
68 err2:
69 	put_module(NET_BUFFER_MODULE_NAME);
70 err1:
71 	put_module(NET_STACK_MODULE_NAME);
72 	return status;
73 }
74 
75 
76 status_t
77 loopback_uninit(net_device *_device)
78 {
79 	loopback_device *device = (loopback_device *)_device;
80 
81 	put_module(NET_STACK_MODULE_NAME);
82 	put_module(NET_BUFFER_MODULE_NAME);
83 	delete device;
84 
85 	return B_OK;
86 }
87 
88 
89 status_t
90 loopback_up(net_device *device)
91 {
92 	return B_OK;
93 }
94 
95 
96 void
97 loopback_down(net_device *device)
98 {
99 }
100 
101 
102 status_t
103 loopback_control(net_device *device, int32 op, void *argument,
104 	size_t length)
105 {
106 	return B_BAD_VALUE;
107 }
108 
109 
110 status_t
111 loopback_send_data(net_device *device, net_buffer *buffer)
112 {
113 	status_t status = sStackModule->device_enqueue_buffer(device, buffer);
114 	if (status == B_OK) {
115 		atomic_add64((int64*)&device->stats.send.bytes, buffer->size);
116 		atomic_add((int32*)&device->stats.send.packets, 1);
117 	} else {
118 		atomic_add((int32*)&device->stats.send.errors, 1);
119 	}
120 	return status;
121 }
122 
123 
124 status_t
125 loopback_set_mtu(net_device *device, size_t mtu)
126 {
127 	if (mtu > 65536 || mtu < 16)
128 		return B_BAD_VALUE;
129 
130 	device->mtu = mtu;
131 	return B_OK;
132 }
133 
134 
135 status_t
136 loopback_set_promiscuous(net_device *device, bool promiscuous)
137 {
138 	return EOPNOTSUPP;
139 }
140 
141 
142 status_t
143 loopback_set_media(net_device *device, uint32 media)
144 {
145 	return EOPNOTSUPP;
146 }
147 
148 
149 status_t
150 loopback_add_multicast(net_device *device, const sockaddr *address)
151 {
152 	return B_OK;
153 }
154 
155 
156 status_t
157 loopback_remove_multicast(net_device *device, const sockaddr *address)
158 {
159 	return B_OK;
160 }
161 
162 
163 static status_t
164 loopback_std_ops(int32 op, ...)
165 {
166 	switch (op) {
167 		case B_MODULE_INIT:
168 		case B_MODULE_UNINIT:
169 			return B_OK;
170 
171 		default:
172 			return B_ERROR;
173 	}
174 }
175 
176 
177 net_device_module_info sLoopbackModule = {
178 	{
179 		"network/devices/loopback/v1",
180 		0,
181 		loopback_std_ops
182 	},
183 	loopback_init,
184 	loopback_uninit,
185 	loopback_up,
186 	loopback_down,
187 	loopback_control,
188 	loopback_send_data,
189 	NULL, // receive_data
190 	loopback_set_mtu,
191 	loopback_set_promiscuous,
192 	loopback_set_media,
193 	loopback_add_multicast,
194 	loopback_remove_multicast,
195 };
196 
197 module_info *modules[] = {
198 	(module_info *)&sLoopbackModule,
199 	NULL
200 };
201