>From the "debug OSC during lecture talks" dept.
 * dump UDP data from a port to stdout
 * forward/relay UDP data to one or more UDP ports.
 - C source attached - no compile flags needed

The "hacked in Berlin's U-bahn" dept. pre-releases
   jplay2 (formerly jadio) - jack-plays-it-all
   http://mir.dnsalias.com/oss/jplay2/start
 - current Feature cloud:
   Open-Sound-Controlled  resample   JACK-transport   vari-speed
   scrub-audio   ffmpeg   libquicktime   libsndfile  audio-cache

The "no more xruns on app shutdown" dept. has added a few
jack_deactivate() calls to various xj* gj* SVN and git repos.

and finally the "berlin sync-it syndicate" announces it's involvement in
http://ltcsmpte.sf.net

#basically all of it is C-code in progress that I did not consider to be
#releasable software before the LAC2007 ;-) - anyway they're helpers for
#an average day of A/V R&D..
#robin
/*
    udp_repeater - 
    Copyright (C) 1999,2006 Robin Gareus <[EMAIL PROTECTED]>
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

    $Id: repeater_udp.c,v 1.1.1.1 2006/07/16 11:24:50 rgareus Exp $
*/


#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>


typedef struct {
	int sock;
	struct sockaddr_in server, from;
	char *hostname; // debug info
	int port; // debug info
} remoteconnection;



void usage (char *name) {
	fprintf(stderr, " usage: %s <listen-port> -d \n",name);
	fprintf(stderr, "    UDP dumper - listen on a local UDP port and dump\n    raw data to STDOUT\n");
	fprintf(stderr, " usage: %s <listen-port> [host]:<port> [ [host]:<port> ]* \n",name);
	fprintf(stderr, "    UDP repeater - this program listens on a local UDP port and \n    forwards messages to one or more UDP ports.\n    Not specifiying a hostname is equivalent to 'localhost'\n    example: %s 3333 :3334 :3335 192.168.6.66:666 receiver.jails.org:3333\n", name);
	exit(0);
}

int splithp (char *arg, char **host, int *port) {
	char *tmp = strchr(arg,':');
	if (!tmp) return (1);

	*tmp=0;
	if (port) *port= atoi(tmp+1);
	if (host) { if (arg == tmp) *host=strdup("localhost"); else *host= strdup(arg); }
	*tmp=':';
	return (0);
}


void error(const char *format,...) {
        va_list arglist;
        char text[BUFSIZ];
        va_start(arglist, format);
        vsnprintf(text, BUFSIZ, format, arglist);
        va_end(arglist);
        text[BUFSIZ -1] =0;
	perror(text);
	exit(0);
}

int open_rc(remoteconnection *rc, char *host, int port) {

	struct hostent *hp;
	rc->sock= socket(AF_INET, SOCK_DGRAM, 0);
	if (rc->sock < 0) error("socket");
	rc->server.sin_family = AF_INET;
	hp = gethostbyname(host);
	if (hp==0) error("Unknown host: '%s'",host);
	memmove((char *)&rc->server.sin_addr,(char *)hp->h_addr, hp->h_length);
	rc->server.sin_port = htons(port);
	return(0);
}

int send_rc (remoteconnection *rc, char *buffer, size_t len) {
	int n;
	socklen_t length = sizeof(struct sockaddr_in);
	n=sendto(rc->sock,buffer, len,0,(struct sockaddr *)&(rc->server),length);
   	if (n < 0) error("Sendto (%s:%i)",rc->hostname,rc->port);
	return (0);
}


int main(int argc, char *argv[])
{
	int want_dump = 0;
	int sock, n;
	size_t length, fromlen;
	struct sockaddr_in server;
	struct sockaddr_in from;
	char buf[BUFSIZ];

	int lport = 3333;

	int i = 2;

	remoteconnection *rc = NULL; 

	if (argc < 3) {
		usage(argv[0]);
	}
	lport = atoi(argv[1]);
	// printf(" read from ANY LOCAL INTERFACE p:%i\n",lport);
	rc=calloc((argc-2),sizeof(remoteconnection));

	if (argc == 3 && !strncmp(argv[2],"-d",2)) {
		want_dump = 1;	
		printf("raw data dump mode!\n");
		argc=2;
	}
	for (i=2; i < argc; i++) {
		char *hostname=NULL;
		int port=0;
		if(!splithp(argv[i],&hostname,&port)) {
			open_rc(&(rc[(i-2)]),hostname,port);
			rc[(i-2)].port=port;
			rc[(i-2)].hostname=hostname;
			//printf(" dup to h:%s p:%i\n",hostname,port);
			//free(hostname);
		}
	}
 
	sock=socket(AF_INET, SOCK_DGRAM, 0);
	if (sock < 0) error("Opening socket");
	length = sizeof(server);
	bzero(&server,length);
	server.sin_family=AF_INET;
	server.sin_addr.s_addr=INADDR_ANY;
	server.sin_port=htons(lport);
	if (bind(sock,(struct sockaddr *)&server,length)<0) error("binding to port %i failed.",lport);
	fromlen = sizeof(struct sockaddr_in);

	while (1) {
		n = recvfrom(sock,buf,BUFSIZ,0,(struct sockaddr *)&from,&fromlen);
		if (want_dump) {
			write(1,"Received a datagram: ",21);
			write(1,buf,n);
			printf("\n"); 
		}
		if (n < 0) error("recvfrom");
		for (i=2; i < argc; i++) {
			send_rc(&(rc[i-2]),buf,n);
		}
	}
	return (0);
}

Reply via email to