bpf_share.c
上传用户:tjescc
上传日期:2021-02-23
资源大小:419k
文件大小:19k
源码类别:

Telnet服务器

开发平台:

Unix_Linux

  1. /* Copyright (C) 2003 Renaud Deraison
  2.  *
  3.  * This program is free software; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License version 2,
  5.  * as published by the Free Software Foundation
  6.  *
  7.  * This program is distributed in the hope that it will be useful,
  8.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  * GNU General Public License for more details.
  11.  *
  12.  * You should have received a copy of the GNU General Public License
  13.  * along with this program; if not, write to the Free Software
  14.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15.  *
  16.  */
  17.  
  18. #include <includes.h>
  19. #undef DEBUG_FORWARD
  20. #undef DEBUG
  21. #undef DEBUG_HIGH
  22. #define NUM_CLIENTS 128
  23. #define NUM_BPF_PER_CLIENT 5
  24. #define BPF_SOCKET_PATH NESSUS_STATE_DIR"/nessus/bpf"
  25. #define BPF_SERVER_PID_FILE NESSUS_STATE_DIR"/nessus/bpf_server.pid"
  26. /*
  27.  * The traditional pcap code is much more handy, so we'll try to use
  28.  * it instead if our hack is not necessary
  29.  */
  30. #ifdef HAVE_DEV_BPFN 
  31. #define CLNT_BUF_SIZ 1600
  32. struct bpf_listener {
  33. int soc;
  34. char filter[512];
  35. char iface[128] ;
  36.         int flag;
  37. struct bpf_program bpf_filter;
  38. };
  39. struct bpf_pcap {
  40. pcap_t * pcap;
  41. char iface[128];
  42. struct bpf_program bpf_filter;
  43. struct bpf_pcap * next;
  44. };
  45. struct bpf_client {
  46. int soc;
  47. int datalink;
  48. unsigned char *packet;
  49. };
  50. /* Server-side */
  51. static struct bpf_listener clients[NUM_CLIENTS];
  52. static struct bpf_pcap * pcaps;
  53. /* Client-side */
  54. static struct bpf_client clnts[NUM_BPF_PER_CLIENT];
  55. static void setbufsize(int soc)
  56. {
  57.  int optval = CLNT_BUF_SIZ * 40;
  58.  if(setsockopt(soc, SOL_SOCKET, SO_SNDBUF, &optval, sizeof(optval)) < 0)
  59. perror("inc sndbuf");
  60.  if(setsockopt(soc, SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval)) < 0)
  61. perror("inc sndbuf");
  62. }
  63. static void sigterm()
  64. {
  65.  unlink(BPF_SOCKET_PATH);
  66.  _EXIT(0);
  67. }
  68. #ifdef DEBUG
  69.  void dump_packet(char * p, int len)
  70. {
  71.  int i;
  72.  printf("n----n");
  73.  for(i=0;i<len;i+=16)
  74.  {
  75.   int j;
  76.   for(j=0;j<16;j++)
  77.   {
  78.    printf("%.2x ", (unsigned char)p[j+i]);
  79.    if(j %8 == 0)printf(" ");
  80.   }
  81.   printf("n");
  82.  }
  83. }
  84. #endif
  85. /*------------------------------------------------------------------------*
  86.  * Server part    *
  87.  *------------------------------------------------------------------------*/
  88. int bpf_svr_close(int);
  89. static struct bpf_pcap * add_pcap(char * iface, pcap_t * pcap)
  90. {
  91.  struct bpf_pcap * bpc;
  92.  bpf_u_int32 netmask, network;
  93.  
  94.  
  95.  if(pcap == NULL)
  96.   return pcaps;
  97.  bpc = malloc(sizeof(*bpc));
  98.  bpc->pcap = pcap;
  99.  strncpy(bpc->iface, iface, sizeof(bpc->iface) - 1);
  100.  bpc->iface[sizeof(bpc->iface) - 1] = '';
  101.  pcap_lookupnet(iface, &network, &netmask, 0);
  102.  pcap_compile(pcap, &bpc->bpf_filter, "", 1, netmask); 
  103.  bpc->next = pcaps;
  104.  pcaps = bpc;
  105.  return bpc;
  106. }
  107. static void rm_pcap(char * iface )
  108. {
  109.  struct bpf_pcap * bpc = pcaps, * prev = NULL;
  110.  while( bpc != NULL )
  111.  {
  112.   if(strcmp(bpc->iface, iface) == 0)
  113. {
  114.    struct bpf_pcap * next;
  115.  next = bpc->next;
  116.  pcap_close(bpc->pcap);
  117.  efree(&bpc);
  118.  if ( prev ) prev->next = next;
  119.  else pcaps = next;
  120. }
  121.   prev = bpc;
  122.   if ( bpc != NULL )
  123.    bpc = bpc->next;
  124.  }
  125. }
  126. static pcap_t * get_pcap(char * iface)
  127. {
  128.  struct bpf_pcap * bpc = pcaps;
  129.  while( bpc != NULL )
  130.  {
  131.   if(strcmp(bpc->iface, iface) == 0)
  132.    return bpc->pcap;
  133.   bpc = bpc->next;
  134.  }
  135.  return NULL;
  136. }
  137. static pcap_t * new_pcap(char * iface)
  138. {
  139.  char errbuf[PCAP_ERRBUF_SIZE];
  140.  bpf_u_int32 netmask, network;
  141.  struct bpf_program filter_prog;
  142.  char filter[] = "ip";
  143.  pcap_t *  pcap;
  144.  if(strcmp(iface, "lo") == 0 ||
  145.     strcmp(iface, "lo0") == 0)return NULL;
  146.  pcap = pcap_open_live(iface, 1500, 0, 1, errbuf);
  147.  if(pcap == NULL)
  148.   {
  149.    fprintf(stderr, "new_pcap(%s) failed - %sn", iface, errbuf);
  150.    return NULL;
  151.   }
  152.   
  153.   if(pcap_lookupnet(iface, &network, &netmask, 0) < 0)
  154.  { 
  155.    printf("pcap_lookupnet failedn");
  156.    pcap_close(pcap);
  157.    return NULL;
  158.  }
  159.  
  160.  if(pcap_compile(pcap, &filter_prog, filter, 1, netmask) < 0)
  161.  {
  162.   pcap_perror(pcap, "pcap_compile");
  163.   pcap_close(pcap);
  164.   return NULL;
  165.  }
  166.  
  167.  if(pcap_setfilter(pcap, &filter_prog) < 0) 
  168.  {
  169.   pcap_perror(pcap, "pcap_setfiltern");
  170.   pcap_close(pcap);
  171.   return NULL;
  172.  }
  173.  return pcap;
  174. }
  175. static pcap_t * bpf_add_pcap(char * iface)
  176. {
  177.  pcap_t * ret = get_pcap(iface);
  178.  if(ret != NULL) 
  179.   return ret;
  180.  else 
  181.    add_pcap(iface, new_pcap(iface));
  182.    
  183.  return get_pcap(iface);
  184. }
  185.  
  186. static int bpf_recv_line(int soc, char * buf, int len)
  187. {
  188.  int r = 0;
  189.  bzero(buf, len);
  190.  for(;r<len;)
  191.  {
  192.  int e;
  193. again: 
  194.   e = recv(soc, &(buf[r]), 1, 0);
  195.  if(e <= 0) {
  196.     if(e < 0 && errno == EINTR)goto again;
  197.     return e;
  198.     }
  199.  r ++;
  200.  if(buf[r-1] == 'n'){
  201. return r;
  202. }
  203.  }
  204.  return r;
  205. }
  206. static int process(char * iface, u_char * p, int len)
  207. {
  208.  int i;
  209. #ifdef DEBUG_HIGH
  210.  printf("bpf_share: process()n");
  211. #endif 
  212.  for(i=0;i<NUM_CLIENTS;i++)
  213.  {
  214. #ifdef DEBUG_HIGH 
  215. if(clients[i].soc != 0)
  216.   printf("%d) %d, %s %s %sn", i, clients[i].soc, clients[i].iface, iface, clients[i].filter);
  217. #endif  
  218.   if(clients[i].soc > 0 && (strcmp(clients[i].iface, iface) == 0))
  219.   {
  220.    if(clients[i].filter[0] == '' || bpf_filter(clients[i].bpf_filter.bf_insns, p, len, len) != 0)
  221.     {
  222.     int e;
  223.     int n;
  224.     int lim;
  225.     
  226. #ifdef DEBUG_FORWARD 
  227.     printf("Found packet that matches %s %dn", clients[i].filter, i);
  228. #endif        
  229. #ifdef DEBUG    
  230.     printf("bpf_share: forward data to %dn", i);
  231. #endif    
  232.     n = 0;
  233.     while( n != sizeof(len))
  234.     {
  235.      fd_set wr;
  236.      struct timeval tv;
  237. again:       
  238.     FD_ZERO(&wr);
  239.     FD_SET(clients[i].soc, &wr);
  240.     tv.tv_sec = tv.tv_usec = 0;
  241.     e = select(clients[i].soc + 1, NULL, &wr, NULL, &tv);
  242.     if(e <= 0)
  243.     {
  244.      if(e < 0 && errno == EINTR)goto again;
  245.      else break;
  246.     }
  247.     e = send(clients[i].soc, (char*)(&len)+n, sizeof(len)-n, 0);
  248.     if(e <= 0)
  249.     {
  250.      if(e < 0 && errno == EINTR)goto again;
  251.      if(errno != EPIPE)perror("bpf_share.c:process():send ");
  252.      bpf_svr_close(i);
  253.      goto endfor;
  254.     }
  255.     else n += e;
  256.     }
  257.     
  258.     n = 0;
  259.     
  260.     if(len > CLNT_BUF_SIZ)
  261.      lim = CLNT_BUF_SIZ;
  262.     else
  263.         lim = len;
  264.     
  265.     
  266.     while(n != lim)
  267.     {
  268.      fd_set wr;
  269.     struct timeval tv;
  270. again2:    
  271.     FD_ZERO(&wr);
  272.     FD_SET(clients[i].soc, &wr);
  273.     tv.tv_sec = tv.tv_usec = 0;
  274.     e = select(clients[i].soc + 1, NULL, &wr, NULL, &tv);
  275.     if(e <= 0)
  276.     {
  277.      if(e < 0 && errno == EINTR)goto again2;
  278.      else break;
  279.     }
  280.     e =  send(clients[i].soc, (char*)p + n, lim - n, 0);
  281.     if(e <= 0)
  282.      {
  283.      if ( e < 0 && errno == EINTR )goto again2;
  284.      
  285.      if(errno != EPIPE)perror("bpf_share.c:process():send ");
  286.      bpf_svr_close(i);
  287.      goto endfor;
  288.      }
  289.     else n+=e;
  290.     }
  291. #ifdef DEBUG_FORWARD    
  292.      printf("====>PACKET FORWARDED TO %d->%dn", i, clients[i].soc);
  293. #endif     
  294.   endfor:
  295.      ;
  296.     }
  297.   }
  298.  }
  299.  return 0;
  300. }
  301. static int mklistener()
  302. {
  303.  struct sockaddr_un addr;
  304.  char name[] =  BPF_SOCKET_PATH;
  305.  int soc;
  306.  int one = 1;
  307.  struct stat st;
  308.  
  309.  if(stat(name, &st) == 0)
  310.  {
  311.   unlink(name);
  312.  }
  313.  
  314.  
  315.  soc = socket(AF_UNIX, SOCK_STREAM, 0);
  316.  if(soc < 0)
  317.   return -1;
  318.  
  319.  bzero(&addr, sizeof(addr));
  320.  addr.sun_family = AF_UNIX;
  321.  bcopy(name, addr.sun_path, strlen(name));
  322.  setsockopt(soc, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
  323.  if(bind(soc, (struct sockaddr*)(&addr), sizeof(addr)) == -1)
  324.  {
  325.   perror("bpf_share.c:mklistener():bind ");
  326.  }
  327.  chmod(name, 0700);
  328.  if(listen(soc, NUM_CLIENTS - 1) < 0)
  329.   perror("bpf_share.c:mklistener():listen ");
  330.  return soc;
  331. }
  332. static int add_client(int soc)
  333. {
  334.  int i;
  335.  for(i=0;i<NUM_CLIENTS && clients[i].soc;i++);
  336.  if(clients[i].soc)
  337.  {
  338.   fprintf(stderr, "bpf_share: Too many clients already.n");
  339.   close(soc);
  340.   return -1;
  341.  }
  342.  
  343.  clients[i].soc = soc;
  344.  clients[i].filter[0] = '';
  345.  clients[i].iface[0] = '';
  346. #ifdef DEBUG 
  347.  printf("Added client at index %d (%d)n", i, clients[i].soc);
  348. #endif
  349.  return i;
  350. }
  351. static int read_clients()
  352. {
  353.  fd_set rd;
  354.  int i;
  355.  char buf[512];
  356.  int max = -1;
  357.  struct timeval tv = {0, 0};
  358.  
  359.  FD_ZERO(&rd);
  360.  for(i=0;i<NUM_CLIENTS;i++)
  361.  {
  362.   if(clients[i].soc > 0)
  363.   {
  364.    FD_SET(clients[i].soc, &rd);
  365.    if(clients[i].soc > max) max = clients[i].soc;
  366.   }
  367.  }
  368.  
  369.  if(max == -1)
  370.  {
  371.   usleep(50000);
  372.   return 0;
  373.  }
  374.  
  375.  if(select(max+1, &rd, NULL, NULL, &tv) > 0)
  376.  {
  377.   for(i=0;i<NUM_CLIENTS;i++)
  378.   {
  379.    if(clients[i].soc && FD_ISSET(clients[i].soc, &rd))
  380.    {
  381.     int n;
  382.     
  383.     n = bpf_recv_line(clients[i].soc, buf, sizeof(buf));
  384. #ifdef DEBUG
  385.     printf("Received %sn", buf);
  386. #endif    
  387.     if(n <= 0)
  388.     {
  389. #ifdef DEBUG_FORWARD
  390.      printf("Connection closed for %dn", i);
  391. #endif     
  392.      /* connection was closed */
  393.      bpf_svr_close(i);
  394.     }
  395.     else
  396.     {
  397.      if(clients[i].iface[0] == '')
  398.      { 
  399.        int dl; 
  400.        int pcap_compile_failed = 0;
  401.        pcap_t * pcap;
  402.        bpf_u_int32 netmask, network;
  403.        if(buf[0] != '')buf[strlen(buf) - 1 ] = '';
  404.        clients[i].iface[sizeof(clients[i].iface) - 1] = '';
  405.        strncpy(clients[i].iface, buf, sizeof(clients[i].iface) - 1);
  406.        send(clients[i].soc, ".", 1, 0);
  407.        
  408.        
  409. again:
  410.        pcap = bpf_add_pcap(clients[i].iface);
  411.        
  412.      
  413.        if(pcap != NULL)
  414.        {
  415.        dl = htonl(pcap_datalink(pcap));
  416.        send(clients[i].soc, &dl, sizeof(dl), 0);
  417.        n = bpf_recv_line(clients[i].soc, buf, sizeof(buf));
  418.        if(buf[0] != '')buf[strlen(buf) - 1 ] = '';
  419.        clients[i].filter[sizeof(clients[i].filter) - 1] = '';
  420.        strncpy(clients[i].filter, buf, sizeof(clients[i].filter) - 1);
  421. #ifdef DEBUG       
  422.        printf("FILTER = %s (%s) %dn", buf, clients[i].filter, i);
  423. #endif       
  424.        pcap_lookupnet(clients[i].iface, &network, &netmask, 0);
  425.      /*  pcap_restart(NULL);    */    
  426.        if ( pcap_compile(pcap, &clients[i].bpf_filter, buf, 1, netmask) 
  427. < 0 )
  428.  {
  429.  if ( pcap_compile_failed == 0 )
  430. {
  431.  rm_pcap(clients[i].iface);
  432.  pcap_compile_failed++;
  433.  goto again;
  434. }
  435.   else {
  436.    fprintf(stderr, "pcap_compile(%s) failedn", buf);
  437.    send(clients[i].soc, "e", 1, 0);
  438.            }
  439.  }
  440.         else 
  441.  clients[i].flag = 1;
  442.       }
  443.        else send(clients[i].soc, "e", 1, 0);
  444.      }
  445.     }
  446.    }
  447.   }
  448.  }
  449.  for(i=0;i<NUM_CLIENTS;i++)
  450.  {
  451.   if(clients[i].soc && clients[i].flag)
  452.   {
  453.      send(clients[i].soc, ",", 1, 0);
  454.      clients[i].flag = 0;
  455.   }
  456.  }
  457.  return 0;
  458. }
  459. static int add_clients(int soc)
  460. {
  461.  fd_set rd;
  462.  struct timeval tv = {0,0};
  463.  unsigned int clnt;
  464.  
  465.  FD_ZERO(&rd);
  466.  FD_SET(soc, &rd);
  467.  if(select(soc+1, &rd, &rd, &rd, &tv) > 0)
  468.  {
  469.   struct sockaddr_un soca;
  470.   unsigned int len = sizeof(soca);
  471.   clnt = accept(soc, (struct sockaddr*)&soca,&len); 
  472.   if(clnt > 0)
  473.   {
  474. #ifdef DEBUG_FORWARD
  475.    printf("New client!n");
  476. #endif     
  477.    setbufsize(clnt);
  478.    add_client(clnt);
  479.    }
  480.  }
  481.  return 0;
  482. }
  483. static int pcaps_read()
  484. {
  485.  struct bpf_pcap * bpc = pcaps;
  486.  
  487.  if(bpc == NULL)usleep(50000);
  488.  
  489.  while(bpc != NULL)
  490.  {
  491.   u_char * p;
  492.   struct pcap_pkthdr head;
  493.   int count = 0;
  494. again:  
  495.   p = (u_char*)pcap_next(bpc->pcap, &head);
  496.   if(p != NULL){
  497.     process(bpc->iface, p, head.caplen);
  498.     count ++;
  499.     if ( count < 30 ) goto again;
  500.    }
  501.   bpc = bpc->next;
  502.  }
  503.  return 0;
  504. }
  505. int bpf_server()
  506. {
  507.  int i;
  508.  int lst;
  509.  int pid;
  510.  int fd  = open(BPF_SERVER_PID_FILE, O_RDONLY);
  511.  
  512.  
  513.  if ( fd >= 0 )
  514.  {
  515.   char buf[256];
  516.   pid_t pid;
  517.   read(fd, buf, sizeof(buf) - 1);
  518.   buf[sizeof(buf) - 1] = 0;
  519.   pid = atoi(buf);
  520.   close(fd);
  521.   if ( kill(pid, 0) == 0 ) return pid; /* Already running */
  522.   else unlink(BPF_SERVER_PID_FILE);
  523.  }
  524.  
  525.  
  526.  for(i=0;i<NUM_CLIENTS;i++)bzero(&clients[i], sizeof(clients[i]));
  527.  if((pid = fork()) == 0)
  528.  {
  529.   fd = open(BPF_SERVER_PID_FILE, O_CREAT|O_TRUNC|O_WRONLY, 0644);
  530.   if ( fd >= 0 )
  531.   {
  532.    char buf[256];
  533.    snprintf(buf, sizeof(buf), "%d", getpid());
  534.    write(fd, buf, strlen(buf));
  535.    close(fd);
  536.   }
  537.   signal(SIGPIPE, SIG_IGN);
  538.   signal(SIGHUP, SIG_IGN);
  539.   signal(SIGTERM, sigterm);
  540.   setproctitle("bpf server"); 
  541.   lst = mklistener();
  542.   for(;;)
  543.   {
  544.    add_clients(lst);
  545.    read_clients();
  546.    pcaps_read();
  547.    }
  548.   }
  549.  return pid;
  550. }
  551. int bpf_svr_close(int n)
  552. {
  553.  if(clients[n].soc) {
  554. shutdown(clients[n].soc, 2);
  555. close(clients[n].soc);
  556. }
  557.  if(clients[n].bpf_filter.bf_insns != NULL)free(clients[n].bpf_filter.bf_insns);
  558.  bzero(&clients[n], sizeof(clients[n]));
  559.  return 0;
  560. }
  561. /*--------------------------------------------------------------------------*
  562.  * Client part      *
  563.  *--------------------------------------------------------------------------*/
  564.  
  565. static int bpf_set_iface(int soc, char * iface)
  566.  char buf[2]  = {0, 0};
  567.  char snd[256];
  568.  fd_set fds;
  569.  struct timeval tv;
  570.  int e;
  571.  
  572.  
  573.  snprintf(snd, sizeof(snd), "%sn", iface);
  574.  
  575. again:
  576.  FD_ZERO(&fds);
  577.  tv.tv_sec = 1; 
  578.  tv.tv_usec = 0;
  579.  FD_SET(soc, &fds);
  580.  e = select(soc + 1, NULL, &fds, NULL, &tv);
  581.  if ( e <= 0 )
  582.  {
  583.   if(e < 0 && errno == EINTR)goto again;
  584.   else return -1;
  585.  }
  586.  
  587.  e = send(soc, snd, strlen(snd), 0);
  588.  if ( e <= 0 )
  589.  {
  590.   if ( e < 0 && errno == EINTR )goto again;
  591.   else return -1;
  592.  }
  593.  
  594. recv_again: 
  595.  FD_ZERO(&fds);
  596.  tv.tv_sec = 1; 
  597.  tv.tv_usec = 0;
  598.  FD_SET(soc, &fds);
  599.  e = select(soc + 1, &fds, NULL, NULL, &tv);
  600.  if ( e <= 0 )
  601.  {
  602.   if(e < 0 && errno == EINTR)goto recv_again;
  603.   else return -1;
  604.  }
  605.  
  606.  
  607.  e = recv(soc, buf, 1, 0);
  608.  if(e <= 0 )
  609.  {
  610.   if ( e < 0 && errno == EINTR ) goto recv_again;
  611.   else return -1;
  612.  }
  613.  if(buf[0] == '.')
  614.   {
  615.   int dl;
  616.   recv(soc, &dl, sizeof(dl), 0);
  617.   dl = ntohl(dl);
  618.   return dl;
  619.   }
  620.  else
  621.   return -1;
  622. }
  623. static int bpf_set_filter(int soc, char * filter)
  624. {
  625.   char buf[2]  = {0, 0};
  626.   char snd[1024];
  627.   struct timeval tv;
  628.   fd_set fds;
  629.   int e;
  630.   
  631.   snprintf(snd, sizeof(snd), "%sn", filter);
  632. again:  
  633.    FD_ZERO(&fds);
  634.    tv.tv_sec = 1; 
  635.    tv.tv_usec = 0;
  636.    FD_SET(soc, &fds);
  637.    e = select(soc + 1, NULL, &fds, NULL, &tv);
  638.    if(e <= 0)
  639.    {
  640.     if ( e < 0 && errno == EINTR )goto again;
  641.     else return -1;
  642.    }
  643.    
  644.    e = send(soc, snd, strlen(snd), 0);
  645.    if ( e <= 0 )
  646.    { 
  647.     if ( e < 0 && errno == EINTR ) goto again;
  648.     else return -1;
  649.    }
  650.    
  651. recv_again:  
  652.    FD_ZERO(&fds);
  653.    tv.tv_sec = 1; 
  654.    tv.tv_usec = 0;
  655.    FD_SET(soc, &fds);
  656.    e = select(soc + 1, &fds, NULL, NULL, &tv);
  657.    if(e <= 0)
  658.    {
  659.     if ( e < 0 && errno == EINTR )goto recv_again;
  660.     else return -1;
  661.    }
  662.    
  663.    e = recv(soc, buf, 1, 0);
  664.    if ( e <= 0 )
  665.    { 
  666.     if ( e < 0 && errno == EINTR ) goto recv_again;
  667.     else return -1;
  668.    }
  669.    
  670.  
  671.   if(buf[0] == ',')
  672.    return 0;
  673.   else
  674.    return -1;
  675. }
  676.  
  677.  
  678. int bpf_open_live(char * iface, char * filter)
  679. {
  680.  int soc;
  681.  struct sockaddr_un addr;
  682.  int len = sizeof(addr);
  683.  char name[] = BPF_SOCKET_PATH;
  684.  char errbuf[PCAP_ERRBUF_SIZE];
  685.  
  686.  int i;
  687.  
  688.  for(i=0;i<NUM_BPF_PER_CLIENT && clnts[i].soc != 0;i++);
  689.  
  690.  if(clnts[i].soc != 0)
  691.   return -1;
  692.   
  693.  
  694.  if(iface == NULL)
  695.   iface = pcap_lookupdev(errbuf); 
  696.   
  697.  
  698.  soc = socket(AF_UNIX, SOCK_STREAM, 0);
  699.   if(soc < 0)
  700.   {
  701.    perror("bpf_open_live():socket ");
  702.    return -1;
  703.   } 
  704.  bzero(&addr, sizeof(addr));
  705.  addr.sun_family = AF_UNIX;
  706.  bcopy(name, addr.sun_path, strlen(name));
  707.  setbufsize(soc);
  708.  if(connect(soc, (struct sockaddr*)&addr, len) ==  -1 )
  709.  { 
  710.   perror("bpf_open_live():connect ");
  711.   close(soc);
  712.   return -1;
  713.  }
  714.  
  715.  clnts[i].datalink = bpf_set_iface(soc, iface);
  716.  if(clnts[i].datalink < 0 )
  717.   {
  718.   close(soc);
  719.   bzero(&clnts[i], sizeof(clnts[i]));
  720.   return -1;
  721.   }
  722.   
  723.  if( bpf_set_filter(soc, filter) < 0)
  724.  {
  725.   close(soc);
  726.   bzero(&clnts[i], sizeof(clnts[i]));
  727.   return -1;
  728.  }
  729.  clnts[i].packet = emalloc(CLNT_BUF_SIZ);
  730.  clnts[i].soc = soc;
  731.  return i;
  732. }
  733. ExtFunc u_char* bpf_next_tv(int clnt, int * caplen, struct timeval * tv)
  734. {
  735.  fd_set rd;
  736.  int soc;
  737.  int lim;
  738.  struct timeval tmp;
  739.  int e;
  740.  
  741.  if(clnt < 0 )return NULL;
  742.  
  743.  soc = clnts[clnt].soc;
  744.  if( soc <= 0 ){
  745.     fprintf(stderr, "[%d] bpf_next_tv() : called on a closed bpf !n", getpid());
  746.     return NULL;
  747.     }
  748.  
  749.  bzero(clnts[clnt].packet, CLNT_BUF_SIZ);
  750. again: 
  751.  errno = 0;
  752.  tmp = *tv;
  753.  
  754.  
  755.  FD_ZERO(&rd);
  756.  FD_SET(soc, &rd);
  757. #ifdef DEBUG 
  758.  printf("(%d) bpf_nextn", getpid());
  759. #endif 
  760.  e = select(soc + 1, &rd, NULL, NULL, &tmp);
  761.  if ( e < 0 && errno == EINTR)goto again;
  762.  
  763.  if(e > 0)
  764.  {
  765.   int n = 0;
  766.   
  767. #ifdef DEBUG  
  768.   printf("(%d) Select(%d->%d)n", getpid(), clnt, soc);
  769. #endif  
  770.   while(n != sizeof(*caplen))
  771.   {
  772.   char * x = (char*)caplen;
  773.   int e;
  774. recv_again:  
  775.   e = recv(soc, x+n, sizeof(*caplen)-n, 0);
  776.   if( e <= 0 )
  777.    {
  778.     if(e < 0 && errno == EINTR)goto recv_again;
  779.     perror("bpf_next():recv ");
  780.     bpf_close(clnt);
  781.     return NULL;
  782.    }
  783.   else
  784.    n += e;
  785.   }
  786.   
  787. #ifdef DEBUG  
  788.   printf("(%d) HEAD received (%d->%d)n", getpid(), clnt, soc);
  789. #endif  
  790.  
  791.   
  792.  
  793.   if( *caplen > CLNT_BUF_SIZ)
  794.    lim = CLNT_BUF_SIZ;
  795.   else
  796.    lim = *caplen;
  797.     
  798.    
  799.   n = 0;
  800.   while(n != lim)
  801.   {
  802.   int e;
  803. recv_again2:  
  804.   e = recv(soc, &(clnts[clnt].packet[n]), lim-n, 0);
  805.   if(e < 0 && errno == EINTR)goto recv_again2;
  806.   
  807.   if(e <= 0 ) 
  808.    {
  809.    bpf_close(clnt);
  810.    return NULL;
  811.    }
  812.   else
  813.    n+=e;
  814.   }
  815. #ifdef DEBUG
  816.   dump_packet(clnts[clnt].packet, lim);
  817. #endif  
  818.   return clnts[clnt].packet;
  819.  }
  820.  return NULL;
  821. }
  822. ExtFunc u_char* bpf_next(int clnt, int * caplen)
  823. {
  824.  struct timeval tv = {0, 100000};
  825.  return bpf_next_tv(clnt, caplen, &tv);
  826. }
  827. int bpf_datalink(int bpf)
  828. {
  829.  return clnts[bpf].datalink;
  830. }
  831. void bpf_close(int bpf)
  832. {
  833.  if(clnts[bpf].soc){
  834. shutdown(clnts[bpf].soc, 2);
  835. close(clnts[bpf].soc);
  836. }
  837.  efree(&clnts[bpf].packet);       
  838.  bzero(&clnts[bpf], sizeof(clnts[bpf]));
  839. }
  840. #else
  841. static pcap_t * pcaps[NUM_CLIENTS];
  842. int bpf_open_live(char * iface, char * filter)
  843. {
  844.  char errbuf[PCAP_ERRBUF_SIZE];
  845.  pcap_t * ret;
  846.  bpf_u_int32 netmask, network;
  847.  struct bpf_program filter_prog;
  848.  int i;
  849.  
  850.  for(i=0;i< NUM_CLIENTS && pcaps[i];i++);
  851.  if(pcaps[i])
  852.  {
  853.   printf("no free pcapn");
  854.   return -1;
  855.  }
  856.   
  857.  
  858.  if(iface == NULL)
  859.   iface = pcap_lookupdev(errbuf);
  860.  
  861.  ret = pcap_open_live(iface, 1500, 0, 1, errbuf);
  862.  if(ret == NULL)
  863.  {
  864.     printf("%sn", errbuf);  
  865.   return -1;
  866.  }
  867.  if(pcap_lookupnet(iface, &network, &netmask, 0) < 0)
  868.  { 
  869.    printf("pcap_lookupnet failedn");
  870.    pcap_close(ret);
  871.    return -1;
  872.  }
  873.  
  874.  if(pcap_compile(ret, &filter_prog, filter, 1, netmask) < 0)
  875.  {
  876.   pcap_perror(ret, "pcap_compile");
  877.   pcap_close(ret);
  878.   return -1;
  879.  }
  880.  
  881.  if(pcap_setfilter(ret, &filter_prog) < 0) 
  882.  {
  883.   pcap_perror(ret, "pcap_setfiltern");
  884.   pcap_close(ret);
  885.   return -1;
  886.  }
  887.  pcaps[i] = ret;
  888.  return i;
  889. }
  890. u_char* bpf_next_tv(int bpf, int * caplen, struct timeval * tv)
  891. {
  892.   u_char * p = NULL;
  893.   struct pcap_pkthdr head;
  894.   struct timeval timeout, now;
  895.   gettimeofday(&timeout, NULL);
  896.   timeout.tv_sec += tv->tv_sec;
  897.   timeout.tv_usec += tv->tv_usec;
  898.   while ( timeout.tv_usec >= 1000000 ) {
  899.         timeout.tv_sec ++;
  900.         timeout.tv_usec -= 1000000;
  901.   }
  902.   
  903.  do {
  904.   p = (u_char*)pcap_next(pcaps[bpf], &head);
  905.   *caplen  = head.caplen;
  906.   if ( p != NULL ) break;
  907.   gettimeofday(&now, NULL);
  908.  } while ( !((now.tv_sec > timeout.tv_sec) ||
  909.              (now.tv_sec == timeout.tv_sec && now.tv_usec >= timeout.tv_usec ) ));
  910.  return p;
  911. }
  912. u_char* bpf_next(int bpf, int * caplen)
  913. {
  914.  struct timeval tv = {0, 100000};
  915.  
  916.  return bpf_next_tv(bpf, caplen, &tv);
  917. }
  918. int bpf_datalink(int bpf)
  919. {
  920.  return pcap_datalink(pcaps[bpf]);
  921. }
  922. void bpf_close(int bpf)
  923. {
  924.  pcap_close(pcaps[bpf]);
  925.  pcaps[bpf] = NULL;
  926. }
  927. int bpf_server()
  928. {
  929.   return 0;
  930. }
  931. #endif /* HAVE_DEV_BPFN */
  932. #undef __STANDALONE__
  933. #ifdef __STANDALONE__
  934. /*
  935.  * This code tests our bpf sharer
  936.  */
  937. int main()
  938. {
  939.  printf("Hello humann");
  940.  bpf_server();
  941.  
  942.  
  943. }
  944. #endif