diff -urNp havp-0.86/havp/default.h.in havp-0.86-ignore/havp/default.h.in
--- havp-0.86/havp/default.h.in	2007-06-17 19:46:44.000000000 +0300
+++ havp-0.86-ignore/havp/default.h.in	2007-06-17 19:38:25.000000000 +0300
@@ -49,7 +49,8 @@
  "ENABLEAVAST","AVASTSOCKET","AVASTSERVER","AVASTPORT", \
  "ENABLEARCAVIR","ARCAVIRSOCKET", \
  "REDIRECT", \
- "IGNORE_KAV_ERROR"
+ "IGNORE_KAV_ERROR", \
+ "WEBFILTER" 
 //SCANNERS
 
 
@@ -103,6 +104,8 @@
 #define ERROR_BODY	"error.html"
 #define ERROR_BLACKLIST	"blacklist.html"
 #define ERROR_MAXSIZE	"maxsize.html"
+#define WEBFILTER	"webfilter.html"
+#define ERROR_WEBFILTER	"webfilter_error.html"
 
 // DONT TOUCH - run configure
 #undef CONFIGFILE
diff -urNp havp-0.86/havp/proxyhandler.cpp havp-0.86-ignore/havp/proxyhandler.cpp
--- havp-0.86/havp/proxyhandler.cpp	2007-06-17 19:46:41.000000000 +0300
+++ havp-0.86-ignore/havp/proxyhandler.cpp	2007-06-17 19:40:58.000000000 +0300
@@ -135,6 +135,26 @@ void ProxyHandler::Proxy( SocketHandler 
             continue;
         }
 
+        if (Params::GetConfigInt("WEBFILTER"))
+        {
+            string category;
+            int webFilteringRC =  WebFilter::webFilterProcess(ToBrowser.GetHost(), category);
+            if (1 == webFilteringRC) // Block because of forbidden category
+            {
+                ToBrowser.PrepareHeaderForServer( false, UseParentProxy );
+                ProxyMessage( -47, category );
+                DropBrowser = true;
+                continue;
+            }
+            else if (2 == webFilteringRC) // Timeout/Error on web filtering 
+            {
+                ToBrowser.PrepareHeaderForServer( false, UseParentProxy );
+                ProxyMessage( -48, "" );
+                DropBrowser = true;
+                continue;
+            }
+        }
+
 #ifdef SSLTUNNEL
     }
 #endif
@@ -1348,6 +1368,20 @@ bool ProxyHandler::ProxyMessage( int Com
 
         break;
 
+        case -47:
+            LogFile::AccessMessage("%s %s %d %s %d+%lld WEBFILTER\n", ToBrowser.GetIP().c_str(), ToBrowser.GetRequestType().c_str(), ToServer.GetResponse(), ToBrowser.GetCompleteRequest().c_str(), TransferredHeader, TransferredBody);
+            message = Answer;
+            filename = WEBFILTER;
+            break;
+
+        case -48:
+            LogFile::AccessMessage("%s %s %d %s %d+%lld WEBFILTER\n", ToBrowser.GetIP().c_str(), ToBrowser.GetRequestType().c_str(), ToServer.GetResponse(), ToBrowser.GetCompleteRequest().c_str(), TransferredHeader, TransferredBody);
+            message = Answer;
+            filename = ERROR_WEBFILTER;
+            break;
+
+        break;
+
         case -50:
             message = ToBrowser.GetHost();
             filename = ERROR_DNS;
diff -urNp havp-0.86/havp/whitelist.cpp havp-0.86-ignore/havp/whitelist.cpp
--- havp-0.86/havp/whitelist.cpp	2007-06-17 19:46:41.000000000 +0300
+++ havp-0.86-ignore/havp/whitelist.cpp	2007-06-17 19:45:42.000000000 +0300
@@ -22,6 +22,12 @@
 #include <iostream>
 #include <fstream>
 
+#include <sys/un.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <unistd.h>
+
 using namespace std;
 
 bool URLList::CreateURLList(string URLListFileT)
@@ -358,3 +364,61 @@ bool PatternList::FindPattern(const stri
 
     return false;
 }
+
+
+int WebFilter::webFilterProcess(const string& host, string& category)
+{
+    struct sockaddr_un cliaddr, servaddr;
+    int rc = 0;
+
+    int sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0); 
+    bzero(&cliaddr, sizeof(cliaddr));              
+    cliaddr.sun_family = AF_LOCAL;
+
+    char* filename = tmpnam(NULL);
+    strcpy(cliaddr.sun_path, filename);   
+    bind(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)); 
+
+    bzero(&servaddr, sizeof(servaddr));   
+    servaddr.sun_family = AF_LOCAL;     
+
+    strcpy(servaddr.sun_path, "/tmp/surfcontrol.sock"); 
+
+    sendto(sockfd, host.c_str(), host.length(), 0, (struct sockaddr *) &servaddr, sizeof(servaddr));
+    
+
+    fd_set rset;
+    FD_ZERO(&rset);
+    FD_SET(sockfd, &rset);
+
+    struct timeval timeout;
+    timeout.tv_usec = 0;
+    timeout.tv_sec = 25;
+
+    if (-1 != select(sockfd + 1, &rset, NULL, NULL, &timeout) && 
+        FD_ISSET(sockfd, &rset))
+    {
+        const int MAX_MSG_LEN = 128;
+        char reply[MAX_MSG_LEN];
+        int n = recvfrom(sockfd, reply, MAX_MSG_LEN, 0, NULL, NULL);
+        reply[n] = '\0';
+        
+        if (!strncmp("Forbidden", reply, 9))
+        {
+            category.assign(&reply[10]);
+            rc = 1;
+        }
+        else {
+        category.assign(&reply[3]); } // In case of "OK <category>"
+    }
+    else
+    {
+        rc = 2;
+    }
+    
+
+    unlink(filename);
+    close(sockfd);
+
+    return rc;
+}
diff -urNp havp-0.86/havp/whitelist.h havp-0.86-ignore/havp/whitelist.h
--- havp-0.86/havp/whitelist.h	2007-06-17 19:46:41.000000000 +0300
+++ havp-0.86-ignore/havp/whitelist.h	2007-06-17 19:41:26.000000000 +0300
@@ -68,4 +68,13 @@ private:
     PatternPair m_patternList;
 };
 
+class WebFilter
+{
+public:
+    static int webFilterProcess(const string& host, string& category);
+
+private:
+    WebFilter();
+};
+
 #endif
