void process_arp(void) { cur_pkt->arp_hdr = (arp_hdr_t *) (cur_pkt->buf + sizeof(eth_hdr_t)); if (likely(cur_pkt->arp_hdr->opcode == ARP_OPCODE_REQUEST)) { process_arp_request(); } }
void arpModel() { int n; // puts("----->ARP: Ready for requests..."); while (1) { // rset = allset; FD_ZERO(&rset); FD_SET(un_listenfd, &rset); FD_SET(if_sockfd, &rset); maxfd = max(un_listenfd, if_sockfd); if (un_connfd != -1){ printf("Add un_connfd to fs_set %d\n", un_connfd); FD_SET(un_connfd, &rset); maxfd = (maxfd, un_connfd); } Select(maxfd + 1, &rset, NULL, NULL, NULL); if (FD_ISSET(un_listenfd, &rset)) { // puts("----->ARP: Request to establish domain socket connection."); accept_conn(un_listenfd); } if (un_connfd != -1 && FD_ISSET(un_connfd, &rset)) { struct hwaddr hwaddr_info; bzero(&hwaddr_info, sizeof(struct hwaddr)); if ((n = recv_un(un_connfd, &hwaddr_info)) > 0) { // puts("----->ARP: Incoming un_packet. Handing over..."); // printf("Requested IP is: %s\n", hwaddr_info.sll_ip); process_un(un_connfd, &hwaddr_info); } else if(n == 0) { puts("----->ARP: Time out."); close(un_connfd); un_connfd = -1; } } if (FD_ISSET(if_sockfd, &rset)) { struct arp_msg msg; bzero(&msg, sizeof(struct arp_msg)); if ((n = recv_arp(if_sockfd, &msg)) == 0) { // puts("*********MSG received***********"); // print_msg(&msg); if (msg.op == ARP_REQ) { // puts("----->ARP: Incoming PF_PACKET: ARP request. Handing over..."); process_arp_request(if_sockfd, &msg); } else if (msg.op == ARP_REP) { // puts("----->ARP: Incoming PF_PACKET: ARP reply. Handing over..."); process_arp_reply(if_sockfd, &msg); } } } } }
/*--------------------------------------------------------------------- * Method: process_arp(struct sr_instance* sr, * uint8_t * packet, * unsigned int len, * char* interface) * Scope: Internal * * This function processes an arp packe that was received. It handles * two cases, one where it is a request and one where it is a response. * *---------------------------------------------------------------------*/ void process_arp(struct sr_instance* sr, uint8_t * packet, unsigned int len, char* interface) { struct sr_arpentry *arp_entry; struct sr_arpreq *arp_req; struct sr_arp_hdr *arp_hdr; struct sr_if* rec_if; /* Validate the arp packet */ if (!valid_arp(packet, len)) return; /* Is the arp addressed to me? NOTE: I do not follow the RFC recommendation to * update existing cache entries with the received arp packet's ip-mac mapping * before checking whether the packet was addressed me. This is because we do * not have a good way to strictly 'update' cache entries without inserting a new * one and I would like to avoid duplicate valid cache entries for the same ip. */ rec_if = sr_get_interface(sr, interface); arp_hdr = arp_header(packet); if (rec_if->ip != arp_hdr->ar_tip) return; /* Add the sender's protocol address to my table. */ arp_entry = sr_arpcache_lookup(&sr->cache, arp_hdr->ar_sip); /* Arp entry already exists. NOTE: arp_entry is a copy in this case so free it.*/ if (arp_entry != 0) { free(arp_entry); /* Arp entry doesn't exist so add it. */ } else { arp_req = sr_arpcache_insert(&sr->cache, arp_hdr->ar_sha, arp_hdr->ar_sip); /* There are packets waiting on this arp request. Send them. */ if (arp_req != 0) { sr_arpreq_send_packets(sr, arp_req); } } /* Handle a request. */ if (arp_opcode(arp_hdr) == arp_op_request) { process_arp_request(sr, arp_hdr, rec_if); } }
void process_arp_packet( struct sr_instance *sr, const uint8_t *packet, unsigned int len, const char *interface) { assert(sr); assert(packet); assert(interface); arp_hdr *arp_packet = get_arp_hdr(packet, len); switch(ntohs(arp_packet->arp_op)) { case ARP_OP_REQUEST: process_arp_request(sr, packet, len, interface); break; case ARP_OP_REPLY: process_arp_reply(sr, packet, len, interface); break; default: return; } }