打印系统中所有状态的tcp

实现将系统中所有状态的tcp打印出来,代码如下:

char* GetConnState(unsigned char state)
{
	char* p = "";
	switch (state)
	{
		case TCP_ESTABLISHED:
			p = "TCP_ESTABLISHED";
		break;
		case TCP_LISTEN:
			p = "TCP_LISTEN";
		break;
		case TCP_SYN_SENT:
			p = "TCP_SYN_SENT";
		break;
		case TCP_CLOSE:
			p = "TCP_CLOSE";
		break;
		case TCP_SYN_RECV:
			p = "TCP_SYN_RECV";
		break;
		case TCP_LAST_ACK:
			p = "TCP_LAST_ACK";
		break;
		case TCP_CLOSING:
			p = "TCP_CLOSING";
		break;
		case TCP_NEW_SYN_RECV:
			p = "TCP_NEW_SYN_RECV";
		break;
		case TCP_TIME_WAIT:
			p = "TCP_TIME_WAIT";
		break;
	}

	return p;
}

static int hello_open(struct inode* inode, struct file*filep)
{
	struct task_struct *tsk = current;

	struct inet_bind_hashbucket *head;
	int i;
	struct inet_bind_bucket *tb;
	struct sock* sk;

	// 获取hinfo方法1
	//struct inet_hashinfo *hinfo = tcp_prot.h.hashinfo;

	// 获取hinfo方法2
	struct net *net = tsk->nsproxy->net_ns;
	struct inet_timewait_death_row *tcp_death_row = &net->ipv4.tcp_death_row;
	struct inet_hashinfo *hinfo = tcp_death_row->hashinfo;

	// 获取hinfo方法3,如果函数有struct sock类型的入参时,可使用此方法。
	// sk->sk_prot实际为tcp_prot
	//struct inet_hashinfo *hinfo = sk->sk_prot->h.hashinfo;

	// 32768
	printk("inet_hashinfo.bhash_size = %d\n", hinfo->bhash_size);

	// 获取head方法1,判断本地某个端口是否被占用时可使用此方法
	//head = &hinfo->bhash[inet_bhashfn(net, port,
	//	hinfo->bhash_size)];

	for (i = 0; i < hinfo->bhash_size; ++i)
	{
		// 获取head方法2,因为要获取所有的tcp,所以用此方法
		head = &hinfo->bhash[i];

		spin_lock_bh(&head->lock);
		inet_bind_bucket_for_each(tb, &head->chain) {

			printk("port = %d\n", tb->port);

			sk_for_each_bound(sk, &tb->owners) {
				printk("saddr = %x\n", sk->sk_rcv_saddr);
				printk("daddr = %x\n", sk->sk_daddr);
				printk("sk_dport = %d\n", ntohs(sk->sk_dport)); // 转为主机序
				// 状态
				printk("sk_state = %s\n", GetConnState(sk->sk_state));
			}
			printk("\n");
		}

		spin_unlock_bh(&head->lock);

	}

	return 0;
}

// 用netstat查看的网络连接

tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 关闭 (0.00/0/0)

tcp 0 0 192.168.0.106:22 192.168.0.109:55859 ESTABLISHED 保持连接 (6040.63/0/0)

tcp6 0 0 :::22 :::* LISTEN 关闭 (0.00/0/0)

// 内核打印的日志

[14221.754364] inet_hashinfo.bhash_size = 32768

[14221.754531] port = 22

[14221.754532] saddr = 6a00a8c0

[14221.754533] daddr = 6d00a8c0

[14221.754533] sk_dport = 55859

[14221.754534] sk_state = TCP_ESTABLISHED

[14221.754535] saddr = 0

[14221.754535] daddr = 0

[14221.754536] sk_dport = 0

[14221.754537] sk_state = TCP_LISTEN

[14221.754537] saddr = 0

[14221.754538] daddr = 0

[14221.754538] sk_dport = 0

[14221.754539] sk_state = TCP_LISTEN

弄懂了上面的代码,可有助于理解内核中新建tcp连接时,获取本地端口部分的逻辑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值