xref: /haiku/src/apps/networkstatus/NetworkStatusView.cpp (revision 2a17be44d7239ef57784ced4dba6f1aa2961cdbc)
1f01106c3SAxel Dörfler /*
2f01106c3SAxel Dörfler  * Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
3f01106c3SAxel Dörfler  * Distributed under the terms of the MIT License.
4f01106c3SAxel Dörfler  *
5f01106c3SAxel Dörfler  * Authors:
6f01106c3SAxel Dörfler  *		Axel Dörfler, axeld@pinc-software.de
7f01106c3SAxel Dörfler  *		Hugo Santos, hugosantos@gmail.com
8f01106c3SAxel Dörfler  */
9f01106c3SAxel Dörfler 
10f01106c3SAxel Dörfler 
11f01106c3SAxel Dörfler #include "NetworkStatusView.h"
12f01106c3SAxel Dörfler 
13f01106c3SAxel Dörfler #include "NetworkStatus.h"
14f01106c3SAxel Dörfler #include "NetworkStatusIcons.h"
15f01106c3SAxel Dörfler 
16f01106c3SAxel Dörfler #include <Alert.h>
17f01106c3SAxel Dörfler #include <Application.h>
18f01106c3SAxel Dörfler #include <Bitmap.h>
19f01106c3SAxel Dörfler #include <Deskbar.h>
20f01106c3SAxel Dörfler #include <Dragger.h>
21f01106c3SAxel Dörfler #include <Drivers.h>
22f01106c3SAxel Dörfler #include <IconUtils.h>
23f01106c3SAxel Dörfler #include <MenuItem.h>
24f01106c3SAxel Dörfler #include <MessageRunner.h>
25f01106c3SAxel Dörfler #include <PopUpMenu.h>
26f01106c3SAxel Dörfler #include <Resources.h>
27f01106c3SAxel Dörfler #include <String.h>
28f01106c3SAxel Dörfler #include <TextView.h>
29f01106c3SAxel Dörfler 
30f01106c3SAxel Dörfler #include <arpa/inet.h>
31f01106c3SAxel Dörfler #include <net/if.h>
32f01106c3SAxel Dörfler #include <stdio.h>
33f01106c3SAxel Dörfler #include <stdlib.h>
34f01106c3SAxel Dörfler #include <string.h>
35f01106c3SAxel Dörfler #include <sys/socket.h>
36f01106c3SAxel Dörfler #include <sys/sockio.h>
37f01106c3SAxel Dörfler #include <unistd.h>
38f01106c3SAxel Dörfler 
39f01106c3SAxel Dörfler #ifndef HAIKU_TARGET_PLATFORM_HAIKU
40f01106c3SAxel Dörfler // BONE compatibility
41f01106c3SAxel Dörfler #	define IF_NAMESIZE IFNAMSIZ
42f01106c3SAxel Dörfler #	define IFF_LINK 0
43f01106c3SAxel Dörfler #	define IFF_CONFIGURING 0
44f01106c3SAxel Dörfler #	define ifc_value ifc_val
45f01106c3SAxel Dörfler #endif
46f01106c3SAxel Dörfler 
47f01106c3SAxel Dörfler static const char *kStatusDescriptions[] = {
48f01106c3SAxel Dörfler 	"Unknown",
49f01106c3SAxel Dörfler 	"No Link",
50f01106c3SAxel Dörfler 	"No stateful configuration",
51f01106c3SAxel Dörfler 	"Configuring",
52f01106c3SAxel Dörfler 	"Ready"
53f01106c3SAxel Dörfler };
54f01106c3SAxel Dörfler 
55f01106c3SAxel Dörfler extern "C" _EXPORT BView *instantiate_deskbar_item(void);
56f01106c3SAxel Dörfler 
57f01106c3SAxel Dörfler 
58f01106c3SAxel Dörfler const uint32 kMsgUpdate = 'updt';
59f01106c3SAxel Dörfler const uint32 kMsgShowConfiguration = 'shcf';
60f01106c3SAxel Dörfler 
61f01106c3SAxel Dörfler const uint32 kMinIconWidth = 16;
62f01106c3SAxel Dörfler const uint32 kMinIconHeight = 16;
63f01106c3SAxel Dörfler 
64f01106c3SAxel Dörfler const bigtime_t kUpdateInterval = 1000000;
65f01106c3SAxel Dörfler 	// every second
66f01106c3SAxel Dörfler 
67f01106c3SAxel Dörfler 
68f01106c3SAxel Dörfler NetworkStatusView::NetworkStatusView(BRect frame, int32 resizingMode,
69f01106c3SAxel Dörfler 		bool inDeskbar)
70f01106c3SAxel Dörfler 	: BView(frame, kDeskbarItemName, resizingMode,
71f01106c3SAxel Dörfler 		B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE),
72f01106c3SAxel Dörfler 	fInDeskbar(inDeskbar),
73f01106c3SAxel Dörfler 	fStatus(kStatusUnknown)
74f01106c3SAxel Dörfler {
75f01106c3SAxel Dörfler 	_Init();
76f01106c3SAxel Dörfler 
77f01106c3SAxel Dörfler 	if (!inDeskbar) {
78f01106c3SAxel Dörfler 		// we were obviously added to a standard window - let's add a dragger
79f01106c3SAxel Dörfler 		frame.OffsetTo(B_ORIGIN);
80f01106c3SAxel Dörfler 		frame.top = frame.bottom - 7;
81f01106c3SAxel Dörfler 		frame.left = frame.right - 7;
82f01106c3SAxel Dörfler 		BDragger* dragger = new BDragger(frame, this,
83f01106c3SAxel Dörfler 			B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM);
84f01106c3SAxel Dörfler 		AddChild(dragger);
85f01106c3SAxel Dörfler 	} else
86f01106c3SAxel Dörfler 		_Update();
87f01106c3SAxel Dörfler }
88f01106c3SAxel Dörfler 
89f01106c3SAxel Dörfler 
90f01106c3SAxel Dörfler NetworkStatusView::NetworkStatusView(BMessage* archive)
91f01106c3SAxel Dörfler 	: BView(archive)
92f01106c3SAxel Dörfler {
93f01106c3SAxel Dörfler 	_Init();
94f01106c3SAxel Dörfler }
95f01106c3SAxel Dörfler 
96f01106c3SAxel Dörfler 
97f01106c3SAxel Dörfler NetworkStatusView::~NetworkStatusView()
98f01106c3SAxel Dörfler {
99f01106c3SAxel Dörfler }
100f01106c3SAxel Dörfler 
101f01106c3SAxel Dörfler 
102f01106c3SAxel Dörfler void
103f01106c3SAxel Dörfler NetworkStatusView::_Init()
104f01106c3SAxel Dörfler {
105f01106c3SAxel Dörfler 	fMessageRunner = NULL;
106f01106c3SAxel Dörfler 
107f01106c3SAxel Dörfler 	for (int i = 0; i < kStatusCount; i++) {
108f01106c3SAxel Dörfler 		fBitmaps[i] = NULL;
109f01106c3SAxel Dörfler 	}
110f01106c3SAxel Dörfler 
111f01106c3SAxel Dörfler 	_UpdateBitmaps();
112f01106c3SAxel Dörfler }
113f01106c3SAxel Dörfler 
114f01106c3SAxel Dörfler 
115f01106c3SAxel Dörfler void
116f01106c3SAxel Dörfler NetworkStatusView::_UpdateBitmaps()
117f01106c3SAxel Dörfler {
118f01106c3SAxel Dörfler 	for (int i = 0; i < kStatusCount; i++) {
119f01106c3SAxel Dörfler 		delete fBitmaps[i];
120f01106c3SAxel Dörfler 		fBitmaps[i] = NULL;
121f01106c3SAxel Dörfler 	}
122f01106c3SAxel Dörfler 
123f01106c3SAxel Dörfler 	image_info info;
124f01106c3SAxel Dörfler 	if (our_image(info) != B_OK)
125f01106c3SAxel Dörfler 		return;
126f01106c3SAxel Dörfler 
127f01106c3SAxel Dörfler 	BFile file(info.name, B_READ_ONLY);
128f01106c3SAxel Dörfler 	if (file.InitCheck() < B_OK)
129f01106c3SAxel Dörfler 		return;
130f01106c3SAxel Dörfler 
131f01106c3SAxel Dörfler 	BResources resources(&file);
132f01106c3SAxel Dörfler #ifdef HAIKU_TARGET_PLATFORM_HAIKU
133f01106c3SAxel Dörfler 	if (resources.InitCheck() < B_OK)
134f01106c3SAxel Dörfler 		return;
135f01106c3SAxel Dörfler #endif
136f01106c3SAxel Dörfler 
137f01106c3SAxel Dörfler 	for (int i = 0; i < kStatusCount; i++) {
138f01106c3SAxel Dörfler 		const void* data = NULL;
139f01106c3SAxel Dörfler 		size_t size;
140f01106c3SAxel Dörfler 		data = resources.LoadResource(B_VECTOR_ICON_TYPE,
141f01106c3SAxel Dörfler 			kNetworkStatusNoDevice + i, &size);
142f01106c3SAxel Dörfler 		if (data != NULL) {
143f01106c3SAxel Dörfler 			BBitmap* icon = new BBitmap(Bounds(), B_RGB32);
144f01106c3SAxel Dörfler 			if (icon->InitCheck() == B_OK
145f01106c3SAxel Dörfler 				&& BIconUtils::GetVectorIcon((const uint8 *)data,
146f01106c3SAxel Dörfler 					size, icon) == B_OK) {
147f01106c3SAxel Dörfler 				fBitmaps[i] = icon;
148f01106c3SAxel Dörfler 			} else
149f01106c3SAxel Dörfler 				delete icon;
150f01106c3SAxel Dörfler 		}
151f01106c3SAxel Dörfler 	}
152f01106c3SAxel Dörfler }
153f01106c3SAxel Dörfler 
154f01106c3SAxel Dörfler 
155f01106c3SAxel Dörfler void
156f01106c3SAxel Dörfler NetworkStatusView::_Quit()
157f01106c3SAxel Dörfler {
158f01106c3SAxel Dörfler 	if (fInDeskbar) {
159f01106c3SAxel Dörfler 		BDeskbar deskbar;
160f01106c3SAxel Dörfler 		deskbar.RemoveItem(kDeskbarItemName);
161f01106c3SAxel Dörfler 	} else
162f01106c3SAxel Dörfler 		be_app->PostMessage(B_QUIT_REQUESTED);
163f01106c3SAxel Dörfler }
164f01106c3SAxel Dörfler 
165f01106c3SAxel Dörfler 
166f01106c3SAxel Dörfler NetworkStatusView *
167f01106c3SAxel Dörfler NetworkStatusView::Instantiate(BMessage* archive)
168f01106c3SAxel Dörfler {
169f01106c3SAxel Dörfler 	if (!validate_instantiation(archive, "NetworkStatusView"))
170f01106c3SAxel Dörfler 		return NULL;
171f01106c3SAxel Dörfler 
172f01106c3SAxel Dörfler 	return new NetworkStatusView(archive);
173f01106c3SAxel Dörfler }
174f01106c3SAxel Dörfler 
175f01106c3SAxel Dörfler 
176f01106c3SAxel Dörfler status_t
177f01106c3SAxel Dörfler NetworkStatusView::Archive(BMessage* archive, bool deep) const
178f01106c3SAxel Dörfler {
179f01106c3SAxel Dörfler 	status_t status = BView::Archive(archive, deep);
180f01106c3SAxel Dörfler 	if (status == B_OK)
181f01106c3SAxel Dörfler 		status = archive->AddString("add_on", kSignature);
182f01106c3SAxel Dörfler 	if (status == B_OK)
183f01106c3SAxel Dörfler 		status = archive->AddString("class", "NetworkStatusView");
184f01106c3SAxel Dörfler 
185f01106c3SAxel Dörfler 	return status;
186f01106c3SAxel Dörfler }
187f01106c3SAxel Dörfler 
188f01106c3SAxel Dörfler 
189f01106c3SAxel Dörfler void
190f01106c3SAxel Dörfler NetworkStatusView::AttachedToWindow()
191f01106c3SAxel Dörfler {
192f01106c3SAxel Dörfler 	BView::AttachedToWindow();
193f01106c3SAxel Dörfler 	if (Parent())
194f01106c3SAxel Dörfler 		SetViewColor(Parent()->ViewColor());
195f01106c3SAxel Dörfler 	else
196f01106c3SAxel Dörfler 		SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
197f01106c3SAxel Dörfler 
198f01106c3SAxel Dörfler 	SetLowColor(ViewColor());
199f01106c3SAxel Dörfler 
200f01106c3SAxel Dörfler 	BMessage update(kMsgUpdate);
201f01106c3SAxel Dörfler 	fMessageRunner = new BMessageRunner(this, &update, kUpdateInterval);
202f01106c3SAxel Dörfler 
203f01106c3SAxel Dörfler 	fSocket = socket(AF_INET, SOCK_DGRAM, 0);
204f01106c3SAxel Dörfler 	_Update();
205f01106c3SAxel Dörfler }
206f01106c3SAxel Dörfler 
207f01106c3SAxel Dörfler 
208f01106c3SAxel Dörfler void
209f01106c3SAxel Dörfler NetworkStatusView::DetachedFromWindow()
210f01106c3SAxel Dörfler {
211f01106c3SAxel Dörfler 	delete fMessageRunner;
212f01106c3SAxel Dörfler 	close(fSocket);
213f01106c3SAxel Dörfler }
214f01106c3SAxel Dörfler 
215f01106c3SAxel Dörfler 
216f01106c3SAxel Dörfler void
217f01106c3SAxel Dörfler NetworkStatusView::MessageReceived(BMessage* message)
218f01106c3SAxel Dörfler {
219f01106c3SAxel Dörfler 	switch (message->what) {
220f01106c3SAxel Dörfler 		case kMsgUpdate:
221f01106c3SAxel Dörfler 			_Update();
222f01106c3SAxel Dörfler 			break;
223f01106c3SAxel Dörfler 
224f01106c3SAxel Dörfler 		case kMsgShowConfiguration:
225f01106c3SAxel Dörfler 			_ShowConfiguration(message);
226f01106c3SAxel Dörfler 			break;
227f01106c3SAxel Dörfler 
228f01106c3SAxel Dörfler 		case B_ABOUT_REQUESTED:
229f01106c3SAxel Dörfler 			_AboutRequested();
230f01106c3SAxel Dörfler 			break;
231f01106c3SAxel Dörfler 
232f01106c3SAxel Dörfler 		case B_QUIT_REQUESTED:
233f01106c3SAxel Dörfler 			_Quit();
234f01106c3SAxel Dörfler 			break;
235f01106c3SAxel Dörfler 
236f01106c3SAxel Dörfler 		default:
237f01106c3SAxel Dörfler 			BView::MessageReceived(message);
238f01106c3SAxel Dörfler 	}
239f01106c3SAxel Dörfler }
240f01106c3SAxel Dörfler 
241f01106c3SAxel Dörfler 
242f01106c3SAxel Dörfler void
243f01106c3SAxel Dörfler NetworkStatusView::FrameResized(float width, float height)
244f01106c3SAxel Dörfler {
245f01106c3SAxel Dörfler 	_UpdateBitmaps();
246f01106c3SAxel Dörfler }
247f01106c3SAxel Dörfler 
248f01106c3SAxel Dörfler 
249f01106c3SAxel Dörfler void
250f01106c3SAxel Dörfler NetworkStatusView::Draw(BRect updateRect)
251f01106c3SAxel Dörfler {
252f01106c3SAxel Dörfler 	if (fBitmaps[fStatus] == NULL)
253f01106c3SAxel Dörfler 		return;
254f01106c3SAxel Dörfler 
255f01106c3SAxel Dörfler 	SetDrawingMode(B_OP_ALPHA);
256f01106c3SAxel Dörfler 	DrawBitmap(fBitmaps[fStatus]);
257f01106c3SAxel Dörfler 	SetDrawingMode(B_OP_COPY);
258f01106c3SAxel Dörfler }
259f01106c3SAxel Dörfler 
260f01106c3SAxel Dörfler 
261f01106c3SAxel Dörfler void
262f01106c3SAxel Dörfler NetworkStatusView::_ShowConfiguration(BMessage* message)
263f01106c3SAxel Dörfler {
264f01106c3SAxel Dörfler 	static const struct information_entry {
265f01106c3SAxel Dörfler 		const char *label;
266f01106c3SAxel Dörfler 		int32 control;
267f01106c3SAxel Dörfler 	} kInformationEntries[] = {
268f01106c3SAxel Dörfler 		{ "Address", SIOCGIFADDR },
269f01106c3SAxel Dörfler 		{ "Broadcast", SIOCGIFBRDADDR },
270f01106c3SAxel Dörfler 		{ "Netmask", SIOCGIFNETMASK },
271f01106c3SAxel Dörfler 		{ NULL }
272f01106c3SAxel Dörfler 	};
273f01106c3SAxel Dörfler 
274f01106c3SAxel Dörfler 	const char *name;
275f01106c3SAxel Dörfler 	if (message->FindString("interface", &name) != B_OK)
276f01106c3SAxel Dörfler 		return;
277f01106c3SAxel Dörfler 
278f01106c3SAxel Dörfler 	ifreq request;
279f01106c3SAxel Dörfler 	if (!_PrepareRequest(request, name))
280f01106c3SAxel Dörfler 		return;
281f01106c3SAxel Dörfler 
282f01106c3SAxel Dörfler 	BString text = name;
283f01106c3SAxel Dörfler 	text += " information:\n";
284f01106c3SAxel Dörfler 	size_t boldLength = text.Length();
285f01106c3SAxel Dörfler 
286f01106c3SAxel Dörfler 	for (int i = 0; kInformationEntries[i].label; i++) {
287f01106c3SAxel Dörfler 		if (ioctl(fSocket, kInformationEntries[i].control, &request,
288f01106c3SAxel Dörfler 				sizeof(request)) < 0) {
289f01106c3SAxel Dörfler 			continue;
290f01106c3SAxel Dörfler 		}
291f01106c3SAxel Dörfler 
292f01106c3SAxel Dörfler 		char address[32];
293f01106c3SAxel Dörfler 		sockaddr_in* inetAddress = NULL;
294f01106c3SAxel Dörfler 		switch (kInformationEntries[i].control) {
295f01106c3SAxel Dörfler 			case SIOCGIFNETMASK:
296f01106c3SAxel Dörfler 				inetAddress = (sockaddr_in*)&request.ifr_mask;
297f01106c3SAxel Dörfler 				break;
298f01106c3SAxel Dörfler 			default:
299f01106c3SAxel Dörfler 				inetAddress = (sockaddr_in*)&request.ifr_addr;
300f01106c3SAxel Dörfler 				break;
301f01106c3SAxel Dörfler 		}
302f01106c3SAxel Dörfler 
303f01106c3SAxel Dörfler 		if (inet_ntop(AF_INET, &inetAddress->sin_addr, address,
304f01106c3SAxel Dörfler 				sizeof(address)) == NULL) {
305f01106c3SAxel Dörfler 			return;
306f01106c3SAxel Dörfler 		}
307f01106c3SAxel Dörfler 
308f01106c3SAxel Dörfler 		text += "\n";
309f01106c3SAxel Dörfler 		text += kInformationEntries[i].label;
310f01106c3SAxel Dörfler 		text += ": ";
311f01106c3SAxel Dörfler 		text += address;
312f01106c3SAxel Dörfler 	}
313f01106c3SAxel Dörfler 
314f01106c3SAxel Dörfler 	BAlert* alert = new BAlert(name, text.String(), "Ok");
315f01106c3SAxel Dörfler 	BTextView* view = alert->TextView();
316f01106c3SAxel Dörfler 	BFont font;
317f01106c3SAxel Dörfler 
318f01106c3SAxel Dörfler 	view->SetStylable(true);
319f01106c3SAxel Dörfler 	view->GetFont(&font);
320f01106c3SAxel Dörfler 	font.SetFace(B_BOLD_FACE);
321f01106c3SAxel Dörfler 	view->SetFontAndColor(0, boldLength, &font);
322f01106c3SAxel Dörfler 
323f01106c3SAxel Dörfler 	alert->Go(NULL);
324f01106c3SAxel Dörfler }
325f01106c3SAxel Dörfler 
326f01106c3SAxel Dörfler 
327f01106c3SAxel Dörfler void
328f01106c3SAxel Dörfler NetworkStatusView::MouseDown(BPoint point)
329f01106c3SAxel Dörfler {
330f01106c3SAxel Dörfler 	BPopUpMenu *menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
331f01106c3SAxel Dörfler 	menu->SetFont(be_plain_font);
332f01106c3SAxel Dörfler 
333f01106c3SAxel Dörfler 	for (int32 i = 0; i < fInterfaces.CountItems(); i++) {
334f01106c3SAxel Dörfler 		BString& name = *fInterfaces.ItemAt(i);
335f01106c3SAxel Dörfler 
336f01106c3SAxel Dörfler 		BString label = name;
337f01106c3SAxel Dörfler 		label += ": ";
338f01106c3SAxel Dörfler 		label += kStatusDescriptions[
339f01106c3SAxel Dörfler 			_DetermineInterfaceStatus(name.String())];
340f01106c3SAxel Dörfler 
341f01106c3SAxel Dörfler 		BMessage* info = new BMessage(kMsgShowConfiguration);
342f01106c3SAxel Dörfler 		info->AddString("interface", name.String());
343f01106c3SAxel Dörfler 		menu->AddItem(new BMenuItem(label.String(), info));
344f01106c3SAxel Dörfler 	}
345f01106c3SAxel Dörfler 
346f01106c3SAxel Dörfler 	menu->AddSeparatorItem();
347f01106c3SAxel Dörfler 	menu->AddItem(new BMenuItem("About" B_UTF8_ELLIPSIS,
348f01106c3SAxel Dörfler 		new BMessage(B_ABOUT_REQUESTED)));
349f01106c3SAxel Dörfler 	if (fInDeskbar)
350f01106c3SAxel Dörfler 		menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED)));
351f01106c3SAxel Dörfler 	menu->SetTargetForItems(this);
352f01106c3SAxel Dörfler 
353f01106c3SAxel Dörfler 	ConvertToScreen(&point);
354f01106c3SAxel Dörfler 	menu->Go(point, true, false, true);
355f01106c3SAxel Dörfler }
356f01106c3SAxel Dörfler 
357f01106c3SAxel Dörfler 
358f01106c3SAxel Dörfler void
359f01106c3SAxel Dörfler NetworkStatusView::_AboutRequested()
360f01106c3SAxel Dörfler {
361f01106c3SAxel Dörfler 	BAlert *alert = new BAlert("about", "NetworkStatus\n"
362f01106c3SAxel Dörfler 		"\twritten by Axel Dörfler and Hugo Santos\n"
363f01106c3SAxel Dörfler 		"\tCopyright 2007, Haiku, Inc.\n", "Ok");
364f01106c3SAxel Dörfler 	BTextView *view = alert->TextView();
365f01106c3SAxel Dörfler 	BFont font;
366f01106c3SAxel Dörfler 
367f01106c3SAxel Dörfler 	view->SetStylable(true);
368f01106c3SAxel Dörfler 
369f01106c3SAxel Dörfler 	view->GetFont(&font);
370f01106c3SAxel Dörfler 	font.SetSize(18);
371f01106c3SAxel Dörfler 	font.SetFace(B_BOLD_FACE);
372f01106c3SAxel Dörfler 	view->SetFontAndColor(0, 13, &font);
373f01106c3SAxel Dörfler 
374f01106c3SAxel Dörfler 	alert->Go();
375f01106c3SAxel Dörfler }
376f01106c3SAxel Dörfler 
377f01106c3SAxel Dörfler 
378f01106c3SAxel Dörfler bool
379f01106c3SAxel Dörfler NetworkStatusView::_PrepareRequest(struct ifreq& request, const char* name)
380f01106c3SAxel Dörfler {
381f01106c3SAxel Dörfler 	if (strlen(name) > IF_NAMESIZE)
382f01106c3SAxel Dörfler 		return false;
383f01106c3SAxel Dörfler 
384f01106c3SAxel Dörfler 	strcpy(request.ifr_name, name);
385f01106c3SAxel Dörfler 	return true;
386f01106c3SAxel Dörfler }
387f01106c3SAxel Dörfler 
388f01106c3SAxel Dörfler 
389f01106c3SAxel Dörfler int32
390f01106c3SAxel Dörfler NetworkStatusView::_DetermineInterfaceStatus(const char* name)
391f01106c3SAxel Dörfler {
392f01106c3SAxel Dörfler 	ifreq request;
393f01106c3SAxel Dörfler 	if (!_PrepareRequest(request, name))
394f01106c3SAxel Dörfler 		return kStatusUnknown;
395f01106c3SAxel Dörfler 
396f01106c3SAxel Dörfler 	uint32 flags = 0;
397f01106c3SAxel Dörfler 	if (ioctl(fSocket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0)
398f01106c3SAxel Dörfler 		flags = request.ifr_flags;
399f01106c3SAxel Dörfler 
400f01106c3SAxel Dörfler 	int32 status = kStatusNoLink;
401f01106c3SAxel Dörfler 
402f01106c3SAxel Dörfler 	// TODO: no kStatusLinkNoConfig yet
403f01106c3SAxel Dörfler 
404f01106c3SAxel Dörfler 	if (flags & IFF_CONFIGURING)
405f01106c3SAxel Dörfler 		status = kStatusConnecting;
406*2a17be44SAxel Dörfler 	else if ((flags & (IFF_UP | IFF_LINK)) == (IFF_UP | IFF_LINK))
407f01106c3SAxel Dörfler 		status = kStatusReady;
408f01106c3SAxel Dörfler 
409f01106c3SAxel Dörfler 	return status;
410f01106c3SAxel Dörfler }
411f01106c3SAxel Dörfler 
412f01106c3SAxel Dörfler 
413f01106c3SAxel Dörfler void
414f01106c3SAxel Dörfler NetworkStatusView::_Update(bool force)
415f01106c3SAxel Dörfler {
416f01106c3SAxel Dörfler 	// iterate over all interfaces and retrieve minimal status
417f01106c3SAxel Dörfler 
418f01106c3SAxel Dörfler 	ifconf config;
419f01106c3SAxel Dörfler 	config.ifc_len = sizeof(config.ifc_value);
420f01106c3SAxel Dörfler 	if (ioctl(fSocket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
421f01106c3SAxel Dörfler 		return;
422f01106c3SAxel Dörfler 
423f01106c3SAxel Dörfler 	uint32 count = (uint32)config.ifc_value;
424f01106c3SAxel Dörfler 	if (count == 0)
425f01106c3SAxel Dörfler 		return;
426f01106c3SAxel Dörfler 
427f01106c3SAxel Dörfler 	void *buffer = malloc(count * sizeof(struct ifreq));
428f01106c3SAxel Dörfler 	if (buffer == NULL)
429f01106c3SAxel Dörfler 		return;
430f01106c3SAxel Dörfler 
431f01106c3SAxel Dörfler 	config.ifc_len = count * sizeof(struct ifreq);
432f01106c3SAxel Dörfler 	config.ifc_buf = buffer;
433f01106c3SAxel Dörfler 	if (ioctl(fSocket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
434f01106c3SAxel Dörfler 		return;
435f01106c3SAxel Dörfler 
436f01106c3SAxel Dörfler 	ifreq *interface = (ifreq *)buffer;
437f01106c3SAxel Dörfler 
438f01106c3SAxel Dörfler 	int32 oldStatus = fStatus;
439f01106c3SAxel Dörfler 	fStatus = kStatusUnknown;
440f01106c3SAxel Dörfler 	fInterfaces.MakeEmpty();
441f01106c3SAxel Dörfler 
442f01106c3SAxel Dörfler 	for (uint32 i = 0; i < count; i++) {
443f01106c3SAxel Dörfler 		if (strncmp(interface->ifr_name, "loop", 4) && interface->ifr_name[0]) {
444f01106c3SAxel Dörfler 			fInterfaces.AddItem(new BString(interface->ifr_name));
445f01106c3SAxel Dörfler 			int32 status = _DetermineInterfaceStatus(interface->ifr_name);
446f01106c3SAxel Dörfler 			if (status > fStatus)
447f01106c3SAxel Dörfler 				fStatus = status;
448f01106c3SAxel Dörfler 		}
449f01106c3SAxel Dörfler 
450f01106c3SAxel Dörfler 		interface = (ifreq *)((addr_t)interface + IF_NAMESIZE
451f01106c3SAxel Dörfler 			+ interface->ifr_addr.sa_len);
452f01106c3SAxel Dörfler 	}
453f01106c3SAxel Dörfler 
454f01106c3SAxel Dörfler 	free(buffer);
455f01106c3SAxel Dörfler 
456f01106c3SAxel Dörfler 	if (fStatus != oldStatus)
457f01106c3SAxel Dörfler 		Invalidate();
458f01106c3SAxel Dörfler }
459f01106c3SAxel Dörfler 
460f01106c3SAxel Dörfler 
461f01106c3SAxel Dörfler //	#pragma mark -
462f01106c3SAxel Dörfler 
463f01106c3SAxel Dörfler 
464f01106c3SAxel Dörfler extern "C" _EXPORT BView *
465f01106c3SAxel Dörfler instantiate_deskbar_item(void)
466f01106c3SAxel Dörfler {
467f01106c3SAxel Dörfler 	return new NetworkStatusView(BRect(0, 0, 15, 15), B_FOLLOW_NONE, true);
468f01106c3SAxel Dörfler }
469f01106c3SAxel Dörfler 
470