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