linux/net/rxrpc/utils.c
<<
>>
Prefs
   1/* Utility routines
   2 *
   3 * Copyright (C) 2015 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public Licence
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the Licence, or (at your option) any later version.
  10 */
  11
  12#include <linux/ip.h>
  13#include <linux/ipv6.h>
  14#include <linux/udp.h>
  15#include "ar-internal.h"
  16
  17/*
  18 * Fill out a peer address from a socket buffer containing a packet.
  19 */
  20int rxrpc_extract_addr_from_skb(struct rxrpc_local *local,
  21                                struct sockaddr_rxrpc *srx,
  22                                struct sk_buff *skb)
  23{
  24        memset(srx, 0, sizeof(*srx));
  25
  26        switch (ntohs(skb->protocol)) {
  27        case ETH_P_IP:
  28                if (local->srx.transport.family == AF_INET6) {
  29                        srx->transport_type = SOCK_DGRAM;
  30                        srx->transport_len = sizeof(srx->transport.sin6);
  31                        srx->transport.sin6.sin6_family = AF_INET6;
  32                        srx->transport.sin6.sin6_port = udp_hdr(skb)->source;
  33                        srx->transport.sin6.sin6_addr.s6_addr32[2] = htonl(0xffff);
  34                        srx->transport.sin6.sin6_addr.s6_addr32[3] = ip_hdr(skb)->saddr;
  35                } else {
  36                        srx->transport_type = SOCK_DGRAM;
  37                        srx->transport_len = sizeof(srx->transport.sin);
  38                        srx->transport.sin.sin_family = AF_INET;
  39                        srx->transport.sin.sin_port = udp_hdr(skb)->source;
  40                        srx->transport.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
  41                }
  42                return 0;
  43
  44#ifdef CONFIG_AF_RXRPC_IPV6
  45        case ETH_P_IPV6:
  46                srx->transport_type = SOCK_DGRAM;
  47                srx->transport_len = sizeof(srx->transport.sin6);
  48                srx->transport.sin6.sin6_family = AF_INET6;
  49                srx->transport.sin6.sin6_port = udp_hdr(skb)->source;
  50                srx->transport.sin6.sin6_addr = ipv6_hdr(skb)->saddr;
  51                return 0;
  52#endif
  53
  54        default:
  55                pr_warn_ratelimited("AF_RXRPC: Unknown eth protocol %u\n",
  56                                    ntohs(skb->protocol));
  57                return -EAFNOSUPPORT;
  58        }
  59}
  60