/** * This is a callback function that is used by the netfilter module * whenever a packet is intercepted and read from the netfilter queue. * @param qh a pointer to the handle for the nfq queue * @param msg a pointer to an nfgenmsg structure * @param pkt a pointer to the packet retrieved from the nfq queue * @param cbData a pointer to the data of the callback function * @return 0 upon success */ static int cb(struct nfq_q_handle *qh, struct nfgenmsg *msg, struct nfq_data *pkt, void *cbData) { // declaration of local variables u_int16_t id; u_int8_t protocol; unsigned char* pktData; Host* data = (Host*) cbData; struct ipPacket* regularPkt; struct ipPacket* newPkt; struct AITFPacket* AITFPkt; struct AITFPacket* newAITFPkt; struct routeRecord* routeRecord; struct nfqnl_msg_packet_hdr *header; // initialization of local variables int len = nfq_get_payload(pkt, &pktData); // ipAddress = (u_int32_t) cbData; // acquire the netfilter id of the received packet if ((header = nfq_get_msg_packet_hdr(pkt))) { id = ntohl(header->packet_id); } // acquire the received packet and read in its contents regularPkt = (struct ipPacket*) pktData; AITFPkt = (struct AITFPacket*) pktData; // determine if the packet is an AITF packet protocol = (u_int8_t) regularPkt->ipHeader.ip_p; // manage the packet when it is recognized as an AITF packet if (protocol == 61) { std::cout << "- Received an AITF packet" << std::endl; // drop the received packet if the route record is malformed if (AITFPkt->rr.position + 1 > AITFPkt->rr.length) { return nfq_set_verdict(qh, id, NF_DROP, 0, NULL); } struct ifaddrs **ifp; struct ifaddrs *ifpoint; struct sockaddr_in *ip_address; getifaddrs(ifp); for (ifpoint = *ifp; ifpoint != NULL; ifpoint = ifpoint->ifa_next) { if (strncmp(ifpoint->ifa_name, "eth0", 10) == 0) { ip_address = (sockaddr_in *) ifpoint->ifa_addr; break; } } // add to the route record of the received AITF packet Hash hsh = Hash(); unsigned int outlen = 0; AITFPkt->rr.pktFlow[AITFPkt->rr.position + 1].ip = ip_address->sin_addr; AITFPkt->rr.pktFlow[AITFPkt->rr.position + 1].nonce = 1; // produce the flow to send to the policy module Flow flow = Flow(AITFPkt->rr.pktFlow, AITFPkt->rr.length); // provide observed packet flow to host policy module HostPolicyModule policyModule = HostPolicyModule(); if (policyModule.checkHighFlowPolicy(flow) == true){ data->sendMessage(flow); } // remove the route record shim from the packet newPkt->ipHeader = AITFPkt->ipHeader; newPkt->ipHeader.ip_p = AITFPkt->rr.protocol; newPkt->ipHeader.ip_sum = checksum((void*) newPkt, sizeof(struct ipPacket)); // drop the modified packet back into to be received by a socket memcpy(newPkt->payload, AITFPkt->payload, 1500); return nfq_set_verdict(qh, id, NF_ACCEPT, sizeof(ipPacket), (const unsigned char*) newPkt); } std::cout << "- Returning packet back to queue" << std::endl; newAITFPkt->ipHeader = regularPkt->ipHeader; memmove(newAITFPkt->payload, regularPkt->payload, 1500); newAITFPkt->rr.length = 10; newAITFPkt->rr.position = 0; newAITFPkt->rr.protocol = 61; newAITFPkt->rr.pktFlow[0].ip = regularPkt->ipHeader.ip_src; newAITFPkt->rr.pktFlow[0].nonce = 1; newAITFPkt->ipHeader.ip_sum = checksum(newAITFPkt, sizeof(AITFPacket)); return nfq_set_verdict(qh, id, NF_ACCEPT, sizeof(AITFPacket), (const unsigned char*) newAITFPkt); }