2005-04-16 15:20:36 -07:00
/*
* X .25 Packet Layer release 002
*
* This is ALPHA test software . This code may break your machine ,
* randomly fail to work with new releases , misbehave and / or generally
2007-02-09 23:25:27 +09:00
* screw up . It might even work .
2005-04-16 15:20:36 -07:00
*
* This code REQUIRES 2.4 with seq_file support
*
* This module :
* This module is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*
* History
* 2002 / 10 / 06 Arnaldo Carvalho de Melo seq_file support
*/
# include <linux/init.h>
# include <linux/proc_fs.h>
# include <linux/seq_file.h>
2011-07-15 11:47:34 -04:00
# include <linux/export.h>
2007-09-12 12:01:34 +02:00
# include <net/net_namespace.h>
2005-04-16 15:20:36 -07:00
# include <net/sock.h>
# include <net/x25.h>
# ifdef CONFIG_PROC_FS
static void * x25_seq_route_start ( struct seq_file * seq , loff_t * pos )
2008-01-13 22:27:52 -08:00
__acquires ( x25_route_list_lock )
2005-04-16 15:20:36 -07:00
{
read_lock_bh ( & x25_route_list_lock ) ;
2010-02-08 23:20:42 +00:00
return seq_list_start_head ( & x25_route_list , * pos ) ;
2005-04-16 15:20:36 -07:00
}
static void * x25_seq_route_next ( struct seq_file * seq , void * v , loff_t * pos )
{
2010-02-08 23:20:42 +00:00
return seq_list_next ( v , & x25_route_list , pos ) ;
2005-04-16 15:20:36 -07:00
}
static void x25_seq_route_stop ( struct seq_file * seq , void * v )
2008-01-13 22:27:52 -08:00
__releases ( x25_route_list_lock )
2005-04-16 15:20:36 -07:00
{
read_unlock_bh ( & x25_route_list_lock ) ;
}
static int x25_seq_route_show ( struct seq_file * seq , void * v )
{
2010-02-08 23:20:42 +00:00
struct x25_route * rt = list_entry ( v , struct x25_route , node ) ;
2005-04-16 15:20:36 -07:00
2010-02-08 23:20:42 +00:00
if ( v = = & x25_route_list ) {
2005-04-16 15:20:36 -07:00
seq_puts ( seq , " Address Digits Device \n " ) ;
goto out ;
}
rt = v ;
seq_printf ( seq , " %-15s %-6d %-5s \n " ,
rt - > address . x25_addr , rt - > sigdigits ,
rt - > dev ? rt - > dev - > name : " ??? " ) ;
out :
return 0 ;
2007-02-09 23:25:27 +09:00
}
2005-04-16 15:20:36 -07:00
static void * x25_seq_socket_start ( struct seq_file * seq , loff_t * pos )
2008-01-13 22:27:52 -08:00
__acquires ( x25_list_lock )
2005-04-16 15:20:36 -07:00
{
read_lock_bh ( & x25_list_lock ) ;
2010-02-08 23:19:04 +00:00
return seq_hlist_start_head ( & x25_list , * pos ) ;
2005-04-16 15:20:36 -07:00
}
static void * x25_seq_socket_next ( struct seq_file * seq , void * v , loff_t * pos )
{
2010-02-08 23:19:04 +00:00
return seq_hlist_next ( v , & x25_list , pos ) ;
2005-04-16 15:20:36 -07:00
}
static void x25_seq_socket_stop ( struct seq_file * seq , void * v )
2008-01-13 22:27:52 -08:00
__releases ( x25_list_lock )
2005-04-16 15:20:36 -07:00
{
read_unlock_bh ( & x25_list_lock ) ;
}
static int x25_seq_socket_show ( struct seq_file * seq , void * v )
{
struct sock * s ;
struct x25_sock * x25 ;
struct net_device * dev ;
const char * devname ;
if ( v = = SEQ_START_TOKEN ) {
seq_printf ( seq , " dest_addr src_addr dev lci st vs vr "
" va t t2 t21 t22 t23 Snd-Q Rcv-Q inode \n " ) ;
goto out ;
}
2010-02-08 23:19:04 +00:00
s = sk_entry ( v ) ;
2005-04-16 15:20:36 -07:00
x25 = x25_sk ( s ) ;
if ( ! x25 - > neighbour | | ( dev = x25 - > neighbour - > dev ) = = NULL )
devname = " ??? " ;
else
devname = x25 - > neighbour - > dev - > name ;
seq_printf ( seq , " %-10s %-10s %-5s %3.3X %d %d %d %d %3lu %3lu "
" %3lu %3lu %3lu %5d %5d %ld \n " ,
! x25 - > dest_addr . x25_addr [ 0 ] ? " * " : x25 - > dest_addr . x25_addr ,
! x25 - > source_addr . x25_addr [ 0 ] ? " * " : x25 - > source_addr . x25_addr ,
devname , x25 - > lci & 0x0FFF , x25 - > state , x25 - > vs , x25 - > vr ,
x25 - > va , x25_display_timer ( s ) / HZ , x25 - > t2 / HZ ,
x25 - > t21 / HZ , x25 - > t22 / HZ , x25 - > t23 / HZ ,
2009-06-17 19:05:41 -07:00
sk_wmem_alloc_get ( s ) ,
sk_rmem_alloc_get ( s ) ,
2005-04-16 15:20:36 -07:00
s - > sk_socket ? SOCK_INODE ( s - > sk_socket ) - > i_ino : 0L ) ;
out :
return 0 ;
2007-02-09 23:25:27 +09:00
}
2005-04-16 15:20:36 -07:00
2007-02-08 13:35:18 -08:00
static void * x25_seq_forward_start ( struct seq_file * seq , loff_t * pos )
2008-01-13 22:27:52 -08:00
__acquires ( x25_forward_list_lock )
2007-02-08 13:35:18 -08:00
{
read_lock_bh ( & x25_forward_list_lock ) ;
2010-02-08 23:20:42 +00:00
return seq_list_start_head ( & x25_forward_list , * pos ) ;
2007-02-08 13:35:18 -08:00
}
static void * x25_seq_forward_next ( struct seq_file * seq , void * v , loff_t * pos )
{
2010-02-08 23:20:42 +00:00
return seq_list_next ( v , & x25_forward_list , pos ) ;
2007-02-08 13:35:18 -08:00
}
static void x25_seq_forward_stop ( struct seq_file * seq , void * v )
2008-01-13 22:27:52 -08:00
__releases ( x25_forward_list_lock )
2007-02-08 13:35:18 -08:00
{
read_unlock_bh ( & x25_forward_list_lock ) ;
}
static int x25_seq_forward_show ( struct seq_file * seq , void * v )
{
2010-02-08 23:20:42 +00:00
struct x25_forward * f = list_entry ( v , struct x25_forward , node ) ;
2007-02-08 13:35:18 -08:00
2010-02-08 23:20:42 +00:00
if ( v = = & x25_forward_list ) {
2007-02-08 13:35:18 -08:00
seq_printf ( seq , " lci dev1 dev2 \n " ) ;
goto out ;
}
f = v ;
seq_printf ( seq , " %d %-10s %-10s \n " ,
f - > lci , f - > dev1 - > name , f - > dev2 - > name ) ;
out :
return 0 ;
}
2007-07-10 23:07:31 -07:00
static const struct seq_operations x25_seq_route_ops = {
2005-04-16 15:20:36 -07:00
. start = x25_seq_route_start ,
. next = x25_seq_route_next ,
. stop = x25_seq_route_stop ,
. show = x25_seq_route_show ,
} ;
2007-07-10 23:07:31 -07:00
static const struct seq_operations x25_seq_socket_ops = {
2005-04-16 15:20:36 -07:00
. start = x25_seq_socket_start ,
. next = x25_seq_socket_next ,
. stop = x25_seq_socket_stop ,
. show = x25_seq_socket_show ,
} ;
2007-07-10 23:07:31 -07:00
static const struct seq_operations x25_seq_forward_ops = {
2007-02-08 13:35:18 -08:00
. start = x25_seq_forward_start ,
. next = x25_seq_forward_next ,
. stop = x25_seq_forward_stop ,
. show = x25_seq_forward_show ,
} ;
2005-04-16 15:20:36 -07:00
static int x25_seq_socket_open ( struct inode * inode , struct file * file )
{
return seq_open ( file , & x25_seq_socket_ops ) ;
}
static int x25_seq_route_open ( struct inode * inode , struct file * file )
{
return seq_open ( file , & x25_seq_route_ops ) ;
}
2007-02-08 13:35:18 -08:00
static int x25_seq_forward_open ( struct inode * inode , struct file * file )
{
return seq_open ( file , & x25_seq_forward_ops ) ;
}
2007-02-12 00:55:36 -08:00
static const struct file_operations x25_seq_socket_fops = {
2005-04-16 15:20:36 -07:00
. open = x25_seq_socket_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
2007-02-12 00:55:36 -08:00
static const struct file_operations x25_seq_route_fops = {
2005-04-16 15:20:36 -07:00
. open = x25_seq_route_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
2008-01-22 18:30:06 -08:00
static const struct file_operations x25_seq_forward_fops = {
2007-02-08 13:35:18 -08:00
. open = x25_seq_forward_open ,
. read = seq_read ,
. llseek = seq_lseek ,
. release = seq_release ,
} ;
2005-04-16 15:20:36 -07:00
int __init x25_proc_init ( void )
{
2013-04-03 00:04:51 -04:00
if ( ! proc_mkdir ( " x25 " , init_net . proc_net ) )
return - ENOMEM ;
2005-04-16 15:20:36 -07:00
2013-04-03 00:04:51 -04:00
if ( ! proc_create ( " x25/route " , S_IRUGO , init_net . proc_net ,
& x25_seq_route_fops ) )
2005-04-16 15:20:36 -07:00
goto out ;
2013-04-03 00:04:51 -04:00
if ( ! proc_create ( " x25/socket " , S_IRUGO , init_net . proc_net ,
& x25_seq_socket_fops ) )
goto out ;
2007-02-08 13:35:18 -08:00
2013-04-03 00:04:51 -04:00
if ( ! proc_create ( " x25/forward " , S_IRUGO , init_net . proc_net ,
& x25_seq_forward_fops ) )
goto out ;
return 0 ;
2007-02-08 13:35:18 -08:00
2005-04-16 15:20:36 -07:00
out :
2013-04-03 00:04:51 -04:00
remove_proc_subtree ( " x25 " , init_net . proc_net ) ;
return - ENOMEM ;
2005-04-16 15:20:36 -07:00
}
void __exit x25_proc_exit ( void )
{
2013-04-03 00:04:51 -04:00
remove_proc_subtree ( " x25 " , init_net . proc_net ) ;
2005-04-16 15:20:36 -07:00
}
# else /* CONFIG_PROC_FS */
int __init x25_proc_init ( void )
{
return 0 ;
}
void __exit x25_proc_exit ( void )
{
}
# endif /* CONFIG_PROC_FS */