Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / apps / kinfocenter / nics / nic.cpp
blob763cc27a6c43118994a7b74b619a44da3fbed254
1 /*
2 * nic.cpp
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>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <sys/socket.h>
29 #include "config-nic.h"
30 #ifdef HAVE_SYS_SOCKIO_H
31 #include <sys/sockio.h>
32 #endif
34 #include <kaboutdata.h>
35 #include <kdialog.h>
36 #include <kglobal.h>
38 #include <QLayout>
39 #include <QPushButton>
40 #include <QTabWidget>
41 #include <QTimer>
42 #include <QVBoxLayout>
43 #include <QHBoxLayout>
44 #include <Q3PtrList>
45 #include <QTreeWidget>
47 #include "nic.h"
49 #ifdef USE_SOLARIS
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 */
52 #define map junkmap
53 #endif
54 # include <net/if.h>
55 #ifdef USE_SOLARIS
56 #undef map
57 #endif
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
66 #endif
68 #if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
69 #include <ifaddrs.h>
70 #include <netdb.h>
72 QString flags_tos (unsigned int flags);
73 #endif
75 K_PLUGIN_FACTORY(KCMNicFactory,
76 registerPlugin<KCMNic>();
78 K_EXPORT_PLUGIN(KCMNicFactory("kcmnic"))
80 struct MyNIC
82 QString name;
83 QString addr;
84 QString netmask;
85 QString state;
86 QString type;
87 QString HWaddr;
90 typedef Q3PtrList<MyNIC> NICList;
92 NICList* findNICs();
94 KCMNic::KCMNic(QWidget *parent, const QVariantList &)
95 :KCModule(KCMNicFactory::componentData(), parent)
97 QVBoxLayout *box=new QVBoxLayout(this);
98 box->setMargin(0);
99 box->setSpacing(KDialog::spacingHint());
100 m_list=new QTreeWidget(this);
101 m_list->setRootIsDecorated(false);
102 box->addWidget(m_list);
103 QStringList columns;
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();
107 box->addItem(hbox);
108 m_updateButton=new QPushButton(i18n("&Update"),this);
109 hbox->addWidget(m_updateButton);
110 hbox->addStretch(1);
111 QTimer* timer=new QTimer(this);
112 timer->start(60000);
113 connect(m_updateButton,SIGNAL(clicked()),this,SLOT(update()));
114 connect(timer,SIGNAL(timeout()),this,SLOT(update()));
115 update();
116 KAboutData *about =
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()
129 m_list->clear();
130 NICList *nics=findNICs();
131 nics->setAutoDelete(true);
132 for (MyNIC* tmp=nics->first(); tmp!=0; tmp=nics->next()) {
133 QStringList lst;
134 lst << tmp->name<<tmp->addr<<tmp->netmask<<tmp->type<<tmp->state<<tmp->HWaddr;
135 new QTreeWidgetItem(m_list,lst);
137 delete nics;
140 static QString HWaddr2String(const char *hwaddr )
142 QString ret;
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)
148 num.prepend("0");
149 if (i>0)
150 ret.append(":");
151 ret.append(num);
153 return ret;
156 NICList* findNICs()
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);
168 char buf[8*1024];
169 struct ifconf ifc;
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 */
182 #else
183 ptr += sizeof(*ifr); /* for next one in buffer */
184 #endif
186 int flags;
187 struct sockaddr_in *sinptr;
188 MyNIC *tmp=0;
189 switch (ifr->ifr_addr.sa_family)
191 case AF_INET:
192 sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
193 flags=0;
195 struct ifreq ifcopy;
196 ifcopy=*ifr;
197 result=ioctl(sockfd,SIOCGIFFLAGS,&ifcopy);
198 flags=ifcopy.ifr_flags;
200 tmp=new MyNIC;
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");
208 #ifndef _AIX
209 else if ((flags & IFF_MULTICAST) == IFF_MULTICAST)
210 tmp->type=i18nc("@item:intext Mode of network card", "Multicast");
211 #endif
212 else if ((flags & IFF_LOOPBACK) == IFF_LOOPBACK)
213 tmp->type=i18nc("@item:intext Mode of network card", "Loopback");
214 else
215 tmp->type=i18nc("@item:intext Mode of network card", "Unknown");
217 tmp->addr=inet_ntoa(sinptr->sin_addr);
219 ifcopy=*ifr;
220 result=ioctl(sockfd,SIOCGIFNETMASK,&ifcopy);
221 if (result==0)
223 sinptr = (struct sockaddr_in *) &ifcopy.ifr_addr;
224 tmp->netmask=inet_ntoa(sinptr->sin_addr);
226 else
227 tmp->netmask=i18nc("Unknown network mask", "Unknown");
230 ifcopy=*ifr;
231 result=-1; // if none of the two #ifs below matches, ensure that result!=0 so that "Unknown" is returned as result
232 #ifdef SIOCGIFHWADDR
233 result=ioctl(sockfd,SIOCGIFHWADDR,&ifcopy);
234 if (result==0)
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);
241 if (result==0)
243 char *n = &ifcopy.ifr_ifru.ifru_enaddr[0];
244 tmp->HWaddr = HWaddr2String(n);
246 #endif
247 if (result!=0)
249 tmp->HWaddr = i18nc("Unknown HWaddr", "Unknown");
252 nl->append(tmp);
253 break;
255 default:
256 break;
259 #else
260 struct ifaddrs *ifap, *ifa;
261 if (getifaddrs(&ifap) != 0) {
262 return nl;
265 MyNIC *tmp=0;
266 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
267 switch (ifa->ifa_addr->sa_family) {
268 case AF_INET6:
269 case AF_INET: {
270 tmp = new MyNIC;
271 tmp->name = ifa->ifa_name;
273 char buf[128];
275 bzero(buf, 128);
276 getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len, buf, 127, 0, 0, NI_NUMERICHOST);
277 tmp->addr = buf;
279 if (ifa->ifa_netmask != NULL) {
280 bzero(buf, 128);
281 getnameinfo(ifa->ifa_netmask, ifa->ifa_netmask->sa_len, buf, 127, 0, 0, NI_NUMERICHOST);
282 tmp->netmask = buf;
285 tmp->state= (ifa->ifa_flags & IFF_UP) ? upMessage : downMessage;
286 tmp->type = flags_tos(ifa->ifa_flags);
288 nl->append(tmp);
289 break;
291 default:
292 break;
296 freeifaddrs(ifap);
297 #endif
298 return nl;
302 #if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
303 QString flags_tos (unsigned int flags)
305 QString tmp;
306 if (flags & IFF_POINTOPOINT) {
307 tmp += i18n("Point to Point");
310 if (flags & IFF_BROADCAST) {
311 if (tmp.length()) {
312 tmp += QLatin1String(", ");
314 tmp += i18n("Broadcast");
317 if (flags & IFF_MULTICAST) {
318 if (tmp.length()) {
319 tmp += QLatin1String(", ");
321 tmp += i18n("Multicast");
324 if (flags & IFF_LOOPBACK) {
325 if (tmp.length()) {
326 tmp += QLatin1String(", ");
328 tmp += i18n("Loopback");
330 return tmp;
332 #endif
334 #include "nic.moc"