/*
 * 	atalk_proc.c - proc support for Appletalk
 *
 * 	Copyright(c) Arnaldo Carvalho de Melo <acme@conectiva.com.br>
 *
 *	This program 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, version 2.
 */

#include <linux/config.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/sock.h>
#include <linux/atalk.h>


static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos)
{
	struct atalk_iface *i;

	for (i = atalk_interfaces; pos && i; i = i->next)
		--pos;

	return i;
}

static void *atalk_seq_interface_start(struct seq_file *seq, loff_t *pos)
{
	loff_t l = *pos;

	read_lock_bh(&atalk_interfaces_lock);
	return l ? atalk_get_interface_idx(--l) : SEQ_START_TOKEN;
}

static void *atalk_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct atalk_iface *i;

	++*pos;
	if (v == SEQ_START_TOKEN) {
		i = NULL;
		if (atalk_interfaces)
			i = atalk_interfaces;
		goto out;
	}
	i = v;
	i = i->next;
out:
	return i;
}

static void atalk_seq_interface_stop(struct seq_file *seq, void *v)
{
	read_unlock_bh(&atalk_interfaces_lock);
}

static int atalk_seq_interface_show(struct seq_file *seq, void *v)
{
	struct atalk_iface *iface;

	if (v == SEQ_START_TOKEN) {
		seq_puts(seq, "Interface        Address   Networks  "
			      "Status\n");
		goto out;
	}

	iface = v;
	seq_printf(seq, "%-16s %04X:%02X  %04X-%04X  %d\n",
		   iface->dev->name, ntohs(iface->address.s_net),
		   iface->address.s_node, ntohs(iface->nets.nr_firstnet),
		   ntohs(iface->nets.nr_lastnet), iface->status);
out:
	return 0;
}

static __inline__ struct atalk_route *atalk_get_route_idx(loff_t pos)
{
	struct atalk_route *r;

	for (r = atalk_routes; pos && r; r = r->next)
		--pos;

	return r;
}

static void *atalk_seq_route_start(struct seq_file *seq, loff_t *pos)
{
	loff_t l = *pos;

	read_lock_bh(&atalk_routes_lock);
	return l ? atalk_get_route_idx(--l) : SEQ_START_TOKEN;
}

static void *atalk_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct atalk_route *r;

	++*pos;
	if (v == SEQ_START_TOKEN) {
		r = NULL;
		if (atalk_routes)
			r = atalk_routes;
		goto out;
	}
	r = v;
	r = r->next;
out:
	return r;
}

static void atalk_seq_route_stop(struct seq_file *seq, void *v)
{
	read_unlock_bh(&atalk_routes_lock);
}

static int atalk_seq_route_show(struct seq_file *seq, void *v)
{
	struct atalk_route *rt;

	if (v == SEQ_START_TOKEN) {
		seq_puts(seq, "Target        Router  Flags Dev\n");
		goto out;
	}

	if (atrtr_default.dev) {
		rt = &atrtr_default;
		seq_printf(seq, "Default     %04X:%02X  %-4d  %s\n",
			       ntohs(rt->gateway.s_net), rt->gateway.s_node,
			       rt->flags, rt->dev->name);
	}

	rt = v;
	seq_printf(seq, "%04X:%02X     %04X:%02X  %-4d  %s\n",
		   ntohs(rt->target.s_net), rt->target.s_node,
		   ntohs(rt->gateway.s_net), rt->gateway.s_node,
		   rt->flags, rt->dev->name);
out:
	return 0;
}

static __inline__ struct sock *atalk_get_socket_idx(loff_t pos)
{
	struct sock *s;
	struct hlist_node *node;

	sk_for_each(s, node, &atalk_sockets)
		if (!pos--)
			goto found;
	s = NULL;
found:
	return s;
}

static void *atalk_seq_socket_start(struct seq_file *seq, loff_t *pos)
{
	loff_t l = *pos;

	read_lock_bh(&atalk_sockets_lock);
	return l ? atalk_get_socket_idx(--l) : SEQ_START_TOKEN;
}

static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct sock *i;

	++*pos;
	if (v == SEQ_START_TOKEN) {
		i = sk_head(&atalk_sockets);
		goto out;
	}
	i = sk_next(v);
