Index: src/airbase-ng.c
===================================================================
--- src/airbase-ng.c	(revision 1112)
+++ src/airbase-ng.c	(working copy)
@@ -58,6 +58,7 @@
 #include <getopt.h>
 #include <sys/file.h>
 #include <fcntl.h>
+#include <ctype.h>
 
 #include "version.h"
 #include "pcap.h"
@@ -196,6 +197,9 @@
 "      -Z type          : same as -z, but for WPA2\n"
 "      -V type          : fake EAPOL 1=MD5 2=SHA1 3=auto\n"
 "      -F prefix        : write all sent and received frames into pcap file\n"
+"      -P               : respond to all probes, even when specifying ESSIDs\n"
+"      -I interval      : sets the beacon interval value in ms\n"
+"      -C seconds       : enables beaconing of probed ESSID values (requires -P)\n"
 "\n"
 "  Filter options:\n"
 "      --bssid MAC      : BSSID to filter/use\n"
@@ -245,12 +249,15 @@
     int weplen, crypt;
 
     int f_essid;
+    int promiscuous;
+    int beacon_cache;
     int channel;
     int setWEP;
     int quiet;
     int mitm;
     int external;
     int hidden;
+    int interval;
     int forceska;
     int skalen;
     int filter;
@@ -311,6 +318,7 @@
     char            *essid;
     unsigned char   len;
     pESSID_t        next;
+	time_t          expire;
 };
 
 typedef struct MAC_list* pMAC_t;
@@ -420,10 +428,12 @@
         alarmed++;
 }
 
-int addESSID(char* essid, int len)
+int addESSID(char* essid, int len, int expiration)
 {
-    pESSID_t cur = rESSID;
-
+    pESSID_t tmp;
+	pESSID_t cur = rESSID;
+	time_t now;
+	
     if(essid == NULL)
         return -1;
 
@@ -433,21 +443,38 @@
     if(rESSID == NULL)
         return -1;
 
-    while(cur->next != NULL)
+    while(cur->next != NULL) {
+        // if it already exists, just update the expiration time
+        if(cur->len == len && ! memcmp(cur->essid, essid, len)) {
+            if(cur->expire && expiration) {
+                time(&now);
+                cur->expire = now + expiration;
+            }
+            return 0;
+        }
         cur = cur->next;
+    }
 
     //alloc mem
-    cur->next = (pESSID_t) malloc(sizeof(struct ESSID_list));
-    cur = cur->next;
+    tmp = (pESSID_t) malloc(sizeof(struct ESSID_list));
 
     //set essid
-    cur->essid = (char*) malloc(len+1);
-    memcpy(cur->essid, essid, len);
-    cur->essid[len] = 0x00;
-    cur->len = len;
+    tmp->essid = (char*) malloc(len+1);
+    memcpy(tmp->essid, essid, len);
+    tmp->essid[len] = 0x00;
+    tmp->len = len;
+	
+    // set expiration date
+    if(expiration) {
+        time(&now);
+        tmp->expire = now + expiration;
+    } else {
+        tmp->expire = 0;   
+    }
 
-    cur->next = NULL;
-
+    tmp->next = NULL;
+	cur->next = tmp;
+		
     return 0;
 }
 
@@ -921,6 +948,40 @@
     return -1;
 }
 
