diff options
-rw-r--r-- | include/linux/inet_diag.h | 2 | ||||
-rw-r--r-- | net/ipv4/inet_diag.c | 55 |
2 files changed, 33 insertions, 24 deletions
diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h index 503674738368..907c899bd41b 100644 --- a/include/linux/inet_diag.h +++ b/include/linux/inet_diag.h | |||
@@ -135,6 +135,7 @@ struct tcpvegas_info { | |||
135 | #ifdef __KERNEL__ | 135 | #ifdef __KERNEL__ |
136 | struct sock; | 136 | struct sock; |
137 | struct inet_hashinfo; | 137 | struct inet_hashinfo; |
138 | struct nlattr; | ||
138 | 139 | ||
139 | struct inet_diag_handler { | 140 | struct inet_diag_handler { |
140 | struct inet_hashinfo *idiag_hashinfo; | 141 | struct inet_hashinfo *idiag_hashinfo; |
@@ -144,6 +145,7 @@ struct inet_diag_handler { | |||
144 | __u16 idiag_type; | 145 | __u16 idiag_type; |
145 | }; | 146 | }; |
146 | 147 | ||
148 | int inet_diag_bc_sk(const struct nlattr *_bc, struct sock *sk); | ||
147 | int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req); | 149 | int inet_diag_check_cookie(struct sock *sk, struct inet_diag_req *req); |
148 | 150 | ||
149 | extern int inet_diag_register(const struct inet_diag_handler *handler); | 151 | extern int inet_diag_register(const struct inet_diag_handler *handler); |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index f50df2ed9af5..08e54989b041 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -449,6 +449,35 @@ static int inet_diag_bc_run(const struct nlattr *_bc, | |||
449 | return len == 0; | 449 | return len == 0; |
450 | } | 450 | } |
451 | 451 | ||
452 | int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk) | ||
453 | { | ||
454 | struct inet_diag_entry entry; | ||
455 | struct inet_sock *inet = inet_sk(sk); | ||
456 | |||
457 | if (bc == NULL) | ||
458 | return 1; | ||
459 | |||
460 | entry.family = sk->sk_family; | ||
461 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
462 | if (entry.family == AF_INET6) { | ||
463 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
464 | |||
465 | entry.saddr = np->rcv_saddr.s6_addr32; | ||
466 | entry.daddr = np->daddr.s6_addr32; | ||
467 | } else | ||
468 | #endif | ||
469 | { | ||
470 | entry.saddr = &inet->inet_rcv_saddr; | ||
471 | entry.daddr = &inet->inet_daddr; | ||
472 | } | ||
473 | entry.sport = inet->inet_num; | ||
474 | entry.dport = ntohs(inet->inet_dport); | ||
475 | entry.userlocks = sk->sk_userlocks; | ||
476 | |||
477 | return inet_diag_bc_run(bc, &entry); | ||
478 | } | ||
479 | EXPORT_SYMBOL_GPL(inet_diag_bc_sk); | ||
480 | |||
452 | static int valid_cc(const void *bc, int len, int cc) | 481 | static int valid_cc(const void *bc, int len, int cc) |
453 | { | 482 | { |
454 | while (len >= 0) { | 483 | while (len >= 0) { |
@@ -509,30 +538,8 @@ static int inet_csk_diag_dump(struct sock *sk, | |||
509 | struct inet_diag_req *r, | 538 | struct inet_diag_req *r, |
510 | const struct nlattr *bc) | 539 | const struct nlattr *bc) |
511 | { | 540 | { |
512 | if (bc != NULL) { | 541 | if (!inet_diag_bc_sk(bc, sk)) |
513 | struct inet_diag_entry entry; | 542 | return 0; |
514 | struct inet_sock *inet = inet_sk(sk); | ||
515 | |||
516 | entry.family = sk->sk_family; | ||
517 | #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) | ||
518 | if (entry.family == AF_INET6) { | ||
519 | struct ipv6_pinfo *np = inet6_sk(sk); | ||
520 | |||
521 | entry.saddr = np->rcv_saddr.s6_addr32; | ||
522 | entry.daddr = np->daddr.s6_addr32; | ||
523 | } else | ||
524 | #endif | ||
525 | { | ||
526 | entry.saddr = &inet->inet_rcv_saddr; | ||
527 | entry.daddr = &inet->inet_daddr; | ||
528 | } | ||
529 | entry.sport = inet->inet_num; | ||
530 | entry.dport = ntohs(inet->inet_dport); | ||
531 | entry.userlocks = sk->sk_userlocks; | ||
532 | |||
533 | if (!inet_diag_bc_run(bc, &entry)) | ||
534 | return 0; | ||
535 | } | ||
536 | 543 | ||
537 | return inet_csk_diag_fill(sk, skb, r, | 544 | return inet_csk_diag_fill(sk, skb, r, |
538 | NETLINK_CB(cb->skb).pid, | 545 | NETLINK_CB(cb->skb).pid, |