out:
	return i;
}

static void atalk_seq_socket_stop(struct seq_file *seq, void *v)
{
	read_unlock_bh(&atalk_sockets_lock);
}

static int atalk_seq_socket_show(struct seq_file *seq, void *v)
{
	struct sock *s;
	struct atalk_sock *at;

	if (v == SEQ_START_TOKEN) {
		seq_printf(seq, "Type Local_addr  Remote_addr Tx_queue "
				"Rx_queue St UID\n");
		goto out;
	}

	s = v;
	at = at_sk(s);

	seq_printf(seq, "%02X   %04X:%02X:%02X  %04X:%02X:%02X  %08X:%08X "
			"%02X %d\n",
		   s->sk_type, ntohs(at->src_net), at->src_node, at->src_port,
		   ntohs(at->dest_net), at->dest_node, at->dest_port,
		   atomic_read(&s->sk_wmem_alloc),
		   atomic_read(&s->sk_rmem_alloc),
		   s->sk_state, SOCK_INODE(s->sk_socket)->i_uid);
out:
	return 0;
}

static struct seq_operations atalk_seq_interface_ops = {
	.start  = atalk_seq_interface_start,
	.next   = atalk_seq_interface_next,
	.stop   = atalk_seq_interface_stop,
	.show   = atalk_seq_interface_show,
};

static struct seq_operations atalk_seq_route_ops = {
	.start  = atalk_seq_route_start,
	.next   = atalk_seq_route_next,
	.stop   = atalk_seq_route_stop,
	.show   = atalk_seq_route_show,
};

static struct seq_operations atalk_seq_socket_ops = {
	.start  = atalk_seq_socket_start,
	.next   = atalk_seq_socket_next,
	.stop   = atalk_seq_socket_stop,
	.show   = atalk_seq_socket_show,
};

static int atalk_seq_interface_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &atalk_seq_interface_ops);
}

static int atalk_seq_route_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &atalk_seq_route_ops);
}

static int atalk_seq_socket_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &atalk_seq_socket_ops);
}

static struct file_operations atalk_seq_interface_fops = {
	.owner		= THIS_MODULE,
	.open		= atalk_seq_interface_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

static struct file_operations atalk_seq_route_fops = {
	.owner		= THIS_MODULE,
	.open		= atalk_seq_route_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

static struct file_operations atalk_seq_socket_fops = {
	.owner		= THIS_MODULE,
	.open		= atalk_seq_socket_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};

static struct proc_dir_entry *atalk_proc_dir;

int __init atalk_proc_init(void)
{
	struct proc_dir_entry *p;
	int rc = -ENOMEM;

	atalk_proc_dir = proc_mkdir("atalk", proc_net);
	if (!atalk_proc_dir)
		goto out;
	atalk_proc_dir->owner = THIS_MODULE;

	p = create_proc_entry("interface", S_IRUGO, atalk_proc_dir);
	if (!p)
		goto out_interface;
	p->proc_fops = &atalk_seq_interface_fops;

	p = create_proc_entry("route", S_IRUGO, atalk_proc_dir);
	if (!p)
		goto out_route;
	p->proc_fops = &atalk_seq_route_fops;

	p = create_proc_entry("socket", S_IRUGO, atalk_proc_dir);
	if (!p)
		goto out_socket;
	p->proc_fops = &atalk_seq_socket_fops;

	p = create_proc_entry("arp", S_IRUGO, atalk_proc_dir);
	if (!p) 
		goto out_arp;
	p->proc_fops = &atalk_seq_arp_fops;

	rc = 0;
out:
	return rc;
out_arp:
	remove_proc_entry("socket", atalk_proc_dir);
out_socket:
	remove_proc_entry("route", atalk_proc_dir);
out_route:
	remove_proc_entry("interface", atalk_proc_dir);
out_interface:
	remove_proc_entry("atalk", proc_net);
	goto out;
}

void __exit atalk_proc_exit(void)
{
	remove_proc_entry("interface", atalk_proc_dir);
	remove_proc_entry("route", atalk_proc_dir);
	remove_proc_entry("socket", atalk_proc_dir);
	remove_proc_entry("arp", atalk_proc_dir);
	remove_proc_entry("atalk", proc_net);
}
