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.
23 #include <sys/types.h>
24 #include <sys/param.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
29 #include <sys/socket.h>
31 #include "config-nic.h"
32 #ifdef HAVE_SYS_SOCKIO_H
33 #include <sys/sockio.h>
36 #include <kaboutdata.h>
41 #include <QPushButton>
44 #include <QVBoxLayout>
45 #include <QHBoxLayout>
46 #include <QTreeWidget>
49 /* net/if.h is incompatible with STL on Solaris 2.6 - 2.8, redefine
50 map in the header file because we don't need it. -- Simon Josefsson */
58 #include <sys/ioctl.h>
59 #include <KPluginFactory>
60 #include <KPluginLoader>
62 #ifndef HAVE_STRUCT_SOCKADDR_SA_LEN
63 #undef HAVE_GETNAMEINFO
64 #undef HAVE_GETIFADDRS
67 #if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
71 QString
flags_tos (unsigned int flags
);
74 K_PLUGIN_FACTORY(KCMNicFactory
,
75 registerPlugin
<KCMNic
>();
77 K_EXPORT_PLUGIN(KCMNicFactory("kcmnic"))
88 QList
<MyNIC
*> findNICs();
90 KCMNic::KCMNic(QWidget
*parent
, const QVariantList
&) :
91 KCModule(KCMNicFactory::componentData(), parent
) {
92 QVBoxLayout
*box
=new QVBoxLayout(this);
94 box
->setSpacing(KDialog::spacingHint());
95 m_list
=new QTreeWidget(this);
96 m_list
->setRootIsDecorated(false);
97 box
->addWidget(m_list
);
99 columns
<<i18n("Name")<<i18n("IP Address")<<i18n("Network Mask")<<i18n("Type")<<i18n("State")<<i18n("HWAddr");
100 m_list
->setHeaderLabels(columns
);
101 QHBoxLayout
*hbox
=new QHBoxLayout();
103 m_updateButton
=new QPushButton(i18n("&Update"),this);
104 hbox
->addWidget(m_updateButton
);
106 QTimer
* timer
=new QTimer(this);
108 connect(m_updateButton
, SIGNAL(clicked()), this, SLOT(update()));
109 connect(timer
, SIGNAL(timeout()), this, SLOT(update()));
111 KAboutData
*about
= new KAboutData(I18N_NOOP("kcminfo"), 0,
112 ki18n("KDE Panel System Information Control Module"),
113 0, KLocalizedString(), KAboutData::License_GPL
,
114 ki18n("(c) 2001 - 2002 Alexander Neundorf"));
116 about
->addAuthor(ki18n("Alexander Neundorf"), KLocalizedString(), "neundorf@kde.org");
121 void KCMNic::update() {
123 QList
<MyNIC
*> nics
=findNICs();
125 foreach(MyNIC
* tmp
, nics
) {
127 lst
<< tmp
->name
<<tmp
->addr
<<tmp
->netmask
<<tmp
->type
<<tmp
->state
<<tmp
->HWaddr
;
128 new QTreeWidgetItem(m_list
,lst
);
137 static QString
HWaddr2String(const char *hwaddr
) {
139 for (int i
=0; i
<6; i
++, hwaddr
++) {
140 int v
= (*hwaddr
& 0xff);
141 QString num
= QString("%1").arg(v
, 0, 16);
142 if (num
.length() < 2)
151 QList
<MyNIC
*> findNICs() {
152 QString
upMessage(i18nc("State of network card is connected", "Up") );
153 QString
downMessage(i18nc("State of network card is disconnected", "Down") );
157 #if !defined(HAVE_GETIFADDRS) || !defined(HAVE_GETNAMEINFO)
159 int sockfd
= socket(AF_INET
, SOCK_DGRAM
, 0);
163 ifc
.ifc_len
= sizeof(buf
);
164 ifc
.ifc_req
= (struct ifreq
*) buf
;
165 int result
=ioctl(sockfd
, SIOCGIFCONF
, &ifc
);
167 for (char* ptr
= buf
; ptr
< buf
+ ifc
.ifc_len
;) {
168 struct ifreq
*ifr
=(struct ifreq
*) ptr
;
169 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
170 int len
= sizeof(struct sockaddr
);
171 if (ifr
->ifr_addr
.sa_len
> len
)
172 len
= ifr
->ifr_addr
.sa_len
; /* length > 16 */
173 ptr
+= sizeof(ifr
->ifr_name
) + len
; /* for next one in buffer */
175 ptr
+= sizeof(*ifr
); /* for next one in buffer */
179 struct sockaddr_in
*sinptr
;
181 switch (ifr
->ifr_addr
.sa_family
) {
183 sinptr
= (struct sockaddr_in
*) &ifr
->ifr_addr
;
188 result
=ioctl(sockfd
, SIOCGIFFLAGS
, &ifcopy
);
189 flags
=ifcopy
.ifr_flags
;
192 tmp
->name
=ifr
->ifr_name
;
193 tmp
->state
= ((flags
& IFF_UP
) == IFF_UP
) ? upMessage
: downMessage
;
195 if ((flags
& IFF_BROADCAST
) == IFF_BROADCAST
)
196 tmp
->type
=i18nc("@item:intext Mode of network card", "Broadcast");
197 else if ((flags
& IFF_POINTOPOINT
) == IFF_POINTOPOINT
)
198 tmp
->type
=i18nc("@item:intext Mode of network card", "Point to Point");
200 else if ((flags
& IFF_MULTICAST
) == IFF_MULTICAST
)
201 tmp
->type
=i18nc("@item:intext Mode of network card", "Multicast");
203 else if ((flags
& IFF_LOOPBACK
) == IFF_LOOPBACK
)
204 tmp
->type
=i18nc("@item:intext Mode of network card", "Loopback");
206 tmp
->type
=i18nc("@item:intext Mode of network card", "Unknown");
208 tmp
->addr
=inet_ntoa(sinptr
->sin_addr
);
211 result
=ioctl(sockfd
, SIOCGIFNETMASK
, &ifcopy
);
213 sinptr
= (struct sockaddr_in
*) &ifcopy
.ifr_addr
;
214 tmp
->netmask
=inet_ntoa(sinptr
->sin_addr
);
216 tmp
->netmask
=i18nc("Unknown network mask", "Unknown");
219 result
=-1; // if none of the two #ifs below matches, ensure that result!=0 so that "Unknown" is returned as result
221 result
=ioctl(sockfd
, SIOCGIFHWADDR
, &ifcopy
);
223 char *n
= &ifcopy
.ifr_ifru
.ifru_hwaddr
.sa_data
[0];
224 tmp
->HWaddr
= HWaddr2String(n
);
226 #elif defined SIOCGENADDR
227 result
=ioctl(sockfd
,SIOCGENADDR
,&ifcopy
);
230 char *n
= &ifcopy
.ifr_ifru
.ifru_enaddr
[0];
231 tmp
->HWaddr
= HWaddr2String(n
);
235 tmp
->HWaddr
= i18nc("Unknown HWaddr", "Unknown");
246 struct ifaddrs
*ifap
, *ifa
;
247 if (getifaddrs(&ifap
) != 0) {
252 for (ifa
= ifap
; ifa
; ifa
= ifa
->ifa_next
) {
253 switch (ifa
->ifa_addr
->sa_family
) {
257 tmp
->name
= ifa
->ifa_name
;
262 getnameinfo(ifa
->ifa_addr
, ifa
->ifa_addr
->sa_len
, buf
, 127, 0, 0, NI_NUMERICHOST
);
265 if (ifa
->ifa_netmask
!= NULL
) {
267 getnameinfo(ifa
->ifa_netmask
, ifa
->ifa_netmask
->sa_len
, buf
, 127, 0, 0, NI_NUMERICHOST
);
271 tmp
->state
= (ifa
->ifa_flags
& IFF_UP
) ? upMessage
: downMessage
;
272 tmp
->type
= flags_tos(ifa
->ifa_flags
);
287 #if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
288 QString
flags_tos (unsigned int flags
)
291 if (flags
& IFF_POINTOPOINT
) {
292 tmp
+= i18n("Point to Point");
295 if (flags
& IFF_BROADCAST
) {
297 tmp
+= QLatin1String(", ");
299 tmp
+= i18n("Broadcast");
302 if (flags
& IFF_MULTICAST
) {
304 tmp
+= QLatin1String(", ");
306 tmp
+= i18n("Multicast");
309 if (flags
& IFF_LOOPBACK
) {
311 tmp
+= QLatin1String(", ");
313 tmp
+= i18n("Loopback");