~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to kinfocenter/Modules/nics/nic.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * nic.cpp
 
3
 *
 
4
 *  Copyright (C) 2001 Alexander Neundorf <neundorf@kde.org>
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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.
 
19
 */
 
20
 
 
21
#include "nic.h"
 
22
 
 
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>
 
30
 
 
31
#include "config-nic.h"
 
32
#ifdef HAVE_SYS_SOCKIO_H
 
33
#include <sys/sockio.h>
 
34
#endif
 
35
 
 
36
#include <kaboutdata.h>
 
37
#include <kdialog.h>
 
38
#include <kglobal.h>
 
39
 
 
40
#include <QLayout>
 
41
#include <QPushButton>
 
42
#include <QTabWidget>
 
43
#include <QTimer>
 
44
#include <QVBoxLayout>
 
45
#include <QHBoxLayout>
 
46
#include <QTreeWidget>
 
47
 
 
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
 
57
 
 
58
#include <sys/ioctl.h>
 
59
#include <KPluginFactory>
 
60
#include <KPluginLoader>
 
61
 
 
62
#ifndef HAVE_STRUCT_SOCKADDR_SA_LEN
 
63
#undef HAVE_GETNAMEINFO
 
64
#undef HAVE_GETIFADDRS
 
65
#endif
 
66
 
 
67
#if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
 
68
#include <ifaddrs.h>
 
69
#include <netdb.h>
 
70
 
 
71
QString flags_tos (unsigned int flags);
 
72
#endif
 
73
 
 
74
K_PLUGIN_FACTORY(KCMNicFactory,
 
75
                registerPlugin<KCMNic>();
 
76
)
 
77
K_EXPORT_PLUGIN(KCMNicFactory("kcmnic"))
 
78
 
 
79
struct MyNIC {
 
80
        QString name;
 
81
        QString addr;
 
82
        QString netmask;
 
83
        QString state;
 
84
        QString type;
 
85
        QString HWaddr;
 
86
};
 
87
 
 
88
QList<MyNIC*> findNICs();
 
89
 
 
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("System Information Control Module"),
 
113
                        0, KLocalizedString(), KAboutData::License_GPL,
 
114
                        ki18n("(c) 2001 - 2002 Alexander Neundorf"));
 
115
 
 
116
        about->addAuthor(ki18n("Alexander Neundorf"), KLocalizedString(), "neundorf@kde.org");
 
117
        setAboutData(about);
 
118
 
 
119
}
 
120
 
 
121
void KCMNic::update() {
 
122
        m_list->clear();
 
123
        QList<MyNIC*> nics=findNICs();
 
124
 
 
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);
 
129
 
 
130
                delete tmp;
 
131
        }
 
132
 
 
133
        nics.clear();
 
134
 
 
135
}
 
136
 
 
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);
 
147
        }
 
148
        return ret;
 
149
}
 
150
 
 
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") );
 
154
 
 
155
        QList<MyNIC*> nl;
 
156
 
 
157
#if !defined(HAVE_GETIFADDRS) || !defined(HAVE_GETNAMEINFO)
 
158
 
 
159
        int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 
160
 
 
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);
 
166
 
 
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
 
177
 
 
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;
 
185
 
 
186
                        struct ifreq ifcopy;
 
187
                        ifcopy=*ifr;
 
188
                        result=ioctl(sockfd, SIOCGIFFLAGS, &ifcopy);
 
189
                        flags=ifcopy.ifr_flags;
 
190
 
 
191
                        tmp=new MyNIC;
 
192
                        tmp->name=ifr->ifr_name;
 
193
                        tmp->state= ((flags & IFF_UP) == IFF_UP) ? upMessage : downMessage;
 
194
 
 
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");
 
207
 
 
208
                        tmp->addr=inet_ntoa(sinptr->sin_addr);
 
209
 
 
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");
 
217
 
 
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);
 
225
                        }
 
226
#elif defined SIOCGENADDR
 
227
                        result=ioctl(sockfd,SIOCGENADDR,&ifcopy);
 
228
                        if (result==0)
 
229
                        {
 
230
                                char *n = &ifcopy.ifr_ifru.ifru_enaddr[0];
 
231
                                tmp->HWaddr = HWaddr2String(n);
 
232
                        }
 
233
#endif
 
234
                        if (result!=0) {
 
235
                                tmp->HWaddr = i18nc("Unknown HWaddr", "Unknown");
 
236
                        }
 
237
 
 
238
                        nl.append(tmp);
 
239
                        break;
 
240
 
 
241
                default:
 
242
                        break;
 
243
                }
 
244
        }
 
245
#else
 
246
        struct ifaddrs *ifap, *ifa;
 
247
        if (getifaddrs(&ifap) != 0) {
 
248
                return nl;
 
249
        }
 
250
 
 
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;
 
258
 
 
259
                                char buf[128];
 
260
 
 
261
                                bzero(buf, 128);
 
262
                                getnameinfo(ifa->ifa_addr, ifa->ifa_addr->sa_len, buf, 127, 0, 0, NI_NUMERICHOST);
 
263
                                tmp->addr = buf;
 
264
 
 
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;
 
269
                                }
 
270
 
 
271
                                tmp->state= (ifa->ifa_flags & IFF_UP) ? upMessage : downMessage;
 
272
                                tmp->type = flags_tos(ifa->ifa_flags);
 
273
 
 
274
                                nl.append(tmp);
 
275
                                break;
 
276
                        }
 
277
                        default:
 
278
                        break;
 
279
                }
 
280
        }
 
281
 
 
282
        freeifaddrs(ifap);
 
283
#endif
 
284
        return nl;
 
285
}
 
286
 
 
287
#if defined(HAVE_GETNAMEINFO) && defined(HAVE_GETIFADDRS)
 
288
QString flags_tos (unsigned int flags)
 
289
{
 
290
        QString tmp;
 
291
        if (flags & IFF_POINTOPOINT) {
 
292
                tmp += i18n("Point to Point");
 
293
        }
 
294
 
 
295
        if (flags & IFF_BROADCAST) {
 
296
                if (tmp.length()) {
 
297
                        tmp += QLatin1String(", ");
 
298
                }
 
299
                tmp += i18n("Broadcast");
 
300
        }
 
301
 
 
302
        if (flags & IFF_MULTICAST) {
 
303
                if (tmp.length()) {
 
304
                        tmp += QLatin1String(", ");
 
305
                }
 
306
                tmp += i18n("Multicast");
 
307
        }
 
308
 
 
309
        if (flags & IFF_LOOPBACK) {
 
310
                if (tmp.length()) {
 
311
                        tmp += QLatin1String(", ");
 
312
                }
 
313
                tmp += i18n("Loopback");
 
314
        }
 
315
        return tmp;
 
316
}
 
317
#endif
 
318
 
 
319
#include "nic.moc"