4 * Copyright (C) 2001 Alexander Neundorf <neundorf@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include <sys/types.h>
22 #include <sys/param.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
27 #include <sys/socket.h>
29 #include "config-nic.h"
30 #ifdef HAVE_SYS_SOCKIO_H
31 #include <sys/sockio.h>
34 #include <kaboutdata.h>
39 #include <QPushButton>
42 #include <QVBoxLayout>
43 #include <QHBoxLayout>
45 #include <QTreeWidget>
50 /* net/if.h is incompatible with STL on Solaris 2.6 - 2.8, redefine
51 map in the header file because we don't need it. -- Simon Josefsson */
59 #include <sys/ioctl.h>
60 #include <KPluginFactory>
61 #include <KPluginLoader>
63 #ifndef HAVE_STRUCT_SOCKADDR_SA_LEN
64 #undef HAVE_GETNAMEINFO
65 #undef HAVE_GETIFADDRS
68 #if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
72 QString
flags_tos (unsigned int flags
);
75 K_PLUGIN_FACTORY(KCMNicFactory
,
76 registerPlugin
<KCMNic
>();
78 K_EXPORT_PLUGIN(KCMNicFactory("kcmnic"))
90 typedef Q3PtrList
<MyNIC
> NICList
;
94 KCMNic::KCMNic(QWidget
*parent
, const QVariantList
&)
95 :KCModule(KCMNicFactory::componentData(), parent
)
97 QVBoxLayout
*box
=new QVBoxLayout(this);
99 box
->setSpacing(KDialog::spacingHint());
100 m_list
=new QTreeWidget(this);
101 m_list
->setRootIsDecorated(false);
102 box
->addWidget(m_list
);
104 columns
<<i18n("Name")<<i18n("IP Address")<<i18n("Network Mask")<<i18n("Type")<<i18n("State")<<i18n("HWAddr");
105 m_list
->setHeaderLabels(columns
);
106 QHBoxLayout
*hbox
=new QHBoxLayout();
108 m_updateButton
=new QPushButton(i18n("&Update"),this);
109 hbox
->addWidget(m_updateButton
);
111 QTimer
* timer
=new QTimer(this);
113 connect(m_updateButton
,SIGNAL(clicked()),this,SLOT(update()));
114 connect(timer
,SIGNAL(timeout()),this,SLOT(update()));
117 new KAboutData(I18N_NOOP("kcminfo"), 0,
118 ki18n("KDE Panel System Information Control Module"),
119 0, KLocalizedString(), KAboutData::License_GPL
,
120 ki18n("(c) 2001 - 2002 Alexander Neundorf"));
122 about
->addAuthor(ki18n("Alexander Neundorf"), KLocalizedString(), "neundorf@kde.org");
123 setAboutData( about
);
127 void KCMNic::update()
130 NICList
*nics
=findNICs();
131 nics
->setAutoDelete(true);
132 for (MyNIC
* tmp
=nics
->first(); tmp
!=0; tmp
=nics
->next()) {
134 lst
<< tmp
->name
<<tmp
->addr
<<tmp
->netmask
<<tmp
->type
<<tmp
->state
<<tmp
->HWaddr
;
135 new QTreeWidgetItem(m_list
,lst
);
140 static QString
HWaddr2String(const char *hwaddr
)
143 for (int i
=0; i
<6; i
++, hwaddr
++)
145 int v
= (*hwaddr
& 0xff);
146 QString num
= QString("%1").arg(v
,0,16);
147 if (num
.length() < 2)
158 QString
upMessage( i18nc("State of network card is connected", "Up") );
159 QString
downMessage( i18nc("State of network card is disconnected", "Down") );
161 NICList
* nl
=new NICList
;
162 nl
->setAutoDelete(true);
164 #if !defined(HAVE_GETIFADDRS) || !defined(HAVE_GETNAMEINFO)
166 int sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
170 ifc
.ifc_len
= sizeof(buf
);
171 ifc
.ifc_req
= (struct ifreq
*) buf
;
172 int result
=ioctl(sockfd
, SIOCGIFCONF
, &ifc
);
174 for (char* ptr
= buf
; ptr
< buf
+ ifc
.ifc_len
; )
176 struct ifreq
*ifr
=(struct ifreq
*) ptr
;
177 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
178 int len
= sizeof(struct sockaddr
);
179 if (ifr
->ifr_addr
.sa_len
> len
)
180 len
= ifr
->ifr_addr
.sa_len
; /* length > 16 */
181 ptr
+= sizeof(ifr
->ifr_name
) + len
; /* for next one in buffer */
183 ptr
+= sizeof(*ifr
); /* for next one in buffer */
187 struct sockaddr_in
*sinptr
;
189 switch (ifr
->ifr_addr
.sa_family
)
192 sinptr
= (struct sockaddr_in
*) &ifr
->ifr_addr
;
197 result
=ioctl(sockfd
,SIOCGIFFLAGS
,&ifcopy
);
198 flags
=ifcopy
.ifr_flags
;
201 tmp
->name
=ifr
->ifr_name
;
202 tmp
->state
= ((flags
& IFF_UP
) == IFF_UP
) ? upMessage
: downMessage
;
204 if ((flags
& IFF_BROADCAST
) == IFF_BROADCAST
)
205 tmp
->type
=i18nc("@item:intext Mode of network card", "Broadcast");
206 else if ((flags
& IFF_POINTOPOINT
) == IFF_POINTOPOINT
)
207 tmp
->type
=i18nc("@item:intext Mode of network card", "Point to Point");
209 else if ((flags
& IFF_MULTICAST
) == IFF_MULTICAST
)
210 tmp
->type
=i18nc("@item:intext Mode of network card", "Multicast");
212 else if ((flags
& IFF_LOOPBACK
) == IFF_LOOPBACK
)
213 tmp
->type
=i18nc("@item:intext Mode of network card", "Loopback");
215 tmp
->type
=i18nc("@item:intext Mode of network card", "Unknown");
217 tmp
->addr
=inet_ntoa(sinptr
->sin_addr
);
220 result
=ioctl(sockfd
,SIOCGIFNETMASK
,&ifcopy
);
223 sinptr
= (struct sockaddr_in
*) &ifcopy
.ifr_addr
;
224 tmp
->netmask
=inet_ntoa(sinptr
->sin_addr
);
227 tmp
->netmask
=i18nc("Unknown network mask", "Unknown");
231 result
=-1; // if none of the two #ifs below matches, ensure that result!=0 so that "Unknown" is returned as result
233 result
=ioctl(sockfd
,SIOCGIFHWADDR
,&ifcopy
);
236 char *n
= &ifcopy
.ifr_ifru
.ifru_hwaddr
.sa_data
[0];
237 tmp
->HWaddr
= HWaddr2String(n
);
239 #elif defined SIOCGENADDR
240 result
=ioctl(sockfd
,SIOCGENADDR
,&ifcopy
);
243 char *n
= &ifcopy
.ifr_ifru
.ifru_enaddr
[0];
244 tmp
->HWaddr
= HWaddr2String(n
);
249 tmp
->HWaddr
= i18nc("Unknown HWaddr", "Unknown");
260 struct ifaddrs
*ifap
, *ifa
;
261 if (getifaddrs(&ifap
) != 0) {
266 for (ifa
= ifap
; ifa
; ifa
= ifa
->ifa_next
) {
267 switch (ifa
->ifa_addr
->sa_family
) {
271 tmp
->name
= ifa
->ifa_name
;
276 getnameinfo(ifa
->ifa_addr
, ifa
->ifa_addr
->sa_len
, buf
, 127, 0, 0, NI_NUMERICHOST
);
279 if (ifa
->ifa_netmask
!= NULL
) {
281 getnameinfo(ifa
->ifa_netmask
, ifa
->ifa_netmask
->sa_len
, buf
, 127, 0, 0, NI_NUMERICHOST
);
285 tmp
->state
= (ifa
->ifa_flags
& IFF_UP
) ? upMessage
: downMessage
;
286 tmp
->type
= flags_tos(ifa
->ifa_flags
);
302 #if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
303 QString
flags_tos (unsigned int flags
)
306 if (flags
& IFF_POINTOPOINT
) {
307 tmp
+= i18n("Point to Point");
310 if (flags
& IFF_BROADCAST
) {
312 tmp
+= QLatin1String(", ");
314 tmp
+= i18n("Broadcast");
317 if (flags
& IFF_MULTICAST
) {
319 tmp
+= QLatin1String(", ");
321 tmp
+= i18n("Multicast");
324 if (flags
& IFF_LOOPBACK
) {
326 tmp
+= QLatin1String(", ");
328 tmp
+= i18n("Loopback");