int main (int argc, char ** argv) { char * ptr; char * str; FILE * f = NULL; char c; int i, i2; hostspec_t hostspec; /* TODO: s 1. Redefine default filter source file (/etc/ipf.rules) t 2. Redefine default filter target file (/var/bee/ipf.rules.effecive) d 3. Redefine destination host (any) i 4. Redefine target interface (tun0) r 5. Redefine resource name (inet) f 6. Redefine allowed filename (/var/bee/allowed.inet) P 7. Redefine dest_s (NULL) p 8. Redefine host_s (NULL) m 9. Redefine filter file rsmark (#<beerules>) S 10. Redefine rule_s (NULL) R 11. Reverse in & out l 12. Redefine log mark(NULL) o 13. One rule only (to destination) */ #define OPTS "s:t:d:i:r:f:P:p:m:S:Rl:oT:" while ((c = getopt(argc, argv, OPTS)) != -1) { switch (c) { case 's': srcrules = optarg; break; case 't': dstrules = optarg; break; case 'r': snprintf(namebuf, sizeof(namebuf),"/var/bee/allowed.%s", optarg); srchosts = namebuf; break; case 'f': srchosts = optarg; break; default: usage(-1); } } // 1. Load current acl if (strcmp(srcrules, "-") != 0) { f=fopen(srcrules, "r"); if (f==NULL) { syslog(LOG_ERR, "fopen(%s): %m", srcrules); exit (-1); } } else f = stdin; while(fgets(buf, sizeof(buf), f) != NULL) { ptr = buf; memset(&hostspec, 0, sizeof(hostspec)); // printf("%s", ptr); // rule check str = next_token(&ptr, " \t\n"); if (str == NULL) continue; if (strcmp(str, "permit") != 0) continue; // printf("got '%s' (permit)\n", str); str = next_token(&ptr, " \t\n"); if (str == NULL) continue; if (strcmp(str, "ip") != 0) continue; // printf("got '%s' (ip)\n", str); // host/net specification str = next_token(&ptr, " \t\n"); if (str == NULL) continue; if (strcmp(str, "host") == 0) { // printf("got '%s' (host)\n", str); // set host mask /32 hostspec.bmask = 0xffffffff; str = next_token(&ptr, " \t\n"); if (str == NULL) continue; } if (inet_pton(AF_INET, str, &(hostspec.bhost)) == 0) continue; // printf("got '%s' (ipaddr)\n", str); if (hostspec.bmask != 0xffffffff) { // parse net wildcard str = next_token(&ptr, " \t\n"); if (str == NULL) continue; if (inet_pton(AF_INET, str, &(hostspec.bmask)) == 0) continue; hostspec.bmask = ~hostspec.bmask; // printf("got '%s' (ipmask)\n", str); } // attach host spec to list da_ins(&cnt_current, &itm_current, sizeof(*itm_current), (-1), &hostspec); } if (f != stdin) fclose(f); // 2. Load allowed list if (strcmp(srchosts, "-") != 0) { f=fopen(srchosts, "r"); if (f==NULL) { syslog(LOG_ERR, "open(%s): %m", srchosts); exit (-1); } } else f = stdin; while(fgets(buf, sizeof(buf), f) != NULL) { ptr = buf; memset(&hostspec, 0, sizeof(hostspec)); str = next_token(&ptr, " \t\n"); if (str == NULL) continue; if (make_addrandmask(str, &hostspec.bhost, &hostspec.bmask) < 0) continue; // attach host spec to list da_ins(&cnt_allow, &itm_allow, sizeof(*itm_allow), (-1), &hostspec); } if (f != stdin) fclose(f); // 3. Sort current acl da_bsort(&cnt_current, &itm_current, sizeof(*itm_current), ip_compare); // 4. Sort allowed list da_bsort(&cnt_allow, &itm_allow, sizeof(*itm_allow), ip_compare); // 5. Remove equal items i = 0; i2 = 0; while(i < cnt_current && i2 < cnt_allow) { if (itm_current[i].bhost == itm_allow[i2].bhost && itm_current[i].bmask == itm_allow[i2].bmask) { da_rm(&cnt_current, &itm_current, sizeof(*itm_current), i, NULL); da_rm(&cnt_allow, &itm_allow, sizeof(*itm_allow), i2, NULL); continue; } if (ip_compare(itm_current+i, itm_allow+i2)) i2++; else i++; } // 6. Generate additon commands from allow list remains if (strcmp(dstrules, "-") != 0) { f = fopen(dstrules, "w"); if (f == NULL) { syslog(LOG_ERR, "fopen(%s): %m", dstrules); exit (-1); } } else f = stdout; for (i=0; i < cnt_allow; i++) { hostspec = itm_allow[i]; hostspec.bmask = ~hostspec.bmask; fprintf(f, " %s %s %s%s\n", head_add, inet_ntop(AF_INET, &hostspec.bhost, addrbuf1, sizeof(addrbuf1)), inet_ntop(AF_INET, &hostspec.bmask, addrbuf2, sizeof(addrbuf2)), tail_add ? tail_add : "" ); } // 7. Generate removal commands from current list remains for (i=0; i < cnt_current; i++) { hostspec = itm_current[i]; hostspec.bmask = ~hostspec.bmask; fprintf(f, " %s %s %s%s\n", head_rm, inet_ntop(AF_INET, &hostspec.bhost, addrbuf1, sizeof(addrbuf1)), inet_ntop(AF_INET, &hostspec.bmask, addrbuf2, sizeof(addrbuf2)), tail_rm ? tail_rm : "" ); } if (f != stdout) fclose(f); return 0; }
int pcap_io_recv(void* packet, int max_len) { int res; struct pcap_pkthdr *header; const u_char *pkt_data1; static u_char pkt_data[32768]; if(pcap_io_running<=0) return -1; if((res = pcap_next_ex(adhandle, &header, &pkt_data1)) > 0) { ethernet_header *ph=(ethernet_header*)pkt_data; memcpy(pkt_data,pkt_data1,header->len); if (pcap_mode==bridged) { if(((ethernet_header*)pkt_data)->protocol == 0x0008) { ip_header *iph=((ip_header*)((u8*)pkt_data+sizeof(ethernet_header))); if(ip_compare(iph->dst,virtual_ip)==0) { ((ethernet_header*)pkt_data)->dst = virtual_mac; } } if(((ethernet_header*)pkt_data)->protocol == 0x0608) { arp_packet *aph=((arp_packet*)((u8*)pkt_data+sizeof(ethernet_header))); if(ip_compare(aph->p_dst,virtual_ip)==0) { ((ethernet_header*)pkt_data)->dst = virtual_mac; ((arp_packet*)((u8*)packet+sizeof(ethernet_header)))->h_dst = virtual_mac; } } } if((memcmp(pkt_data,dev9.eeprom,6)!=0)&&(memcmp(pkt_data,&broadcast_mac,6)!=0)) { //ignore strange packets return 0; } if(memcmp(pkt_data+6,dev9.eeprom,6)==0) { //avoid pcap looping packets return 0; } memcpy(packet,pkt_data,header->len); if(dump_pcap) pcap_dump((u_char*)dump_pcap,header,(u_char*)packet); if(packet_log) { int i=0; int n=0; int plen=header->len; fprintf(packet_log,"PACKET RECV: %d BYTES\n",plen); for(i=0,n=0;i<plen;i++) { fprintf(packet_log,"%02x",((unsigned char*)packet)[i]); n++; if(n==16) { fprintf(packet_log,"\n"); n=0; } else fprintf(packet_log," "); } fprintf(packet_log,"\n"); } return header->len; } return -1; }