[dhcp_probe] Added rpm src

Daniel Bruno dbruno at fedoraproject.org
Sat Sep 25 15:26:34 UTC 2010


commit 963c20a8dde5f28d01e5f96179a506c30c30ca00
Author: Daniel Bruno <dbruno at fedoraproject.org>
Date:   Sat Sep 25 11:28:13 2010 -0400

     Added rpm src

 .gitignore                                         |    1 +
 ...0-guignard-03_implicit_point_conv_bootp.c.patch |   21 ++
 ...robe-1.3.0-guignard-04_linux_32_or_64bits.patch |   33 +++
 dhcp_probe-1.3.0-virta-01-pcap-loop.patch          |  164 +++++++++++
 dhcp_probe-1.3.0-virta-02-keep-pcap.patch          |  286 ++++++++++++++++++++
 dhcp_probe-1.3.0-virta-03-drop-privs.patch         |  129 +++++++++
 dhcp_probe.init                                    |  162 +++++++++++
 dhcp_probe.spec                                    |   88 ++++++
 sources                                            |    1 +
 9 files changed, 885 insertions(+), 0 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index e69de29..1ea8b8e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/dhcp_probe-1.3.0.tar.gz
diff --git a/dhcp_probe-1.3.0-guignard-03_implicit_point_conv_bootp.c.patch b/dhcp_probe-1.3.0-guignard-03_implicit_point_conv_bootp.c.patch
new file mode 100644
index 0000000..0b0582c
--- /dev/null
+++ b/dhcp_probe-1.3.0-guignard-03_implicit_point_conv_bootp.c.patch
@@ -0,0 +1,21 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 03_implicit_point_conv_bootp.c.dpatch by Laurent Guignard <lguignard.debian at 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 at debian.org>
+##
+
+ at 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-1.3.0-guignard-04_linux_32_or_64bits.patch b/dhcp_probe-1.3.0-guignard-04_linux_32_or_64bits.patch
new file mode 100644
index 0000000..ce6e3f0
--- /dev/null
+++ b/dhcp_probe-1.3.0-guignard-04_linux_32_or_64bits.patch
@@ -0,0 +1,33 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 04_linux_32_or_64bits.dpatch by Laurent Guignard <lguignard.debian at 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 ???
+
+ at 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-1.3.0-virta-01-pcap-loop.patch b/dhcp_probe-1.3.0-virta-01-pcap-loop.patch
new file mode 100644
index 0000000..1913379
--- /dev/null
+++ b/dhcp_probe-1.3.0-virta-01-pcap-loop.patch
@@ -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-1.3.0-virta-02-keep-pcap.patch b/dhcp_probe-1.3.0-virta-02-keep-pcap.patch
new file mode 100644
index 0000000..c5a6739
--- /dev/null
+++ b/dhcp_probe-1.3.0-virta-02-keep-pcap.patch
@@ -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-1.3.0-virta-03-drop-privs.patch b/dhcp_probe-1.3.0-virta-03-drop-privs.patch
new file mode 100644
index 0000000..b84aa43
--- /dev/null
+++ b/dhcp_probe-1.3.0-virta-03-drop-privs.patch
@@ -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 100755
index 0000000..88e31cb
--- /dev/null
+++ b/dhcp_probe.init
@@ -0,0 +1,162 @@
+#!/bin/bash
+#
+# chkconfig: - 65 55
+# 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
+
+. /etc/init.d/functions
+
+CWD=$(pwd)
+cd /etc/sysconfig/network-scripts
+. ./network-functions
+
+PIDFILE="/var/run/dhcp_probe.pid"
+RETVAL=0
+DHCP_PROBE="/usr/sbin/dhcp_probe"
+prog=dhcp_probe
+lockfile=/var/lock/subsys/$prog
+ip="/sbin/ip"
+
+check_down( ){
+        if LC_ALL=C $ip -o link show dev $1 2>/dev/null | grep -q "DOWN" ; then
+                return 1
+        else
+                return 0
+        fi
+}
+
+checkdevices( ){
+	INETS=$(nmcli dev |grep eth |cut -d " " -f 1)
+	for dev in $INETS
+	do
+        	check_down $dev
+	        rtnvl=$?
+		if [ $rtnvl == "0" ]
+		then
+			let cntdv++
+		fi
+	done
+	if [ -z $cntdv ]
+	then
+		return 1
+	else
+		return 0
+	fi
+}
+
+start() {
+	echo -n "Starting $prog: "
+	checkdevices
+	rtrnch=$?
+	if [ $rtrnch == 0 ]
+	then
+		$DHCP_PROBE ${INETS[0]} >/dev/null
+		success
+		echo
+		RETVAL=0
+	else
+		failure
+		echo
+		RETVAL=1
+	fi
+	[ $RETVAL == 0 ] && touch $lockfile 
+	return $RETVAL
+}	
+
+stop() {
+	echo -n "Shutting down $prog: "
+	killproc $DHCP_PROBE
+	echo
+	RETVAL=$?
+	[ $RETVAL -eq 0 ] && rm -f $lockfile
+
+	return $RETVAL
+}
+restart() {
+	if [ -e $PIDFILE ]
+	then
+		stop
+		start
+		RETVAL=$?
+		else
+			echo -n "$prog not running"
+			failure
+			echo
+			RETVAL=$?
+	fi
+	return $RETVAL
+}
+reload(){
+	if [ -e $PIDFILE ]
+	then
+	killproc -p $PIDFILE $prog -HUP
+	echo
+	RETVAL=$?
+	else
+		echo -n "$prog not running"
+		failure
+		echo
+		RETVAL=$?
+	fi
+	return $RETVAL
+}
+status() {
+	if [ -e $PIDFILE ]
+	then
+		echo "$prog running."
+		echo "PID: $(cat $PIDFILE)"
+	else
+		echo "$prog NOT running"
+	fi
+}
+force_reload(){
+	restart
+}
+rh_status(){
+	status -p $PIDFILE $prog
+}
+rh_status_q() {
+	rh_status >/dev/null 2>&1
+}
+
+case "$1" in
+    start)
+	start
+	;;
+    stop)
+	stop
+	;;
+    status)
+	status
+	;;
+    restart)
+	restart
+	;;
+    reload)
+	reload	
+	;;
+   force-reload)
+	force_reload
+	;;	
+   condrestart|try-restart)
+	rh_status_q || exit 0
+	restart
+	;;
+    *)
+	echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" 
+	exit 2
+	;;
+esac
+exit $RETVAL 
diff --git a/dhcp_probe.spec b/dhcp_probe.spec
new file mode 100644
index 0000000..304e7a5
--- /dev/null
+++ b/dhcp_probe.spec
@@ -0,0 +1,88 @@
+Name: dhcp_probe
+Version: 1.3.0
+Release: 6%{?dist}
+Summary: Tool for discover DHCP and BootP servers
+License: GPLv2+ and MIT
+Group: System Environment/Daemons
+
+Url: http://www.net.princeton.edu/software/dhcp_probe/
+
+Source0: http://www.net.princeton.edu/software/dhcp_probe/%{name}-%{version}.tar.gz
+Source1: dhcp_probe.init
+
+# Patchs from upstream
+Patch0: dhcp_probe-1.3.0-guignard-03_implicit_point_conv_bootp.c.patch
+Patch1: dhcp_probe-1.3.0-guignard-04_linux_32_or_64bits.patch
+Patch2: dhcp_probe-1.3.0-virta-01-pcap-loop.patch 
+Patch3: dhcp_probe-1.3.0-virta-02-keep-pcap.patch 
+Patch4: dhcp_probe-1.3.0-virta-03-drop-privs.patch
+
+BuildRequires: libnet-devel libpcap-devel
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+Requires(post): /sbin/chkconfig
+Requires(preun): /sbin/service, /sbin/chkconfig
+
+%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.
+
+%prep
+%setup -q
+%patch0
+%patch1
+%patch2
+%patch3
+%patch4
+
+%post
+/sbin/chkconfig --add %{name} 
+
+%preun
+if [ $1 = 0 ] ; then
+    /sbin/service %{name} stop >/dev/null 2>&1
+    /sbin/chkconfig --del %{name}
+fi
+
+%build
+%configure
+make %{?_smp_mflags}
+
+%install
+rm -rf %{buildroot} 
+make DESTDIR=%{buildroot} INSTALL="install -p" CP="cp -p" install
+install -p -m 644 -D extras/dhcp_probe.cf.sample %{buildroot}/%{_sysconfdir}/dhcp_probe.cf
+install -p -m 755 -D %{SOURCE1} %{buildroot}/%{_initrddir}/dhcp_probe
+
+%clean
+rm -rf %{buildroot} 
+
+%files
+%defattr(-,root,root,-)
+%doc AUTHORS NEWS TODO README COPYING.GPL COPYING COPYING.LIB
+%config(noreplace) %{_sysconfdir}/dhcp_probe.cf
+%{_sbindir}/%{name}
+%{_mandir}/man8/dhcp_probe.8*
+%{_mandir}/man5/dhcp_probe.cf.5*
+%{_initrddir}/dhcp_probe
+
+%changelog
+* Tue Sep 21 2010 Daniel Bruno <dbruno at fedoraproject.org> - 1.3.0-6
+- condrestart|try-restart functions was implemented
+- service default enabled removed
+
+* Wed Sep 01 2010 Daniel Bruno dbruno at fedoraproject.org - 1.3.0-5
+- Fixed the bug on start function
+
+* Mon Aug 23 2010 Daniel Bruno dbruno at fedoraproject.org - 1.3.0-4
+- Improved the restart function and added reload script on init script.
+
+* Tue Aug 17 2010 Daniel Bruno dbruno at fedoraproject.org - 1.3.0-3
+- Fix the init script on the source
+
+* Wed Aug 11 2010 Daniel Bruno dbruno at fedoraproject.org - 1.3.0-2
+- Added init script
+
+* Wed Aug 11 2010 Daniel Bruno dbruno at fedoraproject.org - 1.3.0-1
+- First Fedora RPM Package
diff --git a/sources b/sources
index e69de29..a883f9c 100644
--- a/sources
+++ b/sources
@@ -0,0 +1 @@
+8067e696fbd88120bdcc2ffef4b64da2  dhcp_probe-1.3.0.tar.gz


More information about the scm-commits mailing list