procfs: Add support for routing tables.
This commit is contained in:
parent
fdca465da6
commit
65698da12d
9 changed files with 300 additions and 122 deletions
5
TODO
5
TODO
|
@ -2097,6 +2097,11 @@ o Build system
|
|||
|
||||
$ make apps_distclean
|
||||
|
||||
One solution to this might be to making the special target
|
||||
.PRECIOUS depend on apps/libapps.a. Then if make receives a
|
||||
signal, it will not delete apps/libapps.a. This would have to
|
||||
be done in all Makefiles.
|
||||
|
||||
Status Open
|
||||
Priority: Medium-High. It is a rare event that control-C happens at just the
|
||||
point in time. However, when it does occur the resulting code may
|
||||
|
|
|
@ -63,6 +63,11 @@ config FS_PROCFS_EXCLUDE_NET
|
|||
depends on NET
|
||||
default n
|
||||
|
||||
config FS_PROC_EXCLUDE_ROUTE
|
||||
bool "Exclude routing table"
|
||||
depends on !FS_PROCFS_EXCLUDE_NET && NET_ROUTE
|
||||
default n
|
||||
|
||||
config FS_PROCFS_EXCLUDE_MTD
|
||||
bool "Exclude mtd"
|
||||
depends on MTD
|
||||
|
|
|
@ -87,6 +87,7 @@ extern const struct procfs_operations uptime_operations;
|
|||
*/
|
||||
|
||||
extern const struct procfs_operations net_procfsoperations;
|
||||
extern const struct procfs_operations net_procfs_routeoperations;
|
||||
extern const struct procfs_operations mtd_procfsoperations;
|
||||
extern const struct procfs_operations part_procfsoperations;
|
||||
extern const struct procfs_operations smartfs_procfsoperations;
|
||||
|
@ -112,42 +113,46 @@ static const struct procfs_entry_s g_procfs_entries[] =
|
|||
#endif
|
||||
{
|
||||
#ifndef CONFIG_FS_PROCFS_EXCLUDE_PROCESS
|
||||
{ "[0-9]*/**", &proc_operations },
|
||||
{ "[0-9]*", &proc_operations },
|
||||
{ "[0-9]*/**", &proc_operations, PROCFS_UNKOWN_TYPE },
|
||||
{ "[0-9]*", &proc_operations, PROCFS_DIR_TYPE },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_CPULOAD) && !defined(CONFIG_FS_PROCFS_EXCLUDE_CPULOAD)
|
||||
{ "cpuload", &cpuload_operations },
|
||||
{ "cpuload", &cpuload_operations, PROCFS_FILE_TYPE },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MM_KERNEL_HEAP) && !defined(CONFIG_FS_PROCFS_EXCLUDE_KMM)
|
||||
{ "kmm", &kmm_operations },
|
||||
{ "kmm", &kmm_operations, PROCFS_FILE_TYPE },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MODULE) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)
|
||||
{ "modules", &module_operations },
|
||||
{ "modules", &module_operations, PROCFS_DIR_TYPE },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FS_SMARTFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_SMARTFS)
|
||||
//{ "fs/smartfs", &smartfs_procfsoperations },
|
||||
{ "fs/smartfs**", &smartfs_procfsoperations },
|
||||
//{ "fs/smartfs", &smartfs_procfsoperations, PROCFS_DIR_TYPE },
|
||||
{ "fs/smartfs**", &smartfs_procfsoperations, PROCFS_UNKOWN_TYPE },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_NET) && !defined(CONFIG_FS_PROCFS_EXCLUDE_NET)
|
||||
{ "net", &net_procfsoperations },
|
||||
{ "net/**", &net_procfsoperations },
|
||||
{ "net", &net_procfsoperations, PROCFS_DIR_TYPE },
|
||||
#if defined(CONFIG_NET_ROUTE) && !defined(CONFIG_FS_PROCFS_EXCLUDE_ROUTE)
|
||||
{ "net/route", &net_procfs_routeoperations, PROCFS_DIR_TYPE },
|
||||
{ "net/route/**", &net_procfs_routeoperations, PROCFS_UNKOWN_TYPE },
|
||||
#endif
|
||||
{ "net/**", &net_procfsoperations, PROCFS_UNKOWN_TYPE },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MTD) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MTD)
|
||||
{ "mtd", &mtd_procfsoperations },
|
||||
{ "mtd", &mtd_procfsoperations, PROCFS_FILE_TYPE },
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MTD_PARTITION) && !defined(CONFIG_FS_PROCFS_EXCLUDE_PARTITIONS)
|
||||
{ "partitions", &part_procfsoperations },
|
||||
{ "partitions", &part_procfsoperations, PROCFS_DIR_TYPE },
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_FS_PROCFS_EXCLUDE_UPTIME)
|
||||
{ "uptime", &uptime_operations },
|
||||
{ "uptime", &uptime_operations, PROCFS_FILE_TYPE },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -348,6 +353,7 @@ static int procfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
|
||||
((struct procfs_file_s *) filep->f_priv)->procfsentry =
|
||||
&g_procfs_entries[x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -673,6 +679,7 @@ static int procfs_closedir(FAR struct inode *mountpt,
|
|||
|
||||
static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
||||
{
|
||||
FAR const struct procfs_entry_s *entry = NULL;
|
||||
FAR struct procfs_dir_priv_s *priv;
|
||||
FAR struct procfs_level0_s *level0;
|
||||
FAR struct tcb_s *tcb;
|
||||
|
@ -705,7 +712,9 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
|||
|
||||
while (index < priv->nentries + g_procfs_entrycount)
|
||||
{
|
||||
name = g_procfs_entries[index - priv->nentries].pathpattern;
|
||||
entry = &g_procfs_entries[index - priv->nentries];
|
||||
name = entry->pathpattern;
|
||||
|
||||
while (*name != '/' && *name != '\0')
|
||||
{
|
||||
if (*name == '*' || *name == '[' || *name == '?')
|
||||
|
@ -772,7 +781,7 @@ static int procfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir)
|
|||
strncpy(dir->fd_dir.d_name, name, level0->lastlen);
|
||||
dir->fd_dir.d_name[level0->lastlen] = '\0';
|
||||
|
||||
if (name[level0->lastlen] == '/')
|
||||
if (entry->type == PROCFS_DIR_TYPE)
|
||||
{
|
||||
dir->fd_dir.d_type = DTYPE_DIRECTORY;
|
||||
}
|
||||
|
|
|
@ -93,6 +93,15 @@ struct procfs_operations
|
|||
|
||||
/* Procfs handler prototypes ************************************************/
|
||||
|
||||
/* These are the types of entries that may appear in the procfs: */
|
||||
|
||||
enum procfs_entry_e
|
||||
{
|
||||
PROCFS_UNKOWN_TYPE = 0, /* Unknown type */
|
||||
PROCFS_FILE_TYPE, /* File type */
|
||||
PROCFS_DIR_TYPE, /* Directory type */
|
||||
};
|
||||
|
||||
/* This is a procfs entry that each handler should provide to supply
|
||||
* specific operations for file and directory handling.
|
||||
*/
|
||||
|
@ -101,6 +110,7 @@ struct procfs_entry_s
|
|||
{
|
||||
FAR const char *pathpattern;
|
||||
FAR const struct procfs_operations *ops;
|
||||
uint8_t type;
|
||||
};
|
||||
|
||||
/* Specifies the common elements for an open file in the procfs
|
||||
|
|
|
@ -47,6 +47,12 @@ ifeq ($(CONFIG_NET_STATISTICS),y)
|
|||
NET_CSRCS += net_statistics.c
|
||||
endif
|
||||
|
||||
# Routing table
|
||||
|
||||
ifeq ($(CONFIG_NET_ROUTE),y)
|
||||
NET_CSRCS += net_procfs_route.c
|
||||
endif
|
||||
|
||||
# Include packet socket build support
|
||||
|
||||
DEPPATH += --dep-path procfs
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include <nuttx/fs/fs.h>
|
||||
#include <nuttx/fs/procfs.h>
|
||||
#include <nuttx/fs/dirent.h>
|
||||
#include <nuttx/lib/regex.h>
|
||||
#include <nuttx/net/netdev.h>
|
||||
|
||||
#include "netdev/netdev.h"
|
||||
|
@ -64,6 +65,26 @@
|
|||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_FS_PROCFS) && \
|
||||
!defined(CONFIG_FS_PROCFS_EXCLUDE_NET)
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Directory entry indices */
|
||||
|
||||
#if defined(CONFIG_NET_STATISTICS) && defined(CONFIG_NET_ROUTE)
|
||||
# define STAT_INDEX 0
|
||||
# define ROUTE_INDEX 1
|
||||
# define DEV_INDEX 2
|
||||
#elif defined(CONFIG_NET_STATISTICS)
|
||||
# define STAT_INDEX 0
|
||||
# define DEV_INDEX 1
|
||||
#elif defined(CONFIG_NET_ROUTE)
|
||||
# define ROUTE_INDEX 0
|
||||
# define DEV_INDEX 1
|
||||
#else
|
||||
# define DEV_INDEX 0
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
@ -112,6 +133,8 @@ const struct procfs_operations net_procfsoperations =
|
|||
netprocfs_stat /* stat */
|
||||
};
|
||||
|
||||
extern const struct procfs_operations net_procfs_routeoperations;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -125,6 +148,7 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
{
|
||||
FAR struct netprocfs_file_s *priv;
|
||||
FAR struct net_driver_s *dev;
|
||||
enum netprocfs_entry_e entry;
|
||||
|
||||
finfo("Open '%s'\n", relpath);
|
||||
|
||||
|
@ -141,18 +165,29 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
return -EACCES;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
/* "net/stat" is an acceptable value for the relpath only if network layer
|
||||
* statistics are enabled.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
if (strcmp(relpath, "net/stat") == 0)
|
||||
{
|
||||
/* A NULL network device reference is a clue that we are processing
|
||||
* the network statistics file.
|
||||
*/
|
||||
entry = NETPROCFS_SUBDIR_STAT;
|
||||
dev = NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
dev = NULL;
|
||||
#ifdef CONFIG_NET_ROUTE
|
||||
/* "net/route" is an acceptable value for the relpath only if routing
|
||||
* table support is initialized.
|
||||
*/
|
||||
|
||||
if (match("net/route/**", relpath))
|
||||
{
|
||||
/* Use the /net/route directory */
|
||||
|
||||
return net_procfs_routeoperations.open(filep, relpath, oflags, mode);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -180,11 +215,14 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
ferr("ERROR: relpath is '%s'\n", relpath);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
entry = NETPROCFS_SUBDIR_DEV;
|
||||
}
|
||||
|
||||
/* Allocate the open file structure */
|
||||
|
||||
priv = (FAR struct netprocfs_file_s *)kmm_zalloc(sizeof(struct netprocfs_file_s));
|
||||
priv = (FAR struct netprocfs_file_s *)
|
||||
kmm_zalloc(sizeof(struct netprocfs_file_s));
|
||||
if (!priv)
|
||||
{
|
||||
ferr("ERROR: Failed to allocate file attributes\n");
|
||||
|
@ -193,7 +231,8 @@ static int netprocfs_open(FAR struct file *filep, FAR const char *relpath,
|
|||
|
||||
/* Initialize the open-file structure */
|
||||
|
||||
priv->dev = dev;
|
||||
priv->dev = dev;
|
||||
priv->entry = entry;
|
||||
|
||||
/* Save the open file structure as the open-specific state in
|
||||
* filep->f_priv.
|
||||
|
@ -240,24 +279,33 @@ static ssize_t netprocfs_read(FAR struct file *filep, FAR char *buffer,
|
|||
priv = (FAR struct netprocfs_file_s *)filep->f_priv;
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
/* A NULL device structure reference is the key that we are showing the
|
||||
* network statistics.
|
||||
*/
|
||||
/* Read according to the sub-directory */
|
||||
|
||||
if (priv->dev == NULL)
|
||||
switch (priv->entry)
|
||||
{
|
||||
/* Show the network layer statistics */
|
||||
case NETPROCFS_SUBDIR_DEV:
|
||||
/* Show device-specific statistics */
|
||||
|
||||
nreturned = netprocfs_read_netstats(priv, buffer, buflen);
|
||||
}
|
||||
else
|
||||
nreturned = netprocfs_read_devstats(priv, buffer, buflen);
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
case NETPROCFS_SUBDIR_STAT:
|
||||
/* Show the network layer statistics */
|
||||
|
||||
nreturned = netprocfs_read_netstats(priv, buffer, buflen);
|
||||
break;
|
||||
#endif
|
||||
{
|
||||
/* Otherwise, we are showing device-specific statistics */
|
||||
|
||||
nreturned = netprocfs_read_devstats(priv, buffer, buflen);
|
||||
}
|
||||
#ifdef CONFIG_NET_ROUTE
|
||||
case NETPROCFS_SUBDIR_ROUTE:
|
||||
nerr("ERROR: Cannot read from directory net/route\n");
|
||||
#endif
|
||||
|
||||
default:
|
||||
nerr("ERROR: Invalid entry for reading: %u\n", priv->entry);
|
||||
nreturned = -EINVAL;
|
||||
}
|
||||
|
||||
/* Update the file offset */
|
||||
|
||||
|
@ -321,13 +369,56 @@ static int netprocfs_opendir(FAR const char *relpath,
|
|||
{
|
||||
FAR struct netprocfs_level1_s *level1;
|
||||
int ndevs;
|
||||
int ret;
|
||||
|
||||
finfo("relpath: \"%s\"\n", relpath ? relpath : "NULL");
|
||||
DEBUGASSERT(relpath && dir && !dir->u.procfs);
|
||||
|
||||
/* "net" is the only value of relpath that is a directory */
|
||||
/* "net" and "net/route" are the only values of relpath that are
|
||||
* directories.
|
||||
*/
|
||||
|
||||
if (strcmp(relpath, "net") != 0)
|
||||
#ifdef CONFIG_NET_ROUTE
|
||||
if (match("net/route", relpath) || match("net/route/**", relpath))
|
||||
{
|
||||
/* Use the /net/route directory */
|
||||
|
||||
return net_procfs_routeoperations.opendir(relpath, dir);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Assume that path refers to the 1st level subdirectory. Allocate the
|
||||
* level1 the dirent structure before checking.
|
||||
*/
|
||||
|
||||
level1 = (FAR struct netprocfs_level1_s *)
|
||||
kmm_zalloc(sizeof(struct netprocfs_level1_s));
|
||||
|
||||
if (level1 == NULL)
|
||||
{
|
||||
ferr("ERROR: Failed to allocate the level1 directory structure\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
level1->base.level = 1;
|
||||
|
||||
if (strcmp(relpath, "net") == 0)
|
||||
{
|
||||
/* Count the number of network devices */
|
||||
|
||||
ndevs = netdev_count();
|
||||
|
||||
/* Initialze base structure components */
|
||||
|
||||
level1->base.nentries = ndevs;
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
level1->base.nentries++;
|
||||
#endif
|
||||
#ifdef CONFIG_NET_ROUTE
|
||||
level1->base.nentries++;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* REVISIT: We really need to check if the relpath refers to a network
|
||||
* device. In that case, we need to return -ENOTDIR. Otherwise, we
|
||||
|
@ -335,38 +426,16 @@ static int netprocfs_opendir(FAR const char *relpath,
|
|||
*/
|
||||
|
||||
ferr("ERROR: Bad relpath: %s\n", relpath);
|
||||
return -ENOTDIR;
|
||||
ret = -ENOTDIR;
|
||||
goto errout_with_alloc;
|
||||
}
|
||||
|
||||
/* The path refers to the 1st level sbdirectory. Allocate the level1
|
||||
* dirent structure.
|
||||
*/
|
||||
|
||||
level1 = (FAR struct netprocfs_level1_s *)
|
||||
kmm_zalloc(sizeof(struct netprocfs_level1_s));
|
||||
|
||||
if (!level1)
|
||||
{
|
||||
ferr("ERROR: Failed to allocate the level1 directory structure\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Count the number of network devices */
|
||||
|
||||
ndevs = netdev_count();
|
||||
|
||||
/* Initialze base structure components */
|
||||
|
||||
level1->base.level = 1;
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
level1->base.nentries = ndevs + 1;
|
||||
#else
|
||||
level1->base.nentries = ndevs;
|
||||
#endif
|
||||
level1->base.index = 0;
|
||||
|
||||
dir->u.procfs = (FAR void *) level1;
|
||||
dir->u.procfs = (FAR void *)level1;
|
||||
return OK;
|
||||
|
||||
errout_with_alloc:
|
||||
kmm_free(level1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -404,63 +473,86 @@ static int netprocfs_readdir(FAR struct fs_dirent_s *dir)
|
|||
FAR struct netprocfs_level1_s *level1;
|
||||
FAR struct net_driver_s *dev;
|
||||
int index;
|
||||
int ret;
|
||||
|
||||
DEBUGASSERT(dir && dir->u.procfs);
|
||||
level1 = dir->u.procfs;
|
||||
DEBUGASSERT(level1->base.level == 1);
|
||||
DEBUGASSERT(level1->base.level > 0);
|
||||
|
||||
/* Have we reached the end of the directory */
|
||||
|
||||
index = level1->base.index;
|
||||
DEBUGASSERT(index <= level1->base.nentries);
|
||||
|
||||
if (index >= level1->base.nentries)
|
||||
{
|
||||
/* We signal the end of the directory by returning the special
|
||||
* error -ENOENT.
|
||||
*/
|
||||
|
||||
finfo("Entry %d: End of directory\n", index);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
else if (index == 0)
|
||||
{
|
||||
/* Copy the network statistics directory entry */
|
||||
|
||||
dir->fd_dir.d_type = DTYPE_FILE;
|
||||
strncpy(dir->fd_dir.d_name, "stat", NAME_MAX + 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
int devndx = index;
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
/* Subtract one to account for index == 0 which is used for network
|
||||
* status.
|
||||
*/
|
||||
|
||||
devndx--;
|
||||
#endif
|
||||
|
||||
/* Find the device corresponding to this device index */
|
||||
|
||||
dev = netdev_findbyindex(devndx);
|
||||
|
||||
/* Copy the device statistics file entry */
|
||||
|
||||
dir->fd_dir.d_type = DTYPE_FILE;
|
||||
strncpy(dir->fd_dir.d_name, dev->d_ifname, NAME_MAX + 1);
|
||||
}
|
||||
|
||||
/* Set up the next directory entry offset. NOTE that we could use the
|
||||
* standard f_pos instead of our own private index.
|
||||
/* Are we searching this directory? Or is it just an intermediate on the
|
||||
* way to a sub-directory?
|
||||
*/
|
||||
|
||||
level1->base.index = index + 1;
|
||||
return OK;
|
||||
if (level1->base.level == 1)
|
||||
{
|
||||
/* This directory.. Have we reached the end of the directory? */
|
||||
|
||||
index = level1->base.index;
|
||||
DEBUGASSERT(index <= level1->base.nentries);
|
||||
|
||||
if (index >= level1->base.nentries)
|
||||
{
|
||||
/* We signal the end of the directory by returning the special
|
||||
* error -ENOENT.
|
||||
*/
|
||||
|
||||
finfo("Entry %d: End of directory\n", index);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
else if (index == STAT_INDEX)
|
||||
{
|
||||
/* Copy the network statistics directory entry */
|
||||
|
||||
dir->fd_dir.d_type = DTYPE_FILE;
|
||||
strncpy(dir->fd_dir.d_name, "stat", NAME_MAX + 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_NET_ROUTE
|
||||
if (index == ROUTE_INDEX)
|
||||
{
|
||||
/* Copy the network statistics directory entry */
|
||||
|
||||
dir->fd_dir.d_type = DTYPE_DIRECTORY;
|
||||
strncpy(dir->fd_dir.d_name, "route", NAME_MAX + 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
int devndx = index - DEV_INDEX;
|
||||
|
||||
/* Find the device corresponding to this device index */
|
||||
|
||||
dev = netdev_findbyindex(devndx);
|
||||
|
||||
/* Copy the device statistics file entry */
|
||||
|
||||
dir->fd_dir.d_type = DTYPE_FILE;
|
||||
strncpy(dir->fd_dir.d_name, dev->d_ifname, NAME_MAX + 1);
|
||||
}
|
||||
|
||||
/* Set up the next directory entry offset. NOTE that we could use the
|
||||
* standard f_pos instead of our own private index.
|
||||
*/
|
||||
|
||||
level1->base.index = index + 1;
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are performing a directory search of one of the subdirectories
|
||||
* and we must let the handler perform the read.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(level1->base.procfsentry != NULL &&
|
||||
level1->base.procfsentry->ops->readdir != NULL);
|
||||
|
||||
ret = level1->base.procfsentry->ops->readdir(dir);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -505,6 +597,15 @@ static int netprocfs_stat(FAR const char *relpath, FAR struct stat *buf)
|
|||
buf->st_mode = S_IFREG | S_IROTH | S_IRGRP | S_IRUSR;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef CONFIG_NET_ROUTE
|
||||
/* Check for network statistics "net/stat" */
|
||||
|
||||
if (strcmp(relpath, "net/route") == 0)
|
||||
{
|
||||
buf->st_mode = S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
FAR struct net_driver_s *dev;
|
||||
|
|
|
@ -82,7 +82,7 @@ static int netprocfs_retransmissions(FAR struct netprocfs_file_s *netfile);
|
|||
|
||||
/* Line generating functions */
|
||||
|
||||
static const linegen_t g_linegen[] =
|
||||
static const linegen_t g_stat_linegen[] =
|
||||
{
|
||||
netprocfs_header,
|
||||
netprocfs_received,
|
||||
|
@ -111,7 +111,7 @@ static const linegen_t g_linegen[] =
|
|||
#endif /* CONFIG_NET_TCP */
|
||||
};
|
||||
|
||||
#define NSTAT_LINES (sizeof(g_linegen) / sizeof(linegen_t))
|
||||
#define NSTAT_LINES (sizeof(g_stat_linegen) / sizeof(linegen_t))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -456,7 +456,7 @@ static int netprocfs_retransmissions(FAR struct netprocfs_file_s *netfile)
|
|||
ssize_t netprocfs_read_netstats(FAR struct netprocfs_file_s *priv,
|
||||
FAR char *buffer, size_t buflen)
|
||||
{
|
||||
return netprocfs_read_linegen(priv, buffer, buflen, g_linegen, NSTAT_LINES);
|
||||
return netprocfs_read_linegen(priv, buffer, buflen, g_stat_linegen, NSTAT_LINES);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS &&
|
||||
|
|
|
@ -84,7 +84,7 @@ static int netprocfs_errors(FAR struct netprocfs_file_s *netfile);
|
|||
|
||||
/* Line generating functions */
|
||||
|
||||
static const linegen_t g_linegen[] =
|
||||
static const linegen_t g_netstat_linegen[] =
|
||||
{
|
||||
netprocfs_linklayer
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
|
@ -105,7 +105,7 @@ static const linegen_t g_linegen[] =
|
|||
#endif /* CONFIG_NETDEV_STATISTICS */
|
||||
};
|
||||
|
||||
#define NSTAT_LINES (sizeof(g_linegen) / sizeof(linegen_t))
|
||||
#define NSTAT_LINES (sizeof(g_netstat_linegen) / sizeof(linegen_t))
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -554,7 +554,8 @@ static int netprocfs_errors(FAR struct netprocfs_file_s *netfile)
|
|||
ssize_t netprocfs_read_devstats(FAR struct netprocfs_file_s *priv,
|
||||
FAR char *buffer, size_t buflen)
|
||||
{
|
||||
return netprocfs_read_linegen(priv, buffer, buflen, g_linegen, NSTAT_LINES);
|
||||
return netprocfs_read_linegen(priv, buffer, buflen, g_netstat_linegen,
|
||||
NSTAT_LINES);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_DISABLE_MOUNTPOINT && CONFIG_FS_PROCFS &&
|
||||
|
|
|
@ -50,6 +50,10 @@
|
|||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_FS_PROCFS_EXCLUDE_ROUTE
|
||||
# undef CONFIG_NET_ROUTE
|
||||
#endif
|
||||
|
||||
/* Determines the size of an intermediate buffer that must be large enough
|
||||
* to handle the longest line generated by this logic.
|
||||
*/
|
||||
|
@ -60,6 +64,19 @@
|
|||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Describes the /net directory entries */
|
||||
|
||||
enum netprocfs_entry_e
|
||||
{
|
||||
NETPROCFS_SUBDIR_DEV = 0 /* Multiple instances, e.g. /proc/net/eth0 */
|
||||
#ifdef CONFIG_NET_STATISTICS
|
||||
, NETPROCFS_SUBDIR_STAT /* /proc/net/stat */
|
||||
#endif
|
||||
#ifdef CONFIG_NET_ROUTE
|
||||
, NETPROCFS_SUBDIR_ROUTE /* /proc/net/route */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* This structure describes one open "file" */
|
||||
|
||||
struct net_driver_s; /* Forward reference */
|
||||
|
@ -70,6 +87,7 @@ struct netprocfs_file_s
|
|||
uint8_t lineno; /* Line number */
|
||||
uint8_t linesize; /* Number of valid characters in line[] */
|
||||
uint8_t offset; /* Offset to first valid character in line[] */
|
||||
uint8_t entry; /* See enum netprocfs_entry_e */
|
||||
char line[NET_LINELEN]; /* Pre-allocated buffer for formatted lines */
|
||||
};
|
||||
|
||||
|
@ -148,6 +166,29 @@ ssize_t netprocfs_read_netstats(FAR struct netprocfs_file_s *priv,
|
|||
FAR char *buffer, size_t buflen);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netprocfs_read_routes
|
||||
*
|
||||
* Description:
|
||||
* Read and format routing table entries.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the network procfs file structure
|
||||
* buffer - The user-provided buffer into which network status will be
|
||||
* returned.
|
||||
* bulen - The size in bytes of the user provided buffer.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success; a negated errno value is returned
|
||||
* on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_NET_ROUTE
|
||||
ssize_t netprocfs_read_routes(FAR struct netprocfs_file_s *priv,
|
||||
FAR char *buffer, size_t buflen);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: netprocfs_read_devstats
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue