]> git.pld-linux.org Git - packages/dhcp_probe.git/commitdiff
- new
authorJan Rękorajski <baggins@pld-linux.org>
Fri, 20 Apr 2012 11:41:22 +0000 (11:41 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    dhcp_probe-guignard-03_implicit_point_conv_bootp.c.patch -> 1.1
    dhcp_probe-guignard-04_linux_32_or_64bits.patch -> 1.1
    dhcp_probe-virta-01-pcap-loop.patch -> 1.1
    dhcp_probe-virta-02-keep-pcap.patch -> 1.1
    dhcp_probe-virta-03-drop-privs.patch -> 1.1
    dhcp_probe.init -> 1.1
    dhcp_probe.spec -> 1.1
    dhcp_probe.sysconfig -> 1.1
    dhcp_probe@.service -> 1.1

dhcp_probe-guignard-03_implicit_point_conv_bootp.c.patch [new file with mode: 0644]
dhcp_probe-guignard-04_linux_32_or_64bits.patch [new file with mode: 0644]
dhcp_probe-virta-01-pcap-loop.patch [new file with mode: 0644]
dhcp_probe-virta-02-keep-pcap.patch [new file with mode: 0644]
dhcp_probe-virta-03-drop-privs.patch [new file with mode: 0644]
dhcp_probe.init [new file with mode: 0644]
dhcp_probe.spec [new file with mode: 0644]
dhcp_probe.sysconfig [new file with mode: 0644]
dhcp_probe@.service [new file with mode: 0644]

diff --git a/dhcp_probe-guignard-03_implicit_point_conv_bootp.c.patch b/dhcp_probe-guignard-03_implicit_point_conv_bootp.c.patch
new file mode 100644 (file)
index 0000000..0b0582c
--- /dev/null
@@ -0,0 +1,21 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 03_implicit_point_conv_bootp.c.dpatch by Laurent Guignard <lguignard.debian@gmail.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Fix implicit Pointer Converstion in bootp.c file.
+##     Fix bug #529635 discovered by Dann Frazier <dannf@debian.org>
+##
+
+@DPATCH@
+diff -urNad src/bootp.c src/bootp.c
+--- src/bootp.c        2009-03-31 14:19:06.000000000 +0200
++++ src/bootp.c        2009-05-21 09:51:26.000000000 +0200
+@@ -11,7 +11,7 @@
+ #include "bootp.h"
+ #include "configfile.h"
+ #include "report.h"
+-
++#include "utils.h"
diff --git a/dhcp_probe-guignard-04_linux_32_or_64bits.patch b/dhcp_probe-guignard-04_linux_32_or_64bits.patch
new file mode 100644 (file)
index 0000000..ce6e3f0
--- /dev/null
@@ -0,0 +1,33 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 04_linux_32_or_64bits.dpatch by Laurent Guignard <lguignard.debian@gmail.com>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: A solution to solve the bug #535361
+##     May be this will be a solution with the right method ???
+
+@DPATCH@
+diff -urNad src/get_myipaddr.c trunk/src/get_myipaddr.c
+--- src/get_myipaddr.c 2009-09-03 13:10:32.000000000 +0200
++++ src/get_myipaddr.c 2009-09-03 13:15:39.671451172 +0200
+@@ -118,7 +118,21 @@
+ #endif /* not STRUCT_SOCKADDR_HAS_SA_LEN */
+               /* increment ptr to next interface for next time through the loop */
++#ifdef __ARCH__       /* Debian GNU/Linux behavior for packaging goal */
++              switch(__ARCH__) {
++                      case 32:        /* 32 bits architectures */
++                              ptr += sizeof(ifr->ifr_name) + len;
++                              break;
++                      case 64:        /* 64 bits architectures */
++                              ptr += sizeof(struct ifreq);
++                              break;
++                      default:        /* Default dhcp_probe behavior */
++                              ptr += sizeof(ifr->ifr_name) + len;
++                              break;
++              }
++#else /* Default dhcp_probe behavior */
+               ptr += sizeof(ifr->ifr_name) + len;
++#endif
+               if (strcmp(ifname, ifr->ifr_name) != 0 )  /* is this the interface we're looking for? */
+                       continue;
diff --git a/dhcp_probe-virta-01-pcap-loop.patch b/dhcp_probe-virta-01-pcap-loop.patch
new file mode 100644 (file)
index 0000000..1913379
--- /dev/null
@@ -0,0 +1,164 @@
+##dhcp-probe-01-pcap-loop.patch - wrap pcap_dispatch in a loop
+--- src/dhcp_probe.c   2009-08-16 12:24:10.000000000 +0300
++++ src/dhcp_probe.c   2009-08-16 11:52:26.000000000 +0300
+@@ -59,6 +59,7 @@
+ volatile sig_atomic_t reopen_log_file; /* for signal handler */
+ volatile sig_atomic_t reopen_capture_file; /* for signal handler */
+ volatile sig_atomic_t quit_requested; /* for signal requested */
++volatile sig_atomic_t alarm_fired; /* for signal requested */
+ pcap_t *pd = NULL;                                    /* libpcap - packet capture descriptor used for actual packet capture */
+ pcap_t *pd_template = NULL;                   /* libpcap - packet capture descriptor just used as template */
+@@ -74,6 +75,27 @@
+ int use_8021q = 0;
+ int vlan_id = 0;
++/* capture packets from pcap for timeout seconds */
++int 
++loop_for_packets(int timeout)
++{
++      int packets_recv = 0;
++      
++      alarm_fired = 0;
++      alarm(timeout);
++      
++      do {
++              int pcap_rc = pcap_dispatch(pd, -1, process_response, NULL);
++              if (pcap_rc == -1)
++                      report(LOG_ERR, "pcap_dispatch(): %s", pcap_geterr(pd));
++              else if (pcap_rc > 0)
++                      packets_recv += pcap_rc;
++      } while(! alarm_fired && !quit_requested);
++      
++      return packets_recv;
++}
++
++
+ int 
+ main(int argc, char **argv)
+ {
+@@ -84,7 +106,6 @@
+       struct sigaction sa;
+       FILE *pid_fp;
+       char *cwd = CWD;
+-      int i;
+       int write_packet_len;
+       int bytes_written;
+@@ -98,9 +119,6 @@
+       int linktype;
+       char pcap_errbuf[PCAP_ERRBUF_SIZE], pcap_errbuf2[PCAP_ERRBUF_SIZE];
+-      /* for libnet */
+-      char libnet_errbuf[LIBNET_ERRBUF_SIZE];
+-
+       /* get progname = last component of argv[0] */
+       prog = strrchr(argv[0], '/');
+       if (prog)
+@@ -265,6 +283,8 @@
+       reread_config_file = 0; /* set by signal handler */
+       reopen_log_file = 0; /* set by signal handler */
+       reopen_capture_file = 0; /* set by signal handler */
++      quit_requested = 0;
++      alarm_fired = 0;
+       
+       ifname = strdup(argv[optind]); /* interface name is a required final argument */
+@@ -332,6 +352,13 @@
+               report(LOG_ERR, "sigaction: %s", get_errmsg());
+               my_exit(1, 1, 1);
+       }
++      sigemptyset(&sa.sa_mask);
++      sa.sa_handler = catcher;
++      sa.sa_flags = 0;
++      if (sigaction(SIGALRM, &sa, NULL) < 0) {
++              report(LOG_ERR, "sigaction: %s", get_errmsg());
++              my_exit(1, 1, 1);
++      }
+@@ -479,8 +506,9 @@
+               for (l = libnet_cq_head(); libnet_cq_last(); l = libnet_cq_next()) { /* write one flavor packet and listen for answers */
+-                      int pcap_rc;
++                      int packets_recv;
+                       int pcap_open_retries;
++                      
+                       /* We set up for packet capture BEFORE writing our packet, to minimize the delay
+                          between our writing and when we are able to start capturing.  (I cannot tell from
+@@ -569,33 +597,16 @@
+                               report(LOG_DEBUG, "listening for answers for %d milliseconds", GetResponse_wait_time());
+-                      /* XXX I often find that pcap_dispatch() returns well before the timeout specified earlier.
+-                         I ensure that there's no alarm() still left over before we start, and also ensure we don't
+-                         get interrupted by SIGCHLD (possible since process_response() could fork an alert_program or alert_program2 child).
+-                         But we STILL often return from pcap_dispatch() too soon!
+-                         April 2001: An update to the pcap(3) man page around version 0.6 (?), along with postings 
+-                         on the tcpdump workers mailing list explains what's going on.  The timeout specified in 
+-                         pcap_open_live() isn't a timeout in the sense one might expect.  The pcap_dispatch() call 
+-                         can return sooner than expected (even immediately), or if no packets are received, might 
+-                         never return at all; the behavior is platform-dependant.  I don't have a way to work
+-                         around this issue; it means this program  just won't work reliably (or at all) on some
+-                         platforms.
+-                      */
+-
+-                      alarm(0); /* just in case a previous alarm was still left */
+-
+                       sigemptyset(&new_sigset);
+                       sigaddset(&new_sigset, SIGCHLD);
+                       sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset);  /* block SIGCHLD */
+-                      pcap_rc = pcap_dispatch(pd, -1, process_response, NULL);
++                      packets_recv = loop_for_packets(GetResponse_wait_time() / 1000);;
+                       sigprocmask(SIG_SETMASK, &old_sigset, NULL);  /* unblock SIGCHLD */
+-                      if (pcap_rc < 0)
+-                              report(LOG_ERR, "pcap_dispatch(): %s", pcap_geterr(pd));
+-                      else if (debug > 10)
+-                              report(LOG_DEBUG, "done listening, captured %d packets", pcap_rc);
++                      if (debug > 10)
++                              report(LOG_DEBUG, "done listening, captured %d packets", packets_recv);
+                       /* I was hoping that perhaps pcap_stats() would return a nonzero number of packets dropped when
+                          the buffer size specified to pcap_open_live() turns out to be too small -- so we could
+@@ -688,6 +699,7 @@
+               pcap_close(pd_template); 
+       my_exit(0, 1, 1);
++      return 0; /* make gcc happy */
+ }
+@@ -986,9 +998,6 @@
+ /* Perform all necessary functions to handle a request to reconfigure.
+    Must not be called until after initial configuration is complete.
+ */
+-   
+-      int i;
+-
+       if (! read_configfile(config_file)) {
+               my_exit(1, 1, 1);
+       }
+@@ -1050,8 +1059,14 @@
+       if ((sig == SIGINT) || (sig == SIGTERM) || (sig == SIGQUIT))  { /* quit gracefully */
+               quit_requested = 1;
++               /* pcap wraps the socket read inside a loop, so the signal doesn't
++                  interrupt it without an explicit call to pcap_breakloop */
++              pcap_breakloop(pd);
++              return;
++      } else if (sig == SIGALRM) { /* timer */
++              pcap_breakloop(pd);
++              alarm_fired = 1;
+               return;
+-
+       } else if (sig == SIGHUP) { /* re-read config file */
+               /* Doing the reread while in the signal handler is way too dangerous.
+                  We'll do it at the start or end of the next main event loop.
+
+
diff --git a/dhcp_probe-virta-02-keep-pcap.patch b/dhcp_probe-virta-02-keep-pcap.patch
new file mode 100644 (file)
index 0000000..c5a6739
--- /dev/null
@@ -0,0 +1,286 @@
+##dhcp-probe-02-keep-pcap.patch - add option to keep pcap open all the time
+--- src/dhcp_probe.c.01        2009-08-16 11:52:26.000000000 +0300
++++ src/dhcp_probe.c   2009-08-16 12:31:22.000000000 +0300
+@@ -49,6 +49,7 @@
+ */
+ int snaplen = CAPTURE_BUFSIZE;
+ int socket_receive_timeout_feature = 0;
++int keep_pcap = 0;
+ char *prog = NULL;
+ char *logfile_name = NULL;
+@@ -75,6 +76,89 @@
+ int use_8021q = 0;
+ int vlan_id = 0;
++int need_promiscuous(void)
++{
++      /* If we're going to claim a chaddr different than my_eaddr, some of the responses
++         may come back to chaddr (as opposed to my_eaddr or broadcast), so we'll need to
++         listen promiscuously.
++         If we're going to claim an ether_src different than my_eaddr, in theory that should
++         make no difference; bootp/dhcp servers should rely on chaddr, not ether_src.  Still,
++         it's possible there's a server out there that does it wrong, and might therefore mistakenly
++         send responses to ether_src.  So lets also listen promiscuously if ether_src != my_eaddr.
++      */
++      int promiscuous = 0;
++      if (bcmp(GetChaddr(), &my_eaddr, sizeof(struct ether_addr)) ||
++          bcmp(GetEther_src(), &my_eaddr, sizeof(struct ether_addr)))
++              promiscuous = 1;
++      return promiscuous;
++}
++
++int init_pcap(int promiscuous, bpf_u_int32 netmask)
++{
++      /* open packet capture descriptor */
++      /* XXX On Solaris 7, sometimes pcap_open_live() fails with a message like:
++                      pcap_open_live qfe0: recv_ack: info unexpected primitive ack 0x8
++         It's not clear what causes this, or what the 0x8 code indicates.
++         The error appears to be transient; retrying sometimes will work, so I've wrapped the call in a retry loop.
++         I've also added a delay after each failure; perhaps the failure has something to do with the fact that
++         we call pcap_open_live() so soon after pcap_close() (for the second and succeeding packets in each cycle);
++         adding a delay might help in that case.
++                      */
++      struct bpf_program bpf_code;
++      char pcap_errbuf[PCAP_ERRBUF_SIZE];
++      int linktype;
++      int pcap_open_retries = PCAP_OPEN_LIVE_RETRY_MAX;
++
++      do {
++              pcap_errbuf[0] = '\0'; /* so we can tell if a warning was produced on success */
++              if ((pd = pcap_open_live(ifname, snaplen, promiscuous, GetResponse_wait_time(), pcap_errbuf)) != NULL) {
++                      break; /* success */
++              } else { /* failure */
++                      if (pcap_open_retries == 0) {
++                              report(LOG_DEBUG, "pcap_open_live(%s): %s; retry count (%d) exceeded, giving up", ifname, pcap_errbuf, PCAP_OPEN_LIVE_RETRY_MAX);
++                              my_exit(1, 1, 1);
++                      } else {
++                              if (debug > 1)
++                                      report(LOG_DEBUG, "pcap_open_live(%s): %s; will retry", ifname, pcap_errbuf);
++                              sleep(PCAP_OPEN_LIVE_RETRY_DELAY); /* before next retry */
++                      }
++              } /* failure */
++      } while (pcap_open_retries--);
++      
++      
++      if (pcap_errbuf[0] != '\0')
++              /* even on success, a warning may be produced */
++              report(LOG_WARNING, "pcap_open_live(%s): succeeded but with warning: %s", ifname, pcap_errbuf);
++              
++      /* make sure this interface is ethernet */
++      linktype = pcap_datalink(pd);
++      if (linktype != DLT_EN10MB) {
++              report(LOG_ERR, "interface %s link layer type %d not ethernet", ifname, linktype);
++              my_exit(1, 1, 1);
++      }
++      /* compile bpf filter to select just udp/ip traffic to udp port bootpc  */
++      if (pcap_compile(pd, &bpf_code, "udp dst port bootpc", 1, netmask) < 0) {
++              report(LOG_ERR, "pcap_compile: %s", pcap_geterr(pd));
++              my_exit(1, 1, 1);
++      }
++      /* install compiled filter */
++      if (pcap_setfilter(pd, &bpf_code) < 0) {
++              report(LOG_ERR, "pcap_setfilter: %s", pcap_geterr(pd));
++              my_exit(1, 1, 1);
++      }
++      if (socket_receive_timeout_feature)
++              set_pcap_timeout(pd);
++
++      return 0;
++}
++
++void 
++reset_pcap() 
++{
++      /* close packet capture descriptor */
++      pcap_close(pd); 
++}
++
+ /* capture packets from pcap for timeout seconds */
+ int 
+ loop_for_packets(int timeout)
+@@ -115,8 +199,6 @@
+       /* for libpcap */
+       bpf_u_int32 netnumber,  netmask;
+-      struct bpf_program bpf_code;
+-      int linktype;
+       char pcap_errbuf[PCAP_ERRBUF_SIZE], pcap_errbuf2[PCAP_ERRBUF_SIZE];
+       /* get progname = last component of argv[0] */
+@@ -126,7 +208,7 @@
+       else 
+               prog = argv[0];
+-      while ((c = getopt(argc, argv, "c:d:fhl:o:p:Q:s:Tvw:")) != EOF) {
++      while ((c = getopt(argc, argv, "c:d:fhkl:o:p:Q:s:Tvw:")) != EOF) {
+               switch (c) {
+                       case 'c':
+                               if (optarg[0] != '/') {
+@@ -151,6 +233,9 @@
+                       case 'h':
+                               usage();
+                               my_exit(0, 0, 0);
++                      case 'k':
++                              keep_pcap = 1;
++                              break;
+                       case 'l':
+                               if (optarg[0] != '/') {
+                                       fprintf(stderr, "%s: invalid log file '%s', must be an absolute pathname\n", prog, optarg);
+@@ -447,8 +532,10 @@
+               }
+       }
++      if (keep_pcap)
++              init_pcap(need_promiscuous(), netmask);
++
+       while (1) { /* MAIN EVENT LOOP */
+-              int promiscuous;
+               libnet_t *l;                                            /* to iterate through libnet context queue */
+               /* struct pcap_stat ps; */                      /* to hold pcap stats */
+@@ -489,26 +576,9 @@
+                  interface in promiscuous mode as little as possible, since that can affect the host's performance.
+               */
+-              /* If we're going to claim a chaddr different than my_eaddr, some of the responses
+-                 may come back to chaddr (as opposed to my_eaddr or broadcast), so we'll need to
+-                 listen promiscuously.
+-                 If we're going to claim an ether_src different than my_eaddr, in theory that should
+-                 make no difference; bootp/dhcp servers should rely on chaddr, not ether_src.  Still,
+-                 it's possible there's a server out there that does it wrong, and might therefore mistakenly
+-                 send responses to ether_src.  So lets also listen promiscuously if ether_src != my_eaddr.
+-              */
+-              if (bcmp(GetChaddr(), &my_eaddr, sizeof(struct ether_addr)) ||
+-                  bcmp(GetEther_src(), &my_eaddr, sizeof(struct ether_addr)))
+-                      promiscuous = 1;
+-              else
+-                      promiscuous = 0;
+-
+-
+               for (l = libnet_cq_head(); libnet_cq_last(); l = libnet_cq_next()) { /* write one flavor packet and listen for answers */
+                       int packets_recv;
+-                      int pcap_open_retries;
+-                      
+                       /* We set up for packet capture BEFORE writing our packet, to minimize the delay
+                          between our writing and when we are able to start capturing.  (I cannot tell from
+@@ -518,54 +588,9 @@
+                          we wanted!
+                       */
+-                      /* open packet capture descriptor */
+-                      /* XXX On Solaris 7, sometimes pcap_open_live() fails with a message like:
+-                                      pcap_open_live qfe0: recv_ack: info unexpected primitive ack 0x8
+-                         It's not clear what causes this, or what the 0x8 code indicates.
+-                         The error appears to be transient; retrying sometimes will work, so I've wrapped the call in a retry loop.
+-                         I've also added a delay after each failure; perhaps the failure has something to do with the fact that
+-                         we call pcap_open_live() so soon after pcap_close() (for the second and succeeding packets in each cycle);
+-                         adding a delay might help in that case.
+-                      */
+-                      pcap_open_retries = PCAP_OPEN_LIVE_RETRY_MAX;
+-                      while (pcap_open_retries--) {
+-                              pcap_errbuf[0] = '\0'; /* so we can tell if a warning was produced on success */
+-                              if ((pd = pcap_open_live(ifname, snaplen, promiscuous, GetResponse_wait_time(), pcap_errbuf)) != NULL) {
+-                                      break; /* success */
+-                              } else { /* failure */
+-                                      if (pcap_open_retries == 0) {
+-                                              report(LOG_DEBUG, "pcap_open_live(%s): %s; retry count (%d) exceeded, giving up", ifname, pcap_errbuf, PCAP_OPEN_LIVE_RETRY_MAX);
+-                                              my_exit(1, 1, 1);
+-                                      } else {
+-                                              if (debug > 1)
+-                                                      report(LOG_DEBUG, "pcap_open_live(%s): %s; will retry", ifname, pcap_errbuf);
+-                                              sleep(PCAP_OPEN_LIVE_RETRY_DELAY); /* before next retry */
+-                                      }
+-                              } /* failure */
+-                      }
+-                      if (pcap_errbuf[0] != '\0')
+-                              /* even on success, a warning may be produced */
+-                              report(LOG_WARNING, "pcap_open_live(%s): succeeded but with warning: %s", ifname, pcap_errbuf);
+-
+-                      /* make sure this interface is ethernet */
+-                      linktype = pcap_datalink(pd);
+-                      if (linktype != DLT_EN10MB) {
+-                              report(LOG_ERR, "interface %s link layer type %d not ethernet", ifname, linktype);
+-                              my_exit(1, 1, 1);
+-                      }
+-                      /* compile bpf filter to select just udp/ip traffic to udp port bootpc  */
+-                      if (pcap_compile(pd, &bpf_code, "udp dst port bootpc", 1, netmask) < 0) {
+-                              report(LOG_ERR, "pcap_compile: %s", pcap_geterr(pd));
+-                              my_exit(1, 1, 1);
+-                      }
+-                      /* install compiled filter */
+-                      if (pcap_setfilter(pd, &bpf_code) < 0) {
+-                              report(LOG_ERR, "pcap_setfilter: %s", pcap_geterr(pd));
+-                              my_exit(1, 1, 1);
+-                      }
+-                      if (socket_receive_timeout_feature)
+-                              set_pcap_timeout(pd);
+-
++                      if (! keep_pcap)
++                              init_pcap(need_promiscuous(), netmask);
++                              
+                       /* write one packet */
+                       if (debug > 10)
+@@ -621,7 +646,8 @@
+                        */
+                       /* close packet capture descriptor */
+-                      pcap_close(pd); 
++                      if (! keep_pcap)
++                              reset_pcap();
+                       /* check for 'quit' request after each packet, since waiting until end of probe cycle
+                          would impose a substantial delay. */
+@@ -669,7 +695,7 @@
+                       reconfigure(write_packet_len);
+                       reread_config_file = 0;
+               }
+-
++              
+               /* We allow must signals that come in during our sleep() to interrupt us.  E.g. we want to cut short
+                  our sleep when we're signalled to exit.  But we must block SIGCHLD during our sleep.  That's because
+                  if we forked an alert_program or alert_program2 child above, its termination will likely happen while we're sleeping;
+@@ -684,7 +710,19 @@
+               sigaddset(&new_sigset, SIGCHLD);
+               sigprocmask(SIG_BLOCK, &new_sigset, &old_sigset);  /* block SIGCHLD */
+-              sleep(time_to_sleep);
++              if (keep_pcap) {
++                      /* If we're going to keep the packet capture running,
++                         we might as well read off all the packets received while
++                         waiting. We shouldn't get any since we don't send any requests
++                         but this should prevent any buffers from accidentally filling
++                         with unhandled packets. */
++                      int packets_recv = loop_for_packets(time_to_sleep);
++
++                      if (packets_recv && debug > 10)
++                              report(LOG_DEBUG, "captured %d packets while sleeping", packets_recv);
++              } else {
++                      sleep(time_to_sleep);
++              }
+               sigprocmask(SIG_SETMASK, &old_sigset, NULL);  /* unblock SIGCHLD */
+@@ -692,8 +730,10 @@
+       } /* MAIN EVENT LOOP */
+-
+       /* we only reach here after receiving a signal requesting we quit */
++      
++      if (keep_pcap)
++              reset_pcap();
+       if (pd_template) /* only used if a capture file requested */
+               pcap_close(pd_template); 
+@@ -1142,6 +1182,7 @@
+       fprintf(stderr, "   -d debuglevel                  enable debugging at specified level\n");
+       fprintf(stderr, "   -f                             don't fork (only use for debugging)\n");
+       fprintf(stderr, "   -h                             display this help message then exit\n");
++      fprintf(stderr, "   -k                             keep pcap open constantly (don't recreate on each cycle)\n");
+       fprintf(stderr, "   -l log_file                    log to file instead of syslog\n");
+       fprintf(stderr, "   -o capture_file                enable capturing of unexpected answers\n");
+       fprintf(stderr, "   -p pid_file                    override default pid file [%s]\n", PID_FILE);
diff --git a/dhcp_probe-virta-03-drop-privs.patch b/dhcp_probe-virta-03-drop-privs.patch
new file mode 100644 (file)
index 0000000..b84aa43
--- /dev/null
@@ -0,0 +1,129 @@
+##dhcp-probe-03-drop-privs.patch - add option to change uid after setup
+--- src/dhcp_probe.c.02        2009-08-16 12:31:22.000000000 +0300
++++ src/dhcp_probe.c   2009-08-16 13:47:29.000000000 +0300
+@@ -26,6 +26,9 @@
+ #include "report.h"
+ #include "utils.h"
++#include <sys/types.h>
++#include <pwd.h>
++
+ #ifndef lint
+ static const char rcsid[] = "dhcp_probe version " VERSION;
+ static const char copyright[] = "Copyright 2000-2008, The Trustees of Princeton University.  All rights reserved.";
+@@ -50,6 +53,8 @@
+ int snaplen = CAPTURE_BUFSIZE;
+ int socket_receive_timeout_feature = 0;
+ int keep_pcap = 0;
++int drop_privs = 0;
++char *username = NULL;
+ char *prog = NULL;
+ char *logfile_name = NULL;
+@@ -179,6 +184,40 @@
+       return packets_recv;
+ }
++/* drop privileges */
++void 
++drop_privileges(const char *username)
++{
++      struct passwd *pw;
++      pw = getpwnam(username);
++      if (pw == NULL) {
++              report(LOG_ERR, "getpwnam: %s", get_errmsg());
++              my_exit(1, 1, 1);
++      }
++      if (debug > 1)
++              report(LOG_INFO, "changing to uid %d gid %d", pw->pw_uid, pw->pw_gid);
++      
++      if (setregid(pw->pw_gid, pw->pw_gid)) {
++              report(LOG_ERR, "setregid: %s", get_errmsg());
++              my_exit(1, 1, 1);
++      }
++      if (setreuid(pw->pw_uid, pw->pw_uid)) {
++              report(LOG_ERR, "setreuid: %s", get_errmsg());
++              my_exit(1, 1, 1);
++      }
++}
++
++void write_pidfile(void)
++{
++      FILE *pid_fp;
++      if ((pid_fp = open_for_writing(pid_file)) == NULL) {
++              report(LOG_ERR, "could not open pid file %s for writing", pid_file);
++              my_exit(1, 0, 1);
++      } else {
++              fprintf(pid_fp, "%d\n", (int) getpid());
++              fclose(pid_fp);
++      }
++}
+ int 
+ main(int argc, char **argv)
+@@ -188,7 +227,6 @@
+       extern char *optarg;
+       extern int optind, opterr, optopt;
+       struct sigaction sa;
+-      FILE *pid_fp;
+       char *cwd = CWD;
+       int write_packet_len;
+@@ -208,7 +246,7 @@
+       else 
+               prog = argv[0];
+-      while ((c = getopt(argc, argv, "c:d:fhkl:o:p:Q:s:Tvw:")) != EOF) {
++      while ((c = getopt(argc, argv, "c:d:fhkl:o:p:Q:s:Tu:vw:")) != EOF) {
+               switch (c) {
+                       case 'c':
+                               if (optarg[0] != '/') {
+@@ -283,6 +321,10 @@
+                               }
+                               break;
+                       }
++                      case 'u':
++                              drop_privs = 1;
++                              username = optarg;
++                              break;
+                       case 'T':
+                               socket_receive_timeout_feature = 1;
+                               break;
+@@ -351,16 +393,6 @@
+               my_exit(1, 0, 1);
+       }
+-
+-      /* write pid file as soon as possible after (possibly) forking */
+-      if ((pid_fp = open_for_writing(pid_file)) == NULL) {
+-              report(LOG_ERR, "could not open pid file %s for writing", pid_file);
+-              my_exit(1, 0, 1);
+-      } else {
+-              fprintf(pid_fp, "%d\n", (int) getpid());
+-              fclose(pid_fp);
+-      }
+-
+       if (! read_configfile(config_file)) {
+               my_exit(1, 1, 1);
+       }
+@@ -535,6 +567,12 @@
+       if (keep_pcap)
+               init_pcap(need_promiscuous(), netmask);
++      if (drop_privs)
++              drop_privileges(username);
++
++      /* write the pid file after dropping privileges to be able to remove it later */
++      write_pidfile();
++
+       while (1) { /* MAIN EVENT LOOP */
+               libnet_t *l;                                            /* to iterate through libnet context queue */
+               /* struct pcap_stat ps; */                      /* to hold pcap stats */
+@@ -1189,6 +1227,7 @@
+       fprintf(stderr, "   -Q vlan_id                     tag outgoing frames with an 802.1Q VLAN ID\n");
+       fprintf(stderr, "   -s capture_bufsize             override default capture bufsize [%d]\n", CAPTURE_BUFSIZE);
+       fprintf(stderr, "   -T                             enable the socket receive timeout feature\n");
++      fprintf(stderr, "   -u username                    change uid after setup (use with -k\n");
+       fprintf(stderr, "   -v                             display version number then exit\n");
+       fprintf(stderr, "   -w cwd                         override default working directory [%s]\n", CWD);
+       fprintf(stderr, "   interface_name                 name of ethernet interface\n");
diff --git a/dhcp_probe.init b/dhcp_probe.init
new file mode 100644 (file)
index 0000000..c7f41eb
--- /dev/null
@@ -0,0 +1,98 @@
+#!/bin/sh
+#
+# chkconfig:   2345 65 35
+# description:  dhcp_probe attempts to discover DHCP and BootP servers on a directly-attached
+#              Ethernet network. A network administrator can use this tool to locate
+#              unauthorized DHCP and BootP servers.
+# processname: dhcp_probe
+# pidfile:     /var/run/dhcp_probe.pid
+# config:      /etc/dhcp_probe.cf
+### BEGIN INIT INFO
+# Provides:            dhcp_probe 
+# Required-Start:      $network 
+# Required-Stop:       $network 
+# Default-Stop:                0 1 2 6 
+# Short-Description:   start/stop/restart the dhcp_probe daemon 
+# Description:         dhcp_probe attempts to discover DHCP and BootP servers.
+### END INIT INFO
+
+# Source function library
+. /etc/rc.d/init.d/functions
+
+# Get network config
+. /etc/sysconfig/network
+
+[ -f /etc/sysconfig/dhcp_probe ] && . /etc/sysconfig/dhcp_probe
+
+start() {
+       if [ -f /var/lock/subsys/dhcp_probe ]; then
+               msg_already_running "dhcp_probe"
+               return
+       fi
+       for nic in $INTERFACES; do
+               msg_starting "dhcp_probe on $nic"
+               daemon /usr/sbin/dhcp_probe -p /var/run/dhcp_probe.$nic.pid $nic
+       done
+       touch /var/lock/subsys/dhcp_probe 
+}      
+
+stop() {
+       if [ ! -f /var/lock/subsys/dhcp_probe ]; then
+               msg_not_running "dhcp_probe"
+               return
+       fi
+       for nic in $INTERFACES; do
+               killproc --pidfile /var/run/dhcp_probe.$nic.pid dhcp_probe
+       done
+       rm -f /var/lock/subsys/dhcp_probe >/dev/null 2>&1
+}
+
+reload(){
+       for nic in $INTERFACES; do
+               killproc --pidfile /var/run/dhcp_probe.$nic.pid dhcp_probe -HUP
+       done
+}
+
+status() {
+       for nic in $INTERFACES; do
+               status --pidfile /var/run/dhcp_probe.$nic.pid dhcp_probe -HUP
+       done
+}
+
+condrestart() {
+       if [ ! -f /var/lock/subsys/dhcp_probe ]; then
+               msg_not_running "dhcp_probe"
+               return
+       fi
+       stop
+       start
+}
+
+RETVAL=0
+# See how we were called.
+case "$1" in
+  start)
+       start
+       ;;
+  stop)
+       stop
+       ;;
+  status)
+       status
+       ;;
+  restart|force-reload)
+       restart
+       ;;
+  reload)
+       reload  
+       ;;
+  condrestart|try-restart)
+       restart
+       ;;
+  *)
+       msg_usage "$0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" 
+       exit 3
+       ;;
+esac
+
+exit $RETVAL 
diff --git a/dhcp_probe.spec b/dhcp_probe.spec
new file mode 100644 (file)
index 0000000..4d09880
--- /dev/null
@@ -0,0 +1,85 @@
+Summary:       Tool for discovering DHCP and BootP servers
+Name:          dhcp_probe
+Version:       1.3.0
+Release:       0.1
+License:       GPLv2+ and MIT
+Group:         Applications
+Source0:       http://www.net.princeton.edu/software/dhcp_probe/%{name}-%{version}.tar.gz
+# Source0-md5: 8067e696fbd88120bdcc2ffef4b64da2
+Source1:       %{name}.init
+Source2:       %{name}.sysconfig
+Source3:       dhcp_probe@.service
+Patch0:                dhcp_probe-guignard-03_implicit_point_conv_bootp.c.patch
+Patch1:                dhcp_probe-guignard-04_linux_32_or_64bits.patch
+Patch2:                dhcp_probe-virta-01-pcap-loop.patch
+Patch3:                dhcp_probe-virta-02-keep-pcap.patch
+Patch4:                dhcp_probe-virta-03-drop-privs.patch
+URL:           http://www.net.princeton.edu/software/dhcp_probe/
+BuildRequires: rpmbuild(macros) >= 1.647
+Requires(post,preun):  /sbin/chkconfig
+Requires(post,preun,postun):   systemd-units >= 38
+BuildRequires: libnet-devel >= 1:1.1.6
+BuildRequires: libpcap-devel
+Requires:      rc-scripts
+Requires:      systemd-units >= 0.38
+BuildRoot:     %{tmpdir}/%{name}-%{version}-root-%(id -u -n)
+
+%description
+dchp_probe attempts to discover DHCP and BootP servers on
+a directly-attached Ethernet network. A network administrator can use
+this tool to locate unauthorized DHCP and BootP servers. 
+
+%prep
+%setup -q
+%patch0 -p0
+%patch1 -p0
+%patch2 -p0
+%patch3 -p0
+%patch4 -p0
+cp -a extras/README README.extras
+
+%build
+%configure
+%{__make}
+
+%install
+rm -rf $RPM_BUILD_ROOT
+install -d $RPM_BUILD_ROOT{/etc/{sysconfig,rc.d/init.d},%{systemdunitdir}}
+
+%{__make} install \
+       DESTDIR=$RPM_BUILD_ROOT
+
+install -p extras/dhcp_probe.cf.sample $RPM_BUILD_ROOT%{_sysconfdir}/dhcp_probe.cf
+install -p %{SOURCE1} $RPM_BUILD_ROOT/etc/rc.d/init.d/dhcp_probe
+install -p %{SOURCE2} $RPM_BUILD_ROOT/etc/sysconfig/dhcp_probe
+install -p %{SOURCE3} $RPM_BUILD_ROOT%{systemdunitdir}/dhcp_probe@.service
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+/sbin/chkconfig --add %{name}
+%service %{name} restart
+%systemd_reload
+
+%preun
+if [ "$1" = "0" ]; then
+       %service -q %{name} stop
+       /sbin/chkconfig --del %{name}
+fi
+%systemd_reload
+
+%postun
+%systemd_reload
+
+%files
+%defattr(644,root,root,755)
+%doc AUTHORS ChangeLog INSTALL.dhcp_probe NEWS README* TODO
+%doc extras/dhcp_probe_notify* extras/mail-throttled
+%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/dhcp_probe.cf
+%attr(755,root,root) %{_sbindir}/dhcp_probe
+%attr(754,root,root) /etc/rc.d/init.d/dhcp_probe
+%config(noreplace) %verify(not md5 mtime size) /etc/sysconfig/dhcp_probe
+%{systemdunitdir}/%{name}@.service
+%{_mandir}/man5/dhcp_probe.cf.5*
+%{_mandir}/man8/dhcp_probe.8*
diff --git a/dhcp_probe.sysconfig b/dhcp_probe.sysconfig
new file mode 100644 (file)
index 0000000..ce08195
--- /dev/null
@@ -0,0 +1,6 @@
+# Extra options for dhcp_probe daemon
+#DHCP_PROBE_OPTIONS=
+
+# Space separated list of interfaces to listen on.
+# Only valid for SysV startup script.
+#INTERFACES="eth0 eth1"
diff --git a/dhcp_probe@.service b/dhcp_probe@.service
new file mode 100644 (file)
index 0000000..d716cae
--- /dev/null
@@ -0,0 +1,19 @@
+# To set-up a new interface do the following (for example eth0):
+#
+# ln -s /lib/systemd/system/dhcp_probe@.service \
+#              /etc/systemd/system/network.target.wants/dhcp_probe@eth0.service
+# or
+# cp -a /lib/systemd/system/dhcp_probe@.service \
+#              /etc/systemd/system/network.target.wants/dhcp_probe@eth0.service
+# if you have to edit this service
+#
+[Unit]
+Description=Start dhcp_probe on %I
+After=network.target
+Wants=network.target
+
+[Service]
+Type=forking
+EnvironmentFile=-/etc/sysconfig/dhcp_probe
+PIDFile=/var/run/dhcp_probe.%I.pid
+ExecStart=/usr/sbin/dhcp_probe $DHCP_PROBE_OPTIONS -p /var/run/dhcp_probe.%I.pid %I
This page took 0.170814 seconds and 4 git commands to generate.