void process_packet(int socket) { unsigned char *buffer; int size = 0; struct sockaddr_in recv_addr; struct iphdr *ipheader; struct ospfhdr *ospfheader; unsigned int iphdr_len, recv_addr_len; struct ospf_interface *oiface; buffer = malloc(sizeof(*buffer)*REPLAY_PACKET_BUFFER); memset(&recv_addr,0,sizeof(recv_addr)); recv_addr_len = sizeof(recv_addr); size = recvfrom(socket, buffer, REPLAY_PACKET_BUFFER, 0, (struct sockaddr *)&recv_addr, &recv_addr_len); if(size>0) { oiface = find_oiface_by_socket(socket); if(recv_addr.sin_addr.s_addr != oiface->iface->ip.s_addr) { ipheader = (struct iphdr *)buffer; iphdr_len = ipheader->ihl*4; ospfheader = (struct ospfhdr *)(buffer+iphdr_len); switch(ospfheader->mesg_type) { case OSPF_MESG_HELLO: process_hello(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface); break; case OSPF_MESG_DBDESC: process_dbdesc(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface); break; case OSPF_MESG_LSR: process_lsr(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface); break; case OSPF_MESG_LSU: process_lsu(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface); break; case OSPF_MESG_LSACK: process_lsack(buffer+iphdr_len,ipheader->saddr,ipheader->daddr,((unsigned int)ntohs(ospfheader->packet_length)),oiface); break; } } } else { //error reading in packet } free(buffer); }
void *recv_loop(void *p) { uint8_t buf[BUFFER_SIZE]; interface *iface; ospf_header *ospfhdr; neighbor *nbr; in_addr_t src; while (*(int *)p) { iface = recv_ospf(sock, buf, BUFFER_SIZE, &src); ospfhdr = (ospf_header *)(buf + sizeof(struct iphdr)); /* check if the packet is from myself */ if (ospfhdr->router_id == myid) continue; for (nbr = iface->nbrs; nbr; nbr = nbr->next) if (ospfhdr->router_id == nbr->router_id) break; switch (ospfhdr->type) { case OSPF_TYPE_HELLO: process_hello(iface, nbr, ospfhdr, src); break; case OSPF_TYPE_DD: process_dd(iface, nbr, ospfhdr); break; case OSPF_TYPE_LSR: process_lsr(nbr, ospfhdr);break; case OSPF_TYPE_LSU: process_lsu(iface->a, nbr, ospfhdr);break; case OSPF_TYPE_LSACK: process_ack(nbr, ospfhdr);break; default: break; } } return NULL; }