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 */ 27 struct pn_sock { 28 struct sock sk; 29 u16 sobject; 30 u16 dobject; 31 u8 resource; 32 }; 33 34 static inline struct pn_sock *pn_sk(struct sock *sk) 35 { 36 return (struct pn_sock *)sk; 37 } 38 39 extern const struct proto_ops phonet_dgram_ops; 40 41 void pn_sock_init(void); 42 struct sock *pn_find_sock_by_sa(struct net *net, const struct sockaddr_pn *sa); 43 void pn_deliver_sock_broadcast(struct net *net, struct sk_buff *skb); 44 void phonet_get_local_port_range(int *min, int *max); 45 int pn_sock_hash(struct sock *sk); 46 void pn_sock_unhash(struct sock *sk); 47 int pn_sock_get_port(struct sock *sk, unsigned short sport); 48 49 struct sock *pn_find_sock_by_res(struct net *net, u8 res); 50 int pn_sock_bind_res(struct sock *sock, u8 res); 51 int pn_sock_unbind_res(struct sock *sk, u8 res); 52 void pn_sock_unbind_all_res(struct sock *sk); 53 54 int pn_skb_send(struct sock *sk, struct sk_buff *skb, 55 const struct sockaddr_pn *target); 56 57 static inline struct phonethdr *pn_hdr(struct sk_buff *skb) 58 { 59 return (struct phonethdr *)skb_network_header(skb); 60 } 61 62 static 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 */ 71 static inline 72 void 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 83 static inline 84 void 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. */ 96 struct phonet_protocol { 97 const struct proto_ops *ops; 98 struct proto *prot; 99 int sock_type; 100 }; 101 102 int phonet_proto_register(unsigned int protocol, 103 const struct phonet_protocol *pp); 104 void phonet_proto_unregister(unsigned int protocol, 105 const struct phonet_protocol *pp); 106 107 int phonet_sysctl_init(void); 108 void phonet_sysctl_exit(void); 109 int isi_register(void); 110 void isi_unregister(void); 111 112 static inline bool sk_is_phonet(struct sock *sk) 113 { 114 return sk->sk_family == PF_PHONET; 115 } 116 117 static 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