net: conn: Utility to print connection handlers

Add support to print connection handler information in net-shell.
There exists one connection handler for each UDP/TCP port that we
are listening. These prints are only available if CONFIG_NET_DEBUG_CONN
is enabled because the net_context has the same information. Thus the
connection handler info is only printed if debugging is active in order
to verify that handler information is proper.

Change-Id: I0be39a5adb89b2cdbd85524c5d943e4a562b0fde
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2017-04-19 14:07:20 +03:00
commit a71a9f9ad1
3 changed files with 100 additions and 0 deletions

View file

@ -771,6 +771,19 @@ drop:
return NET_DROP;
}
void net_conn_foreach(net_conn_foreach_cb_t cb, void *user_data)
{
int i;
for (i = 0; i < CONFIG_NET_MAX_CONN; i++) {
if (!(conns[i].flags & NET_CONN_IN_USE)) {
continue;
}
cb(&conns[i], user_data);
}
}
void net_conn_init(void)
{
#if defined(CONFIG_NET_CONN_CACHE)

View file

@ -143,6 +143,25 @@ static inline enum net_verdict net_conn_input(enum net_ip_protocol proto,
}
#endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */
/**
* @typedef net_conn_foreach_cb_t
* @brief Callback used while iterating over network connection
* handlers.
*
* @param conn A valid pointer on current network connection handler.
* @param user_data A valid pointer on some user data or NULL
*/
typedef void (*net_conn_foreach_cb_t)(struct net_conn *conn, void *user_data);
/**
* @brief Go through all the network connection handlers and call callback
* for each network connection handler.
*
* @param cb User supplied callback function to call.
* @param user_data User specified data.
*/
void net_conn_foreach(net_conn_foreach_cb_t cb, void *user_data);
void net_conn_init(void);
#ifdef __cplusplus

View file

@ -470,6 +470,61 @@ static void context_cb(struct net_context *context, void *user_data)
(*count)++;
}
#if defined(CONFIG_NET_DEBUG_CONN)
static void conn_handler_cb(struct net_conn *conn, void *user_data)
{
#if defined(CONFIG_NET_IPV6) && !defined(CONFIG_NET_IPV4)
#define ADDR_LEN NET_IPV6_ADDR_LEN
#elif defined(CONFIG_NET_IPV4) && !defined(CONFIG_NET_IPV6)
#define ADDR_LEN NET_IPV4_ADDR_LEN
#else
#define ADDR_LEN NET_IPV6_ADDR_LEN
#endif
int *count = user_data;
/* +7 for []:port */
char addr_local[ADDR_LEN + 7];
char addr_remote[ADDR_LEN + 7] = "";
#if defined(CONFIG_NET_IPV6)
if (conn->local_addr.family == AF_INET6) {
snprintk(addr_local, sizeof(addr_local), "[%s]:%u",
net_sprint_ipv6_addr(
&net_sin6(&conn->local_addr)->sin6_addr),
ntohs(net_sin6(&conn->local_addr)->sin6_port));
snprintk(addr_remote, sizeof(addr_remote), "[%s]:%u",
net_sprint_ipv6_addr(
&net_sin6(&conn->remote_addr)->sin6_addr),
ntohs(net_sin6(&conn->remote_addr)->sin6_port));
} else
#endif
#if defined(CONFIG_NET_IPV4)
if (conn->local_addr.family == AF_INET) {
snprintk(addr_local, sizeof(addr_local), "%s:%d",
net_sprint_ipv4_addr(
&net_sin(&conn->local_addr)->sin_addr),
ntohs(net_sin(&conn->local_addr)->sin_port));
snprintk(addr_remote, sizeof(addr_remote), "%s:%d",
net_sprint_ipv4_addr(
&net_sin(&conn->remote_addr)->sin_addr),
ntohs(net_sin(&conn->remote_addr)->sin_port));
} else
#endif
if (conn->local_addr.family == AF_UNSPEC) {
snprintk(addr_local, sizeof(addr_local), "AF_UNSPEC");
} else {
snprintk(addr_local, sizeof(addr_local), "AF_UNK(%d)",
conn->local_addr.family);
}
printk("[%2d] %p %p\t%s\t%16s\t%16s\n",
(*count) + 1, conn, conn->cb, net_proto2str(conn->proto),
addr_local, addr_remote);
(*count)++;
}
#endif /* CONFIG_NET_DEBUG_CONN */
#if defined(CONFIG_NET_TCP)
static void tcp_cb(struct net_tcp *tcp, void *user_data)
{
@ -596,6 +651,19 @@ static int shell_cmd_conn(int argc, char *argv[])
printk("No connections\n");
}
#if defined(CONFIG_NET_DEBUG_CONN)
printk("\n Handler Callback \tProto\t"
"Local \tRemote\n");
count = 0;
net_conn_foreach(conn_handler_cb, &count);
if (count == 0) {
printk("No connection handlers found.\n");
}
#endif
#if defined(CONFIG_NET_TCP)
printk("\nTCP Src port Dst port Send-Seq Send-Ack MSS "
"State\n");