| /**************************************************************************** |
| * apps/netutils/netlib/netlib_getifstatistics.c |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. The |
| * ASF licenses this file to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance with the |
| * License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations |
| * under the License. |
| * |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Included Files |
| ****************************************************************************/ |
| |
| #include <nuttx/config.h> |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <errno.h> |
| #include <debug.h> |
| |
| #include <sys/types.h> |
| |
| #include "netutils/netlib.h" |
| |
| #ifdef CONFIG_NETDEV_STATISTICS |
| |
| /**************************************************************************** |
| * Pre-processor Definitions |
| ****************************************************************************/ |
| |
| /* Determines the size of an intermediate buffer that must be large enough |
| * to handle the longest line generated by this logic. |
| */ |
| |
| #define PROCFS_LINELEN 80 |
| #define PROCFS_NET_PATH "/proc/net/" |
| |
| /* The form of the entry from the netstat file: |
| * |
| * wlan0 Link encap:Ethernet HWaddr 42:37:46:02:16:07 at UP mtu 1500 |
| * inet addr:10.0.1.2 DRaddr:10.0.1.1 Mask:255.255.255.0 |
| * inet6 DRaddr: :: |
| * |
| * RX: Received Fragment Errors Bytes |
| * 000008c1 00000000 00000000 331ca8 |
| * IPv4 IPv6 ARP Dropped |
| * 000008a7 00000018 00000002 00000000 |
| * TX: Queued Sent Errors Timeouts Bytes |
| * 00000973 00000973 00000000 00000000 1b8d3 |
| * Total Errors: 00000000 |
| */ |
| |
| /**************************************************************************** |
| * Public Functions |
| ****************************************************************************/ |
| |
| /**************************************************************************** |
| * Name: netlib_getifstatistics |
| * |
| * Description: |
| * Read the DEV RX/TX statistics. |
| * |
| * Input Parameters: |
| * ifname - The interface to read. |
| * stat - The pointer to return dev statistics. |
| * |
| * Returned Value: |
| * 0 on success. A negated errno value is returned |
| * on any failure. |
| ****************************************************************************/ |
| |
| int netlib_getifstatistics(FAR const char *ifname, |
| FAR struct netdev_statistics_s *stat) |
| { |
| FAR FILE *stream; |
| char path[32]; |
| char line[PROCFS_LINELEN]; |
| int ret = OK; |
| |
| snprintf(path, sizeof(path), "%s%s", PROCFS_NET_PATH, ifname); |
| ninfo("get statistics from %s \n", path); |
| |
| stream = fopen(path, "r"); |
| if (stream == NULL) |
| { |
| fprintf(stderr, "ERROR: Failed to open path:%s \n", path); |
| return -ENOTDIR; |
| } |
| |
| while (fgets(line, sizeof(line), stream) != NULL) |
| { |
| /* Read RX header and next is the data */ |
| |
| if (strstr(line, "RX:") != NULL) |
| { |
| if (fgets(line, sizeof(line), stream) == NULL) |
| { |
| ret = -EINVAL; |
| break; |
| } |
| |
| if (sscanf(line, "%" SCNx32 "%" SCNx32 "%" SCNx32 "%" SCNx64, |
| &stat->rx_packets, |
| &stat->rx_fragments, |
| &stat->rx_errors, |
| &stat->rx_bytes) <= 0) |
| { |
| ret = -EINVAL; |
| break; |
| } |
| } |
| |
| /* Read TX header and next is the data */ |
| |
| if (strstr(line, "TX:") != NULL) |
| { |
| if (fgets(line, sizeof(line), stream) == NULL) |
| { |
| ret = -EINVAL; |
| break; |
| } |
| |
| if (sscanf(line, "%" SCNx32 "%" SCNx32 "%" SCNx32 \ |
| "%" SCNx32 "%" SCNx64, |
| &stat->tx_packets, |
| &stat->tx_done, |
| &stat->tx_errors, |
| &stat->tx_timeouts, |
| &stat->tx_bytes) <= 0) |
| { |
| ret = -EINVAL; |
| break; |
| } |
| } |
| } |
| |
| fclose(stream); |
| return ret; |
| } |
| |
| #endif /* CONFIG_NETDEV_STATISTICS */ |