/**@brief this generates a Fins frame which is sent to the arp module so that the * (1) a host receives an ARP reply, OR (2) sends an ARP request to a network * @param fins_frame is the pointer to the received fins frame * @param task indicates whether the arp message is a request or a reply to or from network */ void fins_from_net(struct finsFrame *fins_frame, int task) { uint32_t IP_addrs_read; uint64_t MAC_addrs; struct ARP_message *msg1 = (struct ARP_message*)malloc(sizeof(struct ARP_message)); struct ARP_message *msg2 = (struct ARP_message*)malloc(sizeof(struct ARP_message)); struct arp_hdr *arp_net = (struct arp_hdr*) malloc(sizeof(struct arp_hdr)); PRINT_DEBUG("\nFins data frame which carries a request or reply ARP from a network\n"); IP_addrs_read = read_IP_addrs(); MAC_addrs = search_MAC_addrs(IP_addrs_read, ptr_neighbor_list); if (task==1){ mimic_net_request(IP_addrs_read, MAC_addrs, msg1); arp_msg_to_hdr(msg1, arp_net); host_to_net(arp_net); arp_to_fins(arp_net, fins_frame); } else if (task==2){ gen_requestARP(IP_addrs_read, msg1); mimic_net_reply(msg1, msg2); arp_msg_to_hdr(msg2, arp_net); host_to_net(arp_net); arp_to_fins(arp_net, fins_frame); } fins_frame->destinationID.id = ARPID; free(msg1); free(msg2); }
/**@brief this function generates a fins frame from the ethernet stub * @param fins_frame is the pointer to the fins frame to be sent into the arp */ void fins_from_stub(struct finsFrame *fins_frame){ uint32_t IP_addrs_read; PRINT_DEBUG("\nFins control frame from link layer stub\n"); IP_addrs_read = read_IP_addrs(); fins_frame->dataOrCtrl = CONTROL; fins_frame->destinationID.id = ARPID; fins_frame->ctrlFrame.opcode = READREQUEST; fins_frame->ctrlFrame.serialNum = 123; fins_frame->ctrlFrame.senderID = ETHERSTUBID; fins_frame->ctrlFrame.paramterID = IP_addrs_read; //IP address passed through this variable }
/**@brief this function tests a set of functions which are used when * (1) a host receives an ARP request, and (2) keeps updating its cache based on * these ARP requests * @param fileName is the file from which the list of neighbors is drawn */ void send_receive_update(char *fileName) { extern struct node *ptr_cacheHeader; struct finsFrame request_fins, reply_fins, *request_fins_ptr, *reply_fins_ptr; struct ARP_message request_ARP1, request_ARP2, reply_ARP1, reply_ARP2; struct ARP_message *request_ARP_ptr1, *request_ARP_ptr2, *reply_ARP_ptr1, *reply_ARP_ptr2; struct arp_hdr hdr_ARP, *hdr_ARP_ptr; uint64_t MAC_addrs; uint32_t IP_addrs_read; int task; /**Following code generates a list of IP/MAC addresses of 'neighbors' and initializes cache*/ ptr_cacheHeader = init_intface(); gen_neighbor_list(fileName); init_recordsARP(fileName); print_cache(); print_neighbors(ptr_neighbor_list); hdr_ARP_ptr = &hdr_ARP; IP_addrs_read = 1; task = 1; /**Begin Initialize/Instantiate Pointers */ request_fins_ptr = &request_fins; reply_fins_ptr = &reply_fins; request_ARP_ptr1 = &request_ARP1; request_ARP_ptr2 = &request_ARP2; reply_ARP_ptr1 = &reply_ARP1; reply_ARP_ptr2 = &reply_ARP2; /**A host can send update its cache based on its own request or a request from another network host*/ while (IP_addrs_read!=0 && (task==0 || task == 1)) { PRINT_DEBUG("\nTest send request and update `0' or test receive a request `1' \n"); scanf("%d", &task); IP_addrs_read = read_IP_addrs(); /**The following functions test the internal operations of the module*/ if (task==0){ gen_requestARP(IP_addrs_read, request_ARP_ptr1); print_msgARP(request_ARP_ptr1); arp_to_fins(request_ARP_ptr1, request_fins_ptr); fins_to_arp(request_fins_ptr, request_ARP_ptr2); mimic_net_reply(request_ARP_ptr2, reply_ARP_ptr1); if (check_valid_arp(reply_ARP_ptr1)==1){ arp_to_fins(reply_ARP_ptr1, reply_fins_ptr); fins_to_arp(reply_fins_ptr, reply_ARP_ptr2); print_msgARP(reply_ARP_ptr2); update_cache(reply_ARP_ptr2);} print_cache(); } else if (task==1){ MAC_addrs = search_MAC_addrs(IP_addrs_read, ptr_neighbor_list); mimic_net_request(IP_addrs_read, MAC_addrs,request_ARP_ptr1); print_msgARP(request_ARP_ptr1); if (check_valid_arp(request_ARP_ptr1)==1){ arp_to_fins(request_ARP_ptr1, request_fins_ptr); fins_to_arp(request_fins_ptr, request_ARP_ptr2); print_msgARP(request_ARP_ptr2); update_cache(request_ARP_ptr2);} print_cache(); } /**The following functions test the external operation of the module*/ if (check_valid_arp(request_ARP_ptr2)==1){ hdr_ARP_ptr = &hdr_ARP; /**convert ARP message to htons format and generate MAC addresses as unsigned char ptr*/ net_fmt_conversion(request_ARP_ptr2, hdr_ARP_ptr); print_arp_hdr(hdr_ARP_ptr);/**print some fields of the ARP message in external format*/ host_fmt_conversion(hdr_ARP_ptr, request_ARP_ptr2);/**convert ARP message to ntohs format*/ print_msgARP(request_ARP_ptr2);/**print ARP message internal format*/ } } term_intface(); }