Add support for vertex shader constants to the stateblock.
[wine/gsoc_dplay.git] / dlls / iphlpapi / ipstats.c
blob28103524e9492e3d4fdec20d3a621c2d9fd5b92c
1 /* Copyright (C) 2003 Juan Lang
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * This file implements statistics getting using the /proc filesystem exported
18 * by Linux, and maybe other OSes.
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/types.h>
29 #ifdef HAVE_SYS_SOCKET_H
30 #include <sys/socket.h>
31 #endif
32 #ifdef HAVE_NETINET_IN_H
33 #include <netinet/in.h>
34 #endif
35 #ifdef HAVE_ARPA_INET_H
36 #include <arpa/inet.h>
37 #endif
38 #ifdef HAVE_NET_IF_H
39 #include <net/if.h>
40 #endif
41 #ifdef HAVE_NET_IF_ARP_H
42 #include <net/if_arp.h>
43 #endif
44 #ifdef HAVE_NETINET_TCP_H
45 #include <netinet/tcp.h>
46 #endif
47 #ifdef HAVE_NETINET_TCP_FSM_H
48 #include <netinet/tcp_fsm.h>
49 #endif
51 #include "windef.h"
52 #include "winbase.h"
53 #include "iprtrmib.h"
54 #include "ifenum.h"
55 #include "ipstats.h"
57 #ifdef linux
58 #define TCPS_ESTABLISHED 1
59 #define TCPS_SYN_SENT 2
60 #define TCPS_SYN_RECEIVED 3
61 #define TCPS_FIN_WAIT_1 4
62 #define TCPS_FIN_WAIT_2 5
63 #define TCPS_TIME_WAIT 6
64 #define TCPS_CLOSED 7
65 #define TCPS_CLOSE_WAIT 8
66 #define TCPS_LAST_ACK 9
67 #define TCPS_LISTEN 10
68 #define TCPS_CLOSING 11
69 #endif
71 DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
73 FILE *fp;
75 if (!name)
76 return ERROR_INVALID_PARAMETER;
77 if (!entry)
78 return ERROR_INVALID_PARAMETER;
80 /* get interface stats from /proc/net/dev, no error if can't
81 no inUnknownProtos, outNUcastPkts, outQLen */
82 fp = fopen("/proc/net/dev", "r");
83 if (fp) {
84 char buf[512] = { 0 }, *ptr;
85 int nameLen = strlen(name), nameFound = 0;
88 ptr = fgets(buf, sizeof(buf), fp);
89 while (ptr && !nameFound) {
90 while (*ptr && isspace(*ptr))
91 ptr++;
92 if (strncasecmp(ptr, name, nameLen) == 0 && *(ptr + nameLen) == ':')
93 nameFound = 1;
94 else
95 ptr = fgets(buf, sizeof(buf), fp);
97 if (nameFound) {
98 char *endPtr;
100 ptr += nameLen + 1;
101 if (ptr && *ptr) {
102 entry->dwInOctets = strtoul(ptr, &endPtr, 10);
103 ptr = endPtr;
105 if (ptr && *ptr) {
106 entry->dwInUcastPkts = strtoul(ptr, &endPtr, 10);
107 ptr = endPtr;
109 if (ptr && *ptr) {
110 entry->dwInErrors = strtoul(ptr, &endPtr, 10);
111 ptr = endPtr;
113 if (ptr && *ptr) {
114 entry->dwInDiscards = strtoul(ptr, &endPtr, 10);
115 ptr = endPtr;
117 if (ptr && *ptr) {
118 strtoul(ptr, &endPtr, 10); /* skip */
119 ptr = endPtr;
121 if (ptr && *ptr) {
122 strtoul(ptr, &endPtr, 10); /* skip */
123 ptr = endPtr;
125 if (ptr && *ptr) {
126 strtoul(ptr, &endPtr, 10); /* skip */
127 ptr = endPtr;
129 if (ptr && *ptr) {
130 entry->dwInNUcastPkts = strtoul(ptr, &endPtr, 10);
131 ptr = endPtr;
133 if (ptr && *ptr) {
134 entry->dwOutOctets = strtoul(ptr, &endPtr, 10);
135 ptr = endPtr;
137 if (ptr && *ptr) {
138 entry->dwOutUcastPkts = strtoul(ptr, &endPtr, 10);
139 ptr = endPtr;
141 if (ptr && *ptr) {
142 entry->dwOutErrors = strtoul(ptr, &endPtr, 10);
143 ptr = endPtr;
145 if (ptr && *ptr) {
146 entry->dwOutDiscards = strtoul(ptr, &endPtr, 10);
147 ptr = endPtr;
150 fclose(fp);
152 return NO_ERROR;
155 DWORD getICMPStats(MIB_ICMP *stats)
157 FILE *fp;
159 if (!stats)
160 return ERROR_INVALID_PARAMETER;
162 memset(stats, 0, sizeof(MIB_ICMP));
163 /* get most of these stats from /proc/net/snmp, no error if can't */
164 fp = fopen("/proc/net/snmp", "r");
165 if (fp) {
166 static const char hdr[] = "Icmp:";
167 char buf[512] = { 0 }, *ptr;
169 do {
170 ptr = fgets(buf, sizeof(buf), fp);
171 } while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
172 if (ptr) {
173 /* last line was a header, get another */
174 ptr = fgets(buf, sizeof(buf), fp);
175 if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
176 char *endPtr;
178 ptr += sizeof(hdr);
179 if (ptr && *ptr) {
180 stats->stats.icmpInStats.dwMsgs = strtoul(ptr, &endPtr, 10);
181 ptr = endPtr;
183 if (ptr && *ptr) {
184 stats->stats.icmpInStats.dwErrors = strtoul(ptr, &endPtr, 10);
185 ptr = endPtr;
187 if (ptr && *ptr) {
188 stats->stats.icmpInStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
189 ptr = endPtr;
191 if (ptr && *ptr) {
192 stats->stats.icmpInStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
193 ptr = endPtr;
195 if (ptr && *ptr) {
196 stats->stats.icmpInStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
197 ptr = endPtr;
199 if (ptr && *ptr) {
200 stats->stats.icmpInStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
201 ptr = endPtr;
203 if (ptr && *ptr) {
204 stats->stats.icmpInStats.dwRedirects = strtoul(ptr, &endPtr, 10);
205 ptr = endPtr;
207 if (ptr && *ptr) {
208 stats->stats.icmpInStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
209 ptr = endPtr;
211 if (ptr && *ptr) {
212 stats->stats.icmpInStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
213 ptr = endPtr;
215 if (ptr && *ptr) {
216 stats->stats.icmpInStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
217 ptr = endPtr;
219 if (ptr && *ptr) {
220 stats->stats.icmpInStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
221 ptr = endPtr;
223 if (ptr && *ptr) {
224 stats->stats.icmpInStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
225 ptr = endPtr;
227 if (ptr && *ptr) {
228 stats->stats.icmpOutStats.dwMsgs = strtoul(ptr, &endPtr, 10);
229 ptr = endPtr;
231 if (ptr && *ptr) {
232 stats->stats.icmpOutStats.dwErrors = strtoul(ptr, &endPtr, 10);
233 ptr = endPtr;
235 if (ptr && *ptr) {
236 stats->stats.icmpOutStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
237 ptr = endPtr;
239 if (ptr && *ptr) {
240 stats->stats.icmpOutStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
241 ptr = endPtr;
243 if (ptr && *ptr) {
244 stats->stats.icmpOutStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
245 ptr = endPtr;
247 if (ptr && *ptr) {
248 stats->stats.icmpOutStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
249 ptr = endPtr;
251 if (ptr && *ptr) {
252 stats->stats.icmpOutStats.dwRedirects = strtoul(ptr, &endPtr, 10);
253 ptr = endPtr;
255 if (ptr && *ptr) {
256 stats->stats.icmpOutStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
257 ptr = endPtr;
259 if (ptr && *ptr) {
260 stats->stats.icmpOutStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
261 ptr = endPtr;
263 if (ptr && *ptr) {
264 stats->stats.icmpOutStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
265 ptr = endPtr;
267 if (ptr && *ptr) {
268 stats->stats.icmpOutStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
269 ptr = endPtr;
271 if (ptr && *ptr) {
272 stats->stats.icmpOutStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
273 ptr = endPtr;
277 fclose(fp);
279 return NO_ERROR;
282 DWORD getIPStats(PMIB_IPSTATS stats)
284 FILE *fp;
286 if (!stats)
287 return ERROR_INVALID_PARAMETER;
289 memset(stats, 0, sizeof(MIB_IPSTATS));
290 stats->dwNumIf = stats->dwNumAddr = getNumInterfaces();
291 stats->dwNumRoutes = getNumRoutes();
293 /* get most of these stats from /proc/net/snmp, no error if can't */
294 fp = fopen("/proc/net/snmp", "r");
295 if (fp) {
296 static const char hdr[] = "Ip:";
297 char buf[512] = { 0 }, *ptr;
299 do {
300 ptr = fgets(buf, sizeof(buf), fp);
301 } while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
302 if (ptr) {
303 /* last line was a header, get another */
304 ptr = fgets(buf, sizeof(buf), fp);
305 if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
306 char *endPtr;
308 ptr += sizeof(hdr);
309 if (ptr && *ptr) {
310 stats->dwForwarding = strtoul(ptr, &endPtr, 10);
311 ptr = endPtr;
313 if (ptr && *ptr) {
314 stats->dwDefaultTTL = strtoul(ptr, &endPtr, 10);
315 ptr = endPtr;
317 if (ptr && *ptr) {
318 stats->dwInReceives = strtoul(ptr, &endPtr, 10);
319 ptr = endPtr;
321 if (ptr && *ptr) {
322 stats->dwInHdrErrors = strtoul(ptr, &endPtr, 10);
323 ptr = endPtr;
325 if (ptr && *ptr) {
326 stats->dwInAddrErrors = strtoul(ptr, &endPtr, 10);
327 ptr = endPtr;
329 if (ptr && *ptr) {
330 stats->dwForwDatagrams = strtoul(ptr, &endPtr, 10);
331 ptr = endPtr;
333 if (ptr && *ptr) {
334 stats->dwInUnknownProtos = strtoul(ptr, &endPtr, 10);
335 ptr = endPtr;
337 if (ptr && *ptr) {
338 stats->dwInDiscards = strtoul(ptr, &endPtr, 10);
339 ptr = endPtr;
341 if (ptr && *ptr) {
342 stats->dwInDelivers = strtoul(ptr, &endPtr, 10);
343 ptr = endPtr;
345 if (ptr && *ptr) {
346 stats->dwOutRequests = strtoul(ptr, &endPtr, 10);
347 ptr = endPtr;
349 if (ptr && *ptr) {
350 stats->dwOutDiscards = strtoul(ptr, &endPtr, 10);
351 ptr = endPtr;
353 if (ptr && *ptr) {
354 stats->dwOutNoRoutes = strtoul(ptr, &endPtr, 10);
355 ptr = endPtr;
357 if (ptr && *ptr) {
358 stats->dwReasmTimeout = strtoul(ptr, &endPtr, 10);
359 ptr = endPtr;
361 if (ptr && *ptr) {
362 stats->dwReasmReqds = strtoul(ptr, &endPtr, 10);
363 ptr = endPtr;
365 if (ptr && *ptr) {
366 stats->dwReasmOks = strtoul(ptr, &endPtr, 10);
367 ptr = endPtr;
369 if (ptr && *ptr) {
370 stats->dwReasmFails = strtoul(ptr, &endPtr, 10);
371 ptr = endPtr;
373 if (ptr && *ptr) {
374 stats->dwFragOks = strtoul(ptr, &endPtr, 10);
375 ptr = endPtr;
377 if (ptr && *ptr) {
378 stats->dwFragFails = strtoul(ptr, &endPtr, 10);
379 ptr = endPtr;
381 if (ptr && *ptr) {
382 stats->dwFragCreates = strtoul(ptr, &endPtr, 10);
383 ptr = endPtr;
385 /* hmm, no routingDiscards */
388 fclose(fp);
390 return NO_ERROR;
393 DWORD getTCPStats(MIB_TCPSTATS *stats)
395 FILE *fp;
397 if (!stats)
398 return ERROR_INVALID_PARAMETER;
400 memset(stats, 0, sizeof(MIB_TCPSTATS));
402 /* get from /proc/net/snmp, no error if can't */
403 fp = fopen("/proc/net/snmp", "r");
404 if (fp) {
405 static const char hdr[] = "Tcp:";
406 char buf[512] = { 0 }, *ptr;
409 do {
410 ptr = fgets(buf, sizeof(buf), fp);
411 } while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
412 if (ptr) {
413 /* last line was a header, get another */
414 ptr = fgets(buf, sizeof(buf), fp);
415 if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
416 char *endPtr;
418 ptr += sizeof(hdr);
419 if (ptr && *ptr) {
420 stats->dwRtoAlgorithm = strtoul(ptr, &endPtr, 10);
421 ptr = endPtr;
423 if (ptr && *ptr) {
424 stats->dwRtoMin = strtoul(ptr, &endPtr, 10);
425 ptr = endPtr;
427 if (ptr && *ptr) {
428 stats->dwRtoMin = strtoul(ptr, &endPtr, 10);
429 ptr = endPtr;
431 if (ptr && *ptr) {
432 stats->dwMaxConn = strtoul(ptr, &endPtr, 10);
433 ptr = endPtr;
435 if (ptr && *ptr) {
436 stats->dwActiveOpens = strtoul(ptr, &endPtr, 10);
437 ptr = endPtr;
439 if (ptr && *ptr) {
440 stats->dwPassiveOpens = strtoul(ptr, &endPtr, 10);
441 ptr = endPtr;
443 if (ptr && *ptr) {
444 stats->dwAttemptFails = strtoul(ptr, &endPtr, 10);
445 ptr = endPtr;
447 if (ptr && *ptr) {
448 stats->dwEstabResets = strtoul(ptr, &endPtr, 10);
449 ptr = endPtr;
451 if (ptr && *ptr) {
452 stats->dwCurrEstab = strtoul(ptr, &endPtr, 10);
453 ptr = endPtr;
455 if (ptr && *ptr) {
456 stats->dwInSegs = strtoul(ptr, &endPtr, 10);
457 ptr = endPtr;
459 if (ptr && *ptr) {
460 stats->dwOutSegs = strtoul(ptr, &endPtr, 10);
461 ptr = endPtr;
463 if (ptr && *ptr) {
464 stats->dwRetransSegs = strtoul(ptr, &endPtr, 10);
465 ptr = endPtr;
467 if (ptr && *ptr) {
468 stats->dwInErrs = strtoul(ptr, &endPtr, 10);
469 ptr = endPtr;
471 if (ptr && *ptr) {
472 stats->dwOutRsts = strtoul(ptr, &endPtr, 10);
473 ptr = endPtr;
475 stats->dwNumConns = getNumTcpEntries();
478 fclose(fp);
480 return NO_ERROR;
483 DWORD getUDPStats(MIB_UDPSTATS *stats)
485 FILE *fp;
487 if (!stats)
488 return ERROR_INVALID_PARAMETER;
490 memset(stats, 0, sizeof(MIB_UDPSTATS));
492 /* get from /proc/net/snmp, no error if can't */
493 fp = fopen("/proc/net/snmp", "r");
494 if (fp) {
495 static const char hdr[] = "Udp:";
496 char buf[512] = { 0 }, *ptr;
499 do {
500 ptr = fgets(buf, sizeof(buf), fp);
501 } while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
502 if (ptr) {
503 /* last line was a header, get another */
504 ptr = fgets(buf, sizeof(buf), fp);
505 if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
506 char *endPtr;
508 ptr += sizeof(hdr);
509 if (ptr && *ptr) {
510 stats->dwInDatagrams = strtoul(ptr, &endPtr, 10);
511 ptr = endPtr;
513 if (ptr && *ptr) {
514 stats->dwNoPorts = strtoul(ptr, &endPtr, 10);
515 ptr = endPtr;
517 if (ptr && *ptr) {
518 stats->dwInErrors = strtoul(ptr, &endPtr, 10);
519 ptr = endPtr;
521 if (ptr && *ptr) {
522 stats->dwOutDatagrams = strtoul(ptr, &endPtr, 10);
523 ptr = endPtr;
525 if (ptr && *ptr) {
526 stats->dwNumAddrs = strtoul(ptr, &endPtr, 10);
527 ptr = endPtr;
531 fclose(fp);
533 return NO_ERROR;
536 static DWORD getNumWithOneHeader(const char *filename)
538 FILE *fp;
539 int ret = 0;
541 fp = fopen(filename, "r");
542 if (fp) {
543 char buf[512] = { 0 }, *ptr;
546 ptr = fgets(buf, sizeof(buf), fp);
547 if (ptr) {
548 do {
549 ptr = fgets(buf, sizeof(buf), fp);
550 if (ptr)
551 ret++;
552 } while (ptr);
554 fclose(fp);
556 return ret;
559 DWORD getNumRoutes(void)
561 return getNumWithOneHeader("/proc/net/route");
564 RouteTable *getRouteTable(void)
566 DWORD numRoutes = getNumRoutes();
567 RouteTable *ret;
569 ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
570 sizeof(RouteTable) + (numRoutes - 1) * sizeof(RouteEntry));
571 if (ret) {
572 FILE *fp;
574 /* get from /proc/net/route, no error if can't */
575 fp = fopen("/proc/net/route", "r");
576 if (fp) {
577 char buf[512] = { 0 }, *ptr;
579 /* skip header line */
580 ptr = fgets(buf, sizeof(buf), fp);
581 while (ptr && ret->numRoutes < numRoutes) {
582 ptr = fgets(buf, sizeof(buf), fp);
583 if (ptr) {
584 DWORD index;
586 while (!isspace(*ptr))
587 ptr++;
588 *ptr = '\0';
589 ptr++;
590 if (getInterfaceIndexByName(buf, &index) == NO_ERROR) {
591 char *endPtr;
593 ret->routes[ret->numRoutes].ifIndex = index;
594 if (*ptr) {
595 ret->routes[ret->numRoutes].dest = strtoul(ptr, &endPtr, 16);
596 ptr = endPtr;
598 if (ptr && *ptr) {
599 ret->routes[ret->numRoutes].gateway = strtoul(ptr, &endPtr, 16);
600 ptr = endPtr;
602 if (ptr && *ptr) {
603 strtoul(ptr, &endPtr, 16); /* flags, skip */
604 ptr = endPtr;
606 if (ptr && *ptr) {
607 strtoul(ptr, &endPtr, 16); /* refcount, skip */
608 ptr = endPtr;
610 if (ptr && *ptr) {
611 strtoul(ptr, &endPtr, 16); /* use, skip */
612 ptr = endPtr;
614 if (ptr && *ptr) {
615 ret->routes[ret->numRoutes].metric = strtoul(ptr, &endPtr, 16);
616 ptr = endPtr;
618 if (ptr && *ptr) {
619 ret->routes[ret->numRoutes].mask = strtoul(ptr, &endPtr, 16);
620 ptr = endPtr;
622 ret->numRoutes++;
626 fclose(fp);
629 return ret;
632 DWORD getNumArpEntries(void)
634 return getNumWithOneHeader("/proc/net/arp");
637 PMIB_IPNETTABLE getArpTable(void)
639 DWORD numEntries = getNumArpEntries();
640 PMIB_IPNETTABLE ret;
642 ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
643 sizeof(MIB_IPNETTABLE) + (numEntries - 1) * sizeof(MIB_IPNETROW));
644 if (ret) {
645 FILE *fp;
647 /* get from /proc/net/arp, no error if can't */
648 fp = fopen("/proc/net/arp", "r");
649 if (fp) {
650 char buf[512] = { 0 }, *ptr;
652 /* skip header line */
653 ptr = fgets(buf, sizeof(buf), fp);
654 while (ptr && ret->dwNumEntries < numEntries) {
655 ptr = fgets(buf, sizeof(buf), fp);
656 if (ptr) {
657 char *endPtr;
659 ret->table[ret->dwNumEntries].dwAddr = inet_addr(ptr);
660 while (ptr && *ptr && !isspace(*ptr))
661 ptr++;
663 if (ptr && *ptr) {
664 strtoul(ptr, &endPtr, 16); /* hw type (skip) */
665 ptr = endPtr;
667 if (ptr && *ptr) {
668 DWORD flags = strtoul(ptr, &endPtr, 16);
670 #ifdef ATF_COM
671 if (flags & ATF_COM)
672 ret->table[ret->dwNumEntries].dwType = MIB_IPNET_TYPE_DYNAMIC;
673 else
674 #endif
675 #ifdef ATF_PERM
676 if (flags & ATF_PERM)
677 ret->table[ret->dwNumEntries].dwType = MIB_IPNET_TYPE_STATIC;
678 else
679 #endif
680 ret->table[ret->dwNumEntries].dwType = MIB_IPNET_TYPE_OTHER;
682 ptr = endPtr;
684 while (ptr && *ptr && isspace(*ptr))
685 ptr++;
686 while (ptr && *ptr && !isspace(*ptr)) {
687 DWORD byte = strtoul(ptr, &endPtr, 16);
689 if (endPtr && *endPtr) {
690 endPtr++;
691 ret->table[ret->dwNumEntries].bPhysAddr[
692 ret->table[ret->dwNumEntries].dwPhysAddrLen++] = byte & 0x0ff;
694 ptr = endPtr;
696 if (ptr && *ptr) {
697 strtoul(ptr, &endPtr, 16); /* mask (skip) */
698 ptr = endPtr;
700 getInterfaceIndexByName(ptr, &ret->table[ret->dwNumEntries].dwIndex);
701 ret->dwNumEntries++;
704 fclose(fp);
707 return ret;
710 DWORD getNumUdpEntries(void)
712 return getNumWithOneHeader("/proc/net/udp");
715 PMIB_UDPTABLE getUdpTable(void)
717 DWORD numEntries = getNumUdpEntries();
718 PMIB_UDPTABLE ret;
720 ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
721 sizeof(MIB_UDPTABLE) + (numEntries - 1) * sizeof(MIB_UDPROW));
722 if (ret) {
723 FILE *fp;
725 /* get from /proc/net/udp, no error if can't */
726 fp = fopen("/proc/net/udp", "r");
727 if (fp) {
728 char buf[512] = { 0 }, *ptr;
730 /* skip header line */
731 ptr = fgets(buf, sizeof(buf), fp);
732 while (ptr && ret->dwNumEntries < numEntries) {
733 ptr = fgets(buf, sizeof(buf), fp);
734 if (ptr) {
735 char *endPtr;
737 if (ptr && *ptr) {
738 strtoul(ptr, &endPtr, 16); /* skip */
739 ptr = endPtr;
741 if (ptr && *ptr) {
742 ptr++;
743 ret->table[ret->dwNumEntries].dwLocalAddr = strtoul(ptr, &endPtr,
744 16);
745 ptr = endPtr;
747 if (ptr && *ptr) {
748 ptr++;
749 ret->table[ret->dwNumEntries].dwLocalPort = strtoul(ptr, &endPtr,
750 16);
751 ptr = endPtr;
753 ret->dwNumEntries++;
756 fclose(fp);
759 return ret;
762 DWORD getNumTcpEntries(void)
764 return getNumWithOneHeader("/proc/net/tcp");
767 PMIB_TCPTABLE getTcpTable(void)
769 DWORD numEntries = getNumTcpEntries();
770 PMIB_TCPTABLE ret;
772 ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
773 sizeof(MIB_TCPTABLE) + (numEntries - 1) * sizeof(MIB_TCPROW));
774 if (ret) {
775 FILE *fp;
777 /* get from /proc/net/tcp, no error if can't */
778 fp = fopen("/proc/net/tcp", "r");
779 if (fp) {
780 char buf[512] = { 0 }, *ptr;
782 /* skip header line */
783 ptr = fgets(buf, sizeof(buf), fp);
784 while (ptr && ret->dwNumEntries < numEntries) {
785 ptr = fgets(buf, sizeof(buf), fp);
786 if (ptr) {
787 char *endPtr;
789 while (ptr && *ptr && *ptr != ':')
790 ptr++;
791 if (ptr && *ptr)
792 ptr++;
793 if (ptr && *ptr) {
794 ret->table[ret->dwNumEntries].dwLocalAddr = strtoul(ptr, &endPtr,
795 16);
796 ptr = endPtr;
798 if (ptr && *ptr) {
799 ptr++;
800 ret->table[ret->dwNumEntries].dwLocalPort = strtoul(ptr, &endPtr,
801 16);
802 ptr = endPtr;
804 if (ptr && *ptr) {
805 ret->table[ret->dwNumEntries].dwRemoteAddr = strtoul(ptr, &endPtr,
806 16);
807 ptr = endPtr;
809 if (ptr && *ptr) {
810 ptr++;
811 ret->table[ret->dwNumEntries].dwRemotePort = strtoul(ptr, &endPtr,
812 16);
813 ptr = endPtr;
815 if (ptr && *ptr) {
816 DWORD state = strtoul(ptr, &endPtr, 16);
818 switch (state)
820 case TCPS_ESTABLISHED:
821 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_ESTAB;
822 break;
823 case TCPS_SYN_SENT:
824 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_SYN_SENT;
825 break;
826 case TCPS_SYN_RECEIVED:
827 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_SYN_RCVD;
828 break;
829 case TCPS_FIN_WAIT_1:
830 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_FIN_WAIT1;
831 break;
832 case TCPS_FIN_WAIT_2:
833 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_FIN_WAIT2;
834 break;
835 case TCPS_TIME_WAIT:
836 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_TIME_WAIT;
837 break;
838 case TCPS_CLOSED:
839 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_CLOSED;
840 break;
841 case TCPS_CLOSE_WAIT:
842 ret->table[ret->dwNumEntries].dwState =
843 MIB_TCP_STATE_CLOSE_WAIT;
844 break;
845 case TCPS_LAST_ACK:
846 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_LAST_ACK;
847 break;
848 case TCPS_LISTEN:
849 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_LISTEN;
850 break;
851 case TCPS_CLOSING:
852 ret->table[ret->dwNumEntries].dwState = MIB_TCP_STATE_CLOSING;
853 break;
855 ptr = endPtr;
857 ret->dwNumEntries++;
860 fclose(fp);
863 return ret;