10c4bfcacSAsias He #include "kvm/uip.h" 20c4bfcacSAsias He 3bdcc9e40SAsias He #include <arpa/inet.h> 4bdcc9e40SAsias He 58f5f2f95SAsias He static inline bool uip_dhcp_is_discovery(struct uip_dhcp *dhcp) 68f5f2f95SAsias He { 78f5f2f95SAsias He return (dhcp->option[2] == UIP_DHCP_DISCOVER && 88f5f2f95SAsias He dhcp->option[1] == UIP_DHCP_TAG_MSG_TYPE_LEN && 98f5f2f95SAsias He dhcp->option[0] == UIP_DHCP_TAG_MSG_TYPE); 108f5f2f95SAsias He } 118f5f2f95SAsias He 128f5f2f95SAsias He static inline bool uip_dhcp_is_request(struct uip_dhcp *dhcp) 138f5f2f95SAsias He { 148f5f2f95SAsias He return (dhcp->option[2] == UIP_DHCP_REQUEST && 158f5f2f95SAsias He dhcp->option[1] == UIP_DHCP_TAG_MSG_TYPE_LEN && 168f5f2f95SAsias He dhcp->option[0] == UIP_DHCP_TAG_MSG_TYPE); 178f5f2f95SAsias He } 188f5f2f95SAsias He 190c4bfcacSAsias He bool uip_udp_is_dhcp(struct uip_udp *udp) 200c4bfcacSAsias He { 210c4bfcacSAsias He struct uip_dhcp *dhcp; 220c4bfcacSAsias He 230c4bfcacSAsias He if (ntohs(udp->sport) != UIP_DHCP_PORT_CLIENT || 240c4bfcacSAsias He ntohs(udp->dport) != UIP_DHCP_PORT_SERVER) 250c4bfcacSAsias He return false; 260c4bfcacSAsias He 270c4bfcacSAsias He dhcp = (struct uip_dhcp *)udp; 280c4bfcacSAsias He 290c4bfcacSAsias He if (ntohl(dhcp->magic_cookie) != UIP_DHCP_MAGIC_COOKIE) 300c4bfcacSAsias He return false; 310c4bfcacSAsias He 320c4bfcacSAsias He return true; 330c4bfcacSAsias He } 34bdcc9e40SAsias He 35bdcc9e40SAsias He int uip_dhcp_get_dns(struct uip_info *info) 36bdcc9e40SAsias He { 37bdcc9e40SAsias He char key[256], val[256]; 38bdcc9e40SAsias He struct in_addr addr; 39bdcc9e40SAsias He int ret = -1; 40bdcc9e40SAsias He int n = 0; 41bdcc9e40SAsias He FILE *fp; 42bdcc9e40SAsias He u32 ip; 43bdcc9e40SAsias He 44bdcc9e40SAsias He fp = fopen("/etc/resolv.conf", "r"); 45bdcc9e40SAsias He if (!fp) 46bdcc9e40SAsias He goto out; 47bdcc9e40SAsias He 48bdcc9e40SAsias He while (!feof(fp)) { 49bdcc9e40SAsias He if (fscanf(fp, "%s %s\n", key, val) != 2) 50bdcc9e40SAsias He continue; 51bdcc9e40SAsias He if (strncmp("domain", key, 6) == 0) 52bdcc9e40SAsias He info->domain_name = strndup(val, UIP_DHCP_MAX_DOMAIN_NAME_LEN); 53bdcc9e40SAsias He else if (strncmp("nameserver", key, 10) == 0) { 54bdcc9e40SAsias He if (!inet_aton(val, &addr)) 55bdcc9e40SAsias He continue; 56bdcc9e40SAsias He ip = ntohl(addr.s_addr); 57bdcc9e40SAsias He if (n < UIP_DHCP_MAX_DNS_SERVER_NR) 58bdcc9e40SAsias He info->dns_ip[n++] = ip; 59bdcc9e40SAsias He ret = 0; 60bdcc9e40SAsias He } 61bdcc9e40SAsias He } 62bdcc9e40SAsias He 63bdcc9e40SAsias He out: 64bdcc9e40SAsias He fclose(fp); 65bdcc9e40SAsias He return ret; 66bdcc9e40SAsias He } 6732a44aafSAsias He 6832a44aafSAsias He static int uip_dhcp_fill_option_name_and_server(struct uip_info *info, u8 *opt, int i) 6932a44aafSAsias He { 7032a44aafSAsias He u8 domain_name_len; 7132a44aafSAsias He u32 *addr; 7232a44aafSAsias He int n; 7332a44aafSAsias He 7432a44aafSAsias He if (info->domain_name) { 7532a44aafSAsias He domain_name_len = strlen(info->domain_name); 7632a44aafSAsias He opt[i++] = UIP_DHCP_TAG_DOMAIN_NAME; 7732a44aafSAsias He opt[i++] = domain_name_len; 7832a44aafSAsias He memcpy(&opt[i], info->domain_name, domain_name_len); 7932a44aafSAsias He i += domain_name_len; 8032a44aafSAsias He } 8132a44aafSAsias He 8232a44aafSAsias He for (n = 0; n < UIP_DHCP_MAX_DNS_SERVER_NR; n++) { 8332a44aafSAsias He if (info->dns_ip[n] == 0) 8432a44aafSAsias He continue; 8532a44aafSAsias He opt[i++] = UIP_DHCP_TAG_DNS_SERVER; 8632a44aafSAsias He opt[i++] = UIP_DHCP_TAG_DNS_SERVER_LEN; 8732a44aafSAsias He addr = (u32 *)&opt[i]; 8832a44aafSAsias He *addr = htonl(info->dns_ip[n]); 8932a44aafSAsias He i += UIP_DHCP_TAG_DNS_SERVER_LEN; 9032a44aafSAsias He } 9132a44aafSAsias He 9232a44aafSAsias He return i; 9332a44aafSAsias He } 94*ab8d80a6SAsias He static int uip_dhcp_fill_option(struct uip_info *info, struct uip_dhcp *dhcp, int reply_msg_type) 95*ab8d80a6SAsias He { 96*ab8d80a6SAsias He int i = 0; 97*ab8d80a6SAsias He u32 *addr; 98*ab8d80a6SAsias He u8 *opt; 99*ab8d80a6SAsias He 100*ab8d80a6SAsias He opt = dhcp->option; 101*ab8d80a6SAsias He 102*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_MSG_TYPE; 103*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_MSG_TYPE_LEN; 104*ab8d80a6SAsias He opt[i++] = reply_msg_type; 105*ab8d80a6SAsias He 106*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_SERVER_ID; 107*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_SERVER_ID_LEN; 108*ab8d80a6SAsias He addr = (u32 *)&opt[i]; 109*ab8d80a6SAsias He *addr = htonl(info->host_ip); 110*ab8d80a6SAsias He i += UIP_DHCP_TAG_SERVER_ID_LEN; 111*ab8d80a6SAsias He 112*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_LEASE_TIME; 113*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_LEASE_TIME_LEN; 114*ab8d80a6SAsias He addr = (u32 *)&opt[i]; 115*ab8d80a6SAsias He *addr = htonl(UIP_DHCP_LEASE_TIME); 116*ab8d80a6SAsias He i += UIP_DHCP_TAG_LEASE_TIME_LEN; 117*ab8d80a6SAsias He 118*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_SUBMASK; 119*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_SUBMASK_LEN; 120*ab8d80a6SAsias He addr = (u32 *)&opt[i]; 121*ab8d80a6SAsias He *addr = htonl(info->guest_netmask); 122*ab8d80a6SAsias He i += UIP_DHCP_TAG_SUBMASK_LEN; 123*ab8d80a6SAsias He 124*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_ROUTER; 125*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_ROUTER_LEN; 126*ab8d80a6SAsias He addr = (u32 *)&opt[i]; 127*ab8d80a6SAsias He *addr = htonl(info->host_ip); 128*ab8d80a6SAsias He i += UIP_DHCP_TAG_ROUTER_LEN; 129*ab8d80a6SAsias He 130*ab8d80a6SAsias He i = uip_dhcp_fill_option_name_and_server(info, opt, i); 131*ab8d80a6SAsias He 132*ab8d80a6SAsias He opt[i++] = UIP_DHCP_TAG_END; 133*ab8d80a6SAsias He 134*ab8d80a6SAsias He return 0; 135*ab8d80a6SAsias He } 136