bool relayd_handle_dhcp_packet(struct relayd_interface *rif, void *data, int len, bool forward, bool parse) { struct ip_packet *pkt = data; struct udphdr *udp; struct dhcp_header *dhcp; struct relayd_host *host; int udplen; uint16_t sum; if (pkt->eth.ether_type != htons(ETH_P_IP)) return false; if (pkt->iph.version != 4) return false; if (pkt->iph.protocol != IPPROTO_UDP) return false; udp = (void *) ((char *) &pkt->iph + (pkt->iph.ihl << 2)); dhcp = (void *) (udp + 1); udplen = ntohs(udp->len); if (udplen > len - ((char *) udp - (char *) data)) return false; if (udp->dest != htons(67) && udp->source != htons(67)) return false; if (dhcp->op != 1 && dhcp->op != 2) return false; if (!forward) return true; if (dhcp->op == 2) { host = relayd_refresh_host(rif, pkt->eth.ether_shost, (void *) &pkt->iph.saddr); if (host && parse) parse_dhcp_options(host, dhcp, udplen - sizeof(struct udphdr)); } DPRINTF(2, "%s: handling DHCP %s\n", rif->ifname, (dhcp->op == 1 ? "request" : "response")); dhcp->flags |= htons(DHCP_FLAG_BROADCAST); udp->check = 0; sum = udplen + IPPROTO_UDP; sum = chksum(sum, (void *) &pkt->iph.saddr, 8); sum = chksum(sum, (void *) udp, udplen); if (sum == 0) sum = 0xffff; udp->check = htons(~sum); relayd_forward_bcast_packet(rif, data, len); return true; }
indigo_error_t indigo_fwd_packet_out (of_packet_out_t *pkt) { of_octets_t data; ppe_packet_t ppep; printf("\n********\n***DUMPING Fwd pkt out Received and Checked\n*************\n"); //of_packet_out_OF_VERSION_1_3_dump((loci_writer_f)aim_printf, &aim_pvs_stdout, pkt); of_packet_out_data_get(pkt, &data); ppe_packet_init(&ppep, data.data, data.bytes); if (ppe_parse(&ppep) < 0) { printf("\nERROR: Packet parsing failed. packet=%p, len=%u", data.data, data.bytes); } //ppe_packet_dump(&ppep,&aim_pvs_stdout); parse_dhcp_options(&ppep, data.bytes, 1, 1); return INDIGO_ERROR_NONE; }
int main( int argc, char *argv[] ) { #ifdef __MINGW32__ WSADATA wsaData; int nCode; #endif int sockfd; struct sockaddr_in my_addr; struct sockaddr_in their_addr; int addr_len, numbytes; DHCPMESSAGE dhcpm; DHCPOPTIONS dhcpo; #ifdef __MINGW32__ if ((nCode = WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0) { perror("WSAStartup"); return 0; } #endif if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror("socket"); exit(1); } init_leases_list(); my_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); my_addr.sin_addr.s_addr = INADDR_ANY; memset(&(my_addr.sin_zero), '\0', 8); if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } addr_len = sizeof(struct sockaddr); while((numbytes=recvfrom(sockfd,&dhcpm, sizeof( DHCPMESSAGE ), 0, (struct sockaddr *)&their_addr, &addr_len)) != -1) { /* Parse DHCP */ display_dhcp_packet( &dhcpm, &dhcpo ); if( parse_dhcp_options( &dhcpm, &dhcpo ) < 0 ) continue; if( display_dhcp_packet( &dhcpm, &dhcpo ) < 0 ) continue; if( process_dhcp_packet( &dhcpm, &dhcpo ) < 0 ) continue; } close(sockfd); #ifdef __MINGW32__ WSACleanup(); #endif return 0; }