Example #1
0
/**
 * 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);
}