1fd55fb66SAxel Dörfler/*
2fd55fb66SAxel Dörfler * Copyright 2006-2015, Haiku, Inc. All Rights Reserved.
3fd55fb66SAxel Dörfler * Distributed under the terms of the MIT License.
4fd55fb66SAxel Dörfler *
5fd55fb66SAxel Dörfler * Authors:
6fd55fb66SAxel Dörfler *		Axel D��rfler, axeld@pinc-software.de
7fd55fb66SAxel Dörfler */
8fd55fb66SAxel Dörfler
9fd55fb66SAxel Dörfler
10fd55fb66SAxel Dörfler#include <NetworkSettings.h>
11fd55fb66SAxel Dörfler
12f16f9ee4SAxel Dörfler#include <netdb.h>
13fd55fb66SAxel Dörfler#include <stdio.h>
14fd55fb66SAxel Dörfler#include <stdlib.h>
15fd55fb66SAxel Dörfler#include <string.h>
16fd55fb66SAxel Dörfler
17fd55fb66SAxel Dörfler#include <Directory.h>
18fd55fb66SAxel Dörfler#include <File.h>
19fd55fb66SAxel Dörfler#include <FindDirectory.h>
20fd55fb66SAxel Dörfler#include <fs_interface.h>
21fd55fb66SAxel Dörfler#include <NetworkDevice.h>
22b00dcbcaSAxel Dörfler#include <NetworkInterface.h>
23fd55fb66SAxel Dörfler#include <Path.h>
24fd55fb66SAxel Dörfler#include <PathMonitor.h>
25fd55fb66SAxel Dörfler#include <String.h>
26fd55fb66SAxel Dörfler
27fd55fb66SAxel Dörfler#include <DriverSettingsMessageAdapter.h>
28f7ccc9afSAxel Dörfler#include <NetServer.h>
29fd55fb66SAxel Dörfler
30fd55fb66SAxel Dörfler
31fd55fb66SAxel Dörflerusing namespace BNetworkKit;
32fd55fb66SAxel Dörfler
33fd55fb66SAxel Dörfler
34fd55fb66SAxel Dörflerstatic const char* kInterfaceSettingsName = "interfaces";
35fd55fb66SAxel Dörflerstatic const char* kServicesSettingsName = "services";
36fd55fb66SAxel Dörflerstatic const char* kNetworksSettingsName = "wireless_networks";
37fd55fb66SAxel Dörfler
38e4f4658aSAxel Dörfler
39fd55fb66SAxel Dörfler// Interface templates
40fd55fb66SAxel Dörfler
41e4f4658aSAxel Dörflernamespace BPrivate {
42e4f4658aSAxel Dörfler
43e4f4658aSAxel Dörfler
44e4f4658aSAxel Dörflerclass InterfaceAddressFamilyConverter : public DriverSettingsConverter {
45e4f4658aSAxel Dörflerpublic:
46e4f4658aSAxel Dörfler	virtual	status_t			ConvertFromDriverSettings(
47e4f4658aSAxel Dörfler									const driver_parameter& parameter,
48687d0bc2SAxel Dörfler									const char* name, int32 index, uint32 type,
49e4f4658aSAxel Dörfler									BMessage& target);
50e4f4658aSAxel Dörfler	virtual	status_t			ConvertToDriverSettings(const BMessage& source,
51e4f4658aSAxel Dörfler									const char* name, int32 index,
52e4f4658aSAxel Dörfler									uint32 type, BString& value);
53e4f4658aSAxel Dörfler};
54e4f4658aSAxel Dörfler
55e4f4658aSAxel Dörfler
56e4f4658aSAxel Dörfler}	// namespace BPrivate
57e4f4658aSAxel Dörfler
58e4f4658aSAxel Dörflerusing BPrivate::InterfaceAddressFamilyConverter;
59e4f4658aSAxel Dörfler
60e4f4658aSAxel Dörfler
61fd55fb66SAxel Dörflerconst static settings_template kInterfaceAddressTemplate[] = {
62e4f4658aSAxel Dörfler	{B_STRING_TYPE, "family", NULL, true, new InterfaceAddressFamilyConverter},
63fd55fb66SAxel Dörfler	{B_STRING_TYPE, "address", NULL},
64fd55fb66SAxel Dörfler	{B_STRING_TYPE, "mask", NULL},
65fd55fb66SAxel Dörfler	{B_STRING_TYPE, "peer", NULL},
66fd55fb66SAxel Dörfler	{B_STRING_TYPE, "broadcast", NULL},
67fd55fb66SAxel Dörfler	{B_STRING_TYPE, "gateway", NULL},
68fd55fb66SAxel Dörfler	{B_BOOL_TYPE, "auto_config", NULL},
69fd55fb66SAxel Dörfler	{0, NULL, NULL}
70fd55fb66SAxel Dörfler};
71fd55fb66SAxel Dörfler
72fd55fb66SAxel Dörflerconst static settings_template kInterfaceNetworkTemplate[] = {
73fd55fb66SAxel Dörfler	{B_STRING_TYPE, "name", NULL, true},
74fd55fb66SAxel Dörfler	{B_STRING_TYPE, "mac", NULL},
75fd55fb66SAxel Dörfler};
76fd55fb66SAxel Dörfler
77fd55fb66SAxel Dörflerconst static settings_template kInterfaceTemplate[] = {
78fd55fb66SAxel Dörfler	{B_STRING_TYPE, "device", NULL, true},
79fd55fb66SAxel Dörfler	{B_BOOL_TYPE, "disabled", NULL},
80fd55fb66SAxel Dörfler	{B_MESSAGE_TYPE, "address", kInterfaceAddressTemplate},
81fd55fb66SAxel Dörfler	{B_MESSAGE_TYPE, "network", kInterfaceNetworkTemplate},
82fd55fb66SAxel Dörfler	{B_INT32_TYPE, "flags", NULL},
83fd55fb66SAxel Dörfler	{B_INT32_TYPE, "metric", NULL},
84fd55fb66SAxel Dörfler	{B_INT32_TYPE, "mtu", NULL},
85fd55fb66SAxel Dörfler	{0, NULL, NULL}
86fd55fb66SAxel Dörfler};
87fd55fb66SAxel Dörfler
88fd55fb66SAxel Dörflerconst static settings_template kInterfacesTemplate[] = {
89fd55fb66SAxel Dörfler	{B_MESSAGE_TYPE, "interface", kInterfaceTemplate},
90fd55fb66SAxel Dörfler	{0, NULL, NULL}
91fd55fb66SAxel Dörfler};
92fd55fb66SAxel Dörfler
93fd55fb66SAxel Dörfler// Network templates
94fd55fb66SAxel Dörfler
95fd55fb66SAxel Dörflerconst static settings_template kNetworkTemplate[] = {
96fd55fb66SAxel Dörfler	{B_STRING_TYPE, "name", NULL, true},
97fd55fb66SAxel Dörfler	{B_STRING_TYPE, "mac", NULL},
98fd55fb66SAxel Dörfler	{B_STRING_TYPE, "password", NULL},
99fd55fb66SAxel Dörfler	{B_STRING_TYPE, "authentication", NULL},
100fd55fb66SAxel Dörfler	{B_STRING_TYPE, "cipher", NULL},
101fd55fb66SAxel Dörfler	{B_STRING_TYPE, "group_cipher", NULL},
102fd55fb66SAxel Dörfler	{B_STRING_TYPE, "key", NULL},
103fd55fb66SAxel Dörfler	{0, NULL, NULL}
104fd55fb66SAxel Dörfler};
105fd55fb66SAxel Dörfler
106fd55fb66SAxel Dörflerconst static settings_template kNetworksTemplate[] = {
107fd55fb66SAxel Dörfler	{B_MESSAGE_TYPE, "network", kNetworkTemplate},
108fd55fb66SAxel Dörfler	{0, NULL, NULL}
109fd55fb66SAxel Dörfler};
110fd55fb66SAxel Dörfler
111fd55fb66SAxel Dörfler// Service templates
112fd55fb66SAxel Dörfler
113fd55fb66SAxel Dörflerconst static settings_template kServiceAddressTemplate[] = {
114fd55fb66SAxel Dörfler	{B_STRING_TYPE, "family", NULL, true},
115fd55fb66SAxel Dörfler	{B_STRING_TYPE, "type", NULL},
116fd55fb66SAxel Dörfler	{B_STRING_TYPE, "protocol", NULL},
117fd55fb66SAxel Dörfler	{B_STRING_TYPE, "address", NULL},
118fd55fb66SAxel Dörfler	{B_INT32_TYPE, "port", NULL},
119fd55fb66SAxel Dörfler	{0, NULL, NULL}
120fd55fb66SAxel Dörfler};
121fd55fb66SAxel Dörfler
122fd55fb66SAxel Dörflerconst static settings_template kServiceTemplate[] = {
123fd55fb66SAxel Dörfler	{B_STRING_TYPE, "name", NULL, true},
1247ca40f60SAxel Dörfler	{B_BOOL_TYPE, "disabled", NULL},
125fd55fb66SAxel Dörfler	{B_MESSAGE_TYPE, "address", kServiceAddressTemplate},
126fd55fb66SAxel Dörfler	{B_STRING_TYPE, "user", NULL},
127fd55fb66SAxel Dörfler	{B_STRING_TYPE, "group", NULL},
128fd55fb66SAxel Dörfler	{B_STRING_TYPE, "launch", NULL},
129fd55fb66SAxel Dörfler	{B_STRING_TYPE, "family", NULL},
130fd55fb66SAxel Dörfler	{B_STRING_TYPE, "type", NULL},
131fd55fb66SAxel Dörfler	{B_STRING_TYPE, "protocol", NULL},
132fd55fb66SAxel Dörfler	{B_INT32_TYPE, "port", NULL},
133fd55fb66SAxel Dörfler	{B_BOOL_TYPE, "stand_alone", NULL},
134fd55fb66SAxel Dörfler	{0, NULL, NULL}
135fd55fb66SAxel Dörfler};
136fd55fb66SAxel Dörfler
137fd55fb66SAxel Dörflerconst static settings_template kServicesTemplate[] = {
138fd55fb66SAxel Dörfler	{B_MESSAGE_TYPE, "service", kServiceTemplate},
139fd55fb66SAxel Dörfler	{0, NULL, NULL}
140fd55fb66SAxel Dörfler};
141fd55fb66SAxel Dörfler
142fd55fb66SAxel Dörfler
143f16f9ee4SAxel Dörflerstruct address_family {
144f16f9ee4SAxel Dörfler	int			family;
145f16f9ee4SAxel Dörfler	const char*	name;
146f16f9ee4SAxel Dörfler	const char*	identifiers[4];
147f16f9ee4SAxel Dörfler};
148f16f9ee4SAxel Dörfler
149f16f9ee4SAxel Dörfler
150f16f9ee4SAxel Dörflerstatic const address_family kFamilies[] = {
151f16f9ee4SAxel Dörfler	{
152f16f9ee4SAxel Dörfler		AF_INET,
153f16f9ee4SAxel Dörfler		"inet",
154f16f9ee4SAxel Dörfler		{"AF_INET", "inet", "ipv4", NULL},
155f16f9ee4SAxel Dörfler	},
156f16f9ee4SAxel Dörfler	{
157f16f9ee4SAxel Dörfler		AF_INET6,
158f16f9ee4SAxel Dörfler		"inet6",
159f16f9ee4SAxel Dörfler		{"AF_INET6", "inet6", "ipv6", NULL},
160f16f9ee4SAxel Dörfler	},
161f16f9ee4SAxel Dörfler	{ -1, NULL, {NULL} }
162f16f9ee4SAxel Dörfler};
163f16f9ee4SAxel Dörfler
164f16f9ee4SAxel Dörfler
165e4f4658aSAxel Dörflerstatic const char*
166e4f4658aSAxel Dörflerget_family_name(int family)
167e4f4658aSAxel Dörfler{
168e4f4658aSAxel Dörfler	for (int32 i = 0; kFamilies[i].family >= 0; i++) {
169e4f4658aSAxel Dörfler		if (kFamilies[i].family == family)
170e4f4658aSAxel Dörfler			return kFamilies[i].name;
171e4f4658aSAxel Dörfler	}
172e4f4658aSAxel Dörfler	return NULL;
173e4f4658aSAxel Dörfler}
174e4f4658aSAxel Dörfler
175e4f4658aSAxel Dörfler
176f16f9ee4SAxel Dörflerstatic int
177f16f9ee4SAxel Dörflerget_address_family(const char* argument)
178f16f9ee4SAxel Dörfler{
179f16f9ee4SAxel Dörfler	for (int32 i = 0; kFamilies[i].family >= 0; i++) {
180f16f9ee4SAxel Dörfler		for (int32 j = 0; kFamilies[i].identifiers[j]; j++) {
181f16f9ee4SAxel Dörfler			if (!strcmp(argument, kFamilies[i].identifiers[j])) {
182f16f9ee4SAxel Dörfler				// found a match
183f16f9ee4SAxel Dörfler				return kFamilies[i].family;
184f16f9ee4SAxel Dörfler			}
185f16f9ee4SAxel Dörfler		}
186f16f9ee4SAxel Dörfler	}
187f16f9ee4SAxel Dörfler
188f16f9ee4SAxel Dörfler	return AF_UNSPEC;
189f16f9ee4SAxel Dörfler}
190f16f9ee4SAxel Dörfler
191f16f9ee4SAxel Dörfler
192f16f9ee4SAxel Dörfler/*!	Parses the \a argument as network \a address for the specified \a family.
193f16f9ee4SAxel Dörfler	If \a family is \c AF_UNSPEC, \a family will be overwritten with the family
194f16f9ee4SAxel Dörfler	of the successfully parsed address.
195f16f9ee4SAxel Dörfler*/
196f16f9ee4SAxel Dörflerstatic bool
197f16f9ee4SAxel Dörflerparse_address(int32& family, const char* argument, BNetworkAddress& address)
198f16f9ee4SAxel Dörfler{
1990a6b5623SAxel Dörfler	if (argument == NULL) {
2000a6b5623SAxel Dörfler		if (family != AF_UNSPEC)
2010a6b5623SAxel Dörfler			address.SetToWildcard(family);
202f16f9ee4SAxel Dörfler		return false;
2030a6b5623SAxel Dörfler	}
204f16f9ee4SAxel Dörfler
205f16f9ee4SAxel Dörfler	status_t status = address.SetTo(family, argument, (uint16)0,
206f16f9ee4SAxel Dörfler		B_NO_ADDRESS_RESOLUTION);
207f16f9ee4SAxel Dörfler	if (status != B_OK)
208f16f9ee4SAxel Dörfler		return false;
209f16f9ee4SAxel Dörfler
210f16f9ee4SAxel Dörfler	if (family == AF_UNSPEC) {
211f16f9ee4SAxel Dörfler		// Test if we support the resulting address family
212f16f9ee4SAxel Dörfler		bool supported = false;
213f16f9ee4SAxel Dörfler
214f16f9ee4SAxel Dörfler		for (int32 i = 0; kFamilies[i].family >= 0; i++) {
215f16f9ee4SAxel Dörfler			if (kFamilies[i].family == address.Family()) {
216f16f9ee4SAxel Dörfler				supported = true;
217f16f9ee4SAxel Dörfler				break;
218f16f9ee4SAxel Dörfler			}
219f16f9ee4SAxel Dörfler		}
220f16f9ee4SAxel Dörfler		if (!supported)
221f16f9ee4SAxel Dörfler			return false;
222f16f9ee4SAxel Dörfler
223f16f9ee4SAxel Dörfler		// Take over family from address
224f16f9ee4SAxel Dörfler		family = address.Family();
225f16f9ee4SAxel Dörfler	}
226f16f9ee4SAxel Dörfler
227f16f9ee4SAxel Dörfler	return true;
228f16f9ee4SAxel Dörfler}
229f16f9ee4SAxel Dörfler
230f16f9ee4SAxel Dörfler
231f16f9ee4SAxel Dörflerstatic int
232f16f9ee4SAxel Dörflerparse_type(const char* string)
233f16f9ee4SAxel Dörfler{
234f16f9ee4SAxel Dörfler	if (!strcasecmp(string, "stream"))
235f16f9ee4SAxel Dörfler		return SOCK_STREAM;
236f16f9ee4SAxel Dörfler
237f16f9ee4SAxel Dörfler	return SOCK_DGRAM;
238f16f9ee4SAxel Dörfler}
239f16f9ee4SAxel Dörfler
240f16f9ee4SAxel Dörfler
241f16f9ee4SAxel Dörflerstatic int
242f16f9ee4SAxel Dörflerparse_protocol(const char* string)
243f16f9ee4SAxel Dörfler{
244f16f9ee4SAxel Dörfler	struct protoent* proto = getprotobyname(string);
245f16f9ee4SAxel Dörfler	if (proto == NULL)
246f16f9ee4SAxel Dörfler		return IPPROTO_TCP;
247f16f9ee4SAxel Dörfler
248f16f9ee4SAxel Dörfler	return proto->p_proto;
249f16f9ee4SAxel Dörfler}
250f16f9ee4SAxel Dörfler
251f16f9ee4SAxel Dörfler
252f16f9ee4SAxel Dörflerstatic int
253f16f9ee4SAxel Dörflertype_for_protocol(int protocol)
254f16f9ee4SAxel Dörfler{
255f16f9ee4SAxel Dörfler	// default determined by protocol
256f16f9ee4SAxel Dörfler	switch (protocol) {
257f16f9ee4SAxel Dörfler		case IPPROTO_TCP:
258f16f9ee4SAxel Dörfler			return SOCK_STREAM;
259f16f9ee4SAxel Dörfler
260f16f9ee4SAxel Dörfler		case IPPROTO_UDP:
261f16f9ee4SAxel Dörfler		default:
262f16f9ee4SAxel Dörfler			return SOCK_DGRAM;
263f16f9ee4SAxel Dörfler	}
264f16f9ee4SAxel Dörfler}
265f16f9ee4SAxel Dörfler
266f16f9ee4SAxel Dörfler
267f16f9ee4SAxel Dörfler// #pragma mark -
268f16f9ee4SAxel Dörfler
269f16f9ee4SAxel Dörfler
270e4f4658aSAxel Dörflerstatus_t
271e4f4658aSAxel DörflerInterfaceAddressFamilyConverter::ConvertFromDriverSettings(
272687d0bc2SAxel Dörfler	const driver_parameter& parameter, const char* name, int32 index,
273687d0bc2SAxel Dörfler	uint32 type, BMessage& target)
274e4f4658aSAxel Dörfler{
275e4f4658aSAxel Dörfler	return B_NOT_SUPPORTED;
276e4f4658aSAxel Dörfler}
277e4f4658aSAxel Dörfler
278e4f4658aSAxel Dörfler
279e4f4658aSAxel Dörflerstatus_t
280e4f4658aSAxel DörflerInterfaceAddressFamilyConverter::ConvertToDriverSettings(const BMessage& source,
281e4f4658aSAxel Dörfler	const char* name, int32 index, uint32 type, BString& value)
282e4f4658aSAxel Dörfler{
283e4f4658aSAxel Dörfler	int32 family;
284e4f4658aSAxel Dörfler	if (source.FindInt32("family", &family) == B_OK) {
285e4f4658aSAxel Dörfler		const char* familyName = get_family_name(family);
286e4f4658aSAxel Dörfler		if (familyName != NULL)
287e4f4658aSAxel Dörfler			value << familyName;
288e4f4658aSAxel Dörfler		else
289e4f4658aSAxel Dörfler			value << family;
290e4f4658aSAxel Dörfler
291e4f4658aSAxel Dörfler		return B_OK;
292e4f4658aSAxel Dörfler	}
293e4f4658aSAxel Dörfler
294e4f4658aSAxel Dörfler	return B_NOT_SUPPORTED;
295e4f4658aSAxel Dörfler}
296e4f4658aSAxel Dörfler
297e4f4658aSAxel Dörfler
298e4f4658aSAxel Dörfler// #pragma mark -
299e4f4658aSAxel Dörfler
300e4f4658aSAxel Dörfler
301fd55fb66SAxel DörflerBNetworkSettings::BNetworkSettings()
302fd55fb66SAxel Dörfler{
303fd55fb66SAxel Dörfler	_Load();
304fd55fb66SAxel Dörfler}
305fd55fb66SAxel Dörfler
306fd55fb66SAxel Dörfler
307fd55fb66SAxel DörflerBNetworkSettings::~BNetworkSettings()
308fd55fb66SAxel Dörfler{
309fd55fb66SAxel Dörfler}
310fd55fb66SAxel Dörfler
311fd55fb66SAxel Dörfler
312fd55fb66SAxel Dörflerstatus_t
313fd55fb66SAxel DörflerBNetworkSettings::GetNextInterface(uint32& cookie, BMessage& interface)
314fd55fb66SAxel Dörfler{
315fd55fb66SAxel Dörfler	status_t status = fInterfaces.FindMessage("interface", cookie, &interface);
316fd55fb66SAxel Dörfler	if (status != B_OK)
317fd55fb66SAxel Dörfler		return status;
318fd55fb66SAxel Dörfler
319fd55fb66SAxel Dörfler	cookie++;
320fd55fb66SAxel Dörfler	return B_OK;
321fd55fb66SAxel Dörfler}
322fd55fb66SAxel Dörfler
323fd55fb66SAxel Dörfler
324d880e2d9SAxel Dörflerstatus_t
325f7ccc9afSAxel DörflerBNetworkSettings::GetInterface(const char* name, BMessage& interface) const
326d880e2d9SAxel Dörfler{
327d880e2d9SAxel Dörfler	int32 index;
328d880e2d9SAxel Dörfler	return _GetItem(fInterfaces, "interface", "device", name, index, interface);
329d880e2d9SAxel Dörfler}
330d880e2d9SAxel Dörfler
331d880e2d9SAxel Dörfler
332fd55fb66SAxel Dörflerstatus_t
333fd55fb66SAxel DörflerBNetworkSettings::AddInterface(const BMessage& interface)
334fd55fb66SAxel Dörfler{
335fd55fb66SAxel Dörfler	const char* name = NULL;
336fd55fb66SAxel Dörfler	if (interface.FindString("device", &name) != B_OK)
337fd55fb66SAxel Dörfler		return B_BAD_VALUE;
338fd55fb66SAxel Dörfler
339d880e2d9SAxel Dörfler	_RemoveItem(fInterfaces, "interface", "device", name);
340fd55fb66SAxel Dörfler
341fd55fb66SAxel Dörfler	status_t result = fInterfaces.AddMessage("interface", &interface);
342fd55fb66SAxel Dörfler	if (result != B_OK)
343fd55fb66SAxel Dörfler		return result;
344fd55fb66SAxel Dörfler
345fd55fb66SAxel Dörfler	return _Save(kInterfaceSettingsName);
346fd55fb66SAxel Dörfler}
347fd55fb66SAxel Dörfler
348fd55fb66SAxel Dörfler
349fd55fb66SAxel Dörflerstatus_t
350fd55fb66SAxel DörflerBNetworkSettings::RemoveInterface(const char* name)
351fd55fb66SAxel Dörfler{
352fd55fb66SAxel Dörfler	return _RemoveItem(fInterfaces, "interface", "device", name,
353fd55fb66SAxel Dörfler		kInterfaceSettingsName);
354fd55fb66SAxel Dörfler}
355fd55fb66SAxel Dörfler
356fd55fb66SAxel Dörfler
357b00dcbcaSAxel DörflerBNetworkInterfaceSettings
358b00dcbcaSAxel DörflerBNetworkSettings::Interface(const char* name)
359b00dcbcaSAxel Dörfler{
360b00dcbcaSAxel Dörfler	BMessage interface;
361b00dcbcaSAxel Dörfler	GetInterface(name, interface);
362b00dcbcaSAxel Dörfler	return BNetworkInterfaceSettings(interface);
363b00dcbcaSAxel Dörfler}
364b00dcbcaSAxel Dörfler
365b00dcbcaSAxel Dörfler
366f7ccc9afSAxel Dörflerconst BNetworkInterfaceSettings
367f7ccc9afSAxel DörflerBNetworkSettings::Interface(const char* name) const
368f7ccc9afSAxel Dörfler{
369f7ccc9afSAxel Dörfler	BMessage interface;
370f7ccc9afSAxel Dörfler	GetInterface(name, interface);
371f7ccc9afSAxel Dörfler	return BNetworkInterfaceSettings(interface);
372f7ccc9afSAxel Dörfler}
373f7ccc9afSAxel Dörfler
374f7ccc9afSAxel Dörfler
375fd55fb66SAxel Dörflerint32
376fd55fb66SAxel DörflerBNetworkSettings::CountNetworks() const
377fd55fb66SAxel Dörfler{
378fd55fb66SAxel Dörfler	int32 count = 0;
379fd55fb66SAxel Dörfler	if (fNetworks.GetInfo("network", NULL, &count) != B_OK)
380fd55fb66SAxel Dörfler		return 0;
381fd55fb66SAxel Dörfler
382fd55fb66SAxel Dörfler	return count;
383fd55fb66SAxel Dörfler}
384fd55fb66SAxel Dörfler
385fd55fb66SAxel Dörfler
386fd55fb66SAxel Dörflerstatus_t
387fd55fb66SAxel DörflerBNetworkSettings::GetNextNetwork(uint32& cookie, BMessage& network) const
388fd55fb66SAxel Dörfler{
389fd55fb66SAxel Dörfler	status_t status = fNetworks.FindMessage("network", cookie, &network);
390fd55fb66SAxel Dörfler	if (status != B_OK)
391fd55fb66SAxel Dörfler		return status;
392fd55fb66SAxel Dörfler
393fd55fb66SAxel Dörfler	cookie++;
394fd55fb66SAxel Dörfler	return B_OK;
395fd55fb66SAxel Dörfler}
396fd55fb66SAxel Dörfler
397fd55fb66SAxel Dörfler
398d880e2d9SAxel Dörflerstatus_t
399f7ccc9afSAxel DörflerBNetworkSettings::GetNetwork(const char* name, BMessage& network) const
400d880e2d9SAxel Dörfler{
401d880e2d9SAxel Dörfler	int32 index;
402d880e2d9SAxel Dörfler	return _GetItem(fNetworks, "network", "name", name, index, network);
403d880e2d9SAxel Dörfler}
404d880e2d9SAxel Dörfler
405d880e2d9SAxel Dörfler
406fd55fb66SAxel Dörflerstatus_t
407fd55fb66SAxel DörflerBNetworkSettings::AddNetwork(const BMessage& network)
408fd55fb66SAxel Dörfler{
409fd55fb66SAxel Dörfler	const char* name = NULL;
410fd55fb66SAxel Dörfler	if (network.FindString("name", &name) != B_OK)
411fd55fb66SAxel Dörfler		return B_BAD_VALUE;
412fd55fb66SAxel Dörfler
413d880e2d9SAxel Dörfler	_RemoveItem(fNetworks, "network", "name", name);
414fd55fb66SAxel Dörfler
415fd55fb66SAxel Dörfler	status_t result = fNetworks.AddMessage("network", &network);
416fd55fb66SAxel Dörfler	if (result != B_OK)
417fd55fb66SAxel Dörfler		return result;
418fd55fb66SAxel Dörfler
419fd55fb66SAxel Dörfler	return _Save(kNetworksSettingsName);
420fd55fb66SAxel Dörfler}
421fd55fb66SAxel Dörfler
422fd55fb66SAxel Dörfler
423fd55fb66SAxel Dörflerstatus_t
424fd55fb66SAxel DörflerBNetworkSettings::RemoveNetwork(const char* name)
425fd55fb66SAxel Dörfler{
426fd55fb66SAxel Dörfler	return _RemoveItem(fNetworks, "network", "name", name,
427fd55fb66SAxel Dörfler		kNetworksSettingsName);
428fd55fb66SAxel Dörfler}
429fd55fb66SAxel Dörfler
430fd55fb66SAxel Dörfler
431d880e2d9SAxel Dörflerconst BMessage&
432d880e2d9SAxel DörflerBNetworkSettings::Services() const
433d880e2d9SAxel Dörfler{
434d880e2d9SAxel Dörfler	return fServices;
435d880e2d9SAxel Dörfler}
436d880e2d9SAxel Dörfler
437d880e2d9SAxel Dörfler
438fd55fb66SAxel Dörflerstatus_t
439fd55fb66SAxel DörflerBNetworkSettings::GetNextService(uint32& cookie, BMessage& service)
440fd55fb66SAxel Dörfler{
441fd55fb66SAxel Dörfler	status_t status = fServices.FindMessage("service", cookie, &service);
442fd55fb66SAxel Dörfler	if (status != B_OK)
443fd55fb66SAxel Dörfler		return status;
444fd55fb66SAxel Dörfler
445fd55fb66SAxel Dörfler	cookie++;
446fd55fb66SAxel Dörfler	return B_OK;
447fd55fb66SAxel Dörfler}
448fd55fb66SAxel Dörfler
449fd55fb66SAxel Dörfler
450d880e2d9SAxel Dörflerstatus_t
451f7ccc9afSAxel DörflerBNetworkSettings::GetService(const char* name, BMessage& service) const
452fd55fb66SAxel Dörfler{
453d880e2d9SAxel Dörfler	int32 index;
454d880e2d9SAxel Dörfler	return _GetItem(fServices, "service", "name", name, index, service);
455fd55fb66SAxel Dörfler}
456fd55fb66SAxel Dörfler
457fd55fb66SAxel Dörfler
458fd55fb66SAxel Dörflerstatus_t
459fd55fb66SAxel DörflerBNetworkSettings::AddService(const BMessage& service)
460fd55fb66SAxel Dörfler{
461a7f408b4SAxel Dörfler	const char* name = service.GetString("name");
462a7f408b4SAxel Dörfler	if (name == NULL)
463fd55fb66SAxel Dörfler		return B_BAD_VALUE;
464fd55fb66SAxel Dörfler
465d880e2d9SAxel Dörfler	_RemoveItem(fServices, "service", "name", name);
466fd55fb66SAxel Dörfler
467fd55fb66SAxel Dörfler	status_t result = fServices.AddMessage("service", &service);
468fd55fb66SAxel Dörfler	if (result != B_OK)
469fd55fb66SAxel Dörfler		return result;
470fd55fb66SAxel Dörfler
471fd55fb66SAxel Dörfler	return _Save(kServicesSettingsName);
472fd55fb66SAxel Dörfler}
473fd55fb66SAxel Dörfler
474fd55fb66SAxel Dörfler
475fd55fb66SAxel Dörflerstatus_t
476fd55fb66SAxel DörflerBNetworkSettings::RemoveService(const char* name)
477fd55fb66SAxel Dörfler{
478fd55fb66SAxel Dörfler	return _RemoveItem(fServices, "service", "name", name,
479fd55fb66SAxel Dörfler		kServicesSettingsName);
480fd55fb66SAxel Dörfler}
481fd55fb66SAxel Dörfler
482fd55fb66SAxel Dörfler
4837ca40f60SAxel DörflerBNetworkServiceSettings
4847ca40f60SAxel DörflerBNetworkSettings::Service(const char* name)
4857ca40f60SAxel Dörfler{
4867ca40f60SAxel Dörfler	BMessage service;
4877ca40f60SAxel Dörfler	GetService(name, service);
4887ca40f60SAxel Dörfler	return BNetworkServiceSettings(service);
4897ca40f60SAxel Dörfler}
4907ca40f60SAxel Dörfler
4917ca40f60SAxel Dörfler
492f7ccc9afSAxel Dörflerconst BNetworkServiceSettings
493f7ccc9afSAxel DörflerBNetworkSettings::Service(const char* name) const
494f7ccc9afSAxel Dörfler{
495f7ccc9afSAxel Dörfler	BMessage service;
496f7ccc9afSAxel Dörfler	GetService(name, service);
497f7ccc9afSAxel Dörfler	return BNetworkServiceSettings(service);
498f7ccc9afSAxel Dörfler}
499f7ccc9afSAxel Dörfler
500f7ccc9afSAxel Dörfler
501fd55fb66SAxel Dörflerstatus_t
502fd55fb66SAxel DörflerBNetworkSettings::StartMonitoring(const BMessenger& target)
503fd55fb66SAxel Dörfler{
504fd55fb66SAxel Dörfler	if (_IsWatching(target))
505fd55fb66SAxel Dörfler		return B_OK;
506fd55fb66SAxel Dörfler	if (_IsWatching())
507fd55fb66SAxel Dörfler		StopMonitoring(fListener);
508fd55fb66SAxel Dörfler
509fd55fb66SAxel Dörfler	fListener = target;
510fd55fb66SAxel Dörfler
511fd55fb66SAxel Dörfler	status_t status = _StartWatching(kInterfaceSettingsName, target);
512fd55fb66SAxel Dörfler	if (status == B_OK)
513fd55fb66SAxel Dörfler		status = _StartWatching(kNetworksSettingsName, target);
514fd55fb66SAxel Dörfler	if (status == B_OK)
515fd55fb66SAxel Dörfler		status = _StartWatching(kServicesSettingsName, target);
516fd55fb66SAxel Dörfler
517fd55fb66SAxel Dörfler	return status;
518fd55fb66SAxel Dörfler}
519fd55fb66SAxel Dörfler
520fd55fb66SAxel Dörfler
521fd55fb66SAxel Dörflerstatus_t
522fd55fb66SAxel DörflerBNetworkSettings::StopMonitoring(const BMessenger& target)
523fd55fb66SAxel Dörfler{
524fd55fb66SAxel Dörfler	// TODO: this needs to be changed in case the server will watch
525fd55fb66SAxel Dörfler	//	anything else but settings
526fd55fb66SAxel Dörfler	return BPrivate::BPathMonitor::StopWatching(target);
527fd55fb66SAxel Dörfler}
528fd55fb66SAxel Dörfler
529fd55fb66SAxel Dörfler
530fd55fb66SAxel Dörflerstatus_t
531fd55fb66SAxel DörflerBNetworkSettings::Update(BMessage* message)
532fd55fb66SAxel Dörfler{
533fd55fb66SAxel Dörfler	const char* pathName;
534fd55fb66SAxel Dörfler	int32 opcode;
535fd55fb66SAxel Dörfler	if (message->FindInt32("opcode", &opcode) != B_OK
536fd55fb66SAxel Dörfler		|| message->FindString("path", &pathName) != B_OK)
537fd55fb66SAxel Dörfler		return B_BAD_VALUE;
538fd55fb66SAxel Dörfler
539fd55fb66SAxel Dörfler	BPath settingsFolderPath;
540fd55fb66SAxel Dörfler	_GetPath(NULL, settingsFolderPath);
541fd55fb66SAxel Dörfler	if (strncmp(pathName, settingsFolderPath.Path(),
542fd55fb66SAxel Dörfler			strlen(settingsFolderPath.Path()))) {
543fd55fb66SAxel Dörfler		return B_NAME_NOT_FOUND;
544fd55fb66SAxel Dörfler	}
545fd55fb66SAxel Dörfler
546fd55fb66SAxel Dörfler	if (message->FindBool("removed")) {
547fd55fb66SAxel Dörfler		// for now, we only consider existing settings files
548fd55fb66SAxel Dörfler		// (ie. deleting "services" won't stop any)
549fd55fb66SAxel Dörfler		return B_OK;
550fd55fb66SAxel Dörfler	}
551fd55fb66SAxel Dörfler
552fd55fb66SAxel Dörfler	int32 fields;
553fd55fb66SAxel Dörfler	if (opcode == B_STAT_CHANGED
554fd55fb66SAxel Dörfler		&& message->FindInt32("fields", &fields) == B_OK
555fd55fb66SAxel Dörfler		&& (fields & (B_STAT_MODIFICATION_TIME | B_STAT_SIZE)) == 0) {
556fd55fb66SAxel Dörfler		// only update when the modified time or size has changed
557fd55fb66SAxel Dörfler		return B_OK;
558fd55fb66SAxel Dörfler	}
559fd55fb66SAxel Dörfler
560fd55fb66SAxel Dörfler	BPath path(pathName);
561fd55fb66SAxel Dörfler	uint32 type;
562fd55fb66SAxel Dörfler	if (_Load(path.Leaf(), &type) == B_OK) {
563fd55fb66SAxel Dörfler		BMessage update(type);
564fd55fb66SAxel Dörfler		fListener.SendMessage(&update);
565fd55fb66SAxel Dörfler	}
566fd55fb66SAxel Dörfler
567fd55fb66SAxel Dörfler	return B_OK;
568fd55fb66SAxel Dörfler}
569fd55fb66SAxel Dörfler
570fd55fb66SAxel Dörfler
571fd55fb66SAxel Dörfler// #pragma mark - private
572fd55fb66SAxel Dörfler
573fd55fb66SAxel Dörfler
574fd55fb66SAxel Dörflerstatus_t
575fd55fb66SAxel DörflerBNetworkSettings::_Load(const char* name, uint32* _type)
576fd55fb66SAxel Dörfler{
577fd55fb66SAxel Dörfler	BPath path;
578fd55fb66SAxel Dörfler	status_t status = _GetPath(NULL, path);
579fd55fb66SAxel Dörfler	if (status != B_OK)
580fd55fb66SAxel Dörfler		return status;
581fd55fb66SAxel Dörfler
582fd55fb66SAxel Dörfler	DriverSettingsMessageAdapter adapter;
583fd55fb66SAxel Dörfler	status = B_ENTRY_NOT_FOUND;
584fd55fb66SAxel Dörfler
585fd55fb66SAxel Dörfler	if (name == NULL || strcmp(name, kInterfaceSettingsName) == 0) {
586fd55fb66SAxel Dörfler		status = adapter.ConvertFromDriverSettings(
587fd55fb66SAxel Dörfler			_Path(path, kInterfaceSettingsName).Path(), kInterfacesTemplate,
588fd55fb66SAxel Dörfler			fInterfaces);
589fd55fb66SAxel Dörfler		if (status == B_OK && _type != NULL)
590fd55fb66SAxel Dörfler			*_type = kMsgInterfaceSettingsUpdated;
591fd55fb66SAxel Dörfler	}
592fd55fb66SAxel Dörfler	if (name == NULL || strcmp(name, kNetworksSettingsName) == 0) {
593fd55fb66SAxel Dörfler		status = adapter.ConvertFromDriverSettings(
594fd55fb66SAxel Dörfler			_Path(path, kNetworksSettingsName).Path(),
595fd55fb66SAxel Dörfler			kNetworksTemplate, fNetworks);
596fd55fb66SAxel Dörfler		if (status == B_OK) {
597fd55fb66SAxel Dörfler			// Convert settings for simpler consumption
598fd55fb66SAxel Dörfler			BMessage network;
599fd55fb66SAxel Dörfler			for (int32 index = 0; fNetworks.FindMessage("network", index,
600fd55fb66SAxel Dörfler					&network); index++) {
601fd55fb66SAxel Dörfler				if (_ConvertNetworkFromSettings(network) == B_OK)
602fd55fb66SAxel Dörfler					fNetworks.ReplaceMessage("network", index, &network);
603fd55fb66SAxel Dörfler			}
604fd55fb66SAxel Dörfler
605fd55fb66SAxel Dörfler			if (_type != NULL)
606f16f9ee4SAxel Dörfler				*_type = kMsgNetworkSettingsUpdated;
607fd55fb66SAxel Dörfler		}
608fd55fb66SAxel Dörfler	}
609fd55fb66SAxel Dörfler	if (name == NULL || strcmp(name, kServicesSettingsName) == 0) {
610fd55fb66SAxel Dörfler		status = adapter.ConvertFromDriverSettings(
611fd55fb66SAxel Dörfler			_Path(path, kServicesSettingsName).Path(), kServicesTemplate,
612fd55fb66SAxel Dörfler			fServices);
613fd55fb66SAxel Dörfler		if (status == B_OK && _type != NULL)
614fd55fb66SAxel Dörfler			*_type = kMsgServiceSettingsUpdated;
615fd55fb66SAxel Dörfler	}
616fd55fb66SAxel Dörfler
617fd55fb66SAxel Dörfler	return status;
618fd55fb66SAxel Dörfler}
619fd55fb66SAxel Dörfler
620fd55fb66SAxel Dörfler
621fd55fb66SAxel Dörflerstatus_t
622fd55fb66SAxel DörflerBNetworkSettings::_Save(const char* name)
623fd55fb66SAxel Dörfler{
624fd55fb66SAxel Dörfler	BPath path;
625fd55fb66SAxel Dörfler	status_t status = _GetPath(NULL, path);
626fd55fb66SAxel Dörfler	if (status != B_OK)
627fd55fb66SAxel Dörfler		return status;
628fd55fb66SAxel Dörfler
629fd55fb66SAxel Dörfler	DriverSettingsMessageAdapter adapter;
630fd55fb66SAxel Dörfler	status = B_ENTRY_NOT_FOUND;
631fd55fb66SAxel Dörfler
632fd55fb66SAxel Dörfler	if (name == NULL || strcmp(name, kInterfaceSettingsName) == 0) {
633fd55fb66SAxel Dörfler		status = adapter.ConvertToDriverSettings(
634fd55fb66SAxel Dörfler			_Path(path, kInterfaceSettingsName).Path(),
635fd55fb66SAxel Dörfler			kInterfacesTemplate, fInterfaces);
636fd55fb66SAxel Dörfler	}
637fd55fb66SAxel Dörfler	if (name == NULL || strcmp(name, kNetworksSettingsName) == 0) {
638fd55fb66SAxel Dörfler		// Convert settings to storage format
639fd55fb66SAxel Dörfler		BMessage networks = fNetworks;
640fd55fb66SAxel Dörfler		BMessage network;
641fd55fb66SAxel Dörfler		for (int32 index = 0; networks.FindMessage("network", index,
642fd55fb66SAxel Dörfler				&network); index++) {
643fd55fb66SAxel Dörfler			if (_ConvertNetworkToSettings(network) == B_OK)
644fd55fb66SAxel Dörfler				networks.ReplaceMessage("network", index, &network);
645fd55fb66SAxel Dörfler		}
646fd55fb66SAxel Dörfler
647fd55fb66SAxel Dörfler		status = adapter.ConvertToDriverSettings(
648fd55fb66SAxel Dörfler			_Path(path, kNetworksSettingsName).Path(),
649fd55fb66SAxel Dörfler			kNetworksTemplate, networks);
650fd55fb66SAxel Dörfler	}
651fd55fb66SAxel Dörfler	if (name == NULL || strcmp(name, kServicesSettingsName) == 0) {
652fd55fb66SAxel Dörfler		status = adapter.ConvertToDriverSettings(
653fd55fb66SAxel Dörfler			_Path(path, kServicesSettingsName).Path(),
654fd55fb66SAxel Dörfler			kServicesTemplate, fServices);
655fd55fb66SAxel Dörfler	}
656fd55fb66SAxel Dörfler
657fd55fb66SAxel Dörfler	return status;
658fd55fb66SAxel Dörfler}
659fd55fb66SAxel Dörfler
660fd55fb66SAxel Dörfler
661fd55fb66SAxel DörflerBPath
662fd55fb66SAxel DörflerBNetworkSettings::_Path(BPath& parent, const char* leaf)
663fd55fb66SAxel Dörfler{
664fd55fb66SAxel Dörfler	return BPath(parent.Path(), leaf);
665fd55fb66SAxel Dörfler}
666fd55fb66SAxel Dörfler
667fd55fb66SAxel Dörfler
668fd55fb66SAxel Dörflerstatus_t
669fd55fb66SAxel DörflerBNetworkSettings::_GetPath(const char* name, BPath& path)
670fd55fb66SAxel Dörfler{
671fd55fb66SAxel Dörfler	if (find_directory(B_SYSTEM_SETTINGS_DIRECTORY, &path, true) != B_OK)
672fd55fb66SAxel Dörfler		return B_ERROR;
673fd55fb66SAxel Dörfler
674fd55fb66SAxel Dörfler	path.Append("network");
675fd55fb66SAxel Dörfler	create_directory(path.Path(), 0755);
676fd55fb66SAxel Dörfler
677fd55fb66SAxel Dörfler	if (name != NULL)
678fd55fb66SAxel Dörfler		path.Append(name);
679fd55fb66SAxel Dörfler	return B_OK;
680fd55fb66SAxel Dörfler}
681fd55fb66SAxel Dörfler
682fd55fb66SAxel Dörfler
683fd55fb66SAxel Dörflerstatus_t
684fd55fb66SAxel DörflerBNetworkSettings::_StartWatching(const char* name, const BMessenger& target)
685fd55fb66SAxel Dörfler{
686fd55fb66SAxel Dörfler	BPath path;
687fd55fb66SAxel Dörfler	status_t status = _GetPath(name, path);
688fd55fb66SAxel Dörfler	if (status != B_OK)
689fd55fb66SAxel Dörfler		return status;
690fd55fb66SAxel Dörfler
691fd55fb66SAxel Dörfler	return BPrivate::BPathMonitor::StartWatching(path.Path(), B_WATCH_STAT,
692fd55fb66SAxel Dörfler		target);
693fd55fb66SAxel Dörfler}
694fd55fb66SAxel Dörfler
695fd55fb66SAxel Dörfler
696fd55fb66SAxel Dörflerstatus_t
697fd55fb66SAxel DörflerBNetworkSettings::_ConvertNetworkToSettings(BMessage& message)
698fd55fb66SAxel Dörfler{
699fd55fb66SAxel Dörfler	BNetworkAddress address;
700fd55fb66SAxel Dörfler	status_t result = message.FindFlat("address", &address);
701fd55fb66SAxel Dörfler	if (result == B_OK)
702fd55fb66SAxel Dörfler		message.RemoveName("address");
703fd55fb66SAxel Dörfler
704fd55fb66SAxel Dörfler	if (result == B_OK && address.Family() == AF_LINK) {
705fd55fb66SAxel Dörfler		size_t addressLength = address.LinkLevelAddressLength();
706fd55fb66SAxel Dörfler		uint8* macAddress = address.LinkLevelAddress();
707fd55fb66SAxel Dörfler		bool usable = false;
708fd55fb66SAxel Dörfler		BString formatted;
709fd55fb66SAxel Dörfler
710fd55fb66SAxel Dörfler		for (size_t index = 0; index < addressLength; index++) {
711fd55fb66SAxel Dörfler			if (index > 0)
712fd55fb66SAxel Dörfler				formatted.Append(":");
713fd55fb66SAxel Dörfler			char buffer[3];
714fd55fb66SAxel Dörfler			snprintf(buffer, sizeof(buffer), "%2x", macAddress[index]);
715fd55fb66SAxel Dörfler			formatted.Append(buffer, sizeof(buffer));
716fd55fb66SAxel Dörfler
717fd55fb66SAxel Dörfler			if (macAddress[index] != 0)
718fd55fb66SAxel Dörfler				usable = true;
719fd55fb66SAxel Dörfler		}
720fd55fb66SAxel Dörfler
721fd55fb66SAxel Dörfler		if (usable)
722fd55fb66SAxel Dörfler			message.AddString("mac", formatted);
723fd55fb66SAxel Dörfler	}
724fd55fb66SAxel Dörfler
725fd55fb66SAxel Dörfler	uint32 authentication = 0;
726fd55fb66SAxel Dörfler	result = message.FindUInt32("authentication_mode", &authentication);
727fd55fb66SAxel Dörfler	if (result == B_OK) {
728fd55fb66SAxel Dörfler		message.RemoveName("authentication_mode");
729fd55fb66SAxel Dörfler
730fd55fb66SAxel Dörfler		const char* authenticationString = NULL;
731fd55fb66SAxel Dörfler		switch (authentication) {
732fd55fb66SAxel Dörfler			case B_NETWORK_AUTHENTICATION_NONE:
733fd55fb66SAxel Dörfler				authenticationString = "none";
734fd55fb66SAxel Dörfler				break;
735fd55fb66SAxel Dörfler			case B_NETWORK_AUTHENTICATION_WEP:
736fd55fb66SAxel Dörfler				authenticationString = "wep";
737fd55fb66SAxel Dörfler				break;
738fd55fb66SAxel Dörfler			case B_NETWORK_AUTHENTICATION_WPA:
739fd55fb66SAxel Dörfler				authenticationString = "wpa";
740fd55fb66SAxel Dörfler				break;
741fd55fb66SAxel Dörfler			case B_NETWORK_AUTHENTICATION_WPA2:
742fd55fb66SAxel Dörfler				authenticationString = "wpa2";
743fd55fb66SAxel Dörfler				break;
744fd55fb66SAxel Dörfler		}
745fd55fb66SAxel Dörfler
746fd55fb66SAxel Dörfler		if (result == B_OK && authenticationString != NULL)
747fd55fb66SAxel Dörfler			message.AddString("authentication", authenticationString);
748fd55fb66SAxel Dörfler	}
749fd55fb66SAxel Dörfler
750fd55fb66SAxel Dörfler	uint32 cipher = 0;
751fd55fb66SAxel Dörfler	result = message.FindUInt32("cipher", &cipher);
752fd55fb66SAxel Dörfler	if (result == B_OK) {
753fd55fb66SAxel Dörfler		message.RemoveName("cipher");
754fd55fb66SAxel Dörfler
755fd55fb66SAxel Dörfler		if ((cipher & B_NETWORK_CIPHER_NONE) != 0)
756fd55fb66SAxel Dörfler			message.AddString("cipher", "none");
757fd55fb66SAxel Dörfler		if ((cipher & B_NETWORK_CIPHER_TKIP) != 0)
758fd55fb66SAxel Dörfler			message.AddString("cipher", "tkip");
759fd55fb66SAxel Dörfler		if ((cipher & B_NETWORK_CIPHER_CCMP) != 0)
760fd55fb66SAxel Dörfler			message.AddString("cipher", "ccmp");
761fd55fb66SAxel Dörfler	}
762fd55fb66SAxel Dörfler
763fd55fb66SAxel Dörfler	uint32 groupCipher = 0;
764fd55fb66SAxel Dörfler	result = message.FindUInt32("group_cipher", &groupCipher);
765fd55fb66SAxel Dörfler	if (result == B_OK) {
766fd55fb66SAxel Dörfler		message.RemoveName("group_cipher");
767fd55fb66SAxel Dörfler
768fd55fb66SAxel Dörfler		if ((groupCipher & B_NETWORK_CIPHER_NONE) != 0)
769fd55fb66SAxel Dörfler			message.AddString("group_cipher", "none");
770fd55fb66SAxel Dörfler		if ((groupCipher & B_NETWORK_CIPHER_WEP_40) != 0)
771fd55fb66SAxel Dörfler			message.AddString("group_cipher", "wep40");
772fd55fb66SAxel Dörfler		if ((groupCipher & B_NETWORK_CIPHER_WEP_104) != 0)
773fd55fb66SAxel Dörfler			message.AddString("group_cipher", "wep104");
774fd55fb66SAxel Dörfler		if ((groupCipher & B_NETWORK_CIPHER_TKIP) != 0)
775fd55fb66SAxel Dörfler			message.AddString("group_cipher", "tkip");
776fd55fb66S