/* * UDP over IPv6 * Linux INET6 implementation * * Authors: * Pedro Roque <roque@di.fc.ul.pt> * * Based on linux/ipv4/udp.c * * Fixes: * Hideaki YOSHIFUJI : sin6_scope_id support * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which * Alexey Kuznetsov allow both IPv4 and IPv6 sockets to bind * a single port at the same time. * Kazunori MIYAZAWA @USAGI: change process style to use ip6_append_data * YOSHIFUJI Hideaki @USAGI: convert /proc/net/udp6 to seq_file. * * 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; either version * 2 of the License, or (at your option) any later version. */#include<linux/errno.h>#include<linux/types.h>#include<linux/socket.h>#include<linux/sockios.h>#include<linux/net.h>#include<linux/in6.h>#include<linux/netdevice.h>#include<linux/if_arp.h>#include<linux/ipv6.h>#include<linux/icmpv6.h>#include<linux/init.h>#include<linux/module.h>#include<linux/skbuff.h>#include<asm/uaccess.h>#include<net/ndisc.h>#include<net/protocol.h>#include<net/transp_v6.h>#include<net/ip6_route.h>#include<net/raw.h>#include<net/tcp_states.h>#include<net/ip6_checksum.h>#include<net/xfrm.h>#include<linux/proc_fs.h>#include<linux/seq_file.h>#include"udp_impl.h"intipv6_rcv_saddr_equal(conststructsock*sk,conststructsock*sk2){conststructin6_addr*sk_rcv_saddr6=&inet6_sk(sk)->rcv_saddr;conststructin6_addr*sk2_rcv_saddr6=inet6_rcv_saddr(sk2);__be32sk_rcv_saddr=inet_sk(sk)->rcv_saddr;__be32sk2_rcv_saddr=inet_rcv_saddr(sk2);intsk_ipv6only=ipv6_only_sock(sk);intsk2_ipv6only=inet_v6_ipv6only(sk2);intaddr_type=ipv6_addr_type(sk_rcv_saddr6);intaddr_type2=sk2_rcv_saddr6?ipv6_addr_type(sk2_rcv_saddr6):IPV6_ADDR_MAPPED;/* if both are mapped, treat as IPv4 */if(addr_type==IPV6_ADDR_MAPPED&&addr_type2==IPV6_ADDR_MAPPED)return(!sk2_ipv6only&&(!sk_rcv_saddr||!sk2_rcv_saddr||sk_rcv_saddr==sk2_rcv_saddr));if(addr_type2==IPV6_ADDR_ANY&&!(sk2_ipv6only&&addr_type==IPV6_ADDR_MAPPED))return1;if(addr_type==IPV6_ADDR_ANY&&!(sk_ipv6only&&addr_type2==IPV6_ADDR_MAPPED))return1;if(sk2_rcv_saddr6&&ipv6_addr_equal(sk_rcv_saddr6,sk2_rcv_saddr6))return1;return0;}intudp_v6_get_port(structsock