ubuntu14.04LTS安裝vmware10.0.1

由於所用Ubuntu系統是32位,而VMware最新版本又不支持32位,只好下載之前版本vmware10.0.1。

vmware10.0.1下載地址:  http://down.it168.com/114/130/14858/index.shtmlphp

附上一組序列號:html

0F63E-20HEM-4ZC49-RKC5M-A22HY
4F2A2-ARHEK-MZJJ0-JH8EH-C2GQG
1U64X-AA351-KZ519-4R85M-A2KJR
HU03A-F83EM-9Z7L8-LT974-3CE7V
1A46W-AHL9H-FZ7Z8-ETC50-0CK4P
1U2WF-64K91-EZQU9-T195H-0A34K
JZ2Q8-DZJ5L-VZWG8-ZH0NH-A3ZNR
NU4KA-48JDM-LZUV9-3J27P-AAJLZ
NU0FD-0C10L-UZJ48-U18XK-2AX4J
1Z01F-2FL11-RZUU8-ZV254-12CP0

 

修改下載文件的權限以及用戶的權限後, linux

在ubuntu14.04LTS下面安裝完成後啓動(可在終端運行vmware)報錯, 在日誌中能夠看到,主要是filter.c的一個文件redis


一.修改方法: ubuntu

修改方法以下,但不是下面方法中的 vnetUserListener.c文件,是filter.c文件
$ cd /tmpsocket

$ tar xf /usr/lib/vmware/modules/source/vmnet.tar
$ cd vmnet-only
$ vi vnetUserListener.c
go to line 37 (after the last include), add this line:  #include 「compat_sched.h」 then save and exit
$ cd /tmp
$ sudo tar cf /usr/lib/vmware/modules/source/vmnet.tar vmnet-only

$  vmwareide

二.修改內容:oop

可直接替換(如下是filter.c的所有內容)post

能夠參考:http://forum.ubuntu.org.cn/viewtopic.php?p=3075443 ui

 

