add more spacing
[personal-kdebase.git] / apps / kinfocenter / nics / nic.cpp
blob109bf46d3e122b1a71370706d7539880b3c130d4
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 "nic.h"
23 #include <sys/types.h>
24 #include <sys/param.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <sys/socket.h>
31 #include "config-nic.h"
32 #ifdef HAVE_SYS_SOCKIO_H
33 #include <sys/sockio.h>
34 #endif
36 #include <kaboutdata.h>
37 #include <kdialog.h>
38 #include <kglobal.h>
40 #include <QLayout>
41 #include <QPushButton>
42 #include <QTabWidget>
43 #include <QTimer>
44 #include <QVBoxLayout>
45 #include <QHBoxLayout>
46 #include <QTreeWidget>
48 #ifdef USE_SOLARIS
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 */
51 #define map junkmap
52 #endif
53 # include <net/if.h>
54 #ifdef USE_SOLARIS
55 #undef map
56 #endif
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
65 #endif
67 #if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
68 #include <ifaddrs.h>
69 #include <netdb.h>
71 QString flags_tos (unsigned int flags);
72 #endif
74 K_PLUGIN_FACTORY(KCMNicFactory,
75 registerPlugin<KCMNic>();
77 K_EXPORT_PLUGIN(KCMNicFactory("kcmnic"))
79 struct MyNIC {
80 QString name;
81 QString addr;
82 QString netmask;
83 QString state;
84 QString type;
85 QString HWaddr;
88 QList<MyNIC*> findNICs();
90 KCMNic::KCMNic(QWidget *parent, const QVariantList &) :
91 KCModule(KCMNicFactory::componentData(), parent) {
92 QVBoxLayout *box=new QVBoxLayout(this);
93 box->setMargin(0);
94 box->setSpacing(KDialog::spacingHint());
95 m_list=new QTreeWidget(this);
96 m_list->setRootIsDecorated(false);
97 box->addWidget(m_list);
98 QStringList columns;
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();
102 box->addItem(hbox);
103 m_updateButton=new QPushButton(i18n("&Update"),this);
104 hbox->addWidget(m_updateButton);
105 hbox->addStretch(1);
106 QTimer* timer=new QTimer(this);
107 timer->start(60000);
108 connect(m_updateButton, SIGNAL(clicked()), this, SLOT(update()));
109 connect(timer, SIGNAL(timeout()), this, SLOT(update()));
110 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");
117 setAboutData(about);
121 void KCMNic::update() {
122 m_list->clear();
123 QList<MyNIC*> nics=findNICs();
125 foreach(MyNIC* tmp, nics) {
126 QStringList lst;
127 lst << tmp->name<<tmp->addr<<tmp->netmask<<tmp->type<<tmp->state<<tmp->HWaddr;
128 new QTreeWidgetItem(m_list,lst);
130 delete tmp;
133 nics.clear();
137 static QString HWaddr2String(const char *hwaddr) {
138 QString ret;
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)
143 num.prepend("0");
144 if (i>0)
145 ret.append(":");
146 ret.append(num);
148 return ret;
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") );
155 QList<MyNIC*> nl;
157 #if !defined(HAVE_GETIFADDRS) || !defined(HAVE_GETNAMEINFO)
159 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
161 char buf[8*1024];
162 struct ifconf ifc;
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 */
174 #else
175 ptr += sizeof(*ifr); /* for next one in buffer */
176 #endif
178 int flags;
179 struct sockaddr_in *sinptr;
180 MyNIC *tmp=0;
181 switch (ifr->ifr_addr.sa_family) {
182 case AF_INET:
183 sinptr = (struct sockaddr_in *) &ifr->ifr_addr;
184 flags=0;
186 struct ifreq ifcopy;
187 ifcopy=*ifr;
188 result=ioctl(sockfd, SIOCGIFFLAGS, &ifcopy);
189 flags=ifcopy.ifr_flags;
191 tmp=new MyNIC;
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");
199 #ifndef _AIX
200 else if ((flags & IFF_MULTICAST) == IFF_MULTICAST)
201 tmp->type=i18nc("@item:intext Mode of network card", "Multicast");
202 #endif
203 else if ((flags & IFF_LOOPBACK) == IFF_LOOPBACK)
204 tmp->type=i18nc("@item:intext Mode of network card", "Loopback");
205 else
206 tmp->type=i18nc("@item:intext Mode of network card", "Unknown");
208 tmp->addr=inet_ntoa(sinptr->sin_addr);
210 ifcopy=*ifr;
211 result=ioctl(sockfd, SIOCGIFNETMASK, &ifcopy);
212 if (result==0) {
213 sinptr = (struct sockaddr_in *) &ifcopy.ifr_addr;
214 tmp->netmask=inet_ntoa(sinptr->sin_addr);
215 } else
216 tmp->netmask=i18nc("Unknown network mask", "Unknown");
218 ifcopy=*ifr;
219 result=-1; // if none of the two #ifs below matches, ensure that result!=0 so that "Unknown" is returned as result
220 #ifdef SIOCGIFHWADDR
221 result=ioctl(sockfd, SIOCGIFHWADDR, &ifcopy);
222 if (result==0) {
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);
228 if (result==0)
230 char *n = &ifcopy.ifr_ifru.ifru_enaddr[0];
231 tmp->HWaddr = HWaddr2String(n);
233 #endif
234 if (result!=0) {
235 tmp->HWaddr = i18nc("Unknown HWaddr", "Unknown");
238 nl.append(tmp);
239 break;
241 default:
242 break;
245 #else
246 struct ifaddrs *ifap, *ifa;
247 if (getifaddrs(&ifap) != 0) {
248 return nl;
251 MyNIC *tmp=0;
252 for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
253 switch (ifa->ifa_addr->sa_family) {
254 case AF_INET6:
255 case AF_INET: {
256 tmp = new MyNIC;
257 tmp->name = ifa->ifa_name;
259 char buf[128];
261 bzero(buf, 128);
262 getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len, buf, 127, 0, 0, NI_NUMERICHOST);
263 tmp->addr = buf;
265 if (ifa->ifa_netmask != NULL) {
266 bzero(buf, 128);
267 getnameinfo(ifa->ifa_netmask, ifa->ifa_netmask->sa_len, buf, 127, 0, 0, NI_NUMERICHOST);
268 tmp->netmask = buf;
271 tmp->state= (ifa->ifa_flags & IFF_UP) ? upMessage : downMessage;
272 tmp->type = flags_tos(ifa->ifa_flags);
274 nl.append(tmp);
275 break;
277 default:
278 break;
282 freeifaddrs(ifap);
283 #endif
284 return nl;
287 #if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
288 QString flags_tos (unsigned int flags)
290 QString tmp;
291 if (flags & IFF_POINTOPOINT) {
292 tmp += i18n("Point to Point");
295 if (flags & IFF_BROADCAST) {
296 if (tmp.length()) {
297 tmp += QLatin1String(", ");
299 tmp += i18n("Broadcast");
302 if (flags & IFF_MULTICAST) {
303 if (tmp.length()) {
304 tmp += QLatin1String(", ");
306 tmp += i18n("Multicast");
309 if (flags & IFF_LOOPBACK) {
310 if (tmp.length()) {
311 tmp += QLatin1String(", ");
313 tmp += i18n("Loopback");
315 return tmp;
317 #endif
319 #include "nic.moc"