unsigned int sec_url_filter_hook( unsigned int hook_no,
     struct sk_buff *skb,
     const struct net_device *dev_in,
     const struct net_device *dev_out,
     int (*handler)(struct sk_buff *))
{
    unsigned int    verdict = NF_ACCEPT;
    if (filterMode)
    {
        if (skb != NULL)
        {
            struct iphdr *iph = (struct iphdr*) ip_hdr(skb);
            if (iph != NULL)
            {
                if (iph->protocol == 6)	// TCP case
                {
                    int             delFlag     = 0;
                    struct tcphdr   *tcph       = (struct tcphdr *)skb_transport_header(skb);
                    tcp_TrackInfo   *rejected   = NULL;
                    if (tcph!= NULL)
                    {
                        delFlag = (tcph->fin || tcph->rst);
                    }
                    verdict     = NF_QUEUE;
                    rejected    = find_tcp_TrackInfo(rejected_TrackInfo, skb, delFlag);     // If this is FIN packet, remove TCP Info.
                    if (rejected != NULL)   // This is Rejected
                    {
                        verdict = NF_DROP;
                    }
                    if (delFlag == 1)
                    {
                        tcp_TrackInfo   *gettingNode    = NULL;

                        verdict = NF_ACCEPT;
                        if (rejected != NULL)
                        {
                            free_tcp_TrackInfo(rejected);
                        }
                        gettingNode = find_tcp_TrackInfo(getting_TrackInfo, skb, 1);    // Find previous TCP Track Info and remove from list
                        free_tcp_TrackInfo(gettingNode);
                    }
                }
            }
        }
    }
    return verdict;
}
Ejemplo n.º 2
0
void    clean_tcp_TrackInfos(tcp_Info_Manager *manager)
{
    unsigned long   flags   = 0;
    tcp_TrackInfo   *node   = NULL;

    if (manager != NULL)
    {
        SEC_spin_lock_irqsave(&manager->tcp_info_lock, flags);
        while (manager->head != NULL)
        {
            node = manager->head;
            manager->head = manager->head->next;
            if (node->q_entry != NULL)
            {
                nf_reinject((struct nf_queue_entry *)node->q_entry, NF_DROP);
                node->q_entry = NULL;
            }
            free_tcp_TrackInfo(node);
        }
        manager->tail = NULL;
        manager->count  = 0;
        SEC_spin_unlock_irqrestore(&manager->tcp_info_lock, flags);
    }
}
//  sec_filter driver write function
ssize_t sec_url_filter_write( struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
    int	result = -EIO;
    if ((buf != NULL) && (count >4))
    {
        short   version = *(short *)buf;
        int     cmd     = *(int *)(buf+sizeof(short));
        char    *data   = (char *)(buf+sizeof(short)+sizeof(int));
        {
            if (version == 0)
            {
                switch(cmd)
                {
                    case SET_FILTER_MODE:   // Turn On and Off filtering.
                    {
                        filterMode    = *(int *)data;
                        result      = count;
                        if (filterMode == FILTER_MODE_OFF)
                        {
                            wake_up_interruptible(&user_noti_Q);
                            clean_tcp_TrackInfos(getting_TrackInfo);
                            clean_tcp_TrackInfos(rejected_TrackInfo);
                            clean_tcp_TrackInfos(notifying_TrackInfo);
                            clean_tcp_TrackInfos(notified_TrackInfo);
                            SEC_FREE(exceptionURL);
                            SEC_FREE(errorMsg);
                        }
                        printk(KERN_INFO "SEC URL Filter Mode : %d\n", filterMode);
                    }
                    break;
                    case SET_USER_SELECT:   //version 2, id 4, choice 2
                    {
                        tcp_TrackInfo   *selectInfo = NULL;
                        int             id          = *((int *)(data));
                        int             choice      = *((int *)(data+sizeof(unsigned int)));
                        unsigned int    verdict     = NF_DROP;
                        struct nf_queue_entry *entry= NULL;
                        selectInfo	= find_tcp_TrackInfo_withID(notified_TrackInfo, id, 1);
                        if (selectInfo != NULL)
                        {
                            result  = count;
                            entry   = (struct nf_queue_entry *)selectInfo->q_entry;
                            selectInfo->q_entry = NULL;
                            selectInfo->status  = choice;
                            if (choice == ALLOW || ((filterMode == FILTER_MODE_ON_RESPONSE)||(filterMode == FILTER_MODE_ON_RESPONSE_REFER)))
                            {
                                verdict	= NF_ACCEPT;    //Response case should send packet
                            }
                            if (choice == BLOCK)
                            {
                                add_tcp_TrackInfo(rejected_TrackInfo, selectInfo);  // Add this node to Rejected List.
                            }
                            else
                            {
                                free_tcp_TrackInfo(selectInfo);
                            }
                            nf_reinject(entry, verdict);    // Reinject packet with the verdict
                        }
                        else
                        {
                            printk("SEC_FILTER_URL : NO SUCH ID\n");
                        }
                    }
                    break;
                    case    SET_EXCEPTION_URL:
                    {
                        int urlLen  = *((int *)(data));
                        SEC_FREE(exceptionURL);
                        exceptionURL    = SEC_MALLOC(urlLen+1);
                        if (exceptionURL != NULL)
                        {
                            memcpy(exceptionURL, (data+sizeof(int)), urlLen);
                            result  = count;
                        }
                    }
                    break;
                    case    SET_ERROR_MSG:
                    {
                        int msgLen  = *((int *)(data));
                        SEC_FREE(errorMsg);
                        errMsgSize  = 0;
                        errorMsg    = SEC_MALLOC(msgLen+1);
                        if (errorMsg != NULL)
                        {
                            memcpy(errorMsg, (data+sizeof(int)), msgLen);
                            errMsgSize = msgLen;
                            result  = count;
                        }
                    }
                    break;
                }
            }
        }
    }
    return result;
}
int sec_url_filter_slow(struct nf_queue_entry *entry, unsigned int queuenum)
{
    if (entry != NULL)
    {
        if (filterMode)
        {
            struct sk_buff  *skb            = entry->skb;
            char            *request        = NULL;
            tcp_TrackInfo   *gettingNode    = NULL;
            tcp_TrackInfo   *notifyNode     = NULL;
            if (skb != NULL)
            {
                struct iphdr *iph   = (struct iphdr*)ip_hdr(skb);
                if (iph != NULL)
                {
                    if (iph->protocol == 6)
                    {
                        struct tcphdr   *tcph = (struct tcphdr *)skb_transport_header(skb);
                        if (tcph!= NULL)
                        {
                            notifyNode  = find_tcp_TrackInfo(notifying_TrackInfo, skb, 0);
                            if (notifyNode != NULL)     // If this is already notified to user, drop it.
                            {
                                unsigned int verdict    = NF_DROP;
                                nf_reinject(entry, verdict);
                                return 0;
                            }
                            gettingNode	= find_tcp_TrackInfo(getting_TrackInfo, skb, 1);    // Find previous TCP Track Info and remove from list
                            if (gettingNode == NULL)            // No previous Info
                            {
                                gettingNode = isURL(skb);       // If this is URL Request then make TCP Track Info
                            }
                            if (gettingNode != NULL)
                            {
                                request	= getPacketData(skb, gettingNode);  // Get Packet
                                if (request != NULL)                        // If there is packet data
                                {
                                    getURL(request, gettingNode);           // Get URL	and update status
                                    kfree(request);
                                    request	= NULL;
                                    if (gettingNode->status == GOT_FULL_URL)		// If get Full URL, then make notify info
                                    {
                                        makeNotifyInfo(gettingNode);
                                        if ((exceptionURL != NULL) && (gettingNode->url !=NULL))
                                        {
                                            if (strstr(&gettingNode->url[sizeof(URL_Info)], exceptionURL) != NULL)  // This is exception URL
                                            {
                                                free_tcp_TrackInfo(gettingNode);
                                                nf_reinject(entry, NF_ACCEPT);
                                                return 0;
                                            }
                                        }
                                        gettingNode->q_entry = entry;
                                        add_tcp_TrackInfo(notifying_TrackInfo, gettingNode);
                                        wake_up_interruptible(&user_noti_Q);    // Wake Up read function
                                        return 0;
                                    }
                                }
                                add_tcp_TrackInfo_ToHead(getting_TrackInfo, gettingNode);
                            }
                        }
                    }
                }
            }
        }
        nf_reinject(entry, NF_ACCEPT);
    }

    return 0;
}