summaryrefslogtreecommitdiff
path: root/cleopatre
diff options
context:
space:
mode:
authorCeline Buret2011-01-11 18:23:47 +0100
committerCeline Buret2011-02-10 18:27:10 +0100
commit25844d12500d50dab334a08e66a376eaf267cffc (patch)
tree797bbe29f6f438a44cb359b9468e35b66ea3ef05 /cleopatre
parent8bddcd1273f62a318e38147943f98660276563ec (diff)
cleo/app/igmpd: create igmp daemon for basic testing, refs #2184
Diffstat (limited to 'cleopatre')
-rw-r--r--cleopatre/application/igmpd/Makefile38
-rw-r--r--cleopatre/application/igmpd/inc/igmpd.h17
-rw-r--r--cleopatre/application/igmpd/src/igmpd.c117
3 files changed, 172 insertions, 0 deletions
diff --git a/cleopatre/application/igmpd/Makefile b/cleopatre/application/igmpd/Makefile
new file mode 100644
index 0000000000..59751143ea
--- /dev/null
+++ b/cleopatre/application/igmpd/Makefile
@@ -0,0 +1,38 @@
+BIN=igmpd
+OBJPATH=obj
+SRCPATH=src
+INCPATH=inc
+
+ifeq ($(CC_FOR_TARGET),) #direct compile
+CC=arm-linux-gcc
+CC_WITH_CFLAGS=$(CC) -I/opt/spidcom/spc300/usr/include -g -Os
+CC_WITHOUT_CFLAGS=$(CC)
+LINUX_DIR=../../linux-2.6.25.10-spc300
+else #compile from buildroot
+CC_WITH_CFLAGS=$(CC)
+CC_WITHOUT_CFLAGS=$(CC_FOR_TARGET)
+endif
+EXTRA_CFLAGS=-I$(INCPATH) -I$(LINUX_DIR)/include -I$(LINUX_DIR)/include/asm-arm/arch-spc300 -MMD
+LIBS=-lpthread
+
+SRCS=$(subst $(SRCPATH)/,,$(wildcard $(SRCPATH)/*.c))
+OBJS=$(addprefix $(OBJPATH)/,$(SRCS:.c=.o))
+DEPS=$(patsubst %o,%d,$(OBJS))
+
+all: $(BIN)
+
+$(BIN): $(OBJPATH) $(OBJS)
+ $(CC_WITHOUT_CFLAGS) -static -o $@ $(OBJS) $(LIBS)
+
+$(OBJPATH)/%.o: $(SRCPATH)/%.c
+ $(CC_WITH_CFLAGS) $(EXTRA_CFLAGS) -o $@ -c $<
+
+$(OBJPATH):
+ mkdir -p $(OBJPATH)
+
+-include $(DEPS)
+
+.PHONY: all clean
+
+clean:
+ rm -f $(OBJS) $(DEPS) $(BIN)
diff --git a/cleopatre/application/igmpd/inc/igmpd.h b/cleopatre/application/igmpd/inc/igmpd.h
new file mode 100644
index 0000000000..27240940cc
--- /dev/null
+++ b/cleopatre/application/igmpd/inc/igmpd.h
@@ -0,0 +1,17 @@
+#ifndef IGMPD_H
+#define IGMPD_H
+
+#include <linux/if_packet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+#define IFNAME "br0"
+
+struct igmpd_ctx
+{
+ int sock;
+ struct sockaddr_ll sll;
+ unsigned char mac_addr[ETH_ALEN];
+};
+
+#endif /* MANAGERD_H */
diff --git a/cleopatre/application/igmpd/src/igmpd.c b/cleopatre/application/igmpd/src/igmpd.c
new file mode 100644
index 0000000000..362dc32dda
--- /dev/null
+++ b/cleopatre/application/igmpd/src/igmpd.c
@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <net/if.h>
+#include <linux/if_ether.h>
+#include <sys/ioctl.h>
+
+#include "igmpd.h"
+
+int
+main (int argc, char **argv)
+{
+ struct igmpd_ctx ctx;
+ struct ifreq ifr;
+ unsigned char buffer[ETH_FRAME_LEN];
+ int t = 0;
+
+ /* Create a receive connection on interface */
+ if (0 > (ctx.sock = socket (AF_PACKET, SOCK_RAW, ETH_P_ALL)))
+ {
+ printf ("cannot open socket on %s (%s)\n", IFNAME, strerror (errno));
+ return -1;
+ }
+
+ /* Prepare socket address */
+ strncpy (ifr.ifr_name, IFNAME, IFNAMSIZ);
+ if (-1 == (ioctl (ctx.sock, SIOCGIFINDEX, &ifr)))
+ {
+ printf ("cannot get interface %s index (%s)\n", IFNAME, strerror (errno));
+ close (ctx.sock);
+ return -1;
+ }
+ ctx.sll.sll_family = AF_PACKET;
+ ctx.sll.sll_protocol = htons (ETH_P_ALL);
+ ctx.sll.sll_pkttype = PACKET_MULTICAST;
+ ctx.sll.sll_ifindex = ifr.ifr_ifindex;
+
+ /* Find mac address */
+ if (-1 == (ioctl (ctx.sock, SIOCGIFHWADDR, &ifr)))
+ {
+ printf ("cannot get interface %s mac address (%s)\n", IFNAME, strerror (errno));
+ close (ctx.sock);
+ return -1;
+ }
+ memcpy (ctx.mac_addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
+
+ /* Bind socket to this interface */
+ if (-1 == (bind (ctx.sock, (struct sockaddr *) &ctx.sll, sizeof (struct sockaddr_ll))))
+ {
+ printf ("cannot bind raw socket to interface %s (%s)\n", IFNAME, strerror (errno));
+ close (ctx.sock);
+ return -1;
+ }
+
+ while (t < 30)
+ {
+ fd_set readfds, exceptfds;
+ struct timeval timeout;
+ int result, i;
+
+ /* Configure timeout */
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ FD_ZERO (&readfds);
+ FD_ZERO (&exceptfds);
+ FD_SET (ctx.sock, &readfds);
+
+ /* Select */
+ result = select (ctx.sock + 1, &readfds, NULL, &exceptfds, &timeout);
+
+ /* Select error */
+ if (0 > result)
+ {
+ /* look for interrupt */
+ if (EINTR == errno)
+ {
+ /* reset errno */
+ errno = 0;
+ /* process interrupt */
+ }
+ else
+ {
+ printf ("select failed (%s)\n", strerror (errno));
+ close (ctx.sock);
+ return -1;
+ }
+ }
+ else if (0 == result)
+ {
+ /* No reception coming */
+ t++;
+ }
+ else if (FD_ISSET (ctx.sock, &readfds))
+ {
+ /* Receive a frame from interface: process it */
+ if (0 > recvfrom (ctx.sock, buffer, ETH_FRAME_LEN, 0, NULL, NULL))
+ {
+ printf ("receive failed on %s (%s)\n", IFNAME, strerror (errno));
+ break;
+ }
+
+ /* Processing this reception */
+ printf ("--- ");
+ for (i = 0; i < ETH_HLEN; i++)
+ {
+ printf ("0x%x ", buffer[i]);
+ }
+ printf ("---\n");
+ }
+ }
+
+ /* Close connection */
+ close (ctx.sock);
+
+ return 0;
+}