+
+void flushESSID(void)
+{
+    pESSID_t old;
+	pESSID_t cur = rESSID;
+	time_t now;
+
+    if(rESSID == NULL)
+        return;
+
+    while(cur->next != NULL)
+    {
+        old = cur->next;
+        if(old->expire)
+        {
+            time(&now);
+            if(now > old->expire)
+            {
+                //got it
+                cur->next = old->next;
+
+                free(old->essid);
+                old->essid = NULL;
+                old->next = NULL;
+                old->len = 0;
+                free(old);
+                return;
+            }
+        }
+        cur = cur->next;
+    }
+}
+
+
 int delMAC(pMAC_t pMAC, char* mac)
 {
     pMAC_t old, cur = pMAC;
@@ -1065,7 +1126,8 @@
 {
     FILE *list;
     char essid[256];
-
+	int x;
+	
     list = fopen(filename, "r");
     if(list == NULL)
     {
@@ -1075,7 +1137,13 @@
 
     while( fgets(essid, 256, list) != NULL )
     {
-        addESSID(essid, strlen(essid));
+        // trim trailing whitespace
+        x = strlen(essid) - 1;
+        while (x >= 0 && isspace(essid[x]))
+            essid[x--] = 0;
+
+        if(strlen(essid))
+            addESSID(essid, strlen(essid), 0);
     }
 
     fclose(list);
@@ -2837,7 +2905,7 @@
             tag = parse_tags(packet+z, 0, length-z, &len);
             if(tag != NULL && tag[0] >= 32 && tag[0] < 127 && len <= 255) //directed probe
             {
-                if( !opt.f_essid || gotESSID((char*)tag, len) == 1)
+                if( opt.promiscuous || !opt.f_essid || gotESSID((char*)tag, len) == 1)
                 {
                     bzero(essid, 256);
                     memcpy(essid, tag, len);
@@ -2847,9 +2915,13 @@
                         if( essid[i] > 0 && essid[i] < ' ' )
                             goto skip_probe;
 
-                    /* got a valid ASCII probed ESSID, check if it's
-                    already in the ring buffer */
-
+                    /* got a valid ASCII probed ESSID */
+                    
+                    /* add this to the beacon queue */
+                    if(opt.beacon_cache)
+                        addESSID(essid, len, opt.beacon_cache);
+                    
+                    /* check if it's already in the ring buffer */
                     for( i = 0; i < NB_PRB; i++ )
                         if( memcmp( st_cur->probes[i], essid, len ) == 0 )
                             goto skip_probe;
@@ -2937,9 +3009,9 @@
 
                     send_packet(packet, length);
 
-                    send_packet(packet, length);
+                    //send_packet(packet, length);
 
-                    send_packet(packet, length);
+                    //send_packet(packet, length);
                     return 0;
                 }
             }
@@ -3339,66 +3411,13 @@
     unsigned char beacon[512];
     int beacon_len=0;
     int seq=0, i=0, n=0;
+    int essid_len;
+    char *essid = "";
+    pESSID_t cur_essid = rESSID;
     float f, ticks[3];
 
     memcpy(&apc, arg, sizeof(struct AP_conf));
 
-    memcpy(beacon, "\x80\x00\x00\x00", 4);  //type/subtype/framecontrol/duration
-    beacon_len+=4;
-    memcpy(beacon+beacon_len , BROADCAST, 6);        //destination
-    beacon_len+=6;
-    if(!opt.adhoc)
-        memcpy(beacon+beacon_len, apc.bssid, 6);        //source
-    else
-        memcpy(beacon+beacon_len, opt.r_smac, 6);        //source
-    beacon_len+=6;
-    memcpy(beacon+beacon_len, apc.bssid, 6);        //bssid
-    beacon_len+=6;
-    memcpy(beacon+beacon_len, "\x00\x00", 2);       //seq+frag
-    beacon_len+=2;
-
-    memcpy(beacon+beacon_len, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12);  //fixed information
-    beacon[beacon_len+8] = (apc.interval) & 0xFF;       //beacon interval
-    beacon[beacon_len+9] = (apc.interval >> 8) & 0xFF;
-    memcpy(beacon+beacon_len+10, apc.capa, 2);          //capability
-    beacon_len+=12;
-
-    beacon[beacon_len] = 0x00; //essid tag
-    beacon[beacon_len+1] = apc.essid_len; //essid tag
-    beacon_len+=2;
-    memcpy(beacon+beacon_len, apc.essid, apc.essid_len); //actual essid
-    beacon_len+=apc.essid_len;
-
-    memcpy(beacon+beacon_len, RATES, 16); //rates+extended rates
-    beacon_len+=16;
-
-    beacon[beacon_len] = 0x03; //channel tag
-    beacon[beacon_len+1] = 0x01;
-    beacon[beacon_len+2] = wi_get_channel(_wi_in); //current channel
-    beacon_len+=3;
-
-    if( opt.allwpa )
-    {
-        memcpy(beacon+beacon_len, WPA_TAGS, 0x56);
-        beacon_len += 0x56;
-    }
-
-    if(opt.wpa2type > 0)
-    {
-        memcpy(beacon+beacon_len, WPA2_TAG, 22);
-        beacon[beacon_len+7] = opt.wpa2type;
-        beacon[beacon_len+13] = opt.wpa2type;
-        beacon_len += 22;
-    }
-
-    if(opt.wpa1type > 0)
-    {
-        memcpy(beacon+beacon_len, WPA1_TAG, 24);
-        beacon[beacon_len+11] = opt.wpa1type;
-        beacon[beacon_len+17] = opt.wpa1type;
-        beacon_len += 24;
-    }
-
     ticks[0]=0;
     ticks[1]=0;
     ticks[2]=0;
@@ -3446,6 +3465,82 @@
 
 //             printf( "4 " );
             fflush(stdout);
+			
+
+            if(cur_essid == NULL) cur_essid = rESSID;
+            if(cur_essid == NULL) {
+	            essid = "default";
+	            essid_len = strlen(essid);	
+            } else {
+                
+                /* flush expired ESSID entries */
+                flushESSID();
+                    
+	            essid     = cur_essid->essid;
+	            essid_len = cur_essid->len;
+	            cur_essid = cur_essid->next;			
+            }
+
+            beacon_len = 0;
+
+            memcpy(beacon, "\x80\x00\x00\x00", 4);  //type/subtype/framecontrol/duration
+            beacon_len+=4;
+            memcpy(beacon+beacon_len , BROADCAST, 6);        //destination
+            beacon_len+=6;
+            if(!opt.adhoc)
+                memcpy(beacon+beacon_len, apc.bssid, 6);        //source
+            else
+                memcpy(beacon+beacon_len, opt.r_smac, 6);        //source
+            beacon_len+=6;
+            memcpy(beacon+beacon_len, apc.bssid, 6);        //bssid
+            beacon_len+=6;
+            memcpy(beacon+beacon_len, "\x00\x00", 2);       //seq+frag
+            beacon_len+=2;
+
+            memcpy(beacon+beacon_len, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12);  //fixed information
+
+            beacon[beacon_len+8] = (apc.interval * MAX(getESSIDcount(), 1) ) & 0xFF;       //beacon interval
+            beacon[beacon_len+9] = (apc.interval * MAX(getESSIDcount(), 1) >> 8) & 0xFF;
+            memcpy(beacon+beacon_len+10, apc.capa, 2);          //capability
+            beacon_len+=12;
+
+            beacon[beacon_len] = 0x00; //essid tag
+            beacon[beacon_len+1] = essid_len; //essid tag
+            beacon_len+=2;
+            memcpy(beacon+beacon_len, essid, essid_len); //actual essid
+            beacon_len+=essid_len;
+
+            memcpy(beacon+beacon_len, RATES, 16); //rates+extended rates
+            beacon_len+=16;
+
+            beacon[beacon_len] = 0x03; //channel tag
+            beacon[beacon_len+1] = 0x01;
+            beacon[beacon_len+2] = wi_get_channel(_wi_in); //current channel
+            beacon_len+=3;
+
+            if( opt.allwpa )
+            {
+                memcpy(beacon+beacon_len, WPA_TAGS, 0x56);
+                beacon_len += 0x56;
+            }
+
+            if(opt.wpa2type > 0)
+            {
+                memcpy(beacon+beacon_len, WPA2_TAG, 22);
+                beacon[beacon_len+7] = opt.wpa2type;
+                beacon[beacon_len+13] = opt.wpa2type;
+                beacon_len += 22;
+            }
+
+            if(opt.wpa1type > 0)
+            {
+                memcpy(beacon+beacon_len, WPA1_TAG, 24);
+                beacon[beacon_len+11] = opt.wpa1type;
+                beacon[beacon_len+17] = opt.wpa1type;
+                beacon_len += 24;
+            }					
+
+		
             //copy timestamp into beacon; a mod 2^64 counter incremented each microsecond
             for(i=0; i<8; i++)
             {
@@ -3457,6 +3552,7 @@
 
 //             printf( "5 " );
             fflush(stdout);
+
             if( send_packet( beacon, beacon_len ) < 0 )
             {
                 printf("Error sending beacon!\n");
@@ -3777,7 +3873,9 @@
     opt.ringbuffer  = 10;
     opt.nb_arp      = 0;
     opt.f_index     = 1;
-
+    opt.interval    = 0x64;
+    opt.beacon_cache = 0; /* disable by default */
+	
     srand( time( NULL ) );
 
     while( 1 )
@@ -3785,6 +3883,7 @@
         int option_index = 0;
 
         static struct option long_options[] = {
+            {"beacon-cache",1, 0, 'C'},
             {"bssid",       1, 0, 'b'},
             {"bssids",      1, 0, 'B'},
             {"channel",     1, 0, 'c'},
@@ -3792,6 +3891,8 @@
             {"clients",     1, 0, 'D'},
             {"essid",       1, 0, 'e'},
             {"essids",      1, 0, 'E'},
+            {"promiscuous", 0, 0, 'P'},
+            {"interval",    1, 0, 'I'},
             {"mitm",        0, 0, 'M'},
             {"hidden",      0, 0, 'X'},
             {"caffe-latte", 0, 0, 'L'},
@@ -3803,7 +3904,7 @@
         };
 
         int option = getopt_long( argc, argv,
-                        "a:h:i:r:w:He:E:c:d:D:f:W:qMY:b:B:XsS:Lx:vAz:Z:yV:0NF:",
+                        "a:h:i:C:I:r:w:HPe:E:c:d:D:f:W:qMY:b:B:XsS:Lx:vAz:Z:yV:0NF:",
                         long_options, &option_index );
 
         if( option < 0 ) break;
@@ -3890,7 +3991,7 @@
 
             case 'e' :
 
-                if( addESSID(optarg, strlen(optarg)) != 0 )
+                if( addESSID(optarg, strlen(optarg), 0) != 0 )
                 {
                     printf( "Invalid ESSID, too long\n" );
                     printf("\"%s --help\" for help.\n", argv[0]);
@@ -3909,7 +4010,25 @@
                 opt.f_essid = 1;
 
                 break;
+				
+            case 'P' :
 
+                opt.promiscuous = 1;
+
+                break;
+				
+            case 'I' :
+
+                opt.interval = atoi(optarg);
+
+                break;
+				
+            case 'C' :
+
+                opt.beacon_cache = atoi(optarg);
+
+                break;
+							
             case 'A' :
 
                 opt.adhoc = 1;
@@ -4461,7 +4580,7 @@
         apc.essid = "\x00";
         apc.essid_len = 1;
     }
-    apc.interval = 0x0064;
+    apc.interval = opt.interval;
     apc.capa[0] = 0x00;
     if(opt.adhoc)
         apc.capa[0] |= 0x02;
