| #ifndef KVM__UIP_H |
| #define KVM__UIP_H |
| |
| #include "linux/types.h" |
| #include "kvm/mutex.h" |
| |
| #include <netinet/in.h> |
| #include <sys/uio.h> |
| |
| #define UIP_BUF_STATUS_FREE 0 |
| #define UIP_BUF_STATUS_INUSE 1 |
| #define UIP_BUF_STATUS_USED 2 |
| |
| #define UIP_ETH_P_IP 0X0800 |
| #define UIP_ETH_P_ARP 0X0806 |
| |
| #define UIP_IP_VER_4 0X40 |
| #define UIP_IP_HDR_LEN 0X05 |
| #define UIP_IP_TTL 0X40 |
| #define UIP_IP_P_UDP 0X11 |
| #define UIP_IP_P_TCP 0X06 |
| #define UIP_IP_P_ICMP 0X01 |
| |
| #define UIP_TCP_HDR_LEN 0x50 |
| #define UIP_TCP_WIN_SIZE 14600 |
| #define UIP_TCP_FLAG_FIN 1 |
| #define UIP_TCP_FLAG_SYN 2 |
| #define UIP_TCP_FLAG_RST 4 |
| #define UIP_TCP_FLAG_PSH 8 |
| #define UIP_TCP_FLAG_ACK 16 |
| #define UIP_TCP_FLAG_URG 32 |
| |
| #define UIP_BOOTP_VENDOR_SPECIFIC_LEN 64 |
| #define UIP_BOOTP_MAX_PAYLOAD_LEN 300 |
| #define UIP_DHCP_VENDOR_SPECIFIC_LEN 312 |
| #define UIP_DHCP_PORT_SERVER 67 |
| #define UIP_DHCP_PORT_CLIENT 68 |
| #define UIP_DHCP_MACPAD_LEN 10 |
| #define UIP_DHCP_HOSTNAME_LEN 64 |
| #define UIP_DHCP_FILENAME_LEN 128 |
| #define UIP_DHCP_MAGIC_COOKIE 0x63825363 |
| #define UIP_DHCP_MAGIC_COOKIE_LEN 4 |
| #define UIP_DHCP_LEASE_TIME 0x00003840 |
| #define UIP_DHCP_MAX_PAYLOAD_LEN (UIP_BOOTP_MAX_PAYLOAD_LEN - UIP_BOOTP_VENDOR_SPECIFIC_LEN + UIP_DHCP_VENDOR_SPECIFIC_LEN) |
| #define UIP_DHCP_OPTION_LEN (UIP_DHCP_VENDOR_SPECIFIC_LEN - UIP_DHCP_MAGIC_COOKIE_LEN) |
| #define UIP_DHCP_DISCOVER 1 |
| #define UIP_DHCP_OFFER 2 |
| #define UIP_DHCP_REQUEST 3 |
| #define UIP_DHCP_ACK 5 |
| #define UIP_DHCP_MAX_DNS_SERVER_NR 3 |
| #define UIP_DHCP_MAX_DOMAIN_NAME_LEN 256 |
| #define UIP_DHCP_TAG_MSG_TYPE 53 |
| #define UIP_DHCP_TAG_MSG_TYPE_LEN 1 |
| #define UIP_DHCP_TAG_SERVER_ID 54 |
| #define UIP_DHCP_TAG_SERVER_ID_LEN 4 |
| #define UIP_DHCP_TAG_LEASE_TIME 51 |
| #define UIP_DHCP_TAG_LEASE_TIME_LEN 4 |
| #define UIP_DHCP_TAG_SUBMASK 1 |
| #define UIP_DHCP_TAG_SUBMASK_LEN 4 |
| #define UIP_DHCP_TAG_ROUTER 3 |
| #define UIP_DHCP_TAG_ROUTER_LEN 4 |
| #define UIP_DHCP_TAG_ROOT 17 |
| #define UIP_DHCP_TAG_ROOT_LEN 4 |
| #define UIP_DHCP_TAG_DNS_SERVER 6 |
| #define UIP_DHCP_TAG_DNS_SERVER_LEN 4 |
| #define UIP_DHCP_TAG_DOMAIN_NAME 15 |
| #define UIP_DHCP_TAG_END 255 |
| |
| /* |
| * IP package maxium len == 64 KBytes |
| * IP header == 20 Bytes |
| * TCP header == 20 Bytes |
| * UDP header == 8 Bytes |
| */ |
| #define UIP_MAX_TCP_PAYLOAD (64*1024 - 20 - 20 - 1) |
| #define UIP_MAX_UDP_PAYLOAD (64*1024 - 20 - 8 - 1) |
| |
| struct uip_eth_addr { |
| u8 addr[6]; |
| }; |
| |
| struct uip_eth { |
| struct uip_eth_addr dst; |
| struct uip_eth_addr src; |
| u16 type; |
| } __attribute__((packed)); |
| |
| struct uip_arp { |
| struct uip_eth eth; |
| u16 hwtype; |
| u16 proto; |
| u8 hwlen; |
| u8 protolen; |
| u16 op; |
| struct uip_eth_addr smac; |
| u32 sip; |
| struct uip_eth_addr dmac; |
| u32 dip; |
| } __attribute__((packed)); |
| |
| struct uip_ip { |
| struct uip_eth eth; |
| u8 vhl; |
| u8 tos; |
| /* |
| * len = IP hdr + IP payload |
| */ |
| u16 len; |
| u16 id; |
| u16 flgfrag; |
| u8 ttl; |
| u8 proto; |
| u16 csum; |
| u32 sip; |
| u32 dip; |
| } __attribute__((packed)); |
| |
| struct uip_icmp { |
| struct uip_ip ip; |
| u8 type; |
| u8 code; |
| u16 csum; |
| u16 id; |
| u16 seq; |
| } __attribute__((packed)); |
| |
| struct uip_udp { |
| /* |
| * FIXME: IP Options (IP hdr len > 20 bytes) are not supported |
| */ |
| struct uip_ip ip; |
| u16 sport; |
| u16 dport; |
| /* |
| * len = UDP hdr + UDP payload |
| */ |
| u16 len; |
| u16 csum; |
| u8 payload[0]; |
| } __attribute__((packed)); |
| |
| struct uip_tcp { |
| /* |
| * FIXME: IP Options (IP hdr len > 20 bytes) are not supported |
| */ |
| struct uip_ip ip; |
| u16 sport; |
| u16 dport; |
| u32 seq; |
| u32 ack; |
| u8 off; |
| u8 flg; |
| u16 win; |
| u16 csum; |
| u16 urgent; |
| } __attribute__((packed)); |
| |
| struct uip_pseudo_hdr { |
| u32 sip; |
| u32 dip; |
| u8 zero; |
| u8 proto; |
| u16 len; |
| } __attribute__((packed)); |
| |
| struct uip_dhcp { |
| struct uip_udp udp; |
| u8 msg_type; |
| u8 hardware_type; |
| u8 hardware_len; |
| u8 hops; |
| u32 id; |
| u16 time; |
| u16 flg; |
| u32 client_ip; |
| u32 your_ip; |
| u32 server_ip; |
| u32 agent_ip; |
| struct uip_eth_addr client_mac; |
| u8 pad[UIP_DHCP_MACPAD_LEN]; |
| u8 server_hostname[UIP_DHCP_HOSTNAME_LEN]; |
| u8 boot_filename[UIP_DHCP_FILENAME_LEN]; |
| u32 magic_cookie; |
| u8 option[UIP_DHCP_OPTION_LEN]; |
| } __attribute__((packed)); |
| |
| struct uip_info { |
| struct list_head udp_socket_head; |
| struct list_head tcp_socket_head; |
| struct mutex udp_socket_lock; |
| struct mutex tcp_socket_lock; |
| struct uip_eth_addr guest_mac; |
| struct uip_eth_addr host_mac; |
| pthread_cond_t buf_free_cond; |
| pthread_cond_t buf_used_cond; |
| struct list_head buf_head; |
| struct mutex buf_lock; |
| pthread_t udp_thread; |
| u8 *udp_buf; |
| int udp_epollfd; |
| int buf_free_nr; |
| int buf_used_nr; |
| u32 guest_ip; |
| u32 guest_netmask; |
| u32 host_ip; |
| u32 dns_ip[UIP_DHCP_MAX_DNS_SERVER_NR]; |
| char *domain_name; |
| u32 buf_nr; |
| u32 vnet_hdr_len; |
| }; |
| |
| struct uip_buf { |
| struct list_head list; |
| struct uip_info *info; |
| int vnet_len; |
| int eth_len; |
| int status; |
| unsigned char *vnet; |
| unsigned char *eth; |
| int id; |
| }; |
| |
| struct uip_udp_socket { |
| struct sockaddr_in addr; |
| struct list_head list; |
| struct mutex *lock; |
| u32 dport, sport; |
| u32 dip, sip; |
| int fd; |
| }; |
| |
| struct uip_tcp_socket { |
| struct sockaddr_in addr; |
| struct list_head list; |
| struct uip_info *info; |
| pthread_cond_t cond; |
| struct mutex *lock; |
| pthread_t thread; |
| u32 dport, sport; |
| u32 guest_acked; |
| u16 window_size; |
| /* |
| * Initial Sequence Number |
| */ |
| u32 isn_server; |
| u32 isn_guest; |
| u32 ack_server; |
| u32 seq_server; |
| int write_done; |
| int read_done; |
| u32 dip, sip; |
| u8 *payload; |
| u8 *buf; |
| int fd; |
| }; |
| |
| struct uip_tx_arg { |
| void *vnet; |
| struct uip_info *info; |
| struct uip_eth *eth; |
| int vnet_len; |
| int eth_len; |
| }; |
| |
| static inline u16 uip_ip_hdrlen(struct uip_ip *ip) |
| { |
| return (ip->vhl & 0x0f) * 4; |
| } |
| |
| static inline u16 uip_ip_len(struct uip_ip *ip) |
| { |
| return htons(ip->len); |
| } |
| |
| static inline u16 uip_udp_hdrlen(struct uip_udp *udp) |
| { |
| return 8; |
| } |
| |
| static inline u16 uip_udp_len(struct uip_udp *udp) |
| { |
| return ntohs(udp->len); |
| } |
| |
| static inline u16 uip_tcp_hdrlen(struct uip_tcp *tcp) |
| { |
| return (tcp->off >> 4) * 4; |
| } |
| |
| static inline u16 uip_tcp_len(struct uip_tcp *tcp) |
| { |
| struct uip_ip *ip; |
| |
| ip = &tcp->ip; |
| |
| return uip_ip_len(ip) - uip_ip_hdrlen(ip); |
| } |
| |
| static inline u16 uip_tcp_payloadlen(struct uip_tcp *tcp) |
| { |
| return uip_tcp_len(tcp) - uip_tcp_hdrlen(tcp); |
| } |
| |
| static inline u8 *uip_tcp_payload(struct uip_tcp *tcp) |
| { |
| return (u8 *)&tcp->sport + uip_tcp_hdrlen(tcp); |
| } |
| |
| static inline bool uip_tcp_is_syn(struct uip_tcp *tcp) |
| { |
| return (tcp->flg & UIP_TCP_FLAG_SYN) != 0; |
| } |
| |
| static inline bool uip_tcp_is_fin(struct uip_tcp *tcp) |
| { |
| return (tcp->flg & UIP_TCP_FLAG_FIN) != 0; |
| } |
| |
| static inline u32 uip_tcp_isn(struct uip_tcp *tcp) |
| { |
| return ntohl(tcp->seq); |
| } |
| |
| static inline u32 uip_tcp_isn_alloc(void) |
| { |
| /* |
| * FIXME: should increase every 4ms |
| */ |
| return 10000000; |
| } |
| |
| static inline u16 uip_eth_hdrlen(struct uip_eth *eth) |
| { |
| return sizeof(*eth); |
| } |
| |
| int uip_tx(struct iovec *iov, u16 out, struct uip_info *info); |
| int uip_rx(struct iovec *iov, u16 in, struct uip_info *info); |
| void uip_static_init(struct uip_info *info); |
| int uip_init(struct uip_info *info); |
| void uip_exit(struct uip_info *info); |
| void uip_tcp_exit(struct uip_info *info); |
| void uip_udp_exit(struct uip_info *info); |
| |
| int uip_tx_do_ipv4_udp_dhcp(struct uip_tx_arg *arg); |
| int uip_tx_do_ipv4_icmp(struct uip_tx_arg *arg); |
| int uip_tx_do_ipv4_tcp(struct uip_tx_arg *arg); |
| int uip_tx_do_ipv4_udp(struct uip_tx_arg *arg); |
| int uip_tx_do_ipv4(struct uip_tx_arg *arg); |
| int uip_tx_do_arp(struct uip_tx_arg *arg); |
| |
| u16 uip_csum_icmp(struct uip_icmp *icmp); |
| u16 uip_csum_udp(struct uip_udp *udp); |
| u16 uip_csum_tcp(struct uip_tcp *tcp); |
| u16 uip_csum_ip(struct uip_ip *ip); |
| |
| struct uip_buf *uip_buf_set_used(struct uip_info *info, struct uip_buf *buf); |
| struct uip_buf *uip_buf_set_free(struct uip_info *info, struct uip_buf *buf); |
| struct uip_buf *uip_buf_get_used(struct uip_info *info); |
| struct uip_buf *uip_buf_get_free(struct uip_info *info); |
| struct uip_buf *uip_buf_clone(struct uip_tx_arg *arg); |
| |
| int uip_udp_make_pkg(struct uip_info *info, struct uip_udp_socket *sk, struct uip_buf *buf, u8 *payload, int payload_len); |
| bool uip_udp_is_dhcp(struct uip_udp *udp); |
| |
| int uip_dhcp_get_dns(struct uip_info *info); |
| void uip_dhcp_exit(struct uip_info *info); |
| #endif /* KVM__UIP_H */ |