Crec que hauria de funcionar almenys el listen... però no va.
--- a/.hgignore Sun Mar 26 16:57:18 2006 +0200
+++ b/.hgignore Sun Mar 26 20:44:16 2006 +0200
@@ -1,2 +1,4 @@
.*\.o
-syslog_npipe
+.*\.a
+syslog_in_npipe
+syslog_in_udp
--- a/Makefile Sun Mar 26 16:57:18 2006 +0200
+++ b/Makefile Sun Mar 26 20:44:16 2006 +0200
@@ -6,15 +6,19 @@
#CC=tcc
#CFLAGS=
-all: syslog_in_npipe
+all: syslog_in_npipe syslog_in_udp
%.a:
ar rc $@ $<
rfc3164.o: rfc3164.h
rfc3164.a: rfc3164.o
+
syslog_in_npipe.o: rfc3164.h syslog_in_npipe.c
+syslog_in_udp.o: syslog_in_udp.c rfc3164.h
+
syslog_in_npipe: syslog_in_npipe.o rfc3164.a
+syslog_in_udp: syslog_in_udp.o rfc3164.a
clean:
rm -f *.o *.a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/syslog_in_udp.c Sun Mar 26 20:44:16 2006 +0200
@@ -0,0 +1,205 @@
+#include <unistd.h> // Per les crides a fitxer
+#include <stdio.h> // Per l'I/O de stdin/stdout
+#include <errno.h> // Pels errors de les crides a fitxer
+#include <string.h> // Per strerror()
+#include <stdlib.h> // Per abort()
+#include <sys/types.h> // Per crides de fitxer
+#include <sys/socket.h> // Per les macros bool,true,false
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h> // Per protoent getprotobyname
+#include <assert.h> // Per assert()
+#include <sys/select.h> // Pel select()
+
+#include "rfc3164.h"
+
+const int const_listen_queue = 10;
+
+void show_help(const char * restrict program)
+{
+ printf("Usage: %s <udp_port>\n", program);
+}
+
+
+int udp_proto_number()
+{
+ struct protoent *protocol;
+
+ /* Get the protocol udp number */
+ protocol = getprotobyname("udp");
+ if (protocol == NULL)
+ {
+ printf("Cannot get the protocol number for udp.\n");
+ abort();
+ }
+
+ return protocol->p_proto;
+}
+
+int listen_ipv6(int port)
+{
+ int socket_ipv6;
+ struct sockaddr_in6 source_ipv6;
+ int result;
+ int on=1;
+
+
+ socket_ipv6 = socket(PF_INET6, SOCK_DGRAM, udp_proto_number() );
+ if (socket_ipv6 == -1)
+ {
+ printf("IPv6 socket failed.\n");
+ abort();
+ }
+
+ /* Fem que poguem reutilitzar l'adreça encara que no s'hagi acabat
+ el timeout després de tancar-se la connexió */
+ if (setsockopt(socket_ipv6, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&on,sizeof(on)) < 0)
+ {
+ printf("IPv6 setsockopt() failed: %s.\n", strerror(errno));
+ abort();
+ }
+
+
+ /* IPv6 listen address */
+ memset(&source_ipv6, 0, sizeof(source_ipv6));
+ source_ipv6.sin6_family = AF_INET6;
+ source_ipv6.sin6_flowinfo = 0;
+ source_ipv6.sin6_port = htons(port);
+ source_ipv6.sin6_addr = in6addr_any;
+ result = bind(socket_ipv6, (struct sockaddr *) &source_ipv6,
+ sizeof(source_ipv6));
+ assert(result == 0);
+
+ result = listen(socket_ipv6, const_listen_queue);
+ if (result != 0)
+ {
+ printf("Error in listen() ipv6: %s\n", strerror(errno));
+ abort();
+ }
+
+ return socket_ipv6;
+}
+
+int listen_ipv4(int port)
+{
+ int socket_ipv4;
+ struct sockaddr_in source_ipv4;
+ int result;
+ int on=1;
+
+
+ socket_ipv4 = socket(PF_INET, SOCK_DGRAM, udp_proto_number() );
+ if (socket_ipv4 == -1)
+ {
+ printf("IPv4 socket not supported.\n");
+ abort();
+ }
+
+ /* Fem que poguem reutilitzar l'adreça encara que no s'hagi acabat
+ el timeout després de tancar-se la connexió */
+ if (setsockopt(socket_ipv4, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&on,sizeof(on)) < 0)
+ {
+ printf("IPv6 setsockopt() failed: %s.\n", strerror(errno));
+ abort();
+ }
+
+ /* IPv4 listen address */
+ memset(&source_ipv4, 0, sizeof(source_ipv4));
+ source_ipv4.sin_family = AF_INET;
+ source_ipv4.sin_port = htons(port);
+ source_ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
+ result = bind(socket_ipv4, (struct sockaddr *) &source_ipv4,
+ sizeof(source_ipv4));
+ assert(result == 0);
+
+ result = listen(socket_ipv4, const_listen_queue);
+ if (result != 0)
+ {
+ printf("Error in listen() ipv4: %s\n", strerror(errno));
+ abort();
+ }
+
+ return socket_ipv4;
+}
+
+
+int server_loop(int port)
+{
+ int socket_ipv6, socket_ipv4;
+ fd_set listen_sockets;
+ struct timeval wait_time;
+ int result;
+ int high_socket;
+
+
+ socket_ipv6 = listen_ipv6(port);
+ socket_ipv4 = listen_ipv4(port);
+
+ /* Establim els FDs que volem esperar al select() */
+ FD_ZERO(&listen_sockets);
+ FD_SET(socket_ipv6, &listen_sockets);
+ FD_SET(socket_ipv4, &listen_sockets);
+
+ /* Establim el temporitzador pel select() */
+ wait_time.tv_sec = 5;
+ wait_time.tv_usec = 0;
+
+ /* Mirem quin és el socket més alt pel select() */
+ high_socket = socket_ipv6;
+ if (high_socket < socket_ipv4)
+ high_socket = socket_ipv4;
+
+ high_socket += 1;
+
+ result = 0;
+ while (result)
+ {
+ result = select(high_socket, &listen_sockets, NULL, NULL,
+ &wait_time);
+ if (result == 0)
+ continue;
+ else if (result == -1)
+ {
+ printf("Error in select(): %s\n", strerror(errno));
+ abort();
+ }
+
+ /* Algun FD té dades... */
+ if (FD_ISSET(socket_ipv4, &listen_sockets))
+ {
+ /* Dummy */
+ printf("Got data in IPv4\n");
+ }
+
+ if (FD_ISSET(socket_ipv6, &listen_sockets))
+ {
+ /* Dummy */
+ printf("Got data in IPv6\n");
+ }
+ }
+}
+
+
+int main(int argn, char **argv)
+{
+ int port;
+
+ /* Processem els paràmetres d'entrada */
+ if (argn != 2) {
+ show_help(argv[0]);
+ return 2;
+ }
+
+ port=atoi(argv[1]);
+ if (port < 0 || port >65535)
+ {
+ show_help(argv[0]);
+ return 2;
+ }
+
+ server_loop(port);
+
+ return 0;
+}