Hello tcpdumpers,
I would like to contribute the following patch to tcpdump.
This patch enables tcpdump to send out packets over udp.
My need for this patch was to "replay" RTP streams for debuggin / server
simulation.
Attached are diffs for the following sources:
tcpdump.c
print-udp.c
print-ether.c
Please note: My development was based on version 3.7.1.
Hope you will find it useful.
Please feel free to contact me for questions / comments,
Dotan Shavit,
Mobixell.
*** ../test/tcpdump-3.7.1/print-udp.c Mon Oct 8 23:25:24 2001
--- print-udp.c Thu Apr 4 18:16:22 2002
***************
*** 30,36 ****
#include <sys/param.h>
#include <sys/time.h>
!
#include <netinet/in.h>
#ifdef SEGSIZE
--- 30,36 ----
#include <sys/param.h>
#include <sys/time.h>
! #include <netdb.h>
#include <netinet/in.h>
#ifdef SEGSIZE
***************
*** 107,112 ****
--- 107,115 ----
#define RTCP_PT_BYE 203
#define RTCP_PT_APP 204
+ void sendUdp(int fd, const char *buff, int length);
+ int openUdpPort(char *outAddr, int outPort);
+
static void
vat_print(const void *hdr, u_int len, register const struct udphdr *up)
{
***************
*** 513,521 ****
udpport_string(dport));
cnfp_print(cp, length, (const u_char *)ip);
break;
! }
! return;
! }
if (!qflag) {
register struct rpc_msg *rp;
--- 516,526 ----
udpport_string(dport));
cnfp_print(cp, length, (const u_char *)ip);
break;
! default:
! sendUdp(packettype & 0x0000FFFF, cp, length);
! }
! return;
! }
if (!qflag) {
register struct rpc_msg *rp;
***************
*** 678,681 ****
--- 683,737 ----
#undef ISPORT
} else
(void)printf("udp %u", (u_int32_t)(ulen - sizeof(*up)));
+ }
+
+ void sendUdp(int fd, const char *buff, int length)
+ {
+ if (fd > 0)
+ send(fd, buff, length, 0);
+ }
+
+ int openUdpPort(char *outAddr, int outPort)
+ {
+ int sd, rc;
+ struct sockaddr_in localAddr, dstAddr;
+ struct hostent *host;
+ struct iovec * vector;
+
+ /* Get server IP address (no check if input is IP address or host name */
+ host = gethostbyname(outAddr);
+ if(host == NULL) {
+ printf("unknown host '%s' \n", outAddr);
+ return -1;
+ }
+ printf("sending data to '%s:%d' (IP:%s)\n", host->h_name, outPort,
+ inet_ntoa(*(struct in_addr *)host->h_addr_list[0]));
+
+ dstAddr.sin_family = host->h_addrtype;
+ memcpy((char *) &dstAddr.sin_addr.s_addr,
+ host->h_addr_list[0], host->h_length);
+ dstAddr.sin_port = htons(outPort);
+
+ /* socket creation */
+ sd = socket(AF_INET,SOCK_DGRAM,0);
+ if(sd<0) {
+ printf("cannot open socket \n");
+ return -1;
+ }
+ /* bind any port */
+ localAddr.sin_family = AF_INET;
+ localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ localAddr.sin_port = htons(0);
+ rc = bind(sd, (struct sockaddr *) &localAddr, sizeof(localAddr));
+ if(rc<0) {
+ printf("cannot bind port\n");
+ return -1;
+ }
+
+ if (connect(sd, &dstAddr, sizeof(struct sockaddr_in)) != 0) {
+ printf("connection failed\n");
+ return -1;
+ }
+
+ return sd;
}
*** ../test/tcpdump-3.7.1/tcpdump.c Sun Dec 23 00:12:23 2001
--- tcpdump.c Thu Apr 4 17:21:35 2002
***************
*** 87,92 ****
--- 87,93 ----
char *espsecret = NULL; /* ESP secret key */
int packettype;
+ extern int openUdpPort(char *outAddr, int outPort);
int infodelay;
int infoprint;
***************
*** 198,203 ****
--- 199,207 ----
struct dump_info dumpinfo;
u_char *pcap_userdata;
char ebuf[PCAP_ERRBUF_SIZE];
+ char *outAddr;
+ char *outPortAddr;
+ int outPort;
cnt = -1;
device = NULL;
***************
*** 218,224 ****
opterr = 0;
while (
! (op = getopt(argc, argv, "ac:C:deE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1)
switch (op) {
case 'a':
--- 222,228 ----
opterr = 0;
while (
! (op = getopt(argc, argv, "ac:C:deE:fF:i:lm:nNOpqr:Rs:StT:U:uvw:xXY")) != -1)
switch (op) {
case 'a':
***************
*** 348,357 ****
else if (strcasecmp(optarg, "cnfp") == 0)
packettype = PT_CNFP;
else
! error("unknown packet type `%s'", optarg);
! break;
! case 'u':
++uflag;
break;
--- 352,385 ----
else if (strcasecmp(optarg, "cnfp") == 0)
packettype = PT_CNFP;
else
! error("unknown packet type `%s'", optarg);
! break;
! case 'U':
! if (strncasecmp(optarg, "sendto-", strlen("sendto-")) == 0)
! {
! outAddr = optarg + strlen("sendto-");
! outPortAddr = strchr(outAddr, ':');
! if (outPortAddr == NULL)
! {
! error("no port number");
! break;
! }
! *outPortAddr = '\0';
! outPortAddr++;
! outPort = atoi(outPortAddr);
! packettype = openUdpPort(outAddr, outPort);
! if (packettype <= 0 || packettype > 0xFFFF)
! {
! error("bad address");
! break;
! }
! packettype |= 0xFFFF0000;
! }
! else
! error("unknown destination `%s'", optarg);
! break;
! case 'u':
++uflag;
break;
***************
*** 642,647 ****
(void)fprintf(stderr,
"\t\t[ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ]\n");
(void)fprintf(stderr,
! "\t\t[ -T type ] [ -w file ] [ -E algo:secret ] [ expression ]\n");
exit(1);
}
--- 670,677 ----
(void)fprintf(stderr,
"\t\t[ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ]\n");
(void)fprintf(stderr,
! "\t\t[ -T type ] [ -U sendto-ip:port ] [ -w file ] [ -E algo:secret ]\n");
! (void)fprintf(stderr,
! "\t\t[ expression ]\n");
exit(1);
}
*** ../test/tcpdump-3.7.1/print-ether.c Thu Jul 5 01:03:14 2001
--- print-ether.c Thu Apr 4 16:55:36 2002
***************
*** 67,72 ****
--- 67,95 ----
length);
}
+ int timeSync(struct timeval timestamp)
+ {
+ struct timeval timeOffset;
+ static struct timeval firstTimeOffset = {0,0};
+ struct timeval now;
+
+ gettimeofday(&now, NULL);
+ if (firstTimeOffset.tv_sec == 0 &&
+ firstTimeOffset.tv_usec == 0) {
+ /* firstTimeOffset = now - timestamp */
+ timersub(&now, ×tamp, &firstTimeOffset);
+ } else {
+ /* timeOffset = timestamp + firstTimeOffset - now */
+ timeradd(×tamp, &firstTimeOffset, &timeOffset);
+ timersub(&timeOffset, &now, &timeOffset);
+ if (timeOffset.tv_sec < 0)
+ return -1; /* Too late */
+ select(0, NULL, NULL, NULL, &timeOffset); /* sleep */
+ }
+
+ return 0;
+ }
+
/*
* This is the top level routine of the printer. 'p' is the points
* to the ether header of the packet, 'h->tv' is the timestamp,
***************
*** 81,86 ****
--- 104,113 ----
struct ether_header *ep;
u_short ether_type;
u_short extracted_ethertype;
+ static struct timeval prevTv = {0,0};
+
+ if (packettype & 0xFFFF0000 == 0xFFFF0000)
+ timeSync(h->ts);
++infodelay;
ts_print(&h->ts);