xref: /kvmtool/include/kvm/uip.h (revision d87b503f4d6e499dfcbc84fad3e4da7a900a3b47)
1 #ifndef KVM__UIP_H
2 #define KVM__UIP_H
3 
4 #include "linux/types.h"
5 #include "kvm/mutex.h"
6 
7 #include <netinet/in.h>
8 #include <sys/uio.h>
9 
10 #define UIP_BUF_STATUS_FREE	0
11 #define UIP_BUF_STATUS_INUSE	1
12 #define UIP_BUF_STATUS_USED	2
13 
14 #define UIP_ETH_P_IP		0X0800
15 #define UIP_ETH_P_ARP		0X0806
16 
17 #define UIP_IP_VER_4		0X40
18 #define UIP_IP_HDR_LEN		0X05
19 #define UIP_IP_TTL		0X40
20 #define UIP_IP_P_UDP		0X11
21 #define UIP_IP_P_TCP		0X06
22 #define UIP_IP_P_ICMP		0X01
23 
24 #define UIP_TCP_HDR_LEN		0x50
25 #define UIP_TCP_WIN_SIZE	14600
26 #define UIP_TCP_FLAG_FIN	1
27 #define UIP_TCP_FLAG_SYN	2
28 #define UIP_TCP_FLAG_RST	4
29 #define UIP_TCP_FLAG_PSH	8
30 #define UIP_TCP_FLAG_ACK	16
31 #define UIP_TCP_FLAG_URG	32
32 
33 #define UIP_BOOTP_VENDOR_SPECIFIC_LEN	64
34 #define UIP_BOOTP_MAX_PAYLOAD_LEN	300
35 #define UIP_DHCP_VENDOR_SPECIFIC_LEN	312
36 #define UIP_DHCP_PORT_SERVER		67
37 #define UIP_DHCP_PORT_CLIENT		68
38 #define UIP_DHCP_MACPAD_LEN		10
39 #define UIP_DHCP_HOSTNAME_LEN		64
40 #define UIP_DHCP_FILENAME_LEN		128
41 #define UIP_DHCP_MAGIC_COOKIE		0x63825363
42 #define UIP_DHCP_MAGIC_COOKIE_LEN	4
43 #define UIP_DHCP_LEASE_TIME		0x00003840
44 #define UIP_DHCP_MAX_PAYLOAD_LEN	(UIP_BOOTP_MAX_PAYLOAD_LEN - UIP_BOOTP_VENDOR_SPECIFIC_LEN +  UIP_DHCP_VENDOR_SPECIFIC_LEN)
45 #define UIP_DHCP_OPTION_LEN		(UIP_DHCP_VENDOR_SPECIFIC_LEN - UIP_DHCP_MAGIC_COOKIE_LEN)
46 #define UIP_DHCP_DISCOVER		1
47 #define UIP_DHCP_OFFER			2
48 #define UIP_DHCP_REQUEST		3
49 #define UIP_DHCP_ACK			5
50 #define UIP_DHCP_MAX_DNS_SERVER_NR	3
51 #define UIP_DHCP_MAX_DOMAIN_NAME_LEN	256
52 #define UIP_DHCP_TAG_MSG_TYPE		53
53 #define UIP_DHCP_TAG_MSG_TYPE_LEN	1
54 #define UIP_DHCP_TAG_SERVER_ID		54
55 #define UIP_DHCP_TAG_SERVER_ID_LEN	4
56 #define UIP_DHCP_TAG_LEASE_TIME		51
57 #define UIP_DHCP_TAG_LEASE_TIME_LEN	4
58 #define UIP_DHCP_TAG_SUBMASK		1
59 #define UIP_DHCP_TAG_SUBMASK_LEN	4
60 #define UIP_DHCP_TAG_ROUTER		3
61 #define UIP_DHCP_TAG_ROUTER_LEN		4
62 #define UIP_DHCP_TAG_ROOT		17
63 #define UIP_DHCP_TAG_ROOT_LEN		4
64 #define UIP_DHCP_TAG_DNS_SERVER		6
65 #define UIP_DHCP_TAG_DNS_SERVER_LEN	4
66 #define UIP_DHCP_TAG_DOMAIN_NAME	15
67 #define UIP_DHCP_TAG_END		255
68 
69 /*
70  * IP package maxium len == 64 KBytes
71  * IP header == 20 Bytes
72  * TCP header == 20 Bytes
73  * UDP header == 8 Bytes
74  */
75 #define UIP_MAX_TCP_PAYLOAD	(64*1024 - 20 - 20 - 1)
76 #define UIP_MAX_UDP_PAYLOAD	(64*1024 - 20 -  8 - 1)
77 
78 struct uip_eth_addr {
79 	u8 addr[6];
80 };
81 
82 struct uip_eth {
83 	struct uip_eth_addr dst;
84 	struct uip_eth_addr src;
85 	u16 type;
86 } __attribute__((packed));
87 
88 struct uip_arp {
89 	struct uip_eth eth;
90 	u16 hwtype;
91 	u16 proto;
92 	u8 hwlen;
93 	u8 protolen;
94 	u16 op;
95 	struct uip_eth_addr smac;
96 	u32 sip;
97 	struct uip_eth_addr dmac;
98 	u32 dip;
99 } __attribute__((packed));
100 
101 struct uip_ip {
102 	struct uip_eth eth;
103 	u8 vhl;
104 	u8 tos;
105 	/*
106 	 * len = IP hdr +  IP payload
107 	 */
108 	u16 len;
109 	u16 id;
110 	u16 flgfrag;
111 	u8 ttl;
112 	u8 proto;
113 	u16 csum;
114 	u32 sip;
115 	u32 dip;
116 } __attribute__((packed));
117 
118 struct uip_icmp {
119 	struct uip_ip ip;
120 	u8 type;
121 	u8 code;
122 	u16 csum;
123 	u16 id;
124 	u16 seq;
125 } __attribute__((packed));
126 
127 struct uip_udp {
128 	/*
129 	 * FIXME: IP Options (IP hdr len > 20 bytes) are not supported
130 	 */
131 	struct uip_ip ip;
132 	u16 sport;
133 	u16 dport;
134 	/*
135 	 * len = UDP hdr +  UDP payload
136 	 */
137 	u16 len;
138 	u16 csum;
139 	u8 payload[0];
140 } __attribute__((packed));
141 
142 struct uip_tcp {
143 	/*
144 	 * FIXME: IP Options (IP hdr len > 20 bytes) are not supported
145 	 */
146 	struct uip_ip ip;
147 	u16 sport;
148 	u16 dport;
149 	u32 seq;
150 	u32 ack;
151 	u8  off;
152 	u8  flg;
153 	u16 win;
154 	u16 csum;
155 	u16 urgent;
156 } __attribute__((packed));
157 
158 struct uip_pseudo_hdr {
159 	u32 sip;
160 	u32 dip;
161 	u8 zero;
162 	u8 proto;
163 	u16 len;
164 } __attribute__((packed));
165 
166 struct uip_dhcp {
167 	struct uip_udp udp;
168 	u8 msg_type;
169 	u8 hardware_type;
170 	u8 hardware_len;
171 	u8 hops;
172 	u32 id;
173 	u16 time;
174 	u16 flg;
175 	u32 client_ip;
176 	u32 your_ip;
177 	u32 server_ip;
178 	u32 agent_ip;
179 	struct uip_eth_addr client_mac;
180 	u8 pad[UIP_DHCP_MACPAD_LEN];
181 	u8 server_hostname[UIP_DHCP_HOSTNAME_LEN];
182 	u8 boot_filename[UIP_DHCP_FILENAME_LEN];
183 	u32 magic_cookie;
184 	u8 option[UIP_DHCP_OPTION_LEN];
185 } __attribute__((packed));
186 
187 struct uip_info {
188 	struct list_head udp_socket_head;
189 	struct list_head tcp_socket_head;
190 	struct mutex udp_socket_lock;
191 	struct mutex tcp_socket_lock;
192 	struct uip_eth_addr guest_mac;
193 	struct uip_eth_addr host_mac;
194 	pthread_cond_t buf_free_cond;
195 	pthread_cond_t buf_used_cond;
196 	struct list_head buf_head;
197 	struct mutex buf_lock;
198 	pthread_t udp_thread;
199 	u8 *udp_buf;
200 	int udp_epollfd;
201 	int buf_free_nr;
202 	int buf_used_nr;
203 	u32 guest_ip;
204 	u32 guest_netmask;
205 	u32 host_ip;
206 	u32 dns_ip[UIP_DHCP_MAX_DNS_SERVER_NR];
207 	char *domain_name;
208 	u32 buf_nr;
209 	u32 vnet_hdr_len;
210 };
211 
212 struct uip_buf {
213 	struct list_head list;
214 	struct uip_info *info;
215 	int vnet_len;
216 	int eth_len;
217 	int status;
218 	unsigned char *vnet;
219 	unsigned char *eth;
220 	int id;
221 };
222 
223 struct uip_udp_socket {
224 	struct sockaddr_in addr;
225 	struct list_head list;
226 	struct mutex *lock;
227 	u32 dport, sport;
228 	u32 dip, sip;
229 	int fd;
230 };
231 
232 struct uip_tcp_socket {
233 	struct sockaddr_in addr;
234 	struct list_head list;
235 	struct uip_info *info;
236 	pthread_cond_t	cond;
237 	struct mutex *lock;
238 	pthread_t thread;
239 	u32 dport, sport;
240 	u32 guest_acked;
241 	u16 window_size;
242 	/*
243 	 * Initial Sequence Number
244 	 */
245 	u32 isn_server;
246 	u32 isn_guest;
247 	u32 ack_server;
248 	u32 seq_server;
249 	int write_done;
250 	int read_done;
251 	u32 dip, sip;
252 	u8 *payload;
253 	u8 *buf;
254 	int fd;
255 };
256 
257 struct uip_tx_arg {
258 	void *vnet;
259 	struct uip_info *info;
260 	struct uip_eth *eth;
261 	int vnet_len;
262 	int eth_len;
263 };
264 
uip_ip_hdrlen(struct uip_ip * ip)265 static inline u16 uip_ip_hdrlen(struct uip_ip *ip)
266 {
267 	return (ip->vhl & 0x0f) * 4;
268 }
269 
uip_ip_len(struct uip_ip * ip)270 static inline u16 uip_ip_len(struct uip_ip *ip)
271 {
272 	return htons(ip->len);
273 }
274 
uip_udp_hdrlen(struct uip_udp * udp)275 static inline u16 uip_udp_hdrlen(struct uip_udp *udp)
276 {
277 	return 8;
278 }
279 
uip_udp_len(struct uip_udp * udp)280 static inline u16 uip_udp_len(struct uip_udp *udp)
281 {
282 	return ntohs(udp->len);
283 }
284 
uip_tcp_hdrlen(struct uip_tcp * tcp)285 static inline u16 uip_tcp_hdrlen(struct uip_tcp *tcp)
286 {
287 	return (tcp->off >> 4) * 4;
288 }
289 
uip_tcp_len(struct uip_tcp * tcp)290 static inline u16 uip_tcp_len(struct uip_tcp *tcp)
291 {
292 	struct uip_ip *ip;
293 
294 	ip = &tcp->ip;
295 
296 	return uip_ip_len(ip) - uip_ip_hdrlen(ip);
297 }
298 
uip_tcp_payloadlen(struct uip_tcp * tcp)299 static inline u16 uip_tcp_payloadlen(struct uip_tcp *tcp)
300 {
301 	return uip_tcp_len(tcp) - uip_tcp_hdrlen(tcp);
302 }
303 
uip_tcp_payload(struct uip_tcp * tcp)304 static inline u8 *uip_tcp_payload(struct uip_tcp *tcp)
305 {
306 	return (u8 *)&tcp->sport + uip_tcp_hdrlen(tcp);
307 }
308 
uip_tcp_is_syn(struct uip_tcp * tcp)309 static inline bool uip_tcp_is_syn(struct uip_tcp *tcp)
310 {
311 	return (tcp->flg & UIP_TCP_FLAG_SYN) != 0;
312 }
313 
uip_tcp_is_fin(struct uip_tcp * tcp)314 static inline bool uip_tcp_is_fin(struct uip_tcp *tcp)
315 {
316 	return (tcp->flg & UIP_TCP_FLAG_FIN) != 0;
317 }
318 
uip_tcp_isn(struct uip_tcp * tcp)319 static inline u32 uip_tcp_isn(struct uip_tcp *tcp)
320 {
321 	return ntohl(tcp->seq);
322 }
323 
uip_tcp_isn_alloc(void)324 static inline u32 uip_tcp_isn_alloc(void)
325 {
326 	/*
327 	 * FIXME: should increase every 4ms
328 	 */
329 	return 10000000;
330 }
331 
uip_eth_hdrlen(struct uip_eth * eth)332 static inline u16 uip_eth_hdrlen(struct uip_eth *eth)
333 {
334 	return sizeof(*eth);
335 }
336 
337 int uip_tx(struct iovec *iov, u16 out, struct uip_info *info);
338 int uip_rx(struct iovec *iov, u16 in, struct uip_info *info);
339 void uip_static_init(struct uip_info *info);
340 int uip_init(struct uip_info *info);
341 void uip_exit(struct uip_info *info);
342 void uip_tcp_exit(struct uip_info *info);
343 void uip_udp_exit(struct uip_info *info);
344 
345 int uip_tx_do_ipv4_udp_dhcp(struct uip_tx_arg *arg);
346 int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg);
347 int uip_tx_do_ipv4_tcp(struct uip_tx_arg *arg);
348 int uip_tx_do_ipv4_udp(struct uip_tx_arg *arg);
349 int uip_tx_do_ipv4(struct uip_tx_arg *arg);
350 int uip_tx_do_arp(struct uip_tx_arg *arg);
351 
352 u16 uip_csum_icmp(struct uip_icmp *icmp);
353 u16 uip_csum_udp(struct uip_udp *udp);
354 u16 uip_csum_tcp(struct uip_tcp *tcp);
355 u16 uip_csum_ip(struct uip_ip *ip);
356 
357 struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf);
358 struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf);
359 struct uip_buf *uip_buf_get_used(struct uip_info *info);
360 struct uip_buf *uip_buf_get_free(struct uip_info *info);
361 struct uip_buf *uip_buf_clone(struct uip_tx_arg *arg);
362 
363 int uip_udp_make_pkg(struct uip_info *info, struct uip_udp_socket *sk, struct uip_buf *buf, u8 *payload, int payload_len);
364 bool uip_udp_is_dhcp(struct uip_udp *udp);
365 
366 int uip_dhcp_get_dns(struct uip_info *info);
367 void uip_dhcp_exit(struct uip_info *info);
368 #endif /* KVM__UIP_H */
369