7 * Bernd Wuebben, wuebben@math.cornell.edu:
9 * Much of this is taken from the pppd sources in particular
10 * /pppstat/pppstat.c, and modified to suit the needs of kppp.
13 * Here the original history of pppstat.c:
15 * perkins@cps.msu.edu: Added compression statistics and alternate
18 * Brad Parker (brad@cayman.com) 6/92
20 * from the original "slstats" by Van Jaconson
22 * Copyright (c) 1989 Regents of the University of California.
23 * All rights reserved.
25 * Redistribution and use in source and binary forms are permitted
26 * provided that the above copyright notice and this paragraph are
27 * duplicated in all such forms and that any documentation,
28 * advertising materials, and other materials related to such
29 * distribution and use acknowledge that the software was developed
30 * by the University of California, Berkeley. The name of the
31 * University may not be used to endorse or promote products derived
32 * from this software without specific prior written permission.
33 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
34 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
35 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
37 * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
38 * - Initial distribution.
42 #include <config-kppp.h>
50 #include <sys/param.h>
51 #include <sys/types.h>
52 #include <sys/ioctl.h>
54 #include <arpa/inet.h>
56 #include <netinet/in.h>
58 #include <net/ppp_layer/ppp_defs.h>
60 #include <net/ppp_defs.h>
66 #if defined(__linux__) && defined(__powerpc__) \
67 && (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
71 #include <sys/socket.h> /* *BSD, Linux, NeXT, Ultrix etc. */
72 #ifndef HAVE_NET_IF_PPP_H
73 #ifdef HAVE_LINUX_IF_PPP_H
75 #include <linux/if_ppp.h>
76 #elif defined(__DragonFly__)
78 #include <net/ppp/if_ppp.h>
82 #include <net/if_ppp.h>
86 #include <sys/socket.h>
87 #include <sys/stropts.h> /* SVR4, Solaris 2, SunOS 4, OSF/1, etc. */
88 #include <net/ppp_defs.h>
89 #include <net/pppio.h>
91 #include <sys/sockio.h>
95 #if defined __OpenBSD__
96 #include <sys/socket.h>
98 #include <net/if_ppp.h>
99 #include <sys/sockio.h>
109 connect(timer
, SIGNAL(timeout()), SLOT(timerClick()));
113 PPPStats::~PPPStats() {
119 void PPPStats::clear()
133 ioStatus
= BytesNone
;
136 void PPPStats::timerClick() {
137 enum IOStatus newStatus
;
141 if((ibytes
!= ibytes_last
) && (obytes
!= obytes_last
))
142 newStatus
= BytesBoth
;
143 else if(ibytes
!= ibytes_last
)
145 else if(obytes
!= obytes_last
)
146 newStatus
= BytesOut
;
148 newStatus
= BytesNone
;
150 if(newStatus
!= ioStatus
)
151 emit
statsChanged(ioStatus
= newStatus
);
153 ibytes_last
= ibytes
;
154 obytes_last
= obytes
;
157 void PPPStats::setUnit(int u
) {
159 sprintf(unitName
, "ppp%d", unit
);
163 void PPPStats::start() {
164 timer
->start(PPP_STATS_INTERVAL
);
168 void PPPStats::stop() {
169 emit
statsChanged(BytesNone
);
174 bool PPPStats::ifIsUp() {
178 #if defined(__svr4__ )
179 usleep(1000000); // Needed for Solaris ?!
183 if ((t
= open("/dev/ppp", O_RDONLY
)) < 0) {
184 perror("pppstats: Couldn't open /dev/ppp: ");
187 if (!strioctl(t
, PPPIO_ATTACH
, (char*)&unit
, sizeof(int), 0)) {
188 fprintf(stderr
, "pppstats: ppp%d is not available\n", unit
);
192 // TODO: close t somewhere again
194 if ((s
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
195 perror("Couldn't create IP socket");
199 strlcpy(ifr
.ifr_name
, unitName
, sizeof(ifr
.ifr_name
));
201 if(ioctl(s
, SIOCGIFFLAGS
, (caddr_t
) &ifr
) < 0) {
203 fprintf(stderr
, "Couldn't find interface %s: %s\n",
204 unitName
, strerror(errno
));
210 if ((ifr
.ifr_flags
& IFF_UP
) && (ifr
.ifr_flags
& IFF_RUNNING
)) {
212 kDebug(5002) << "Interface is up";
218 kDebug(5002) << "Interface is down";
225 bool PPPStats::initStats() {
227 struct sockaddr_in
*sinp
;
232 strlcpy(ifr
.ifr_name
, unitName
, sizeof(ifr
.ifr_name
));
234 if (ioctl(s
, SIOCGIFADDR
, &ifr
) < 0) {
237 sinp
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
239 if(sinp
->sin_addr
.s_addr
)
240 local_ip_address
= inet_ntoa(sinp
->sin_addr
);
242 local_ip_address
= "";
243 kDebug(5002) << "Local IP: " << local_ip_address
;
245 if (ioctl(s
, SIOCGIFDSTADDR
, &ifr
) < 0) {
248 sinp
= (struct sockaddr_in
*)&ifr
.ifr_dstaddr
;
250 if(sinp
->sin_addr
.s_addr
)
251 remote_ip_address
= inet_ntoa(sinp
->sin_addr
);
253 remote_ip_address
= "";
254 kDebug(5002) << "Remote IP: " << remote_ip_address
;
261 bool PPPStats::doStats() {
262 struct ppp_stats cur
;
264 if(! get_ppp_stats(&cur
)){
268 // "in" "pack" "comp" "uncomp" "err"
269 // IN PACK VJCOMP VJUNC VJERR
271 ibytes
= cur
.p
.ppp_ibytes
; // bytes received
272 ipackets
= cur
.p
.ppp_ipackets
; // packets received
273 compressedin
= cur
.vj
.vjs_compressedin
; // inbound compressed packets
274 uncompressedin
= cur
.vj
.vjs_uncompressedin
; // inbound uncompressed packets
275 errorin
= cur
.vj
.vjs_errorin
; //receive errors
277 // "out" "pack" "comp" "uncomp" "ip"
278 // OUT PACK JCOMP VJUNC NON-VJ
280 obytes
= cur
.p
.ppp_obytes
; // raw bytes sent
281 opackets
= cur
.p
.ppp_opackets
; // packets sent
282 compressed
= cur
.vj
.vjs_compressed
; //outbound compressed packets
284 // outbound packets - outbound compressed packets
285 packetsunc
= cur
.vj
.vjs_packets
- cur
.vj
.vjs_compressed
;
287 // packets sent - oubount compressed
288 packetsoutunc
= cur
.p
.ppp_opackets
- cur
.vj
.vjs_packets
;
295 bool PPPStats::get_ppp_stats(struct ppp_stats
*curp
){
297 struct ifpppstatsreq req
;
303 req
.stats_ptr
= (caddr_t
) &req
.stats
;
304 sprintf(req
.ifr__name
, "ppp%d", unit
);
306 sprintf(req
.ifr_name
, "ppp%d", unit
);
308 if (ioctl(s
, SIOCGPPPSTATS
, &req
) < 0) {
310 fprintf(stderr
, "pppstats: kernel support missing\n");
312 perror("ioctl(SIOCGPPPSTATS)");
320 bool PPPStats::get_ppp_stats( struct ppp_stats
*curp
){
322 if (!strioctl(t
, PPPIO_GETSTAT
, (char*)curp
, 0, sizeof(*curp
))) {
324 fprintf(stderr
, "pppstats: kernel support missing\n");
326 perror("pppstats: Couldn't get statistics");
332 bool PPPStats::strioctl(int fd
, int cmd
, char* ptr
, int ilen
, int olen
){
340 if (ioctl(fd
, I_STR
, &str
) == -1)
342 if (str
.ic_len
!= olen
)
343 fprintf(stderr
, "strioctl: expected %d bytes, got %d for cmd %x\n",
344 olen
, str
.ic_len
, cmd
);
349 #include "pppstats.moc"