2016-04-04 16:00:32 +03:00
/* Utility routines
*
* Copyright ( C ) 2015 Red Hat , Inc . All Rights Reserved .
* Written by David Howells ( dhowells @ redhat . com )
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation ; either version
* 2 of the Licence , or ( at your option ) any later version .
*/
# include <linux/ip.h>
2016-06-29 16:40:39 +03:00
# include <linux/ipv6.h>
2016-04-04 16:00:32 +03:00
# include <linux/udp.h>
# include "ar-internal.h"
2016-06-29 16:40:39 +03:00
/*
* Fill out a peer address from a socket buffer containing a packet .
*/
2017-08-29 12:18:37 +03:00
int rxrpc_extract_addr_from_skb ( struct rxrpc_local * local ,
struct sockaddr_rxrpc * srx ,
struct sk_buff * skb )
2016-06-29 16:40:39 +03:00
{
memset ( srx , 0 , sizeof ( * srx ) ) ;
switch ( ntohs ( skb - > protocol ) ) {
case ETH_P_IP :
2017-08-29 12:18:37 +03:00
if ( local - > srx . transport . family = = AF_INET6 ) {
srx - > transport_type = SOCK_DGRAM ;
srx - > transport_len = sizeof ( srx - > transport . sin6 ) ;
srx - > transport . sin6 . sin6_family = AF_INET6 ;
srx - > transport . sin6 . sin6_port = udp_hdr ( skb ) - > source ;
srx - > transport . sin6 . sin6_addr . s6_addr32 [ 2 ] = htonl ( 0xffff ) ;
srx - > transport . sin6 . sin6_addr . s6_addr32 [ 3 ] = ip_hdr ( skb ) - > saddr ;
} else {
srx - > transport_type = SOCK_DGRAM ;
srx - > transport_len = sizeof ( srx - > transport . sin ) ;
srx - > transport . sin . sin_family = AF_INET ;
srx - > transport . sin . sin_port = udp_hdr ( skb ) - > source ;
srx - > transport . sin . sin_addr . s_addr = ip_hdr ( skb ) - > saddr ;
}
2016-06-29 16:40:39 +03:00
return 0 ;
2016-09-17 09:26:01 +03:00
# ifdef CONFIG_AF_RXRPC_IPV6
2016-06-29 16:40:39 +03:00
case ETH_P_IPV6 :
srx - > transport_type = SOCK_DGRAM ;
srx - > transport_len = sizeof ( srx - > transport . sin6 ) ;
srx - > transport . sin6 . sin6_family = AF_INET6 ;
srx - > transport . sin6 . sin6_port = udp_hdr ( skb ) - > source ;
srx - > transport . sin6 . sin6_addr = ipv6_hdr ( skb ) - > saddr ;
return 0 ;
2016-09-17 09:26:01 +03:00
# endif
2016-06-29 16:40:39 +03:00
default :
pr_warn_ratelimited ( " AF_RXRPC: Unknown eth protocol %u \n " ,
ntohs ( skb - > protocol ) ) ;
return - EAFNOSUPPORT ;
}
}