/*********************************************************  * Copyright (C) 2006 VMware, Inc. All rights reserved.  *  * This program is free software; you can redistribute it and/or modify it  * under the terms of the GNU General Public License as published by the  * Free Software Foundation version 2 and no later version.  *  * This program is distributed in the hope that it will be useful, but  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License  * for more details.  *  * You should have received a copy of the GNU General Public License along  * with this program; if not, write to the Free Software Foundation, Inc.,  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA  *  *********************************************************/ #include "driver-config.h" #include <linux/kernel.h> #include <linux/version.h> #include <linux/socket.h> #include <linux/if_ether.h> #include <linux/in.h> #include <linux/ip.h> #include "compat_skbuff.h" #include "compat_module.h" #include <linux/mutex.h> #include <linux/netdevice.h> #include <linux/version.h> #if COMPAT_LINUX_VERSION_CHECK_LT(3, 2, 0) #   include <linux/module.h> #else #   include <linux/export.h> #endif /*  * All this makes sense only if NETFILTER support is configured in our kernel.  */ #ifdef CONFIG_NETFILTER #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> #include <linux/poll.h> #include "vnetFilter.h" #include "vnetFilterInt.h" #include "vnetInt.h" #include "vmnetInt.h" // VNet_FilterLogPacket.action for dropped packets #define VNET_FILTER_ACTION_DRP         (1) #define VNET_FILTER_ACTION_DRP_SHORT   (2) #define VNET_FILTER_ACTION_DRP_MATCH   (3) #define VNET_FILTER_ACTION_DRP_DEFAULT (4) // VNet_FilterLogPacket.action for forwarded packets #define VNET_FILTER_ACTION_FWD         (1<<8 | 1) #define VNET_FILTER_ACTION_FWD_LOOP    (1<<8 | 5) #define VNET_FILTER_ACTION_FWD_MATCH   (1<<8 | 6) #define VNET_FILTER_ACTION_FWD_DEFAULT (1<<8 | 7) /* netfilter hooks for filtering. */ static nf_hookfn VNetFilterHookFn; static struct nf_hook_ops vmnet_nf_ops[] = {    {  .hook = VNetFilterHookFn,       .owner = THIS_MODULE,       .pf = PF_INET,       .hooknum = VMW_NF_INET_LOCAL_IN,       .priority = NF_IP_PRI_FILTER - 1, },    {  .hook = VNetFilterHookFn,       .owner = THIS_MODULE,       .pf = PF_INET,       .hooknum = VMW_NF_INET_POST_ROUTING,       .priority = NF_IP_PRI_FILTER - 1, } }; /* track if we actually set a callback in IP's filter driver */ static Bool installedFilterCallback = FALSE; /* rules to use for filtering */ RuleSet *ruleSetHead = NULL;  /* linked list of all rules */ int32 numRuleSets = 0;        /* number of rule sets in ruleSetHead's linked list */ RuleSet *activeRule = NULL;   /* actual rule set for filter callback to use */ /* locks to protect against concurrent accesses. */ static DEFINE_MUTEX(filterIoctlMutex); /* serialize ioctl()s from user space. */ /*  * user/netfilter hook concurrency lock.  * This spinlock doesn't scale well if/when in the future the netfilter  * callbacks can be concurrently executing on multiple threads on multiple  * CPUs, so we should revisit locking for allowing for that in the future.  */ static DEFINE_SPINLOCK(activeRuleLock); /*  * Logging.  *   * All logging for development build uses LOG(2, (KERN_INFO ...)) because the default  * log level is set to 1 (vnetInt.h). All ACE logging, i.e. policy driven logging, uses  * printk(KERN_INFO ...).  */ static uint32 logLevel = VNET_FILTER_LOGLEVEL_NORMAL; /* the current log level */ static void LogPacket(uint16 action, void *header, void *data,                       uint32 length, Bool drop); static int InsertHostFilterCallback(void); static void RemoveHostFilterCallback(void); static RuleSet *FindRuleSetById(uint32 id, RuleSet ***prevPtr); static int CreateRuleSet(uint32 id, uint32 defaultAction); static void DeleteRule(Rule *rule); static int DeleteRuleSet(uint32 id); static int ChangeRuleSet(uint32 id, Bool enable, Bool disable, uint32 action); static int AddIPv4Rule(uint32 id, VNet_AddIPv4Rule *rule,                        VNet_IPv4Address *addressList,                        VNet_IPv4Port *portList); /*  *----------------------------------------------------------------------  *  * DropPacket --  *  *      Function is used to record information regarding a packet  *      being dropped.  *  * Results:  *      void  *  * Side effects:  *      Might store information regarding the packet.  *  *----------------------------------------------------------------------  */ static INLINE void DropPacket(uint16 action,  // IN: reason code            void *header,   // IN: packet header            void *data,     // IN: packet data            uint32 length)  // IN: packet length {    LogPacket(action, header, data, length, TRUE); } /*  *----------------------------------------------------------------------  *  * ForwardPacket --  *  *      Function is used to record information regarding a packet  *      being forwarded.  *  * Results:  *      void  *  * Side effects:  *      Might store information regarding the packet.  *  *----------------------------------------------------------------------  */ static INLINE void ForwardPacket(uint16 action,  // IN: reason code               void *header,   // IN: packet header               void *data,     // IN: packet data               uint32 length)  // IN: packet length { #ifdef DBG    LogPacket(action, header, data, length, FALSE); #endif } /*  *----------------------------------------------------------------------  *  * VNetFilterHookFn --  *  *      Function is registered as a callback function with the host's  *      IP stack.  This function can be used to filter on specified protocols  *      IP addresses, and/or local and remote ports. It makes use of the Linux  *      netfilter infrastructure, by inserting this function in netfilter at a  *      priority 1 higher than iptables, so that we don't have to worry about  *      any existing iptables based firewall rules on the Linux hosts.  *  * Results:  *      NF_ACCEPT or NF_DROP.  *  * Side effects:  *      None besides those described above.  *  *----------------------------------------------------------------------  */ #define DEBUG_HOST_FILTER 0 #if DEBUG_HOST_FILTER #define HostFilterPrint(a) printk a #else #define HostFilterPrint(a) #endif static unsigned int #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) VNetFilterHookFn(unsigned int hooknum,                 // IN: #else VNetFilterHookFn(const struct nf_hook_ops *ops, // IN: #endif #ifdef VMW_NFHOOK_USES_SKB                  struct sk_buff *skb,                  // IN: #else                  struct sk_buff **pskb,                // IN: #endif                  const struct net_device *in,          // IN:                  const struct net_device *out,         // IN:                  int (*okfn)(struct sk_buff *))        // IN: { #ifndef VMW_NFHOOK_USES_SKB    struct sk_buff *skb = *pskb; #endif    struct iphdr *ip;    uint32 remoteAddr;    uint16 localPort;    uint16 remotePort;    uint8 *packet;    uint8 *packetHeader;    int packetLength;    RuleSet *currRuleSet;    Bool blockByDefault;    Bool transmit; /* TRUE if transmitting, FALSE is receiving */    Rule *currRule;    unsigned int verdict = NF_ACCEPT;    unsigned long flags;    /* Early checks to see  we should even care. */    if (skb->protocol != htons(ETH_P_IP)) {       return verdict;    }    spin_lock_irqsave(&activeRuleLock, flags);    currRuleSet = activeRule;    // ASSERT(currRuleSet);    /*     * Function uses a local copy of ruleSetHead so that we're     * not adversely affected by any rule changes that might occur     * while this function is running.     */    blockByDefault = currRuleSet->action == VNET_FILTER_RULE_BLOCK;    /* When the host transmits, hooknum is VMW_NF_INET_POST_ROUTING. */    /* When the host receives, hooknum is VMW_NF_INET_LOCAL_IN. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)  transmit = (hooknum == VMW_NF_INET_POST_ROUTING); #else  transmit = (ops->hooknum == VMW_NF_INET_POST_ROUTING); #endif    packetHeader = compat_skb_network_header(skb);    ip = (struct iphdr*)packetHeader;    if (transmit) {       /* skb all set up for us. */       packet = compat_skb_transport_header(skb);    } else {       /* skb hasn't had a chance to be processed by TCP yet. */       packet = compat_skb_network_header(skb) + (ip->ihl << 2);    }    HostFilterPrint(("PacketFilter: IP ver %d ihl %d tos %d len %d id %d\n"                     "              offset %d ttl %d proto %d xsum %d\n"                     "              src 0x%08x dest 0x%08x %s\n",                     ip->version, ip->ihl, ip->tos, ip->tot_len, ip->id,           ip->frag_off, ip->ttl, ip->protocol, ip->check,                     ip->saddr, ip->daddr, transmit ? "OUTGOING":"INCOMING"));    /*     * For incoming packets, there should be a skb->dev associated with it, with     * a populated L2 address length.     */    if (skb->dev && skb->dev->hard_header_len) {       packetLength = skb->len - skb->dev->hard_header_len - (ip->ihl << 2);    } else {       /*        * In certain cases, compat_skb_mac_header() has been observed to be NULL. Don't        * know why, but in such cases, this calculation will lead to a negative        * packetLength, and the packet to be dropped.        */       packetLength = skb->len -                       (compat_skb_network_header(skb) - compat_skb_mac_header(skb)) -                       (ip->ihl << 2);    }    if (packetLength < 0) {       HostFilterPrint(("PacketFilter: ill formed packet for IPv4\n"));       HostFilterPrint(("skb: len %d h.raw %p nh.raw %p mac.raw %p, packetLength %d\n",                        skb->len, compat_skb_transport_header(skb),                        compat_skb_network_header(skb),                        compat_skb_mac_header(skb), packetLength));       verdict = NF_DROP;       DropPacket(VNET_FILTER_ACTION_DRP_SHORT, packetHeader, packet, 0);       goto out_unlock;    }    remoteAddr = transmit ? ip->daddr : ip->saddr;    /* always allow 127/8. */    if ((remoteAddr & 0xff) == 127) {       HostFilterPrint(("PacketFilter: allowing %s loopback 0x%08x\n",                        transmit ? "outgoing" : "incoming",                        remoteAddr));       ForwardPacket(VNET_FILTER_ACTION_FWD_LOOP,                     packetHeader, packet, packetLength);       goto out_unlock;    }    /* If we're dealing with TCP or UDP, then extract the port information */    if (ip->protocol == IPPROTO_TCP || ip->protocol == IPPROTO_UDP) {       uint16 srcPort, dstPort; /* used to extract port information from packet */       if (packetLength < 4) {          HostFilterPrint(("PacketFilter: payload too short for "                           "TCP or UDP: %d\n", packetLength));          verdict = NF_DROP;          DropPacket(VNET_FILTER_ACTION_DRP_SHORT,                     packetHeader, packet, packetLength);          goto out_unlock;       }       /* Retrieve UDP/TCP port info */       srcPort = *((uint16*)&packet[0]);       dstPort = *((uint16*)&packet[2]);       if (transmit) { /* transmit */          localPort = ntohs(srcPort);          remotePort = ntohs(dstPort);       } else { /* receive */          localPort = ntohs(dstPort);          remotePort = ntohs(srcPort);       }       HostFilterPrint(("PacketFilter: got local port %d remote port %d\n",                        localPort, remotePort));    } else {       /* these mostly exist to silence compiler warning about uninit variables */       localPort = 0;       remotePort = 0;    }    currRule = currRuleSet->list;    /* traverse all the rules in the rule set */    while (currRule != NULL) {       uint32 i;       Bool matchedAddress;       /* if direction doesn't match rule, then skip */       if ((currRule->direction == VNET_FILTER_DIRECTION_IN && transmit) ||           (currRule->direction == VNET_FILTER_DIRECTION_OUT && !transmit)) {          HostFilterPrint(("PacketFilter: didn't match direction\n"));          /* wrong direction */          goto skipRule;       }       /*        * Check if the packet's address matches the rule.  If the list is empty        * then this means we don't care about address and it's considered a match.        */       matchedAddress = (currRule->addressListLen == 0); /* empty list means don't care */       for (i = 0; i < currRule->addressListLen; ++i) {          if ((remoteAddr & currRule->addressList[i].ipv4Mask) ==              currRule->addressList[i].ipv4Addr) {             matchedAddress = TRUE;             HostFilterPrint(("PacketFilter: rule matched ip addr %u: "                              "0x%08x == 0x%08x\n", i, remoteAddr,                              currRule->addressList[i].ipv4Addr));             break;          } else {             HostFilterPrint(("PacketFilter: rule not match ip addr %u: "                              "0x%08x != 0x%08x\n", i, remoteAddr,                              currRule->addressList[i].ipv4Addr));          }       }       if (!matchedAddress) {          HostFilterPrint(("PacketFilter: rule didn't match ip addr 0x%08x\n",                           remoteAddr));          /* ip addr doesn't match */          goto skipRule;       }       /*        * Check the protocol. ~0 (0xffff) means we don't care about the        * protocol and it's considered a match.        */       if (currRule->proto != 0xffff && currRule->proto != ip->protocol) {          HostFilterPrint(("PacketFilter: didn't match protocol: %u != %u\n",                           ip->protocol, currRule->proto));          /* protocol doesn't match */          goto skipRule;       }       /*        * If the protocol is TCP or UDP then check the port list.  If the list is empty        * then this means we don't care about ports and it's considered a match.        */       if (currRule->proto == IPPROTO_TCP || currRule->proto == IPPROTO_UDP) {          /* An empty list means the rule don't care about port numbers*/          Bool matchedPort = (currRule->portListLen == 0);          for (i = 0; i < currRule->portListLen; ++i) {             RulePort *portRule = currRule->portList + i;             Bool matchedLocal, matchedRemote; /* improves readability */             /*              * It's presumed that if portRule->localPortLow == ~0 then              * portRule->localPortHigh == ~0.  Similiar story for the              * remote ports.              */             matchedLocal = (localPort >= portRule->localPortLow &&                             localPort <= portRule->localPortHigh) ||                            portRule->localPortLow == ~0;             matchedRemote = (remotePort >= portRule->remotePortLow &&                              remotePort <= portRule->remotePortHigh) ||                             portRule->remotePortLow == ~0;             if (matchedLocal && matchedRemote) {                HostFilterPrint(("PacketFilter: matched rule's "                                 "port element %u\n", i));                matchedPort = TRUE;                break;             }             HostFilterPrint(("PacketFilter: didn't match rule's "                              "port element %u\n", i));             HostFilterPrint(("-- local  %4u not in range [%4u, %4u] or \n",                              localPort, portRule->localPortLow,                              portRule->localPortHigh));             HostFilterPrint(("-- remote %4u not in range [%4u, %4u]\n",                              remotePort, portRule->remotePortLow,                              portRule->remotePortHigh));          }          if (!matchedPort) {             HostFilterPrint(("PacketFilter: rule didn't match port "                              "(local %u remote %u)\n", localPort, remotePort));             /* port doesn't match */             goto skipRule;          }       }       /* rule matches so follow orders */       if (currRule->action == VNET_FILTER_RULE_ALLOW) {          HostFilterPrint(("PacketFilter: found match, forwarding\n"));          ForwardPacket(VNET_FILTER_ACTION_FWD_MATCH,                        packetHeader, packet, packetLength);          goto out_unlock;       } else {          HostFilterPrint(("PacketFilter: found match, dropping\n"));          verdict = NF_DROP;          DropPacket(VNET_FILTER_ACTION_DRP_MATCH,                     packetHeader, packet, packetLength);          goto out_unlock;       } skipRule:       currRule = currRule->next;    }    /* Forward or drop packet based on the default rule */    HostFilterPrint(("PacketFilter: Didn't find match for %s "                     "%u.%u.%u.%u, %s packet\n",                     transmit ? "outgoing" : "incoming",                     remoteAddr & 0xff, (remoteAddr >> 8) & 0xff,                     (remoteAddr >> 16) & 0xff, (remoteAddr >> 24) & 0xff,                     blockByDefault ? "drop" : "forward"));    if (blockByDefault) {       verdict = NF_DROP;       DropPacket(VNET_FILTER_ACTION_DRP_DEFAULT,                  packetHeader, packet, packetLength);    } else {       ForwardPacket(VNET_FILTER_ACTION_FWD_DEFAULT,                     packetHeader, packet, packetLength);    } out_unlock:    spin_unlock_irqrestore(&activeRuleLock, flags);    return verdict; } /*  *----------------------------------------------------------------------  *  * InsertHostFilterCallback --  *  *      Function registers a hook in the host's IP stack.  *  * Results:  *      0 on success (or if hook already installed),  *      errno on failure.  *  * Side effects:  *      None.  *  *----------------------------------------------------------------------  */ static int InsertHostFilterCallback(void) {    uint32 i;    int retval = 0;    LOG(2, (KERN_INFO "vnet filter inserting callback\n"));    if (installedFilterCallback) {       LOG(2, (KERN_INFO "vnet filter callback already registered\n"));       goto end;    }    /* Register netfilter hooks. */    for (i = 0; i < ARRAY_SIZE(vmnet_nf_ops); i++) {       if ((retval = nf_register_hook(&vmnet_nf_ops[i])) >= 0) {          continue;       }       /* Encountered an error, back out. */       LOG(2, (KERN_INFO "vnet filter failed to register callback %d: %d\n",               i, retval));       while (i--) {          nf_unregister_hook(&vmnet_nf_ops[i]);       }       goto end;    }    installedFilterCallback = TRUE;    LOG(2, (KERN_INFO "Successfully set packet filter function\n")); end:    return retval; } /*  *----------------------------------------------------------------------  *  * RemoveHostFilterCallback --  *  *      Function deregisters a hook in the host's IP stack.  *  * Results:  *      void  *  * Side effects:  *      None.  *  *----------------------------------------------------------------------  */ static void RemoveHostFilterCallback(void) {    int i;    LOG(2, (KERN_INFO "vnet filter removing callback\n"));    if (installedFilterCallback) {       LOG(2, (KERN_INFO "filter callback was installed: removing filter\n"));       for (i = ARRAY_SIZE(vmnet_nf_ops) - 1; i >= 0; i--) {          nf_unregister_hook(&vmnet_nf_ops[i]);       }       installedFilterCallback = FALSE;    }    LOG(2, (KERN_INFO "vnet filter remove callback done\n")); } /*  *----------------------------------------------------------------------  *  * FindRuleSetById --  *  *      Function is given an ID for a rule set, and returns a  *      pointer to the ruleset with that ID.  The function can  *      optionally report what pointer is pointing to this item  *      (suitable for removing the item from the linked list -- the  *      result might be the prior item's next pointer, or the head).  *  * Results:  *      NULL if rule set not found, otherwise pointer to rule set.  *  * Side effects:  *      None.  *  *----------------------------------------------------------------------  */ static RuleSet * FindRuleSetById(uint32 id,          // IN: id to locate                 RuleSet ***prevPtr) // OUT: pointer to the ->next pointer                                     //      (or head) that points to the                                     //      returned item (optional) {    RuleSet *curr;    RuleSet **prev = NULL;    // ASSERT(id != 0);    curr = ruleSetHead;    prev = &ruleSetHead;    while (curr != NULL) {       if (curr->id == id) {          LOG(2, (KERN_INFO "Found id %u at %p\n", id, curr));          if (prevPtr != NULL) {             *prevPtr = prev;          }          return curr;       }       prev = &curr->next;       curr = curr->next;    }    LOG(2, (KERN_INFO "Didn't find ruleset with id %u\n", id));    /* won't overwrite *prevPtr with NULL */    return NULL; } /*  *----------------------------------------------------------------------  *  * CreateRuleSet --  *  *      Function creates a new rule set with a specified ID and  *      default action.  Call will fail if failed to alloc memory,  *      or if ID is already in use, or if maximum number of  *      rule sets have already been created.  *  * Results:  *      Returns 0 on success, and otherwise returns errno.  *  * Side effects:  *      None.  *  *----------------------------------------------------------------------  */ static int CreateRuleSet(uint32 id,            // IN: requested ID for new rule set               uint32 defaultAction) // IN: default action for rule set {    RuleSet *newRuleSet;    RuleSet *curr;    /* check if too many rule sets already exist */    if (numRuleSets >= MAX_RULE_SETS) {       LOG(2, (KERN_INFO "filter already has all rules (%u of %u) allocated\n",               numRuleSets, MAX_RULE_SETS));       return -EOVERFLOW;    }    /* check if ID is already in use */    curr = FindRuleSetById(id, NULL);    if (curr != NULL) {       LOG(2, (KERN_INFO "filter already has id %u\n", id));       return -EEXIST;    }    /* allocate and init new rule set */    newRuleSet = kmalloc(sizeof *newRuleSet, GFP_USER);    if (newRuleSet == NULL) {       LOG(2, (KERN_INFO "filter mem alloc failed\n"));       return -ENOMEM;    }    memset(newRuleSet, 0, sizeof *newRuleSet);    newRuleSet->next = ruleSetHead;    newRuleSet->id = id;    newRuleSet->enabled = FALSE;    newRuleSet->action = (uint16)defaultAction;    newRuleSet->list = NULL;    newRuleSet->numRules = 0;    newRuleSet->tail = &newRuleSet->list;    /* add new rule set to head of linked list */    numRuleSets++;    ruleSetHead = newRuleSet;    LOG(2, (KERN_INFO "filter created ruleset with id %u\n", id));    return 0; } /*  *----------------------------------------------------------------------  *  * DeleteRule --  *  *      Function frees the memory in a Rule object.  This function  *      frees the arrays in the Rule, but not an elements that  *      are chained on the linked-list via 'next'.  *  * Results:  *      None.  *  * Side effects:  *      None.  *  *----------------------------------------------------------------------  */ static void DeleteRule(Rule *rule)          // IN: Rule to delete. {    // ASSERT(rule);    if (!rule) {       return;    }    if (rule->addressList) {       kfree(rule->addressList);       rule->addressList = NULL;    }    if (rule->portList) {       kfree(rule->portList);       rule->portList = NULL;    }    kfree(rule); } /*  *----------------------------------------------------------------------  *  * DeleteRuleSet --  *  *      Function deletes a rule set with a specified ID. Call will fail  *      if ID not found or if the current rule set is being used for  *      filtering.  *  * Results:  *      Returns 0 on success, errno on failure.  *  * Side effects:  *      None.  *  *----------------------------------------------------------------------  */ static int DeleteRuleSet(uint32 id) // IN: ID of new rule set to delete {    RuleSet **prev = NULL;    RuleSet *curr;    Rule *currRule;    /* locate the ruleset with the specified ID */    curr = FindRuleSetById(id, &prev);    if (curr == NULL) {       LOG(2, (KERN_INFO "filter did not find id %u to delete\n", id));       return -ESRCH;    }    LOG(2, (KERN_INFO "found id %u\n", id));    /* check if in use */    if (curr->enabled) {       LOG(2, (KERN_INFO "Can't delete id %u since enabled\n", id));       return -EBUSY;    }    /* remove item from linked list */    *prev = curr->next;    /* free rules in rule set */    currRule = curr->list;    curr->list = NULL; /* help mitigate any bugs or races */    while (currRule) {       Rule *temp = currRule->next;       currRule->next = NULL; /* help mitigate any bugs or races */       DeleteRule(currRule);       currRule = temp;    }    kfree(curr);    numRuleSets--;    // ASSERT(numRuleSets >= 0);    return 0; } /*  *----------------------------------------------------------------------  *  * ChangeRuleSet --  *  *      This function is used to specify which rule set is to be used  *      for filtering (or stop using for filtering).  If another  *      rule set is currently used for filtering then the specified  *      rule set will replace it.  This funciton can also be used to  *      change the default action for any rule set, but this option  *      should not be used when disabling a rule set.  *  *      Call will fail if ID can't be found, or when attempting to  *      disable a rule set that's not enabled.  *  * Results:  *      Returns 0 on success, errno on failure.  *  * Side effects:  *      May add/remove filter callback.  *  *----------------------------------------------------------------------  */ static int ChangeRuleSet(uint32 id,     // IN: requested ID of rule set               Bool enable,   // IN: TRUE says start using this rule for filtering               Bool disable,  // IN: TRUE says stop using this rule for filtering               uint32 action) // IN: default action for rule set {    RuleSet *curr;    int retval;    unsigned long flags;    // ASSERT(!enable || !disable); /* at most one can be set */    LOG(2, (KERN_INFO "changeruleset %d enable %d disable %d action %x\n", id,            enable, disable, action));    /* locate the specified rule set */    curr = FindRuleSetById(id, NULL);    if (curr == NULL) {       LOG(2, (KERN_INFO "vnet filter can't find ruleset: %u\n", id));       return -ESRCH;    }    if (enable) {       RuleSet *oldActive;       if (action != VNET_FILTER_RULE_NO_CHANGE) {          LOG(2, (KERN_INFO "vnet filter changing default action "                  "of active rule set: %u (id %u)\n", action, id));          curr->action = (uint16)action;       }       /* enable new rule */       curr->enabled = TRUE;       /* Grab activeRule spinlock. */       spin_lock_irqsave(&activeRuleLock, flags);       LOG(2, (KERN_INFO "changing active rule from "               "%p (%u) to %p (%u)\n", activeRule,               activeRule ? activeRule->id : 0,               curr, curr->id));       /* make rule active */       oldActive = activeRule;       activeRule = curr;       /* Safe to release activeRule spinlock now. */       spin_unlock_irqrestore(&activeRuleLock, flags);       /*        * Mark old rule as not enabled, except if it's the same        * as the newly enabled rule set.        */       if (oldActive == NULL) {          // 1) activate (no current active)          LOG(2, (KERN_INFO "No prior rule was active\n"));       } else if (oldActive == curr) {          // 2) activate (current active, and same as this one)          LOG(2, (KERN_INFO "Activated rule that was already active\n"));       } else { /* oldActive != NULL && oldActive != curr */          // 3) activate (current active, and different than this one)          LOG(2, (KERN_INFO "Deactivating old rule: %p (id %u)\n",                  oldActive, oldActive->id));          oldActive->enabled = FALSE;       }       if ((retval = InsertHostFilterCallback()) != 0) {          LOG(2, (KERN_INFO "Failed to insert filter in IP\n"));       }    } else if (disable) {       if (!curr->enabled) {          // 4) deactive (but not currently active)          LOG(2, (KERN_INFO "vnet filter tried to deactive a "                  "non-active rule: %u\n", id));          if (activeRule) {             // ASSERT(activeRule != curr);             LOG(2, (KERN_INFO "-- current active is %p (id %u)\n",                     activeRule, activeRule->id));          } else {             LOG(2, (KERN_INFO "-- no rule is currently active\n"));          }          /* in this case we'll also not change the default action */          return -EINVAL;       }       // 5) deactive (and currently active)       LOG(2, (KERN_INFO "vnet filter deactivating %p (id %u)\n",               curr, id));       RemoveHostFilterCallback();       // ASSERT(activeRule == curr);       /* Grab activeRule spinlock. */       spin_lock_irqsave(&activeRuleLock, flags);       activeRule = NULL;       /* Safe to release activeRule spinlock now. */       spin_unlock_irqrestore(&activeRuleLock, flags);       curr->enabled = FALSE;       if (action != VNET_FILTER_RULE_NO_CHANGE) {          LOG(2, (KERN_INFO "vnet filter changing default action: "                  "%u (id %u)\n", action, id));          curr->action = (uint16)action;       }       retval = 0;    } else { /* !enable && !disable */       if (action == VNET_FILTER_RULE_NO_CHANGE) {          // 6) no activate change (and default not changed)          LOG(2, (KERN_INFO "vnet filter got nothing to change\n"));          retval = 0;       }       // 7) no activate change (but default action changed)       curr->action = (uint16)action;       LOG(2, (KERN_INFO "vnet filter changed action: %u\n", action));       retval = 0;    }    return retval; } /*  *----------------------------------------------------------------------  *  * AddIPv4Rule --  *  *      Function is used to add an IPv4 rule to a rule set.  *      Call will fail if failed to alloc memory, or if specified  *      ID was not found.  The actual rule is not sanity checked,  *      as it's presumed the caller did this.  *  * Results:  *      Returns 0 on success, errno on failure.  *  * Side effects:  *      None.  *  *----------------------------------------------------------------------  */ static int AddIPv4Rule(uint32 id,                       // IN: requested ID of rule set             VNet_AddIPv4Rule *rule,          // IN: rule to add             VNet_IPv4Address *addressList,   // IN: list of addresses             VNet_IPv4Port *portList)         // IN: list of ports {    Rule *newRule;    RuleSet *curr;    // ASSERT(rule && addressList && portList);    /* locate the rule set with the specified ID */    curr = FindRuleSetById(id, NULL);    if (curr == NULL) {       LOG(2, (KERN_INFO "vnet filter can't find ruleset: %u\n", id));       return -ESRCH;    }    /* make sure that we don't have too many rules already */    if (curr->numRules >= MAX_RULES_PER_SET) {       LOG(2, (KERN_INFO "vnet filter has too many rules in ruleset: %u >= %u\n",               curr->numRules, MAX_RULES_PER_SET));       return -EOVERFLOW;    }    /* allocate and init rule */    newRule = kmalloc(sizeof *newRule, GFP_USER);    if (newRule == NULL) {       LOG(2, (KERN_INFO "vnet filter mem alloc failed for rule\n"));       return -ENOMEM;    }    memset(newRule, 0, sizeof *newRule);    newRule->action = (uint16)rule->action;    newRule->direction = (uint16)rule->direction;    newRule->proto = (uint16)rule->proto;    // ASSERT(rule->addressListLen <= 255); /* double-check for data truncation */    newRule->addressListLen = (uint8)rule->addressListLen;    if (newRule->addressListLen == 1 &&        addressList[0].ipv4RemoteAddr == 0 &&        addressList[0].ipv4RemoteMask == 0) {       newRule->addressListLen = 0;       LOG(2, (KERN_INFO "vnet filter address has single don't care rule\n"));    }    // ASSERT(rule->portListLen <= 255); /* double-check for data truncation */    newRule->portListLen = (uint8)rule->portListLen;    if (newRule->portListLen == 1 &&        portList[0].localPortLow == ~0 &&        portList[0].localPortHigh == ~0 &&        portList[0].remotePortLow == ~0 &&        portList[0].remotePortHigh == ~0) {       newRule->portListLen = 0;       LOG(2, (KERN_INFO "vnet filter port has single don't care rule\n"));    }    if (newRule->addressListLen > 0) {       uint32 i;       newRule->addressList =          kmalloc(sizeof(*newRule->addressList) * newRule->addressListLen,                  GFP_USER);       if (newRule->addressList == NULL) {          LOG(2, (KERN_INFO "vnet filter mem alloc failed for rule address\n"));          DeleteRule(newRule);          return -ENOMEM;       }       /* could use memcpy(), but this insulates against API changes */       for (i = 0; i < newRule->addressListLen; ++i) {          newRule->addressList[i].ipv4Addr = addressList[i].ipv4RemoteAddr;          newRule->addressList[i].ipv4Mask = addressList[i].ipv4RemoteMask;       }    }    if (newRule->portListLen > 0) {       uint32 i;       newRule->portList =          kmalloc(sizeof(*newRule->portList) * newRule->portListLen, GFP_USER);       if (newRule->portList == NULL) {          LOG(2, (KERN_INFO "vnet filter mem alloc failed for rule port\n"));          DeleteRule(newRule);          return -ENOMEM;       }       /* could use memcpy(), but this insulates against API changes */       for (i = 0; i < newRule->portListLen; ++i) {          newRule->portList[i].localPortLow   = portList[i].localPortLow;          newRule->portList[i].localPortHigh  = portList[i].localPortHigh;          newRule->portList[i].remotePortLow  = portList[i].remotePortLow;          newRule->portList[i].remotePortHigh = portList[i].remotePortHigh;       }    }    LOG(2, (KERN_INFO "adding rule with %u addresses and %u ports\n",            newRule->addressListLen, newRule->portListLen));    /* add rule to rule set */    newRule->next = NULL;    *(curr->tail) = newRule;    curr->tail = &(newRule->next);    ++curr->numRules;    LOG(2, (KERN_INFO "Added rule %p to set %p, count now %u\n",            newRule, curr, curr->numRules));    return 0; } /*  *----------------------------------------------------------------------------  *  * VNetFilter_HandleUserCall --  *  *      Handle the subcommands from the SIOCSFILTERRULES ioctl command.  *      We end up copying the VNet_RuleHeader bytes twice from userland,  *      once from the calling function, and once here after we've figured out  *      what sub-command we are dealing with.  *  * Returns:  *      0 on success.  *      errno on failure.  *  * Side effects:  *      May add/remove filter callback.  *  *----------------------------------------------------------------------------  */ int VNetFilter_HandleUserCall(VNet_RuleHeader *ruleHeader,      // IN: command header                           unsigned long ioarg)              // IN: ptr to user data {    int retval = 0;    /* Serialize all ioctl()s. */    retval = mutex_lock_interruptible(&filterIoctlMutex);    if (retval != 0) {       return retval;    }    switch (ruleHeader->type) {       case VNET_FILTER_CMD_CREATE_RULE_SET: {          VNet_CreateRuleSet createRequest;          if (copy_from_user(&createRequest, (void *)ioarg, sizeof createRequest)) {             retval = -EFAULT;             goto out_unlock;          }          /* Validate size. */          if (createRequest.header.len != sizeof createRequest) {             LOG(2, (KERN_INFO "invalid length %d/%zd for create filter "                     "request\n", createRequest.header.len,                     sizeof createRequest));             retval = -EINVAL;             goto out_unlock;          }          if (createRequest.ruleSetId == 0) {             LOG(2, (KERN_INFO "invalid id %u for create filter request\n",                     createRequest.ruleSetId));             retval = -EINVAL;             goto out_unlock;          }          if (createRequest.defaultAction != VNET_FILTER_RULE_BLOCK &&              createRequest.defaultAction != VNET_FILTER_RULE_ALLOW) {             LOG(2, (KERN_INFO "invalid action %u for create filter request\n",                     createRequest.defaultAction));             retval = -EINVAL;             goto out_unlock;          }          retval = CreateRuleSet(createRequest.ruleSetId,                                 createRequest.defaultAction);          goto out_unlock;       }       case VNET_FILTER_CMD_DELETE_RULE_SET: {          VNet_DeleteRuleSet deleteRequest;          if (copy_from_user(&deleteRequest, (void *)ioarg, sizeof deleteRequest)) {             retval = -EFAULT;             goto out_unlock;          }          /* Validate size. */          if (deleteRequest.header.len != sizeof deleteRequest) {             LOG(2, (KERN_INFO "invalid length %d/%zd for delete filter "                     "request\n", deleteRequest.header.len,                     sizeof deleteRequest));             retval = -EINVAL;             goto out_unlock;          }          if (deleteRequest.ruleSetId == 0) {             LOG(2, (KERN_INFO "invalid id %u for delete filter request\n",                     deleteRequest.ruleSetId));             retval = -EINVAL;             goto out_unlock;          }          retval = DeleteRuleSet(deleteRequest.ruleSetId);          goto out_unlock;       }       case VNET_FILTER_CMD_CHANGE_RULE_SET: {          VNet_ChangeRuleSet changeRequest;          if (copy_from_user(&changeRequest, (void *)ioarg, sizeof changeRequest)) {             retval = -EFAULT;             goto out_unlock;          }          /* Validate size. */          if (changeRequest.header.len != sizeof changeRequest) {             LOG(2, (KERN_INFO "invalid length %d/%zd for change filter "                     "request\n", changeRequest.header.len,                     sizeof changeRequest));             retval = -EINVAL;             goto out_unlock;          }          if (changeRequest.ruleSetId == 0) {             LOG(2, (KERN_INFO "invalid id %u for change filter request\n",                     changeRequest.ruleSetId));             retval = -EINVAL;             goto out_unlock;          }          if (changeRequest.defaultAction != VNET_FILTER_RULE_NO_CHANGE &&              changeRequest.defaultAction != VNET_FILTER_RULE_BLOCK &&              changeRequest.defaultAction != VNET_FILTER_RULE_ALLOW) {             LOG(2, (KERN_INFO "invalid default action %u for change "                     "filter request\n", changeRequest.defaultAction));             retval = -EINVAL;             goto out_unlock;          }          if (changeRequest.activate != VNET_FILTER_STATE_NO_CHANGE &&              changeRequest.activate != VNET_FILTER_STATE_ENABLE &&              changeRequest.activate != VNET_FILTER_STATE_DISABLE) {             LOG(2, (KERN_INFO "invalid activate %u for change filter "                     "request\n", changeRequest.activate));             retval = -EINVAL;             goto out_unlock;          }          retval = ChangeRuleSet(changeRequest.ruleSetId,                                 changeRequest.activate == VNET_FILTER_STATE_ENABLE,                                 changeRequest.activate == VNET_FILTER_STATE_DISABLE,                                 changeRequest.defaultAction);          goto out_unlock;       }       case VNET_FILTER_CMD_ADD_IPV4_RULE: {          VNet_AddIPv4Rule *addRequest;          VNet_IPv4Address *addressList = NULL;          VNet_IPv4Port *portList = NULL;          int error = -EINVAL;          uint32 i;          /* Validate size. */          if (ruleHeader->len < sizeof *addRequest) {             LOG(2, (KERN_INFO "short length %d/%zd for add filter rule "                     "request\n", ruleHeader->len,                     sizeof *addRequest));             retval = -EINVAL;             goto out_unlock;          }          if (ruleHeader->len > (sizeof *addRequest +                                 (sizeof *addressList * MAX_ADDR_PER_RULE) +                                 (sizeof *portList * MAX_PORT_PER_RULE))) {             LOG(2, (KERN_INFO "long length %d for add filter rule "                     "request\n", ruleHeader->len));             retval = -EINVAL;             goto out_unlock;          }          addRequest = kmalloc(ruleHeader->len, GFP_USER);          if (!addRequest) {             LOG(2, (KERN_INFO "couldn't allocate memory to add filter rule\n"));             retval = -ENOMEM;             goto out_unlock;          }          if (copy_from_user(addRequest, (void *)ioarg, ruleHeader->len)) {             error = -EFAULT;             goto out_error;          }          if (addRequest->addressListLen <= 0 ||              addRequest->addressListLen > MAX_ADDR_PER_RULE) {             LOG(2, (KERN_INFO "add filter rule: invalid addr list length: %u\n",                     addRequest->addressListLen));             goto out_error;          }          if (addRequest->portListLen <= 0 ||              addRequest->portListLen > MAX_PORT_PER_RULE) {             LOG(2, (KERN_INFO "add filter rule: invalid port list length: %u\n",                     addRequest->portListLen));             goto out_error;          }          if (addRequest->header.len !=              (sizeof *addRequest +               addRequest->addressListLen * sizeof(VNet_IPv4Address) +               addRequest->portListLen * sizeof(VNet_IPv4Port))) {             LOG(2, (KERN_INFO "add filter rule: invalid length: %u != %zu\n",                     addRequest->header.len, sizeof *addRequest +                     addRequest->addressListLen * sizeof(VNet_IPv4Address) +                     addRequest->portListLen * sizeof(VNet_IPv4Port)));             goto out_error;          }          /*           * The address list comes after initial struct, and port           * list follows the address list.           */          addressList = (VNet_IPv4Address *)(addRequest + 1);          portList = (VNet_IPv4Port *)(addressList + addRequest->addressListLen);          if (addRequest->ruleSetId == 0) {             LOG(2, (KERN_INFO "add filter rule: invalid request id %u\n",                     addRequest->ruleSetId));             goto out_error;          }          if (addRequest->action != VNET_FILTER_RULE_BLOCK &&              addRequest->action != VNET_FILTER_RULE_ALLOW) {             LOG(2, (KERN_INFO "add filter rule: invalid action %u\n",                     addRequest->action));             goto out_error;          }          if (addRequest->direction != VNET_FILTER_DIRECTION_IN &&              addRequest->direction != VNET_FILTER_DIRECTION_OUT &&              addRequest->direction != VNET_FILTER_DIRECTION_BOTH) {             LOG(2, (KERN_INFO "add filter rule: invalid direction %u\n",                     addRequest->direction));             goto out_error;          }          /*           * Make sure addr is sane for given mask.  Also verify that the address           * and mask, if both zero, are in the first element and the array only           * has one element. This also means that a 0 mask is not allowed in any           * element besides the first.           */          for (i = 0; i < addRequest->addressListLen; i++) {             if (addressList[i].ipv4RemoteAddr !=                 (addressList[i].ipv4RemoteAddr & addressList[i].ipv4RemoteMask)) {                LOG(2, (KERN_INFO "add filter rule got address 0x%08x mask "                        "0x%08x for %u\n", addressList[i].ipv4RemoteAddr,                        addressList[i].ipv4RemoteMask, i));                addressList[i].ipv4RemoteAddr &= addressList[i].ipv4RemoteMask;                LOG(2, (KERN_INFO "-- changed address to 0x%08x\n",                        addressList[i].ipv4RemoteAddr));             }             /*              * If addr==mask==0, then it must be in the first element of the              * address list, and the address list should have only one element.              */             if (addressList[i].ipv4RemoteAddr == 0 &&                 addressList[i].ipv4RemoteMask == 0 &&                 (i > 0 || addRequest->addressListLen > 1)) {                LOG(2, (KERN_INFO "add filter rule got violation for zero IP "                        "addr/mask\n"));                goto out_error;             }          }          if (addRequest->proto > 0xFF && addRequest->proto != (uint16)~0) {             LOG(2, (KERN_INFO "add filter rule got invalid proto %u\n",                     addRequest->proto));             goto out_error;          }          if (addRequest->proto == IPPROTO_TCP ||              addRequest->proto == IPPROTO_UDP) {             for (i = 0; i < addRequest->portListLen; i++) {                if (portList[i].localPortLow > 0xFFFF &&                    portList[i].localPortLow != ~0) {                   LOG(2, (KERN_INFO "add filter rule invalid localPortLow %u\n",                           portList[i].localPortLow));                   goto out_error;                }                if (portList[i].localPortHigh > 0xFFFF &&                    portList[i].localPortHigh != ~0) {                   LOG(2, (KERN_INFO "add filter rule invalid localPortHigh %u\n",                           portList[i].localPortHigh));                   goto out_error;                }                if (portList[i].remotePortLow > 0xFFFF &&                    portList[i].remotePortLow != ~0) {                   LOG(2, (KERN_INFO "add filter rule invalid remotePortLow %u\n",                           portList[i].remotePortLow));                   goto out_error;                }                if (portList[i].remotePortHigh > 0xFFFF &&                    portList[i].remotePortHigh != ~0) {                   LOG(2, (KERN_INFO "add filter rule invalid remotePortHigh %u\n",                           portList[i].remotePortHigh));                   goto out_error;                }                /*                 * Make sure both low and high ports of a port range specify don't                 * care ports.                 */                if ((portList[i].localPortLow   == ~0 && portList[i].localPortHigh  != ~0) ||                    (portList[i].localPortLow   != ~0 && portList[i].localPortHigh  == ~0) ||                    (portList[i].remotePortLow  == ~0 && portList[i].remotePortHigh != ~0) ||                    (portList[i].remotePortLow  != ~0 && portList[i].remotePortHigh == ~0)) {                   LOG(2, (KERN_INFO "add filter rule mismatch in don't care "                           "status of ports\n"));                   LOG(2, (KERN_INFO " -- srcLow %u srcHigh %u dstLow %u dstHigh %u\n",                           portList[i].localPortLow, portList[i].localPortHigh,                           portList[i].remotePortLow, portList[i].remotePortHigh));                   goto out_error;                }                if (portList[i].localPortHigh  < portList[i].localPortLow ||                    portList[i].remotePortHigh < portList[i].remotePortLow) {                   LOG(2, (KERN_INFO "add filter rule high < low on ports\n"));                   LOG(2, (KERN_INFO " -- srcLow %u srcHigh %u dstLow %u dstHigh %u\n",                           portList[i].localPortLow,  portList[i].localPortHigh,                           portList[i].remotePortLow, portList[i].remotePortHigh));                   goto out_error;                }                /*                 * Only allow a don't care on port ranges when it is the only port                 * range specified.                 */                if (portList[i].localPortLow   == ~0 && portList[i].localPortHigh  == ~0 &&                    portList[i].remotePortLow  == ~0 && portList[i].remotePortHigh == ~0 &&                    (i > 0 || addRequest->portListLen > 1)) {                   LOG(2, (KERN_INFO "add filter rule incorrect don't "                           "care on port list\n"));                   goto out_error;                }             }          } else {                  // proto not TCP or UDP             if (addRequest->portListLen != 1 ||                 (portList[0].localPortLow   !=  0 &&                  portList[0].localPortLow   != ~0) ||                 (portList[0].localPortHigh  !=  0 &&                  portList[0].localPortHigh  != ~0) ||                 (portList[0].remotePortLow  !=  0 &&                  portList[0].remotePortLow  != ~0) ||                 (portList[0].remotePortHigh !=  0 &&                  portList[0].remotePortHigh != ~0)) {                LOG(2, (KERN_INFO "add filter rule missing/unnecessary port "                        "information\n"));                for (i = 0; i < addRequest->portListLen; i++) {                   LOG(2, (KERN_INFO " -- srcLow %u srcHigh %u dstLow %u dstHigh %u\n",                           portList[i].localPortLow,  portList[i].localPortHigh,                           portList[i].remotePortLow, portList[i].remotePortHigh));                }                goto out_error;             }          }          retval = AddIPv4Rule(addRequest->ruleSetId, addRequest,                               addressList, portList);          goto out_unlock; out_error:          kfree(addRequest);          retval = error;          goto out_unlock;       }       case VNET_FILTER_CMD_ADD_IPV6_RULE:          LOG(2, (KERN_INFO "add filter rule IPv6 not supported\n"));          retval = -EPROTONOSUPPORT;          goto out_unlock;                 case VNET_FILTER_CMD_SET_LOG_LEVEL: {          VNet_SetLogLevel setLogLevel;                    if (copy_from_user(&setLogLevel, (void *)ioarg, sizeof setLogLevel)) {             retval = -EFAULT;          } else if (setLogLevel.header.len != sizeof setLogLevel) {             LOG(2, (KERN_INFO "set log level invalid header length %u\n",                     setLogLevel.header.len));             retval = -EINVAL;          } else if (VNET_FILTER_LOGLEVEL_NONE > setLogLevel.logLevel ||                     setLogLevel.logLevel > VNET_FILTER_LOGLEVEL_MAXIMUM) {             LOG(2, (KERN_INFO "set log level invalid value %u\n",                     setLogLevel.logLevel));             retval = -EINVAL;          } else {             logLevel = setLogLevel.logLevel;          }          goto out_unlock;       }       default:          LOG(2, (KERN_INFO "add filter rule invalid command %u\n",                  ruleHeader->type));          retval = -EINVAL;          goto out_unlock;    } out_unlock:    mutex_unlock(&filterIoctlMutex);    return retval; } /*  *----------------------------------------------------------------------  *  * VNetFilter_Shutdown --  *  *      Function is called when the driver is being unloaded.  *      This function is responsible for removing the callback  *      function from the IP stack and deallocating any remaining  *      state.  *  * Results:  *      None.  *  * Side effects:  *  *----------------------------------------------------------------------  */ void VNetFilter_Shutdown(void) {    LOG(2, (KERN_INFO "shutting down vnet filter\n"));    RemoveHostFilterCallback();    if (activeRule != NULL) {       LOG(2, (KERN_INFO "disabling the active rule %u\n", activeRule->id));       ChangeRuleSet(activeRule->id, FALSE, TRUE, VNET_FILTER_RULE_NO_CHANGE);       // ASSERT(activeRule == NULL);    }    while (ruleSetHead != NULL) {       LOG(2, (KERN_INFO "Deleteing rule set %u\n", ruleSetHead->id));       DeleteRuleSet(ruleSetHead->id);    }    // ASSERT(numRuleSets == 0);    LOG(2, (KERN_INFO "shut down vnet filter\n")); } /*  *----------------------------------------------------------------------  *  * LogPacket --  *  *      This function logs a dropped or forwarded packet.  *  * Results:  *      None.  *  * Side effects:  *      None.  *  *----------------------------------------------------------------------  */ #define LOGPACKET_HEADER_LEN (20) /* presumed length of 'header': IP (20) */ #define LOGPACKET_DATA_LEN   (28) /* TCP/UDP header (20) + 8 payload = 28 */ static void LogPacket(uint16 action,  // IN: reason for packet drop/forward           void *header,   // IN: packet header           void *data,     // IN: packet data           uint32 length,  // IN: packet length (of 'data', not including 'header')           Bool drop)      // IN: drop versus forward {    char packet[(LOGPACKET_HEADER_LEN + LOGPACKET_DATA_LEN) * 3 + 1];    int i, n;        /* something to do? */    if (VNET_FILTER_LOGLEVEL_VERBOSE > logLevel) {       return;    }        /* cap packet length */    if (length > LOGPACKET_DATA_LEN) {       length = LOGPACKET_DATA_LEN;    }        /* build packet string */    n = 0;    if (header) {       for (i = 0; i < LOGPACKET_HEADER_LEN; i++) {          sprintf(&packet[n], "%02x ", ((uint8 *)header)[i]);          n += 3;       }    }    for (i = 0; i < length; i++) {       sprintf(&packet[n], "%02x ", ((uint8 *)data)[i]);       n += 3;    }        /* log packet */    printk(KERN_INFO "packet %s: %s\n", drop ? "dropped" : "forwarded", packet); } #endif // CONFIG_NETFILTER
相關文章
相關標籤/搜索