@@ -434,7 +434,7 @@ static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
434
434
/* Initialize sk->sk_rcv_saddr from sctp_addr. */
435
435
static void sctp_v6_to_sk_saddr (union sctp_addr * addr , struct sock * sk )
436
436
{
437
- if (addr -> sa .sa_family == AF_INET && sctp_sk ( sk ) -> v4mapped ) {
437
+ if (addr -> sa .sa_family == AF_INET ) {
438
438
sk -> sk_v6_rcv_saddr .s6_addr32 [0 ] = 0 ;
439
439
sk -> sk_v6_rcv_saddr .s6_addr32 [1 ] = 0 ;
440
440
sk -> sk_v6_rcv_saddr .s6_addr32 [2 ] = htonl (0x0000ffff );
@@ -448,7 +448,7 @@ static void sctp_v6_to_sk_saddr(union sctp_addr *addr, struct sock *sk)
448
448
/* Initialize sk->sk_daddr from sctp_addr. */
449
449
static void sctp_v6_to_sk_daddr (union sctp_addr * addr , struct sock * sk )
450
450
{
451
- if (addr -> sa .sa_family == AF_INET && sctp_sk ( sk ) -> v4mapped ) {
451
+ if (addr -> sa .sa_family == AF_INET ) {
452
452
sk -> sk_v6_daddr .s6_addr32 [0 ] = 0 ;
453
453
sk -> sk_v6_daddr .s6_addr32 [1 ] = 0 ;
454
454
sk -> sk_v6_daddr .s6_addr32 [2 ] = htonl (0x0000ffff );
@@ -556,8 +556,6 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
556
556
if (IPV6_ADDR_ANY == type )
557
557
return 1 ;
558
558
if (type == IPV6_ADDR_MAPPED ) {
559
- if (sp && !sp -> v4mapped )
560
- return 0 ;
561
559
if (sp && ipv6_only_sock (sctp_opt2sk (sp )))
562
560
return 0 ;
563
561
sctp_v6_map_v4 (addr );
@@ -587,8 +585,6 @@ static int sctp_v6_addr_valid(union sctp_addr *addr,
587
585
/* Note: This routine is used in input, so v4-mapped-v6
588
586
* are disallowed here when there is no sctp_sock.
589
587
*/
590
- if (!sp || !sp -> v4mapped )
591
- return 0 ;
592
588
if (sp && ipv6_only_sock (sctp_opt2sk (sp )))
593
589
return 0 ;
594
590
sctp_v6_map_v4 (addr );
@@ -675,11 +671,23 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
675
671
return newsk ;
676
672
}
677
673
678
- /* Map v4 address to mapped v6 address */
679
- static void sctp_v6_addr_v4map (struct sctp_sock * sp , union sctp_addr * addr )
674
+ /* Format a sockaddr for return to user space. This makes sure the return is
675
+ * AF_INET or AF_INET6 depending on the SCTP_I_WANT_MAPPED_V4_ADDR option.
676
+ */
677
+ static int sctp_v6_addr_to_user (struct sctp_sock * sp , union sctp_addr * addr )
680
678
{
681
- if (sp -> v4mapped && AF_INET == addr -> sa .sa_family )
682
- sctp_v4_map_v6 (addr );
679
+ if (sp -> v4mapped ) {
680
+ if (addr -> sa .sa_family == AF_INET )
681
+ sctp_v4_map_v6 (addr );
682
+ } else {
683
+ if (addr -> sa .sa_family == AF_INET6 &&
684
+ ipv6_addr_v4mapped (& addr -> v6 .sin6_addr ))
685
+ sctp_v6_map_v4 (addr );
686
+ }
687
+
688
+ if (addr -> sa .sa_family == AF_INET )
689
+ return sizeof (struct sockaddr_in );
690
+ return sizeof (struct sockaddr_in6 );
683
691
}
684
692
685
693
/* Where did this skb come from? */
@@ -706,82 +714,68 @@ static void sctp_v6_ecn_capable(struct sock *sk)
706
714
inet6_sk (sk )-> tclass |= INET_ECN_ECT_0 ;
707
715
}
708
716
709
- /* Initialize a PF_INET6 socket msg_name. */
710
- static void sctp_inet6_msgname (char * msgname , int * addr_len )
711
- {
712
- struct sockaddr_in6 * sin6 ;
713
-
714
- sin6 = (struct sockaddr_in6 * )msgname ;
715
- sin6 -> sin6_family = AF_INET6 ;
716
- sin6 -> sin6_flowinfo = 0 ;
717
- sin6 -> sin6_scope_id = 0 ; /*FIXME */
718
- * addr_len = sizeof (struct sockaddr_in6 );
719
- }
720
-
721
717
/* Initialize a PF_INET msgname from a ulpevent. */
722
718
static void sctp_inet6_event_msgname (struct sctp_ulpevent * event ,
723
719
char * msgname , int * addrlen )
724
720
{
725
- struct sockaddr_in6 * sin6 , * sin6from ;
726
-
727
- if (msgname ) {
728
- union sctp_addr * addr ;
729
- struct sctp_association * asoc ;
730
-
731
- asoc = event -> asoc ;
732
- sctp_inet6_msgname (msgname , addrlen );
733
- sin6 = (struct sockaddr_in6 * )msgname ;
734
- sin6 -> sin6_port = htons (asoc -> peer .port );
735
- addr = & asoc -> peer .primary_addr ;
721
+ union sctp_addr * addr ;
722
+ struct sctp_association * asoc ;
723
+ union sctp_addr * paddr ;
736
724
737
- /* Note: If we go to a common v6 format, this code
738
- * will change.
739
- */
725
+ if (!msgname )
726
+ return ;
740
727
741
- /* Map ipv4 address into v4-mapped-on-v6 address. */
742
- if (sctp_sk (asoc -> base .sk )-> v4mapped &&
743
- AF_INET == addr -> sa .sa_family ) {
744
- sctp_v4_map_v6 ((union sctp_addr * )sin6 );
745
- sin6 -> sin6_addr .s6_addr32 [3 ] =
746
- addr -> v4 .sin_addr .s_addr ;
747
- return ;
748
- }
728
+ addr = (union sctp_addr * )msgname ;
729
+ asoc = event -> asoc ;
730
+ paddr = & asoc -> peer .primary_addr ;
749
731
750
- sin6from = & asoc -> peer .primary_addr .v6 ;
751
- sin6 -> sin6_addr = sin6from -> sin6_addr ;
752
- if (ipv6_addr_type (& sin6 -> sin6_addr ) & IPV6_ADDR_LINKLOCAL )
753
- sin6 -> sin6_scope_id = sin6from -> sin6_scope_id ;
732
+ if (paddr -> sa .sa_family == AF_INET ) {
733
+ addr -> v4 .sin_family = AF_INET ;
734
+ addr -> v4 .sin_port = htons (asoc -> peer .port );
735
+ addr -> v4 .sin_addr = paddr -> v4 .sin_addr ;
736
+ } else {
737
+ addr -> v6 .sin6_family = AF_INET6 ;
738
+ addr -> v6 .sin6_flowinfo = 0 ;
739
+ if (ipv6_addr_type (& paddr -> v6 .sin6_addr ) & IPV6_ADDR_LINKLOCAL )
740
+ addr -> v6 .sin6_scope_id = paddr -> v6 .sin6_scope_id ;
741
+ else
742
+ addr -> v6 .sin6_scope_id = 0 ;
743
+ addr -> v6 .sin6_port = htons (asoc -> peer .port );
744
+ addr -> v6 .sin6_addr = paddr -> v6 .sin6_addr ;
754
745
}
746
+
747
+ * addrlen = sctp_v6_addr_to_user (sctp_sk (asoc -> base .sk ), addr );
755
748
}
756
749
757
750
/* Initialize a msg_name from an inbound skb. */
758
751
static void sctp_inet6_skb_msgname (struct sk_buff * skb , char * msgname ,
759
752
int * addr_len )
760
753
{
754
+ union sctp_addr * addr ;
761
755
struct sctphdr * sh ;
762
- struct sockaddr_in6 * sin6 ;
763
-
764
- if (msgname ) {
765
- sctp_inet6_msgname (msgname , addr_len );
766
- sin6 = (struct sockaddr_in6 * )msgname ;
767
- sh = sctp_hdr (skb );
768
- sin6 -> sin6_port = sh -> source ;
769
-
770
- /* Map ipv4 address into v4-mapped-on-v6 address. */
771
- if (sctp_sk (skb -> sk )-> v4mapped &&
772
- ip_hdr (skb )-> version == 4 ) {
773
- sctp_v4_map_v6 ((union sctp_addr * )sin6 );
774
- sin6 -> sin6_addr .s6_addr32 [3 ] = ip_hdr (skb )-> saddr ;
775
- return ;
776
- }
777
756
778
- /* Otherwise, just copy the v6 address. */
779
- sin6 -> sin6_addr = ipv6_hdr (skb )-> saddr ;
780
- if (ipv6_addr_type (& sin6 -> sin6_addr ) & IPV6_ADDR_LINKLOCAL ) {
757
+ if (!msgname )
758
+ return ;
759
+
760
+ addr = (union sctp_addr * )msgname ;
761
+ sh = sctp_hdr (skb );
762
+
763
+ if (ip_hdr (skb )-> version == 4 ) {
764
+ addr -> v4 .sin_family = AF_INET ;
765
+ addr -> v4 .sin_port = sh -> source ;
766
+ addr -> v4 .sin_addr .s_addr = ip_hdr (skb )-> saddr ;
767
+ } else {
768
+ addr -> v6 .sin6_family = AF_INET6 ;
769
+ addr -> v6 .sin6_flowinfo = 0 ;
770
+ addr -> v6 .sin6_port = sh -> source ;
771
+ addr -> v6 .sin6_addr = ipv6_hdr (skb )-> saddr ;
772
+ if (ipv6_addr_type (& addr -> v6 .sin6_addr ) & IPV6_ADDR_LINKLOCAL ) {
781
773
struct sctp_ulpevent * ev = sctp_skb2event (skb );
782
- sin6 -> sin6_scope_id = ev -> iif ;
774
+ addr -> v6 . sin6_scope_id = ev -> iif ;
783
775
}
784
776
}
777
+
778
+ * addr_len = sctp_v6_addr_to_user (sctp_sk (skb -> sk ), addr );
785
779
}
786
780
787
781
/* Do we support this AF? */
@@ -857,9 +851,6 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
857
851
return 0 ;
858
852
}
859
853
rcu_read_unlock ();
860
- } else if (type == IPV6_ADDR_MAPPED ) {
861
- if (!opt -> v4mapped )
862
- return 0 ;
863
854
}
864
855
865
856
af = opt -> pf -> af ;
@@ -914,6 +905,23 @@ static int sctp_inet6_supported_addrs(const struct sctp_sock *opt,
914
905
return 1 ;
915
906
}
916
907
908
+ /* Handle SCTP_I_WANT_MAPPED_V4_ADDR for getpeername() and getsockname() */
909
+ static int sctp_getname (struct socket * sock , struct sockaddr * uaddr ,
910
+ int * uaddr_len , int peer )
911
+ {
912
+ int rc ;
913
+
914
+ rc = inet6_getname (sock , uaddr , uaddr_len , peer );
915
+
916
+ if (rc != 0 )
917
+ return rc ;
918
+
919
+ * uaddr_len = sctp_v6_addr_to_user (sctp_sk (sock -> sk ),
920
+ (union sctp_addr * )uaddr );
921
+
922
+ return rc ;
923
+ }
924
+
917
925
static const struct proto_ops inet6_seqpacket_ops = {
918
926
.family = PF_INET6 ,
919
927
.owner = THIS_MODULE ,
@@ -922,7 +930,7 @@ static const struct proto_ops inet6_seqpacket_ops = {
922
930
.connect = inet_dgram_connect ,
923
931
.socketpair = sock_no_socketpair ,
924
932
.accept = inet_accept ,
925
- .getname = inet6_getname ,
933
+ .getname = sctp_getname ,
926
934
.poll = sctp_poll ,
927
935
.ioctl = inet6_ioctl ,
928
936
.listen = sctp_inet_listen ,
@@ -974,8 +982,6 @@ static struct sctp_af sctp_af_inet6 = {
974
982
.copy_addrlist = sctp_v6_copy_addrlist ,
975
983
.from_skb = sctp_v6_from_skb ,
976
984
.from_sk = sctp_v6_from_sk ,
977
- .to_sk_saddr = sctp_v6_to_sk_saddr ,
978
- .to_sk_daddr = sctp_v6_to_sk_daddr ,
979
985
.from_addr_param = sctp_v6_from_addr_param ,
980
986
.to_addr_param = sctp_v6_to_addr_param ,
981
987
.cmp_addr = sctp_v6_cmp_addr ,
@@ -1005,7 +1011,9 @@ static struct sctp_pf sctp_pf_inet6 = {
1005
1011
.send_verify = sctp_inet6_send_verify ,
1006
1012
.supported_addrs = sctp_inet6_supported_addrs ,
1007
1013
.create_accept_sk = sctp_v6_create_accept_sk ,
1008
- .addr_v4map = sctp_v6_addr_v4map ,
1014
+ .addr_to_user = sctp_v6_addr_to_user ,
1015
+ .to_sk_saddr = sctp_v6_to_sk_saddr ,
1016
+ .to_sk_daddr = sctp_v6_to_sk_daddr ,
1009
1017
.af = & sctp_af_inet6 ,
1010
1018
};
1011
1019
0 commit comments