tcp_diag.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:15k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * tcp_diag.c Module for monitoring TCP sockets.
  3.  *
  4.  * Version: $Id: tcp_diag.c,v 1.2 2001/11/05 09:42:22 davem Exp $
  5.  *
  6.  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  *      modify it under the terms of the GNU General Public License
  10.  *      as published by the Free Software Foundation; either version
  11.  *      2 of the License, or (at your option) any later version.
  12.  */
  13. #include <linux/config.h>
  14. #include <linux/module.h>
  15. #include <linux/types.h>
  16. #include <linux/fcntl.h>
  17. #include <linux/random.h>
  18. #include <linux/cache.h>
  19. #include <linux/init.h>
  20. #include <net/icmp.h>
  21. #include <net/tcp.h>
  22. #include <net/ipv6.h>
  23. #include <net/inet_common.h>
  24. #include <linux/inet.h>
  25. #include <linux/stddef.h>
  26. #include <linux/tcp_diag.h>
  27. static struct sock *tcpnl;
  28. #define TCPDIAG_PUT(skb, attrtype, attrlen) 
  29. ({ int rtalen = RTA_LENGTH(attrlen);        
  30.    struct rtattr *rta;                      
  31.    if (skb_tailroom(skb) < RTA_ALIGN(rtalen)) goto nlmsg_failure; 
  32.    rta = (void*)__skb_put(skb, RTA_ALIGN(rtalen)); 
  33.    rta->rta_type = attrtype;                
  34.    rta->rta_len = rtalen;                   
  35.    RTA_DATA(rta); })
  36. static int tcpdiag_fill(struct sk_buff *skb, struct sock *sk,
  37. int ext, u32 pid, u32 seq)
  38. {
  39. struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
  40. struct tcpdiagmsg *r;
  41. struct nlmsghdr  *nlh;
  42. struct tcp_info  *info = NULL;
  43. struct tcpdiag_meminfo  *minfo = NULL;
  44. unsigned char  *b = skb->tail;
  45. nlh = NLMSG_PUT(skb, pid, seq, TCPDIAG_GETSOCK, sizeof(*r));
  46. r = NLMSG_DATA(nlh);
  47. if (sk->state != TCP_TIME_WAIT) {
  48. if (ext & (1<<(TCPDIAG_MEMINFO-1)))
  49. minfo = TCPDIAG_PUT(skb, TCPDIAG_MEMINFO, sizeof(*minfo));
  50. if (ext & (1<<(TCPDIAG_INFO-1)))
  51. info = TCPDIAG_PUT(skb, TCPDIAG_INFO, sizeof(*info));
  52. }
  53. r->tcpdiag_family = sk->family;
  54. r->tcpdiag_state = sk->state;
  55. r->tcpdiag_timer = 0;
  56. r->tcpdiag_retrans = 0;
  57. r->id.tcpdiag_sport = sk->sport;
  58. r->id.tcpdiag_dport = sk->dport;
  59. r->id.tcpdiag_src[0] = sk->rcv_saddr;
  60. r->id.tcpdiag_dst[0] = sk->daddr;
  61. r->id.tcpdiag_if = sk->bound_dev_if;
  62. *((struct sock **)&r->id.tcpdiag_cookie) = sk;
  63. if (r->tcpdiag_state == TCP_TIME_WAIT) {
  64. struct tcp_tw_bucket *tw = (struct tcp_tw_bucket*)sk;
  65. long tmo = tw->ttd - jiffies;
  66. if (tmo < 0)
  67. tmo = 0;
  68. r->tcpdiag_state = tw->substate;
  69. r->tcpdiag_timer = 3;
  70. r->tcpdiag_expires = (tmo*1000+HZ-1)/HZ;
  71. r->tcpdiag_rqueue = 0;
  72. r->tcpdiag_wqueue = 0;
  73. r->tcpdiag_uid = 0;
  74. r->tcpdiag_inode = 0;
  75. #ifdef CONFIG_IPV6
  76. if (r->tcpdiag_family == AF_INET6) {
  77. memcpy(r->id.tcpdiag_src, &tw->v6_rcv_saddr, 16);
  78. memcpy(r->id.tcpdiag_dst, &tw->v6_daddr, 16);
  79. }
  80. #endif
  81. nlh->nlmsg_len = skb->tail - b;
  82. return skb->len;
  83. }
  84. #ifdef CONFIG_IPV6
  85. if (r->tcpdiag_family == AF_INET6) {
  86. memcpy(r->id.tcpdiag_src, &sk->net_pinfo.af_inet6.rcv_saddr, 16);
  87. memcpy(r->id.tcpdiag_dst, &sk->net_pinfo.af_inet6.daddr, 16);
  88. }
  89. #endif
  90. #define EXPIRES_IN_MS(tmo)  ((tmo-jiffies)*1000+HZ-1)/HZ
  91. if (tp->pending == TCP_TIME_RETRANS) {
  92. r->tcpdiag_timer = 1;
  93. r->tcpdiag_retrans = tp->retransmits;
  94. r->tcpdiag_expires = EXPIRES_IN_MS(tp->timeout);
  95. } else if (tp->pending == TCP_TIME_PROBE0) {
  96. r->tcpdiag_timer = 4;
  97. r->tcpdiag_retrans = tp->probes_out;
  98. r->tcpdiag_expires = EXPIRES_IN_MS(tp->timeout);
  99. } else if (timer_pending(&sk->timer)) {
  100. r->tcpdiag_timer = 2;
  101. r->tcpdiag_retrans = tp->probes_out;
  102. r->tcpdiag_expires = EXPIRES_IN_MS(sk->timer.expires);
  103. } else {
  104. r->tcpdiag_timer = 0;
  105. r->tcpdiag_expires = 0;
  106. }
  107. #undef EXPIRES_IN_MS
  108. r->tcpdiag_rqueue = tp->rcv_nxt - tp->copied_seq;
  109. r->tcpdiag_wqueue = tp->write_seq - tp->snd_una;
  110. r->tcpdiag_uid = sock_i_uid(sk);
  111. r->tcpdiag_inode = sock_i_ino(sk);
  112. if (minfo) {
  113. minfo->tcpdiag_rmem = atomic_read(&sk->rmem_alloc);
  114. minfo->tcpdiag_wmem = sk->wmem_queued;
  115. minfo->tcpdiag_fmem = sk->forward_alloc;
  116. minfo->tcpdiag_tmem = atomic_read(&sk->wmem_alloc);
  117. }
  118. if (info) {
  119. u32 now = tcp_time_stamp;
  120. info->tcpi_state = sk->state;
  121. info->tcpi_ca_state = tp->ca_state;
  122. info->tcpi_retransmits = tp->retransmits;
  123. info->tcpi_probes = tp->probes_out;
  124. info->tcpi_backoff = tp->backoff;
  125. info->tcpi_options = 0;
  126. if (tp->tstamp_ok)
  127. info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
  128. if (tp->sack_ok)
  129. info->tcpi_options |= TCPI_OPT_SACK;
  130. if (tp->wscale_ok) {
  131. info->tcpi_options |= TCPI_OPT_WSCALE;
  132. info->tcpi_snd_wscale = tp->snd_wscale;
  133. info->tcpi_rcv_wscale = tp->rcv_wscale;
  134. } else {
  135. info->tcpi_snd_wscale = 0;
  136. info->tcpi_rcv_wscale = 0;
  137. }
  138. #ifdef CONFIG_INET_ECN
  139. if (tp->ecn_flags&TCP_ECN_OK)
  140. info->tcpi_options |= TCPI_OPT_ECN;
  141. #endif
  142. info->tcpi_rto = (1000000*tp->rto)/HZ;
  143. info->tcpi_ato = (1000000*tp->ack.ato)/HZ;
  144. info->tcpi_snd_mss = tp->mss_cache;
  145. info->tcpi_rcv_mss = tp->ack.rcv_mss;
  146. info->tcpi_unacked = tp->packets_out;
  147. info->tcpi_sacked = tp->sacked_out;
  148. info->tcpi_lost = tp->lost_out;
  149. info->tcpi_retrans = tp->retrans_out;
  150. info->tcpi_fackets = tp->fackets_out;
  151. info->tcpi_last_data_sent = ((now - tp->lsndtime)*1000)/HZ;
  152. info->tcpi_last_ack_sent = 0;
  153. info->tcpi_last_data_recv = ((now - tp->ack.lrcvtime)*1000)/HZ;
  154. info->tcpi_last_ack_recv = ((now - tp->rcv_tstamp)*1000)/HZ;
  155. info->tcpi_pmtu = tp->pmtu_cookie;
  156. info->tcpi_rcv_ssthresh = tp->rcv_ssthresh;
  157. info->tcpi_rtt = ((1000000*tp->srtt)/HZ)>>3;
  158. info->tcpi_rttvar = ((1000000*tp->mdev)/HZ)>>2;
  159. info->tcpi_snd_ssthresh = tp->snd_ssthresh;
  160. info->tcpi_snd_cwnd = tp->snd_cwnd;
  161. info->tcpi_advmss = tp->advmss;
  162. info->tcpi_reordering = tp->reordering;
  163. }
  164. nlh->nlmsg_len = skb->tail - b;
  165. return skb->len;
  166. nlmsg_failure:
  167. skb_trim(skb, b - skb->data);
  168. return -1;
  169. }
  170. extern struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
  171. #ifdef CONFIG_IPV6
  172. extern struct sock *tcp_v6_lookup(struct in6_addr *saddr, u16 sport,
  173.   struct in6_addr *daddr, u16 dport,
  174.   int dif);
  175. #endif
  176. static int tcpdiag_get_exact(struct sk_buff *in_skb, struct nlmsghdr *nlh)
  177. {
  178. int err;
  179. struct sock *sk;
  180. struct tcpdiagreq *req = NLMSG_DATA(nlh);
  181. struct sk_buff *rep;
  182. if (req->tcpdiag_family == AF_INET) {
  183. sk = tcp_v4_lookup(req->id.tcpdiag_dst[0], req->id.tcpdiag_dport,
  184.    req->id.tcpdiag_src[0], req->id.tcpdiag_sport,
  185.    req->id.tcpdiag_if);
  186. }
  187. #ifdef CONFIG_IPV6
  188. else if (req->tcpdiag_family == AF_INET6) {
  189. sk = tcp_v6_lookup((struct in6_addr*)req->id.tcpdiag_dst, req->id.tcpdiag_dport,
  190.    (struct in6_addr*)req->id.tcpdiag_src, req->id.tcpdiag_sport,
  191.    req->id.tcpdiag_if);
  192. }
  193. #endif
  194. else {
  195. return -EINVAL;
  196. }
  197. if (sk == NULL)
  198. return -ENOENT;
  199. err = -ESTALE;
  200. if ((req->id.tcpdiag_cookie[0] != TCPDIAG_NOCOOKIE ||
  201.      req->id.tcpdiag_cookie[1] != TCPDIAG_NOCOOKIE) &&
  202.     sk != *((struct sock **)&req->id.tcpdiag_cookie[0]))
  203. goto out;
  204. err = -ENOMEM;
  205. rep = alloc_skb(NLMSG_SPACE(sizeof(struct tcpdiagmsg)+
  206.     sizeof(struct tcpdiag_meminfo)+
  207.     sizeof(struct tcp_info)+64), GFP_KERNEL);
  208. if (!rep)
  209. goto out;
  210. if (tcpdiag_fill(rep, sk, req->tcpdiag_ext,
  211.  NETLINK_CB(in_skb).pid,
  212.  nlh->nlmsg_seq) <= 0)
  213. BUG();
  214. err = netlink_unicast(tcpnl, rep, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
  215. if (err > 0)
  216. err = 0;
  217. out:
  218. if (sk) {
  219. if (sk->state == TCP_TIME_WAIT)
  220. tcp_tw_put((struct tcp_tw_bucket*)sk);
  221. else
  222. sock_put(sk);
  223. }
  224. return err;
  225. }
  226. int bitstring_match(u32 *a1, u32 *a2, int bits)
  227. {
  228. int words = bits >> 5;
  229. bits &= 0x1f;
  230. if (words) {
  231. if (memcmp(a1, a2, words << 2))
  232. return 0;
  233. }
  234. if (bits) {
  235. __u32 w1, w2;
  236. __u32 mask;
  237. w1 = a1[words];
  238. w2 = a2[words];
  239. mask = htonl((0xffffffff) << (32 - bits));
  240. if ((w1 ^ w2) & mask)
  241. return 0;
  242. }
  243. return 1;
  244. }
  245. int tcpdiag_bc_run(char *bc, int len, struct sock *sk)
  246. {
  247. while (len > 0) {
  248. int yes = 1;
  249. struct tcpdiag_bc_op *op = (struct tcpdiag_bc_op*)bc;
  250. switch (op->code) {
  251. case TCPDIAG_BC_NOP:
  252. break;
  253. case TCPDIAG_BC_JMP:
  254. yes = 0;
  255. break;
  256. case TCPDIAG_BC_S_GE:
  257. yes = (sk->num >= op[1].no);
  258. break;
  259. case TCPDIAG_BC_S_LE:
  260. yes = (sk->num <= op[1].no);
  261. break;
  262. case TCPDIAG_BC_D_GE:
  263. yes = (ntohs(sk->dport) >= op[1].no);
  264. break;
  265. case TCPDIAG_BC_D_LE:
  266. yes = (ntohs(sk->dport) <= op[1].no);
  267. break;
  268. case TCPDIAG_BC_AUTO:
  269. yes = !(sk->userlocks&SOCK_BINDPORT_LOCK);
  270. break;
  271. case TCPDIAG_BC_S_COND:
  272. case TCPDIAG_BC_D_COND:
  273. {
  274. struct tcpdiag_hostcond *cond = (struct tcpdiag_hostcond*)(op+1);
  275. u32 *addr;
  276. if (cond->port != -1 &&
  277.     cond->port != (op->code == TCPDIAG_BC_S_COND ? sk->num : ntohs(sk->dport))) {
  278. yes = 0;
  279. break;
  280. }
  281. if (cond->prefix_len == 0)
  282. break;
  283. #ifdef CONFIG_IPV6
  284. if (sk->family == AF_INET6) {
  285. if (op->code == TCPDIAG_BC_S_COND)
  286. addr = (u32*)&sk->net_pinfo.af_inet6.rcv_saddr;
  287. else
  288. addr = (u32*)&sk->net_pinfo.af_inet6.daddr;
  289. } else
  290. #endif
  291. {
  292. if (op->code == TCPDIAG_BC_S_COND)
  293. addr = &sk->rcv_saddr;
  294. else
  295. addr = &sk->daddr;
  296. }
  297. if (bitstring_match(addr, cond->addr, cond->prefix_len))
  298. break;
  299. if (sk->family == AF_INET6 && cond->family == AF_INET) {
  300. if (addr[0] == 0 && addr[1] == 0 &&
  301.     addr[2] == __constant_htonl(0xffff) &&
  302.     bitstring_match(addr+3, cond->addr, cond->prefix_len))
  303. break;
  304. }
  305. yes = 0;
  306. break;
  307. }
  308. }
  309. if (yes) { 
  310. len -= op->yes;
  311. bc += op->yes;
  312. } else {
  313. len -= op->no;
  314. bc += op->no;
  315. }
  316. }
  317. return (len == 0);
  318. }
  319. int valid_cc(char *bc, int len, int cc)
  320. {
  321. while (len >= 0) {
  322. struct tcpdiag_bc_op *op = (struct tcpdiag_bc_op*)bc;
  323. if (cc > len)
  324. return 0;
  325. if (cc == len)
  326. return 1;
  327. if (op->yes < 4)
  328. return 0;
  329. len -= op->yes;
  330. bc  += op->yes;
  331. }
  332. return 0;
  333. }
  334. int tcpdiag_bc_audit(char *bytecode, int bytecode_len)
  335. {
  336. char *bc = bytecode;
  337. int  len = bytecode_len;
  338. while (len > 0) {
  339. struct tcpdiag_bc_op *op = (struct tcpdiag_bc_op*)bc;
  340. //printk("BC: %d %d %d {%d} / %dn", op->code, op->yes, op->no, op[1].no, len);
  341. switch (op->code) {
  342. case TCPDIAG_BC_AUTO:
  343. case TCPDIAG_BC_S_COND:
  344. case TCPDIAG_BC_D_COND:
  345. case TCPDIAG_BC_S_GE:
  346. case TCPDIAG_BC_S_LE:
  347. case TCPDIAG_BC_D_GE:
  348. case TCPDIAG_BC_D_LE:
  349. if (op->yes < 4 || op->yes > len+4)
  350. return -EINVAL;
  351. case TCPDIAG_BC_JMP:
  352. if (op->no < 4 || op->no > len+4)
  353. return -EINVAL;
  354. if (op->no < len &&
  355.     !valid_cc(bytecode, bytecode_len, len-op->no))
  356. return -EINVAL;
  357. break;
  358. case TCPDIAG_BC_NOP:
  359. if (op->yes < 4 || op->yes > len+4)
  360. return -EINVAL;
  361. break;
  362. default:
  363. return -EINVAL;
  364. }
  365. bc += op->yes;
  366. len -= op->yes;
  367. }
  368. return len == 0 ? 0 : -EINVAL;
  369. }
  370. int tcpdiag_dump(struct sk_buff *skb, struct netlink_callback *cb)
  371. {
  372. int i, num;
  373. int s_i, s_num;
  374. struct tcpdiagreq *r = NLMSG_DATA(cb->nlh);
  375. struct rtattr *bc = NULL;
  376. if (cb->nlh->nlmsg_len > 4+NLMSG_SPACE(sizeof(struct tcpdiagreq)))
  377. bc = (struct rtattr*)(r+1);
  378. s_i = cb->args[1];
  379. s_num = num = cb->args[2];
  380. if (cb->args[0] == 0) {
  381. if (!(r->tcpdiag_states&(TCPF_LISTEN|TCPF_SYN_RECV)))
  382. goto skip_listen_ht;
  383. tcp_listen_lock();
  384. for (i = s_i; i < TCP_LHTABLE_SIZE; i++) {
  385. struct sock *sk = tcp_listening_hash[i];
  386. if (i > s_i)
  387. s_num = 0;
  388. for (sk = tcp_listening_hash[i], num = 0;
  389.      sk != NULL;
  390.      sk = sk->next, num++) {
  391. if (num < s_num)
  392. continue;
  393. if (!(r->tcpdiag_states&TCPF_LISTEN) ||
  394.     r->id.tcpdiag_dport)
  395. continue;
  396. if (r->id.tcpdiag_sport != sk->sport && r->id.tcpdiag_sport)
  397. continue;
  398. if (bc && !tcpdiag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), sk))
  399. continue;
  400. if (tcpdiag_fill(skb, sk, r->tcpdiag_ext,
  401.  NETLINK_CB(cb->skb).pid,
  402.  cb->nlh->nlmsg_seq) <= 0) {
  403. tcp_listen_unlock();
  404. goto done;
  405. }
  406. }
  407. }
  408. tcp_listen_unlock();
  409. skip_listen_ht:
  410. cb->args[0] = 1;
  411. s_i = num = s_num = 0;
  412. }
  413. if (!(r->tcpdiag_states&~(TCPF_LISTEN|TCPF_SYN_RECV)))
  414. return skb->len;
  415. for (i = s_i; i < tcp_ehash_size; i++) {
  416. struct tcp_ehash_bucket *head = &tcp_ehash[i];
  417. struct sock *sk;
  418. if (i > s_i)
  419. s_num = 0;
  420. read_lock_bh(&head->lock);
  421. for (sk = head->chain, num = 0;
  422.      sk != NULL;
  423.      sk = sk->next, num++) {
  424. if (num < s_num)
  425. continue;
  426. if (!(r->tcpdiag_states&(1<<sk->state)))
  427. continue;
  428. if (r->id.tcpdiag_sport != sk->sport && r->id.tcpdiag_sport)
  429. continue;
  430. if (r->id.tcpdiag_dport != sk->dport && r->id.tcpdiag_dport)
  431. continue;
  432. if (bc && !tcpdiag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), sk))
  433. continue;
  434. if (tcpdiag_fill(skb, sk, r->tcpdiag_ext,
  435.  NETLINK_CB(cb->skb).pid,
  436.  cb->nlh->nlmsg_seq) <= 0) {
  437. read_unlock_bh(&head->lock);
  438. goto done;
  439. }
  440. }
  441. if (r->tcpdiag_states&TCPF_TIME_WAIT) {
  442. for (sk = tcp_ehash[i+tcp_ehash_size].chain;
  443.      sk != NULL;
  444.      sk = sk->next, num++) {
  445. if (num < s_num)
  446. continue;
  447. if (!(r->tcpdiag_states&(1<<sk->zapped)))
  448. continue;
  449. if (r->id.tcpdiag_sport != sk->sport && r->id.tcpdiag_sport)
  450. continue;
  451. if (r->id.tcpdiag_dport != sk->dport && r->id.tcpdiag_dport)
  452. continue;
  453. if (bc && !tcpdiag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), sk))
  454. continue;
  455. if (tcpdiag_fill(skb, sk, r->tcpdiag_ext,
  456.  NETLINK_CB(cb->skb).pid,
  457.  cb->nlh->nlmsg_seq) <= 0) {
  458. read_unlock_bh(&head->lock);
  459. goto done;
  460. }
  461. }
  462. }
  463. read_unlock_bh(&head->lock);
  464. }
  465. done:
  466. cb->args[1] = i;
  467. cb->args[2] = num;
  468. return skb->len;
  469. }
  470. static int tcpdiag_dump_done(struct netlink_callback *cb)
  471. {
  472. return 0;
  473. }
  474. static __inline__ int
  475. tcpdiag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
  476. {
  477. if (!(nlh->nlmsg_flags&NLM_F_REQUEST))
  478. return 0;
  479. if (nlh->nlmsg_type != TCPDIAG_GETSOCK)
  480. goto err_inval;
  481. if (NLMSG_LENGTH(sizeof(struct tcpdiagreq)) > skb->len)
  482. goto err_inval;
  483. if (nlh->nlmsg_flags&NLM_F_DUMP) {
  484. if (nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(struct tcpdiagreq))) {
  485. struct rtattr *rta = (struct rtattr*)(NLMSG_DATA(nlh) + sizeof(struct tcpdiagreq));
  486. if (rta->rta_type != TCPDIAG_REQ_BYTECODE ||
  487.     rta->rta_len < 8 ||
  488.     rta->rta_len > nlh->nlmsg_len - NLMSG_SPACE(sizeof(struct tcpdiagreq)))
  489. goto err_inval;
  490. if (tcpdiag_bc_audit(RTA_DATA(rta), RTA_PAYLOAD(rta)))
  491. goto err_inval;
  492. }
  493. return netlink_dump_start(tcpnl, skb, nlh,
  494.   tcpdiag_dump,
  495.   tcpdiag_dump_done);
  496. } else {
  497. return tcpdiag_get_exact(skb, nlh);
  498. }
  499. err_inval:
  500. return -EINVAL;
  501. }
  502. extern __inline__ void tcpdiag_rcv_skb(struct sk_buff *skb)
  503. {
  504. int err;
  505. struct nlmsghdr * nlh;
  506. if (skb->len >= NLMSG_SPACE(0)) {
  507. nlh = (struct nlmsghdr *)skb->data;
  508. if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
  509. return;
  510. err = tcpdiag_rcv_msg(skb, nlh);
  511. if (err) 
  512. netlink_ack(skb, nlh, err);
  513. }
  514. }
  515. static void tcpdiag_rcv(struct sock *sk, int len)
  516. {
  517. struct sk_buff *skb;
  518. while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
  519. tcpdiag_rcv_skb(skb);
  520. kfree_skb(skb);
  521. }
  522. }
  523. void __init tcpdiag_init(void)
  524. {
  525. tcpnl = netlink_kernel_create(NETLINK_TCPDIAG, tcpdiag_rcv);
  526. if (tcpnl == NULL)
  527. panic("tcpdiag_init: Cannot create netlink socket.");
  528. }