Implement native ipset request (netlink request)
authorNeutron Soutmun <neo.neutron@gmail.com>
Wed, 20 Aug 2008 17:09:13 +0000 (00:09 +0700)
committerNeutron Soutmun <neo.neutron@gmail.com>
Sun, 2 Nov 2008 19:43:11 +0000 (02:43 +0700)
2008-08-21  Neutron Soutmun <neo.neutron@gmail.com>

* src/rahunasd.{h,c}, src/rh-ipset.{h,c}, src/rh-xmlrpc-server.c:
  Implement the native ipset command, the codes are adapted from ipset
  userspace program.
* src/ipset-control.{h,c}: Removed as they are replaced by new native ipset
  implementation.
* src/Makefile.am: Adjust to support new native ipset implementation.

ChangeLog
src/Makefile.am
src/Makefile.in [deleted file]
src/ipset-control.c [deleted file]
src/ipset-control.h [deleted file]
src/rahunasd.c
src/rahunasd.h
src/rh-ipset.c
src/rh-ipset.h
src/rh-xmlrpc-server.c

index 65299ec..640758d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-08-21  Neutron Soutmun <neo.neutron@gmail.com>
+
+       * src/Makefile.am:
+       * src/rahunasd.{h,c}, src/rh-ipset.{h,c}, src/rh-xmlrpc-server.c:
+         Implement the native ipset command, the codes are adapted from ipset 
+         userspace program.
+       * src/ipset-control.{h,c}: Removed as they are replaced by new native ipset
+         implementation.
+
 2008-08-20  Neutron Soutmun <neo.neutron@gmail.com>
 
        * src/rahunas.{h,c}:
index 1be8d2a..8f1ccd1 100644 (file)
@@ -1,8 +1,14 @@
 bin_PROGRAMS = rahunasd
 
-AM_CFLAGS = $(LIBGNET_CFLAGS)
+IPSET_VERSION:=2.3.3
+
+AM_CFLAGS = $(LIBGNET_CFLAGS) -I$(top_builddir)/src/include/ \
+       -DIPSET_VERSION=\"$(IPSET_VERSION)\"
+
+rahunasd_SOURCES = rahunasd.c \
+       rh-xmlrpc-server.c \
+  rh-ipset.c   
 
-rahunasd_SOURCES = rahunasd.c rh-xmlrpc-server.c ipset-control.c
 rahunasd_LDADD =  \
        $(top_builddir)/xmlrpc/libgnetxmlrpc.a \
        $(LIBGNET_LIBS)
diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644 (file)
index 88975cc..0000000
+++ /dev/null
@@ -1,421 +0,0 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-bin_PROGRAMS = rahunasd$(EXEEXT)
-subdir = src
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-       $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-am__installdirs = "$(DESTDIR)$(bindir)"
-binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
-PROGRAMS = $(bin_PROGRAMS)
-am_rahunasd_OBJECTS = rahunasd.$(OBJEXT) rh-xmlrpc-server.$(OBJEXT) \
-       ipset-control.$(OBJEXT)
-rahunasd_OBJECTS = $(am_rahunasd_OBJECTS)
-am__DEPENDENCIES_1 =
-rahunasd_DEPENDENCIES = $(top_builddir)/xmlrpc/libgnetxmlrpc.a \
-       $(am__DEPENDENCIES_1)
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
-       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(rahunasd_SOURCES)
-DIST_SOURCES = $(rahunasd_SOURCES)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBGNET_CFLAGS = @LIBGNET_CFLAGS@
-LIBGNET_LIBS = @LIBGNET_LIBS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PKG_CONFIG = @PKG_CONFIG@
-RANLIB = @RANLIB@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build_alias = @build_alias@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host_alias = @host_alias@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-AM_CFLAGS = $(LIBGNET_CFLAGS)
-rahunasd_SOURCES = rahunasd.c rh-xmlrpc-server.c ipset-control.c
-rahunasd_LDADD = \
-       $(top_builddir)/xmlrpc/libgnetxmlrpc.a \
-       $(LIBGNET_LIBS)
-
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
-       @for dep in $?; do \
-         case '$(am__configure_deps)' in \
-           *$$dep*) \
-             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
-               && exit 0; \
-             exit 1;; \
-         esac; \
-       done; \
-       echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign  src/Makefile'; \
-       cd $(top_srcdir) && \
-         $(AUTOMAKE) --foreign  src/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-       @case '$?' in \
-         *config.status*) \
-           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-         *) \
-           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-       esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
-       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
-       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-install-binPROGRAMS: $(bin_PROGRAMS)
-       @$(NORMAL_INSTALL)
-       test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
-       @list='$(bin_PROGRAMS)'; for p in $$list; do \
-         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
-         if test -f $$p \
-         ; then \
-           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
-          echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
-          $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
-         else :; fi; \
-       done
-
-uninstall-binPROGRAMS:
-       @$(NORMAL_UNINSTALL)
-       @list='$(bin_PROGRAMS)'; for p in $$list; do \
-         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
-         echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
-         rm -f "$(DESTDIR)$(bindir)/$$f"; \
-       done
-
-clean-binPROGRAMS:
-       -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-rahunasd$(EXEEXT): $(rahunasd_OBJECTS) $(rahunasd_DEPENDENCIES) 
-       @rm -f rahunasd$(EXEEXT)
-       $(LINK) $(rahunasd_OBJECTS) $(rahunasd_LDADD) $(LIBS)
-
-mostlyclean-compile:
-       -rm -f *.$(OBJEXT)
-
-distclean-compile:
-       -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipset-control.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rahunasd.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rh-xmlrpc-server.Po@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@   mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
-       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       mkid -fID $$unique
-tags: TAGS
-
-TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
-       tags=; \
-       here=`pwd`; \
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
-         test -n "$$unique" || unique=$$empty_fix; \
-         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
-           $$tags $$unique; \
-       fi
-ctags: CTAGS
-CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
-               $(TAGS_FILES) $(LISP)
-       tags=; \
-       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
-       unique=`for i in $$list; do \
-           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
-         done | \
-         $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
-             END { if (nonempty) { for (i in files) print i; }; }'`; \
-       test -z "$(CTAGS_ARGS)$$tags$$unique" \
-         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
-            $$tags $$unique
-
-GTAGS:
-       here=`$(am__cd) $(top_builddir) && pwd` \
-         && cd $(top_srcdir) \
-         && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
-       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
-       @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-       list='$(DISTFILES)'; \
-         dist_files=`for file in $$list; do echo $$file; done | \
-         sed -e "s|^$$srcdirstrip/||;t" \
-             -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-       case $$dist_files in \
-         */*) $(MKDIR_P) `echo "$$dist_files" | \
-                          sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-                          sort -u` ;; \
-       esac; \
-       for file in $$dist_files; do \
-         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-         if test -d $$d/$$file; then \
-           dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
-           fi; \
-           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
-         else \
-           test -f $(distdir)/$$file \
-           || cp -p $$d/$$file $(distdir)/$$file \
-           || exit 1; \
-         fi; \
-       done
-check-am: all-am
-check: check-am
-all-am: Makefile $(PROGRAMS)
-installdirs:
-       for dir in "$(DESTDIR)$(bindir)"; do \
-         test -z "$$dir" || $(MKDIR_P) "$$dir"; \
-       done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
-       @echo "This command is intended for maintainers to use"
-       @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
-
-distclean: distclean-am
-       -rm -rf ./$(DEPDIR)
-       -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
-       distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-exec-am: install-binPROGRAMS
-
-install-html: install-html-am
-
-install-info: install-info-am
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-ps: install-ps-am
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-       -rm -rf ./$(DEPDIR)
-       -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-binPROGRAMS
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
-       clean-generic ctags distclean distclean-compile \
-       distclean-generic distclean-tags distdir dvi dvi-am html \
-       html-am info info-am install install-am install-binPROGRAMS \
-       install-data install-data-am install-dvi install-dvi-am \
-       install-exec install-exec-am install-html install-html-am \
-       install-info install-info-am install-man install-pdf \
-       install-pdf-am install-ps install-ps-am install-strip \
-       installcheck installcheck-am installdirs maintainer-clean \
-       maintainer-clean-generic mostlyclean mostlyclean-compile \
-       mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
-       uninstall-am uninstall-binPROGRAMS
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/ipset-control.c b/src/ipset-control.c
deleted file mode 100644 (file)
index 96e5274..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/**
- * ipset control implementation
- * Author: Neutron Soutmun <neo.neutron@gmail.com>
- * Date:   2008-08-07
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <syslog.h>
-
-#include "ipset-control.h"
-
-int _issue_ipset_cmd(unsigned short cmd_type, const char *ip)
-{
-       char *cmd = NULL; 
-       int   idx  = 0;
-       char  line[256];
-       int   pipefd[2];
-  int   status;
-       char  buf;
-       pid_t cpid;
-       
-       if (cmd_type == RH_IPSET_CMD_ADD)
-         cmd = strdup("-A");
-       else if (cmd_type == RH_IPSET_CMD_DEL)
-         cmd = strdup("-D");
-       else if (cmd_type == RH_IPSET_CMD_FLS)
-    cmd = strdup("-F");
-       else
-         return (-1);
-
-  if (pipe(pipefd) == (-1)) {
-    syslog(LOG_ERR, "Could not create pipe");
-               return (-1);
-       }
-
-       cpid = fork();
-       if (cpid == 0) {
-    close(pipefd[0]);
-               dup2(pipefd[1], STDOUT_FILENO);
-    
-    if (ip == NULL)
-                 logmsg(RH_LOG_DEBUG, "ipset %s %s", cmd, SET_NAME);
-    else
-                 logmsg(RH_LOG_DEBUG, "ipset %s %s %s", cmd, SET_NAME, ip);
-
-               execlp("ipset", "ipset", cmd, SET_NAME, ip, NULL);
-               close(pipefd[1]);
-               return (-1);
-       }
-
-  cpid = wait(&status);
-
-  close(pipefd[1]);
-       while (getline(pipefd[0], line, sizeof line) > 0) {
-    logmsg(RH_LOG_DEBUG, line);
-       }
-       close(pipefd[0]);
-
-       if (cmd)
-         free(cmd);
-
-  if (WIFEXITED(status) && (WEXITSTATUS(status) == 0))
-    return 0;
-  else
-         return (-1);
-}
-
-int ctrl_add_to_set(struct rahunas_map *map, uint32_t id)
-{
-       struct rahunas_member *members = NULL;
-  struct in_addr sess_addr;
-       int ret;
-
-       if (!map)
-         return (-1);
-
-  if (!map->members)
-    return (-1);
-
-  members = map->members;
-
-       if (id > ((map->size) - 1) || id < 0)
-         return (-1);
-
-       if (members[id].flags)
-         return 0;
-               
-  ret = _issue_ipset_cmd(RH_IPSET_CMD_ADD, idtoip(map, id));
-
-       chk_set(map);
-
-       if (ret == 0 && members[id].flags)
-    return 0;
-       else
-         return (-1);
-}
-
-int ctrl_del_from_set(struct rahunas_map *map, uint32_t id)
-{
-       struct rahunas_member *members = NULL;
-  struct in_addr sess_addr;
-       int ret;
-
-       if (!map)
-         return (-1);
-
-  if (!map->members)
-    return (-1);
-
-  members = map->members;
-
-       if (id > ((map->size) - 1) || id < 0)
-         return (-1);
-
-       if (!members[id].flags)
-         return 0;
-       
-  ret = _issue_ipset_cmd(RH_IPSET_CMD_DEL, idtoip(map, id));
-
-       if (ret == 0)
-         members[id].flags = 0;
-       
-       return ret;
-}
-
-int ctrl_flush()
-{
-  return _issue_ipset_cmd(RH_IPSET_CMD_FLS, NULL);
-}
diff --git a/src/ipset-control.h b/src/ipset-control.h
deleted file mode 100644 (file)
index 4199851..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * ipset control header 
- * Author: Neutron Soutmun <neo.neutron@gmail.com>
- * Date:   2008-08-07
- */
-
-#ifndef __IPSET_CONTROL_H
-#define __IPSET_CONTROL_H
-
-#include "rahunasd.h"
-
-#define        RH_IPSET_CMD_ADD  1
-#define RH_IPSET_CMD_DEL  2
-#define RH_IPSET_CMD_FLS  3
-
-int ctrl_add_to_set(struct rahunas_map *map, uint32_t id);
-
-int ctrl_del_from_set(struct rahunas_map *map, uint32_t id);
-
-int ctrl_flush();
-
-#endif //__IPSET_CONTROL_H
-
index 6aae97d..e087c10 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "rahunasd.h"
 #include "rh-xmlrpc-server.h"
+#include "rh-ipset.h"
 #include "ipset-control.h"
 
 /* Abstract functions */
@@ -27,8 +28,6 @@ int logmsg(int priority, const char *msg, ...);
 int getline(int fd, char *buf, size_t size);
 int finish();
 int ipset_flush();
-int chk_set(struct rahunas_map *map);
-int update_set(struct rahunas_map *map);
 
 struct rahunas_map* rh_init_map();
 int rh_init_members(struct rahunas_map *map);
@@ -40,6 +39,10 @@ int send_xmlrpc_stopacct(struct rahunas_map *map, uint32_t id);
 
 /* Declaration */
 struct rahunas_map *map = NULL;
+struct set *rahunas_set = NULL;
+
+struct set **set_list = NULL;
+ip_set_id_t max_sets = 0;
 
 uint32_t iptoid(struct rahunas_map *map, const char *ip) {
   uint32_t ret;
@@ -98,6 +101,17 @@ void rh_free(void **data)
   *data = NULL;
 }
 
+void rh_free_member (struct rahunas_member *member)
+{
+  if (member->username)
+    free(member->username);
+
+  if (member->session_id)
+    free(member->session_id);
+  
+  memset(member, 0, sizeof(struct rahunas_member));
+}
+
 int rh_openlog(const char *filename)
 {
   return open(filename, O_WRONLY | O_APPEND);
@@ -167,7 +181,7 @@ void rh_shutdown(int sig)
 int ipset_flush()
 {
   logmsg(RH_LOG_NORMAL, "Flushing IPSET...");
-  return ctrl_flush();
+  /* TODO: Flush the ipset */
 }
 
 int finish()
@@ -194,6 +208,7 @@ int finish()
                rh_free(&map);
        }
 
+  rh_free(&rahunas_set);
   logmsg(RH_LOG_NORMAL, exitmsg);
        syslog(LOG_INFO, exitmsg);
   return 0;
@@ -307,113 +322,6 @@ int parse_set_list(const char *in, struct rahunas_map *map)
        return id;
 }
 
-int chk_set(struct rahunas_map *map) 
-{
-  struct rahunas_member *members = NULL;
-       unsigned short set_start = 0;
-       char  line[256];
-  int   pipefd[2];
-       pid_t cpid;
-       uint32_t  id;
-
-       members = map->members;
-
-       if (pipe(pipefd) == -1) {
-    syslog(LOG_ERR, "Could not create pipe");
-               return -1;
-       }
-
-       cpid = fork();
-       if (cpid == 0) {
-         close(pipefd[0]);
-               dup2(pipefd[1], STDOUT_FILENO);
-               execlp("ipset", "ipset", "-nL", SET_NAME, NULL);
-               return (-1);
-               close(pipefd[1]);
-       }
-
-  wait(NULL);
-
-  close(pipefd[1]);
-
-       while (getline(pipefd[0], line, sizeof line) > 0) {
-
-    if (strstr(line, "Bindings:") != NULL)
-                 set_start = 0;
-
-               if (set_start)
-                 parse_set_list(line, map);
-
-               // Capture header
-    if (strstr(line, "Header:") != NULL)
-                 if (map != NULL && map->size == 0) {
-        parse_set_header(line, map);
-                               break;
-                       }
-
-               if (strstr(line, "Members:") != NULL)
-                 set_start = 1;
-       }
-       close(pipefd[0]); 
-
-       return 0;
-}
-
-
-int update_set(struct rahunas_map *map) 
-{
-  struct rahunas_member *members = NULL;
-  unsigned int i;
-  unsigned short no_detail = 0;
-  if (!map)
-         return (-1);
-       
-       members = map->members;
-
-       for (i=0; i < map->size; i++) {
-    no_detail = 0;
-    if (members[i].flags) {
-      if (!members[i].username || !members[i].session_id)
-        no_detail = 1;
-    
-
-                 if (members[i].expired) {
-         if (!no_detail) {
-                   DP("IP %s, Client: Username %s, "
-                      "Session-ID %s, Session-Start %d, "
-               "Expired %d",
-               idtoip(map, i),
-                            members[i].username, 
-                            members[i].session_id,
-                            members[i].session_start,
-               members[i].expired);
-
-                             send_xmlrpc_stopacct(map, i);
-          }
-
-        if (ctrl_del_from_set(map, i) == 0) {
-          if (!no_detail) {
-            logmsg(RH_LOG_NORMAL, "Session Stop, User: %s, IP: %s, "
-                            "Session ID: %s",
-                            members[i].username, 
-                            idtoip(map, i), 
-                            members[i].session_id); 
-          }
-
-            rh_free(&(members[i].username));
-            rh_free(&(members[i].session_id));
-
-                           memset(&members[i], 0, sizeof(struct rahunas_member));
-                           logmsg(RH_LOG_NORMAL, "Client IP %s was removed!", idtoip(map,i));
-                         }
-                       }
-               }
-       }
-  return 0;
-}
-
 int send_xmlrpc_stopacct(struct rahunas_map *map, uint32_t id) {
   struct rahunas_member *members = NULL;
   GNetXmlRpcClient *client = NULL;
@@ -439,10 +347,12 @@ int send_xmlrpc_stopacct(struct rahunas_map *map, uint32_t id) {
     return (-1);
   }
        
-       params = g_strdup_printf("%s|%s|%d", 
+       params = g_strdup_printf("%s|%s|%s|%d|%s", 
+                           idtoip(map, id),
                                 members[id].username,
                                                                                                         members[id].session_id,
-                                                                                                        members[id].session_start);
+                                                                                                        members[id].session_start,
+                           mac_tostring(members[id].mac_address));
 
   if (params == NULL)
     return (-1);
@@ -495,11 +405,126 @@ int rh_init_members (struct rahunas_map* map)
 gboolean polling(gpointer data) {
   struct rahunas_map *map = (struct rahunas_map *)data;
        DP("%s", "Start polling!");
-       chk_set (map);
-       update_set (map);
+  walk_through_set();
   return TRUE;
 }
 
+size_t expired_check(void *data)
+{
+  struct ip_set_list *setlist = (struct ip_set_list *) data;
+  struct set *set = set_list[setlist->index];
+  size_t offset;
+  struct ip_set_rahunas *table = NULL;
+  struct rahunas_member *members = map->members;
+  unsigned int i;
+  char *ip = NULL;
+  ip_set_ip_t current_ip;
+  int res  = 0;
+
+  offset = sizeof(struct ip_set_list) + setlist->header_size;
+  table = (struct ip_set_rahunas *)(data + offset);
+
+  DP("Map size %d", map->size);
+  for (i = 0; i < map->size; i++) {
+    if (test_bit(IPSET_RAHUNAS_ISSET,
+          (void *)&table[i].flags)) {
+      if ((time(NULL) - table[i].timestamp) > IDLE_THRESHOLD) {
+        DP("Found IP: %s expired", idtoip(map, i));
+        current_ip = ntohl(map->first_ip) + i;
+        res = set_adtip_nb(rahunas_set, &current_ip, &table[i].ethernet,
+                           IP_SET_OP_DEL_IP);  
+        DP("set_adtip_nb() res=%d errno=%d", res, errno);
+
+        if (res == 0) {
+                           send_xmlrpc_stopacct(map, i);
+          rh_free_member(&members[i]);
+        }
+      } 
+    }
+  }
+}
+
+int get_header_from_set ()
+{
+  struct ip_set_req_rahunas_create *header = NULL;
+  void *data = NULL;
+  ip_set_id_t idx;
+  socklen_t size, req_size;
+  size_t offset;
+  int res = 0;
+       in_addr_t first_ip;
+       in_addr_t last_ip;
+
+  size = req_size = load_set_list(SET_NAME, &idx, 
+                                  IP_SET_OP_LIST_SIZE, CMD_LIST); 
+
+  DP("Get Set Size: %d", size);
+  
+  if (size) {
+    data = rh_malloc(size);
+    ((struct ip_set_req_list *) data)->op = IP_SET_OP_LIST;
+    ((struct ip_set_req_list *) data)->index = idx;
+    res = kernel_getfrom_handleerrno(data, &size);
+    DP("get_lists getsockopt() res=%d errno=%d", res, errno);
+
+    if (res != 0 || size != req_size) {
+      free(data);
+      return -EAGAIN;
+    }
+    size = 0;
+  }
+
+  offset = sizeof(struct ip_set_list);
+  header = (struct ip_set_req_rahunas_create *) (data + offset);
+
+  first_ip = htonl(header->from); 
+  last_ip = htonl(header->to); 
+  
+  memcpy(&map->first_ip, &first_ip, sizeof(in_addr_t));
+  memcpy(&map->last_ip, &last_ip, sizeof(in_addr_t));
+       map->size = ntohl(map->last_ip) - ntohl(map->first_ip) + 1;
+
+       logmsg(RH_LOG_NORMAL, "First IP: %s", ip_tostring(ntohl(map->first_ip)));
+       logmsg(RH_LOG_NORMAL, "Last  IP: %s", ip_tostring(ntohl(map->last_ip)));
+       logmsg(RH_LOG_NORMAL, "Set Size: %lu", map->size);
+
+  rh_free(&data);
+  return res;
+}
+
+int walk_through_set ()
+{
+  void *data = NULL;
+  ip_set_id_t idx;
+  socklen_t size, req_size;
+  int res = 0;
+
+  size = req_size = load_set_list(SET_NAME, &idx, 
+                                  IP_SET_OP_LIST_SIZE, CMD_LIST); 
+
+  DP("Get Set Size: %d", size);
+  
+  if (size) {
+    data = rh_malloc(size);
+    ((struct ip_set_req_list *) data)->op = IP_SET_OP_LIST;
+    ((struct ip_set_req_list *) data)->index = idx;
+    res = kernel_getfrom_handleerrno(data, &size);
+    DP("get_lists getsockopt() res=%d errno=%d", res, errno);
+
+    if (res != 0 || size != req_size) {
+      free(data);
+      return -EAGAIN;
+    }
+    size = 0;
+  }
+
+  expired_check(data);
+
+  rh_free(&data);
+  return res;
+}
+
 static void
 watch_child(char *argv[])
 {
@@ -623,6 +648,7 @@ int main(int argc, char **argv)
        GNetXmlRpcServer *server = NULL;
        GMainLoop* main_loop     = NULL;
 
+
        watch_child(argv);
   
   gnet_init();
@@ -641,8 +667,13 @@ int main(int argc, char **argv)
        logmsg(RH_LOG_NORMAL, version);
   syslog(LOG_INFO, version);
 
+  rahunas_set = set_adt_get(SET_NAME);
+  DP("getsetname: %s", rahunas_set->name);
+  DP("getsetid: %d", rahunas_set->id);
+  DP("getsetindex: %d", rahunas_set->index);
+
   map = rh_init_map();
-  chk_set(map);
+  get_header_from_set();
   rh_init_members(map);
 
   /* XML RPC Server */
index 50dd2ba..f5196ad 100644 (file)
@@ -11,6 +11,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <time.h>
+#include <linux/if_ether.h>
 
 #define PROGRAM "RuhuNASd"
 #define VERSION "0.1.1"
@@ -18,8 +19,8 @@
 
 /* Configuration */
 #define DEFAULT_LOG "/var/log/rahunas/rahunas.log"
-#define IDLE_THRESHOLD 30
-#define POLLING 30 
+#define IDLE_THRESHOLD 600
+#define POLLING 120 
 #define SET_NAME "rahunas_set"
 #define XMLSERVICE_HOST        "localhost"
 #define XMLSERVICE_PORT        8888
@@ -39,6 +40,7 @@ struct rahunas_member {
        time_t session_start;
        char *username;
   char *session_id;
+  unsigned char mac_address[ETH_ALEN];
 };
 
 uint32_t iptoid(struct rahunas_map *map, const char *ip);
@@ -47,6 +49,8 @@ char *idtoip(struct rahunas_map *map, uint32_t id);
 void *rh_malloc(size_t size);
 void rh_free(void **data);
 
+void rh_free_member (struct rahunas_member *member);
+
 static char *timemsg()
 {
   static char tmsg[32] = "";
index e69de29..e698cdb 100644 (file)
@@ -0,0 +1,320 @@
+/**
+ * RahuNAS ipset implementation
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2008-08-20
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <syslog.h>
+#include "rh-ipset.h"
+
+extern struct set **set_list;
+extern ip_set_id_t max_sets;
+
+int kernel_getsocket(void)
+{
+  int sockfd = -1;
+
+  sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
+  if (sockfd <0) {
+    syslog(LOG_ERR, "You need to be root to run this daemon.");
+    exit(EXIT_FAILURE);
+  }
+  
+  return sockfd;
+}
+
+int wrapped_getsockopt(void *data, socklen_t *size)
+{
+  int res;
+  int sockfd = kernel_getsocket();
+
+  /* Send! */
+  res = getsockopt(sockfd, SOL_IP, SO_IP_SET, data, size);
+  if (res != 0)
+    DP("res=%d errno=%d", res, errno);
+
+  return res;
+}
+
+int wrapped_setsockopt(void *data, socklen_t size)
+{
+  int res;
+  int sockfd = kernel_getsocket();
+
+  /* Send! */
+  res = setsockopt(sockfd, SOL_IP, SO_IP_SET, data, size);
+  if (res != 0)
+    DP("res=%d errno=%d", res, errno);
+  
+  return res; 
+}
+
+void kernel_getfrom(void *data, socklen_t * size)
+{
+  int res = wrapped_getsockopt(data, size);
+
+  if (res != 0)
+    DP("res=%d errno=%d", res, errno);
+}
+
+int kernel_sendto_handleerrno(unsigned op, void *data, socklen_t size)
+{
+  int res = wrapped_setsockopt(data, size);
+
+  if (res !=0) {
+    DP("res=%d errno=%d", res, errno);
+    return -1;
+  }
+
+  return 0;
+}
+
+void kernel_sendto(void *data, size_t size)
+{
+  int res = wrapped_setsockopt(data, size);
+
+  if (res != 0)
+    DP("res=%d errno=%d", res, errno);
+}
+
+int kernel_getfrom_handleerrno(void *data, size_t * size)
+{
+  int res = wrapped_getsockopt(data, size);
+
+  if (res != 0) {
+    DP("res=%d errno=%d", res, errno);
+    return -1;
+  }
+
+  return 0;
+}
+
+struct set *set_adt_get(const char *name)
+{
+  struct ip_set_req_adt_get req_adt_get;
+  struct set *set;
+  socklen_t size;
+
+  DP("%s", name);
+
+  req_adt_get.op = IP_SET_OP_ADT_GET;
+  req_adt_get.version = IP_SET_PROTOCOL_VERSION;
+  strcpy(req_adt_get.set.name, name);
+  size = sizeof(struct ip_set_req_adt_get);
+
+  kernel_getfrom((void *) &req_adt_get, &size);
+
+  set = rh_malloc(sizeof(struct set));
+  strcpy(set->name, name);
+  set->index = req_adt_get.set.index;
+
+  return set;
+}
+
+
+void parse_ip(const char *str, ip_set_ip_t *ip)
+{
+  struct in_addr addr;
+
+  DP("%s", str);
+
+  if (inet_aton(str, &addr) != 0) {
+    *ip = ntohl(addr.s_addr);
+    return;
+  }
+}
+
+void parse_mac(const char *mac, unsigned char *ethernet)
+{
+  unsigned int i = 0;
+  if (strlen(mac) != ETH_ALEN * 3 - 1)
+    return;
+
+  DP("%s", mac);
+
+  for (i = 0; i < ETH_ALEN; i++) {
+    long number;
+    char *end;
+    
+    number = strtol(mac + i * 3, &end, 16);
+    
+    if (end == mac + i * 3 + 2 && number >= 0 && number <=255)
+      ethernet[i] = number;
+    else
+      return;
+  }
+  return;
+}
+
+char *ip_tostring(ip_set_ip_t ip)
+{
+  struct in_addr addr;
+  addr.s_addr = htonl(ip);
+
+  return inet_ntoa(addr);
+}
+
+char *mac_tostring(unsigned char macaddress[ETH_ALEN])
+{
+  static char mac_string[18] = "";
+  sprintf(mac_string, "%02X:%02X:%02X:%02X:%02X:%02X", 
+          macaddress[0], macaddress[1], macaddress[2],
+          macaddress[3], macaddress[4], macaddress[5]);
+  return mac_string; 
+}
+
+int set_adtip(struct set *rahunas_set, const char *adtip, const char *adtmac, 
+              unsigned op)
+{
+  ip_set_ip_t ip;
+  unsigned char mac[ETH_ALEN];
+  parse_ip(adtip, &ip);  
+  parse_mac(adtmac, &mac);
+
+  return set_adtip_nb(rahunas_set, &ip, mac, op);
+}
+
+int set_adtip_nb(struct set *rahunas_set, ip_set_ip_t *adtip, 
+                     unsigned char adtmac[ETH_ALEN], unsigned op)
+{
+  struct ip_set_req_adt *req_adt = NULL;
+  struct ip_set_req_rahunas req;
+
+  size_t size;
+  void *data;
+  int res = 0;
+
+  if (rahunas_set == NULL)
+    return -1;
+
+  size = sizeof(struct ip_set_req_adt) + sizeof(struct ip_set_req_rahunas);
+  data = rh_malloc(size);
+
+  memcpy(&req.ip, adtip, sizeof(ip_set_ip_t));
+  memcpy(&req.ethernet, adtmac, ETH_ALEN);
+
+  req_adt = (struct ip_set_req_adt *) data;
+  req_adt->op = op;
+  req_adt->index = rahunas_set->index;
+  memcpy(data + sizeof(struct ip_set_req_adt), &req, 
+           sizeof(struct ip_set_req_rahunas));
+
+  if (kernel_sendto_handleerrno(op, data, size) == -1)
+               switch (op) {
+               case IP_SET_OP_ADD_IP:
+                 DP("%s:%s is already in set", ip_tostring(adtip), mac_tostring(adtmac));
+      res = RH_IS_IN_SET;
+                       break;
+               case IP_SET_OP_DEL_IP:
+      DP("%s:%s is not in set", ip_tostring(adtip), mac_tostring(adtmac));
+      res = RH_IS_NOT_IN_SET; 
+                       break;
+               case IP_SET_OP_TEST_IP:
+      DP("%s:%s is in set", ip_tostring(adtip), mac_tostring(adtmac));
+      res = RH_IS_IN_SET;
+                       break;
+               default:
+                       break;
+               }
+       else
+               switch (op) {
+               case IP_SET_OP_TEST_IP:
+      DP("%s:%s is not in set", ip_tostring(adtip), mac_tostring(adtmac));
+      res = RH_IS_NOT_IN_SET;
+                       break;
+               default:
+                       break;   
+    }
+
+  free(data);
+
+  return res;
+}
+
+size_t load_set_list(const char name[IP_SET_MAXNAMELEN],
+                           ip_set_id_t *idx,
+                           unsigned op, unsigned cmd)
+{
+       void *data = NULL;
+       struct ip_set_req_max_sets req_max_sets;
+       struct ip_set_name_list *name_list;
+       struct set *set;
+       ip_set_id_t i;
+       socklen_t size, req_size;
+       int repeated = 0, res = 0;
+
+       DP("%s %s", cmd == CMD_MAX_SETS ? "MAX_SETS"
+                   : cmd == CMD_LIST_SIZE ? "LIST_SIZE"
+                   : "SAVE_SIZE",
+                   name);
+       
+tryagain:
+       if (set_list) {
+               for (i = 0; i < max_sets; i++)
+                       if (set_list[i])
+                               free(set_list[i]);
+               free(set_list);
+               set_list = NULL;
+       }
+       /* Get max_sets */
+       req_max_sets.op = IP_SET_OP_MAX_SETS;
+       req_max_sets.version = IP_SET_PROTOCOL_VERSION;
+       strcpy(req_max_sets.set.name, name);
+       size = sizeof(req_max_sets);
+       kernel_getfrom(&req_max_sets, &size);
+
+       DP("got MAX_SETS: sets %d, max_sets %d",
+          req_max_sets.sets, req_max_sets.max_sets);
+
+       max_sets = req_max_sets.max_sets;
+       set_list = rh_malloc(max_sets * sizeof(struct set *));
+       memset(set_list, 0, max_sets * sizeof(struct set *));
+       *idx = req_max_sets.set.index;
+
+       if (req_max_sets.sets == 0)
+               /* No sets in kernel */
+               return 0;
+
+       /* Get setnames */
+       size = req_size = sizeof(struct ip_set_req_setnames) 
+                         + req_max_sets.sets * sizeof(struct ip_set_name_list);
+       data = rh_malloc(size);
+       ((struct ip_set_req_setnames *) data)->op = op;
+       ((struct ip_set_req_setnames *) data)->index = *idx;
+
+       res = kernel_getfrom_handleerrno(data, &size);
+
+       if (res != 0 || size != req_size) {
+               free(data);
+               if (repeated++ < LIST_TRIES)
+                       goto tryagain;
+
+               DP("Tried to get sets from kernel %d times"
+                          " and failed. Please try again when the load on"
+                          " the sets has gone down.", LIST_TRIES);
+    return -1;
+       }
+               
+       /* Load in setnames */
+       size = sizeof(struct ip_set_req_setnames);                      
+       while (size + sizeof(struct ip_set_name_list) <= req_size) {
+               name_list = (struct ip_set_name_list *)
+                       (data + size);
+               set = rh_malloc(sizeof(struct set));
+               strcpy(set->name, name_list->name);
+               set->index = name_list->index;
+               set->id = name_list->id;
+               set_list[name_list->index] = set;
+               size += sizeof(struct ip_set_name_list);
+       }
+       /* Size to get set members, bindings */
+       size = ((struct ip_set_req_setnames *)data)->size;
+       free(data);
+       
+       return size;
+}
index e69de29..09525ed 100644 (file)
@@ -0,0 +1,91 @@
+/**
+ * RahuNAS ipset implementation header
+ * Author: Neutron Soutmun <neo.neutron@gmail.com>
+ * Date:   2008-08-20
+ */
+
+#ifndef __RH_IPSET_H
+#define __RH_IPSET_H
+
+#include "rahunasd.h"
+#include <linux/if_ether.h>
+#include <linux/netfilter_ipv4/ip_set.h>
+#include <linux/netfilter_ipv4/ip_set_rahunas.h>
+
+#define LIST_TRIES 5
+
+/* The view of an ipset in userspace */
+struct set {
+       char name[IP_SET_MAXNAMELEN];           /* Name of the set */
+       ip_set_id_t id;                         /* Unique set id */
+       ip_set_id_t index;                      /* Array index */
+       unsigned ref;                           /* References in kernel */
+       struct settype *settype;                /* Pointer to set type functions */
+};
+
+enum rh_adt_result {
+  RH_IS_IN_SET,
+  RH_IS_NOT_IN_SET,
+};
+
+/* Commands */
+enum set_commands {
+       CMD_NONE,
+       CMD_CREATE,             /* -N */
+       CMD_DESTROY,            /* -X */
+       CMD_FLUSH,              /* -F */
+       CMD_RENAME,             /* -E */
+       CMD_SWAP,               /* -W */
+       CMD_LIST,               /* -L */
+       CMD_SAVE,               /* -S */
+       CMD_RESTORE,            /* -R */
+       CMD_ADD,                /* -A */
+       CMD_DEL,                /* -D */
+       CMD_TEST,               /* -T */
+       CMD_BIND,               /* -B */
+       CMD_UNBIND,             /* -U */
+       CMD_HELP,               /* -H */
+       CMD_VERSION,            /* -V */
+       NUMBER_OF_CMD = CMD_VERSION,
+       /* Internal commands */
+       CMD_MAX_SETS,
+       CMD_LIST_SIZE,
+       CMD_SAVE_SIZE,
+       CMD_ADT_GET,
+};
+
+enum exittype {
+       OTHER_PROBLEM = 1,
+       PARAMETER_PROBLEM,
+       VERSION_PROBLEM
+};
+
+int kernel_getsocket(void);
+int wrapped_getsockopt(void *data, socklen_t *size);
+int wrapped_setsockopt(void *data, socklen_t size);
+void kernel_getfrom(void *data, socklen_t * size);
+int kernel_sendto_handleerrno(unsigned op, void *data, socklen_t size);
+void kernel_sendto(void *data, size_t size);
+int kernel_getfrom_handleerrno(void *data, size_t * size);
+struct set *set_adt_get(const char *name);
+int set_adtip(struct set *rahunas_set, const char *adtip, const char *adtmac, 
+              unsigned op);
+
+int set_adtip_nb(struct set *rahunas_set, ip_set_ip_t *adtip, 
+                     unsigned char adtmac[ETH_ALEN], unsigned op);
+
+size_t load_set_list(const char name[IP_SET_MAXNAMELEN],
+                           ip_set_id_t *idx,
+                           unsigned op, unsigned cmd);
+
+void parse_ip(const char *str, ip_set_ip_t *ip);
+void parse_mac(const char *mac, unsigned char *ethernet);
+char *ip_tostring(ip_set_ip_t ip);
+char *mac_tostring(unsigned char macaddress[ETH_ALEN]);
+
+#define BITSPERBYTE (8*sizeof(char))
+#define ID2BYTE(id) ((id)/BITSPERBYTE)
+#define ID2MASK(id) (1 << ((id)%BITSPERBYTE))
+#define test_bit(id, heap)  ((((char *)(heap))[ID2BYTE(id)] & ID2MASK(id)) != 0)
+
+#endif //__RH_IPSET_H
index 25bc05a..68ecb63 100644 (file)
@@ -8,7 +8,10 @@
 #include <stdlib.h>
 #include "rahunasd.h"
 #include "rh-xmlrpc-server.h"
-#include "ipset-control.h"
+#include "rh-ipset.h"
+
+
+extern struct set *rahunas_set;
 
 int do_startsession(GNetXmlRpcServer *server,
                     const gchar *command,
@@ -18,12 +21,15 @@ int do_startsession(GNetXmlRpcServer *server,
 {
   struct rahunas_map *map = (struct rahunas_map *)user_data;
        struct rahunas_member *members = NULL;
+  unsigned char ethernet[ETH_ALEN];
        gchar *ip = NULL;
        gchar *username = NULL;
        gchar *session_id = NULL;
+  gchar *mac_address = NULL;
        gchar *pStart = NULL;
        gchar *pEnd = NULL;
        uint32_t id;
+  int res = 0;
 
        if (!map)
          goto out;
@@ -52,8 +58,16 @@ int do_startsession(GNetXmlRpcServer *server,
     goto out;
        }
        username = g_strndup(pStart, pEnd - pStart);
+
+  pStart = pEnd + 1;
+       pEnd = g_strstr_len(pStart, strlen(pStart), "|");
+       if (pEnd == NULL) {
+    goto out;
+       }
+       session_id = g_strndup(pStart, pEnd - pStart);
+
        pStart = pEnd + 1;
-  session_id = g_strndup(pStart, strlen(pStart));
+  mac_address = g_strndup(pStart, strlen(pStart));
 
        id = iptoid(map, ip);
 
@@ -62,28 +76,34 @@ int do_startsession(GNetXmlRpcServer *server,
                return 0;
        }
 
-       if (members[id].flags) {
-    *reply_string = g_strdup("Client already login");
-               return 0;
-       }
 
-  if (ctrl_add_to_set(map, id) == 0) {
-         if (!members[id].username)
-                 free(members[id].username);
-               members[id].username = username;
-    
-               if (!members[id].session_id)
-                 free(members[id].session_id);
-               members[id].session_id = session_id;
+  res = set_adtip(rahunas_set, ip, mac_address, IP_SET_OP_ADD_IP);
+  if (res == 0) {
+    members[id].flags = 1;
+    if (!members[id].username)
+      free(members[id].username);
+
+    if (!members[id].session_id)
+      free(members[id].session_id);
+
+    members[id].username   = strdup(username);
+    members[id].session_id = strdup(session_id);
 
                time(&(members[id].session_start));
 
+    parse_mac(mac_address, &ethernet);
+    memcpy(&members[id].mac_address, &ethernet, ETH_ALEN);
+
     logmsg(RH_LOG_NORMAL, "Session Start, User: %s, IP: %s, "
-                          "Session ID: %s",
+                          "Session ID: %s, MAC: %s",
                           members[id].username, 
                           idtoip(map, id), 
-                          members[id].session_id); 
-       }
+                          members[id].session_id,
+                          mac_tostring(members[id].mac_address)); 
+
+  } else if (res == RH_IS_IN_SET) {
+    members[id].flags = 1;
+  }
 
   *reply_string = g_strdup_printf("Greeting! Got: IP %s, User %s, ID %s", 
                                         ip, members[id].username, 
@@ -105,8 +125,13 @@ int do_stopsession(GNetXmlRpcServer *server,
 {
   struct rahunas_map *map = (struct rahunas_map *)user_data;
        struct rahunas_member *members;
-       gchar *ip;
+       gchar *ip = NULL;
+       gchar *mac_address = NULL;
+       gchar *pStart = NULL;
+       gchar *pEnd = NULL;
        uint32_t   id;
+  int res = 0;
+  unsigned char ethernet[ETH_ALEN];
 
        if (!map)
          goto out;
@@ -119,7 +144,23 @@ int do_stopsession(GNetXmlRpcServer *server,
        if (param == NULL)
          goto out;
 
-  ip = param;
+  DP("RPC Receive: %s", param);
+
+  pStart = param;
+       pEnd = g_strstr_len(pStart, strlen(pStart), "|");
+       if (pEnd == NULL) {
+         goto out;
+       }
+
+       ip = g_strndup(pStart, pEnd - pStart);
+  if (ip == NULL)
+    goto out;
+
+       pStart = pEnd + 1;
+  mac_address = g_strndup(pStart, strlen(pStart));
+  if (mac_address == NULL)
+    goto out;
+
        id = iptoid(map, ip);
 
        if (id < 0) {
@@ -128,29 +169,30 @@ int do_stopsession(GNetXmlRpcServer *server,
        }
 
        if (members[id].flags) {
-         if (ctrl_del_from_set(map, id) == 0) {
-
-    logmsg(RH_LOG_NORMAL, "Session Stop, User: %s, IP: %s, "
-                          "Session ID: %s",
-                          members[id].username, 
-                          idtoip(map, id), 
-                          members[id].session_id); 
-
-      if (members[id].username)
-        free(members[id].username);
-         
-      if (members[id].session_id)
-        free(members[id].session_id);
-
-           memset(&members[id], 0, sizeof(struct rahunas_member));
-                       *reply_string = g_strdup_printf("Client IP %s was removed!", 
-                                                       idtoip(map, id));
-                       return 0;
-               } else {
-      *reply_string = g_strdup_printf("Client IP %s remove error", ip);
-                 return 0;
-               }
-       }
+    parse_mac(mac_address, &ethernet);
+    if (memcmp(&ethernet, &members[id].mac_address, ETH_ALEN) == 0) {
+      res = set_adtip(rahunas_set, idtoip(map, id), mac_address,
+                      IP_SET_OP_DEL_IP);
+      if (res == 0) {
+        logmsg(RH_LOG_NORMAL, "Session Stop, User: %s, IP: %s, "
+                              "Session ID: %s, MAC: %s",
+                              members[id].username, 
+                              idtoip(map, id), 
+                              members[id].session_id,
+                              mac_tostring(members[id].mac_address)); 
+
+        rh_free_member(&members[id]);   
+        *reply_string = g_strdup_printf("Client IP %s was removed!", 
+                                                         idtoip(map, id));
+           return 0;
+      } else {
+         *reply_string = g_strdup_printf("Client IP %s error remove!", 
+                                                       idtoip(map, id));
+                         return 0;
+      }
+               }       
+  }
 
   *reply_string = g_strdup_printf("%s", ip);
        return 0;
@@ -201,10 +243,12 @@ int do_getsessioninfo(GNetXmlRpcServer *server,
       return 0;
     }
     
-    *reply_string = g_strdup_printf("%s|%s|%s|%d", ip, 
-                                                              members[id].username,
-                                                                                                                                                                                                  members[id].session_id,
-                                                                                                                                                                                                  members[id].session_start);
+    *reply_string = g_strdup_printf("%s|%s|%s|%d|%s", 
+                                      ip, 
+                                                 members[id].username,
+                                                                                                                                                 members[id].session_id,
+                                                                                                                                                 members[id].session_start,
+                                      mac_tostring(members[id].mac_address));
                return 0;
        }