1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * File: af_phonet.h 4 * 5 * Phonet sockets kernel definitions 6 * 7 * Copyright (C) 2008 Nokia Corporation. 8 */ 9 10#ifndef AF_PHONET_H 11#define AF_PHONET_H 12 13#include <linux/phonet.h> 14#include <linux/skbuff.h> 15#include <net/sock.h> 16 17/* 18 * The lower layers may not require more space, ever. Make sure it's 19 * enough. 20 */ 21#define MAX_PHONET_HEADER (8 + MAX_HEADER) 22 23/* 24 * Every Phonet* socket has this structure first in its 25 * protocol-specific structure under name c. 26 */ 27struct pn_sock { 28 struct sock sk; 29 u16 sobject; 30 u16 dobject; 31 u8 resource; 32}; 33 34static inline struct pn_sock *pn_sk(struct sock *sk) 35{ 36 return (struct pn_sock *)sk; 37} 38 39extern const struct proto_ops phonet_dgram_ops; 40 41void pn_sock_init(void); 42struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *sa); 43void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb); 44void phonet_get_local_port_range(int *min, int *max); 45int pn_sock_hash(struct sock *sk); 46void pn_sock_unhash(struct sock *sk); 47int pn_sock_get_port(struct sock *sk, unsigned short sport); 48 49struct sock *pn_find_sock_by_res(struct net *net, u8 res); 50int pn_sock_bind_res(struct sock *sock, u8 res); 51int pn_sock_unbind_res(struct sock *sk, u8 res); 52void pn_sock_unbind_all_res(struct sock *sk); 53 54int pn_skb_send(struct sock *sk, struct sk_buff *skb, 55 const struct sockaddr_pn *target); 56 57static inline struct phonethdr *pn_hdr(struct sk_buff *skb) 58{ 59 return (struct phonethdr *)skb_network_header(skb); 60} 61 62static inline struct phonetmsg *pn_msg(struct sk_buff *skb) 63{ 64 return (struct phonetmsg *)skb_transport_header(skb); 65} 66 67/* 68 * Get the other party's sockaddr from received skb. The skb begins 69 * with a Phonet header. 70 */ 71static inline 72void pn_skb_get_src_sockaddr(struct sk_buff *skb, struct sockaddr_pn *sa) 73{ 74 struct phonethdr *ph = pn_hdr(skb); 75 u16 obj = pn_object(ph->pn_sdev, ph->pn_sobj); 76 77 sa->spn_family = AF_PHONET; 78 pn_sockaddr_set_object(sa, obj); 79 pn_sockaddr_set_resource(sa, ph->pn_res); 80 memset(sa->spn_zero, 0, sizeof(sa->spn_zero)); 81} 82 83static inline 84void pn_skb_get_dst_sockaddr(struct sk_buff *skb, struct sockaddr_pn *sa) 85{ 86 struct phonethdr *ph = pn_hdr(skb); 87 u16 obj = pn_object(ph->pn_rdev, ph->pn_robj); 88 89 sa->spn_family = AF_PHONET; 90 pn_sockaddr_set_object(sa, obj); 91 pn_sockaddr_set_resource(sa, ph->pn_res); 92 memset(sa->spn_zero, 0, sizeof(sa->spn_zero)); 93} 94 95/* Protocols in Phonet protocol family. */ 96struct phonet_protocol { 97 const struct proto_ops *ops; 98 struct proto *prot; 99 int sock_type; 100}; 101 102int phonet_proto_register(unsigned int protocol, 103 const struct phonet_protocol *pp); 104void phonet_proto_unregister(unsigned int protocol, 105 const struct phonet_protocol *pp); 106 107int phonet_sysctl_init(void); 108void phonet_sysctl_exit(void); 109int isi_register(void); 110void isi_unregister(void); 111 112static inline bool sk_is_phonet(struct sock *sk) 113{ 114 return sk->sk_family == PF_PHONET; 115} 116 117static inline int phonet_sk_ioctl(struct sock *sk, unsigned int cmd, 118 void __user *arg) 119{ 120 int karg; 121 122 switch (cmd) { 123 case SIOCPNADDRESOURCE: 124 case SIOCPNDELRESOURCE: 125 if (get_user(karg, (int __user *)arg)) 126 return -EFAULT; 127 128 return sk->sk_prot->ioctl(sk, cmd, &karg); 129 } 130 /* A positive return value means that the ioctl was not processed */ 131 return 1; 132} 133#endif 134