1 /* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Definitions for inet_sock 7 * 8 * Authors: Many, reorganised here by 9 * Arnaldo Carvalho de Melo <acme@mandriva.com> 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License 13 * as published by the Free Software Foundation; either version 14 * 2 of the License, or (at your option) any later version. 15 */ 16 #ifndef _INET_SOCK_H 17 #define _INET_SOCK_H 18 19 20 #include <linux/string.h> 21 #include <linux/types.h> 22 23 #include <net/flow.h> 24 #include <net/sock.h> 25 #include <net/request_sock.h> 26 27 /** struct ip_options - IP Options 28 * 29 * @faddr - Saved first hop address 30 * @is_data - Options in __data, rather than skb 31 * @is_strictroute - Strict source route 32 * @srr_is_hit - Packet destination addr was our one 33 * @is_changed - IP checksum more not valid 34 * @rr_needaddr - Need to record addr of outgoing dev 35 * @ts_needtime - Need to record timestamp 36 * @ts_needaddr - Need to record addr of outgoing dev 37 */ 38 struct ip_options { 39 __be32 faddr; 40 unsigned char optlen; 41 unsigned char srr; 42 unsigned char rr; 43 unsigned char ts; 44 unsigned char is_data:1, 45 is_strictroute:1, 46 srr_is_hit:1, 47 is_changed:1, 48 rr_needaddr:1, 49 ts_needtime:1, 50 ts_needaddr:1; 51 unsigned char router_alert; 52 unsigned char cipso; 53 unsigned char __pad2; 54 unsigned char __data[0]; 55 }; 56 57 #define optlength(opt) (sizeof(struct ip_options) + opt->optlen) 58 59 struct inet_request_sock { 60 struct request_sock req; 61 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 62 u16 inet6_rsk_offset; 63 /* 2 bytes hole, try to pack */ 64 #endif 65 __be32 loc_addr; 66 __be32 rmt_addr; 67 __be16 rmt_port; 68 u16 snd_wscale : 4, 69 rcv_wscale : 4, 70 tstamp_ok : 1, 71 sack_ok : 1, 72 wscale_ok : 1, 73 ecn_ok : 1, 74 acked : 1; 75 struct ip_options *opt; 76 }; 77 78 static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) 79 { 80 return (struct inet_request_sock *)sk; 81 } 82 83 struct ip_mc_socklist; 84 struct ipv6_pinfo; 85 struct rtable; 86 87 /** struct inet_sock - representation of INET sockets 88 * 89 * @sk - ancestor class 90 * @pinet6 - pointer to IPv6 control block 91 * @daddr - Foreign IPv4 addr 92 * @rcv_saddr - Bound local IPv4 addr 93 * @dport - Destination port 94 * @num - Local port 95 * @saddr - Sending source 96 * @uc_ttl - Unicast TTL 97 * @sport - Source port 98 * @id - ID counter for DF pkts 99 * @tos - TOS 100 * @mc_ttl - Multicasting TTL 101 * @is_icsk - is this an inet_connection_sock? 102 * @mc_index - Multicast device index 103 * @mc_list - Group array 104 * @cork - info to build ip hdr on each ip frag while socket is corked 105 */ 106 struct inet_sock { 107 /* sk and pinet6 has to be the first two members of inet_sock */ 108 struct sock sk; 109 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 110 struct ipv6_pinfo *pinet6; 111 #endif 112 /* Socket demultiplex comparisons on incoming packets. */ 113 __be32 daddr; 114 __be32 rcv_saddr; 115 __be16 dport; 116 __u16 num; 117 __be32 saddr; 118 __s16 uc_ttl; 119 __u16 cmsg_flags; 120 struct ip_options *opt; 121 __be16 sport; 122 __u16 id; 123 __u8 tos; 124 __u8 mc_ttl; 125 __u8 pmtudisc; 126 __u8 recverr:1, 127 is_icsk:1, 128 freebind:1, 129 hdrincl:1, 130 mc_loop:1; 131 int mc_index; 132 __be32 mc_addr; 133 struct ip_mc_socklist *mc_list; 134 struct { 135 unsigned int flags; 136 unsigned int fragsize; 137 struct ip_options *opt; 138 struct rtable *rt; 139 int length; /* Total length of all frames */ 140 __be32 addr; 141 struct flowi fl; 142 } cork; 143 }; 144 145 #define IPCORK_OPT 1 /* ip-options has been held in ipcork.opt */ 146 #define IPCORK_ALLFRAG 2 /* always fragment (for ipv6 for now) */ 147 148 static inline struct inet_sock *inet_sk(const struct sock *sk) 149 { 150 return (struct inet_sock *)sk; 151 } 152 153 static inline void __inet_sk_copy_descendant(struct sock *sk_to, 154 const struct sock *sk_from, 155 const int ancestor_size) 156 { 157 memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1, 158 sk_from->sk_prot->obj_size - ancestor_size); 159 } 160 #if !(defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)) 161 static inline void inet_sk_copy_descendant(struct sock *sk_to, 162 const struct sock *sk_from) 163 { 164 __inet_sk_copy_descendant(sk_to, sk_from, sizeof(struct inet_sock)); 165 } 166 #endif 167 168 extern int inet_sk_rebuild_header(struct sock *sk); 169 170 static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport, 171 const __be32 faddr, const __be16 fport) 172 { 173 unsigned int h = ((__force __u32)laddr ^ lport) ^ ((__force __u32)faddr ^ (__force __u32)fport); 174 h ^= h >> 16; 175 h ^= h >> 8; 176 return h; 177 } 178 179 static inline int inet_sk_ehashfn(const struct sock *sk) 180 { 181 const struct inet_sock *inet = inet_sk(sk); 182 const __be32 laddr = inet->rcv_saddr; 183 const __u16 lport = inet->num; 184 const __be32 faddr = inet->daddr; 185 const __be16 fport = inet->dport; 186 187 return inet_ehashfn(laddr, lport, faddr, fport); 188 } 189 190 #endif /* _INET_SOCK_H */ 191