chiark / gitweb /
Import release 0.07 v0.07
authorStephen Early <steve@greenend.org.uk>
Sun, 23 Sep 2001 23:48:00 +0000 (00:48 +0100)
committerStephen Early <steve@greenend.org.uk>
Wed, 18 May 2011 12:21:08 +0000 (13:21 +0100)
14 files changed:
INSTALL
Makefile.in
config.h.bot
config.h.in
configure
configure.in
example.conf
netlink.c
secnet.c
secnet.h
site.c
transform.c
unaligned.h [new file with mode: 0644]
util.c

diff --git a/INSTALL b/INSTALL
index 2001fa86785948fdf841e3cb265b3bb51810a45a..b384b9ca4e2d5b1265f8ed7d5ff3d5bf7120ce87 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -4,6 +4,8 @@ USE AT YOUR OWN RISK.  THIS IS ALPHA TEST SOFTWARE.  I DO NOT
 GUARANTEE THAT THERE WILL BE PROTOCOL COMPATIBILITY BETWEEN DIFFERENT
 VERSIONS.
 
+PROTOCOL COMPATIBILITY WAS BROKEN BETWEEN secnet-0.06 AND secnet-0.07
+
 * Preparation
 
 ** System software support
@@ -11,6 +13,8 @@ VERSIONS.
 Ensure that you have libgmp2-dev and adns installed (and bison and
 flex, and for that matter gcc...).
 
+[On BSD install /usr/ports/devel/bison and /usr/ports/devel/libgnugetopt]
+
 If you intend to configure secnet to obtain packets from the kernel
 through userv-ipif, install and configure userv-ipif.  It is part of
 userv-utils, available from ftp.chiark.greenend.org.uk in
index 2dea73838574a95fea287ba2c9a44a8fb2e26ddc..a7d9df8175c06a8bf9059ca314b3a8666730dba7 100644 (file)
@@ -18,7 +18,7 @@
 .PHONY:        all clean realclean dist install
 
 PACKAGE:=secnet
-VERSION:=0.06
+VERSION:=0.07
 
 @SET_MAKE@
 
@@ -53,7 +53,7 @@ DISTFILES:=COPYING INSTALL Makefile.in NOTES README TODO conffile.c \
        example-sites-file example.conf install.sh linux md5.c md5.h \
        modules.c modules.h netlink.c random.c resolver.c rsa.c \
        secnet.c secnet.h serpent.c serpent.h serpentsboxes.h \
-       site.c transform.c udp.c util.c util.h
+       site.c transform.c udp.c unaligned.h util.c util.h
 
 %.c:   %.y
 
@@ -72,6 +72,9 @@ Makefile: Makefile.in config.status
 config.status: configure
        $(srcdir)/configure --no-create
 
+config.h: config.h.in config.status
+       $(SHELL) config.status
+
 $(OBJECTS): config.h secnet.h util.h
 conffile.o conffile.tab.o conffile.yy.o: conffile.h conffile_internal.h
 secnet.c: conffile.h
@@ -79,6 +82,7 @@ md5.o: md5.h
 serpent.o transform.o: serpent.h
 serpent.o: serpentsboxes.h
 conffile.o: modules.h
+site.c util.c: unaligned.h
 
 secnet:        $(OBJECTS)
 
index ff6ecda5810d1fbe822e1029976903a7ac76dee8..47befcbc7771f3223bbd78bd0535f18700ad6cf5 100644 (file)
@@ -2,8 +2,14 @@
 
 /* These are from config.h.bot, pasted onto the end of config.h.in. */
 
-#ifdef HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#else
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#error you must define uint32_t, uint16_t etc.
+#endif
 #endif
 
 #endif /* _CONFIG_H */
index 5d31bab7a50077f36378e36b5b117b848782dafb..c52fd8cb74d37555b60f4a9bc0dfe4e7ee43a869 100644 (file)
@@ -1,27 +1,4 @@
 /* config.h.in.  Generated automatically from configure.in by autoheader.  */
-/***************************************************************************
- *
- *              Part II Project, "A secure, private IP network"
- *              Stephen Early <sde1000@cam.ac.uk>
- *   
- *
- *     $RCSfile$
- *
- *  Description: 
- *
- *    Copyright: (C) Stephen Early 1995
- *
- *    $Revision$
- *
- *        $Date$
- *
- *       $State$
- *
- ***************************************************************************/
-
-/* $Log$
- */
-
 #ifndef _CONFIG_H
 #define _CONFIG_H
 
    byte first (like Motorola and SPARC, unlike Intel and VAX).  */
 #undef WORDS_BIGENDIAN
 
+/* Define if you have the <inttypes.h> header file.  */
+#undef HAVE_INTTYPES_H
+
 /* Define if you have the <linux/if.h> header file.  */
 #undef HAVE_LINUX_IF_H
 
+/* Define if you have the <stdint.h> header file.  */
+#undef HAVE_STDINT_H
+
 /* Define if you have the adns library (-ladns).  */
 #undef HAVE_LIBADNS
 
 
 /* These are from config.h.bot, pasted onto the end of config.h.in. */
 
-#ifdef HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#else
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#error you must define uint32_t, uint16_t etc.
+#endif
 #endif
 
 #endif /* _CONFIG_H */
index 4ca20721dbeef18ad6b183a4e2dfd7605fd6a4a2..3bcb172d646e582d1389bb4e72944c085b1c10db 100755 (executable)
--- a/configure
+++ b/configure
@@ -1084,7 +1084,7 @@ EOF
 
 fi
 
-for ac_hdr in linux/if.h
+for ac_hdr in stdint.h inttypes.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
@@ -1124,15 +1124,55 @@ else
 fi
 done
 
+for ac_hdr in linux/if.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1132: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1137 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1142: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:1129: checking whether byte ordering is bigendian" >&5
+echo "configure:1169: checking whether byte ordering is bigendian" >&5
 if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_cv_c_bigendian=unknown
 # See if sys/param.h defines the BYTE_ORDER macro.
 cat > conftest.$ac_ext <<EOF
-#line 1136 "configure"
+#line 1176 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -1143,11 +1183,11 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:1147: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1187: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 1151 "configure"
+#line 1191 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -1158,7 +1198,7 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:1162: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -1178,7 +1218,7 @@ if test "$cross_compiling" = yes; then
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 1182 "configure"
+#line 1222 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -1191,7 +1231,7 @@ main () {
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:1195: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1235: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_bigendian=no
 else
@@ -1216,7 +1256,7 @@ fi
 
 
 echo $ac_n "checking for mpz_init_set_str in -lgmp2""... $ac_c" 1>&6
-echo "configure:1220: checking for mpz_init_set_str in -lgmp2" >&5
+echo "configure:1260: checking for mpz_init_set_str in -lgmp2" >&5
 ac_lib_var=`echo gmp2'_'mpz_init_set_str | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1224,7 +1264,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lgmp2  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1228 "configure"
+#line 1268 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1235,7 +1275,7 @@ int main() {
 mpz_init_set_str()
 ; return 0; }
 EOF
-if { (eval echo configure:1239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1263,7 +1303,7 @@ else
 fi
 
 echo $ac_n "checking for yywrap in -lfl""... $ac_c" 1>&6
-echo "configure:1267: checking for yywrap in -lfl" >&5
+echo "configure:1307: checking for yywrap in -lfl" >&5
 ac_lib_var=`echo fl'_'yywrap | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1271,7 +1311,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lfl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1275 "configure"
+#line 1315 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1282,7 +1322,7 @@ int main() {
 yywrap()
 ; return 0; }
 EOF
-if { (eval echo configure:1286: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1310,7 +1350,7 @@ else
 fi
 
 echo $ac_n "checking for adns_init in -ladns""... $ac_c" 1>&6
-echo "configure:1314: checking for adns_init in -ladns" >&5
+echo "configure:1354: checking for adns_init in -ladns" >&5
 ac_lib_var=`echo adns'_'adns_init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1318,7 +1358,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-ladns  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1322 "configure"
+#line 1362 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1329,7 +1369,7 @@ int main() {
 adns_init()
 ; return 0; }
 EOF
-if { (eval echo configure:1333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
index cb478355a9ead9e2000ad79f96737da30d8e17a5..9bb9248843989816813bbb5ed477102dee86e514 100644 (file)
@@ -12,11 +12,15 @@ AC_PROG_CC
 AC_PROG_INSTALL
 AC_PATH_PROG(RM,rm)
 AC_STDC_HEADERS
+AC_CHECK_HEADERS(stdint.h inttypes.h)
 AC_CHECK_HEADERS(linux/if.h)
 AC_C_BIGENDIAN
 
+AC_CHECK_LIB(gmp,mpz_init_set_str)
 AC_CHECK_LIB(gmp2,mpz_init_set_str)
 AC_CHECK_LIB(fl,yywrap)
 AC_CHECK_LIB(adns,adns_init)
+AC_CHECK_LIB(getopt,getopt_long)
+AC_CHECK_LIB(gnugetopt,getopt_long)
 
 AC_OUTPUT(Makefile)
index 96a84339223e46e08602c4697a23efa0037707da..e3f6011e5fc16c95b4d788abbe2e0d24824d70d4 100644 (file)
@@ -46,6 +46,7 @@ system {
 # wait-time             wait between unsuccessful key setup attempts, in ms
 
 # Use the universal TUN/TAP driver to get packets to and from the kernel
+#  (use tun-old if you are not on Linux-2.4)
 netlink tun {
        name "netlink-tun"; # Printed in log messages from this netlink
 #      interface "tun0"; # You may set your own interface name if you wish;
index 0b1ebe411291b7f4b8f9bb59490693b5e94084ea..9f4626a556ddea553f2237aa73482ee1dd8c7b8c 100644 (file)
--- a/netlink.c
+++ b/netlink.c
@@ -18,8 +18,6 @@
    packet to the kernel we check that the tunnel it came over could
    reasonably have produced it. */
 
-/* XXX now implement TUN. Kernel needs recompiling. */
-
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -961,8 +959,10 @@ static list_t *tun_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->device_path=dict_read_string(dict,"device",False,"tun-netlink",loc);
     st->interface_name=dict_read_string(dict,"interface",False,
                                        "tun-netlink",loc);
-    st->ifconfig_path=dict_read_string(dict,"device",False,"tun-netlink",loc);
-    st->route_path=dict_read_string(dict,"device",False,"tun-netlink",loc);
+    st->ifconfig_path=dict_read_string(dict,"ifconfig-path",
+                                      False,"tun-netlink",loc);
+    st->route_path=dict_read_string(dict,"route-path",
+                                   False,"tun-netlink",loc);
 
     if (!st->device_path) st->device_path="/dev/net/tun";
     if (!st->ifconfig_path) st->ifconfig_path="ifconfig";
@@ -1026,8 +1026,9 @@ static list_t *tun_old_apply(closure_t *self, struct cloc loc, dict_t *context,
                                        "tun-netlink",loc);
     search_for_if=dict_read_bool(dict,"interface-search",False,"tun-netlink",
                                 loc,st->device_path==NULL);
-    st->ifconfig_path=dict_read_string(dict,"device",False,"tun-netlink",loc);
-    st->route_path=dict_read_string(dict,"device",False,"tun-netlink",loc);
+    st->ifconfig_path=dict_read_string(dict,"ifconfig-path",False,
+                                      "tun-netlink",loc);
+    st->route_path=dict_read_string(dict,"route-path",False,"tun-netlink",loc);
 
     if (!st->device_path) st->device_path="/dev/tun";
     if (!st->ifconfig_path) st->ifconfig_path="ifconfig";
@@ -1056,7 +1057,7 @@ static list_t *tun_old_apply(closure_t *self, struct cloc loc, dict_t *context,
                sprintf(st->interface_name,"tun%d",i);
                Message(M_INFO,"%s: allocated network interface %s "
                        "through %s\n",st->nl.name,st->interface_name,dname);
-               continue;
+               break;
            }
        }
        if (st->fd==-1) {
index 1cb38db21207ac04707b40d0484f03bc29135e1d..b1599e1087bf8e7b36460282dbcb356415b47c83 100644 (file)
--- a/secnet.c
+++ b/secnet.c
@@ -11,6 +11,7 @@ extern char version[];
 #include <getopt.h>
 #include <stdarg.h>
 #include <errno.h>
+#include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/poll.h>
 #include <sys/time.h>
@@ -18,7 +19,6 @@ extern char version[];
 #include <arpa/inet.h>
 #include <adns.h>
 #include <pwd.h>
-#include <sys/types.h>
 
 #include "secnet.h"
 #include "util.h"
index db3bee22da322090ac88af4d9d7d38b9abf089f4..92740597008cca2364e56300b18b59c28633e362 100644 (file)
--- a/secnet.h
+++ b/secnet.h
@@ -3,13 +3,12 @@
 #ifndef secnet_h
 #define secnet_h
 
+#include "config.h"
 #include <stdlib.h>
-#include <stdint.h>
 #include <stdarg.h>
 #include <syslog.h>
 #include <sys/poll.h>
 #include <netinet/in.h>
-#include "config.h"
 
 
 typedef char *string_t;
diff --git a/site.c b/site.c
index 1a664ce30c0d6e52d5f3259e2579e746fb11bcd7..4ca53cd75eaed2aeb3548a7f3716f99ebe3d628c 100644 (file)
--- a/site.c
+++ b/site.c
@@ -5,12 +5,13 @@
 
 #include "secnet.h"
 #include "util.h"
+#include "unaligned.h"
 
 #define SETUP_BUFFER_LEN 2048
 
-#define DEFAULT_KEY_LIFETIME 15000
+#define DEFAULT_KEY_LIFETIME 3600000
 #define DEFAULT_SETUP_RETRIES 5
-#define DEFAULT_SETUP_TIMEOUT 500
+#define DEFAULT_SETUP_TIMEOUT 1000
 #define DEFAULT_WAIT_TIME 10000
 
 /* Each site can be in one of several possible states. */
@@ -94,7 +95,7 @@ static string_t state_name(uint32_t state)
 #define LOG_SETUP_TIMEOUT 0x00000004
 #define LOG_ACTIVATE_KEY  0x00000008
 #define LOG_TIMEOUT_KEY   0x00000010
-#define LOG_SECURITY      0x00000020
+#define LOG_SEC      0x00000020
 #define LOG_STATE         0x00000040
 #define LOG_DROP          0x00000080
 #define LOG_DUMP          0x00000100
@@ -186,7 +187,7 @@ static void enter_state_wait(struct site *st);
 #define CHECK_EMPTY(b) do { if ((b)->size!=0) return False; } while(0)
 #define CHECK_TYPE(b,t) do { uint32_t type; \
     CHECK_AVAIL((b),4); \
-    type=*(uint32_t *)buf_unprepend((b),4); \
+    type=buf_unprepend_uint32((b)); \
     if (type!=(t)) return False; } while(0)
 
 struct msg {
@@ -217,10 +218,10 @@ static bool_t generate_msg(struct site *st, uint32_t type, string_t what)
     st->retries=st->setup_retries;
     BUF_ALLOC(&st->buffer,what);
     buffer_init(&st->buffer,0);
-    *(uint32_t *)buf_append(&st->buffer,4)=
-       (type==LABEL_MSG1?0:st->setup_session_id);
-    *(uint32_t *)buf_append(&st->buffer,4)=(uint32_t)st;
-    *(uint32_t *)buf_append(&st->buffer,4)=type;
+    buf_append_uint32(&st->buffer,
+       (type==LABEL_MSG1?0:st->setup_session_id));
+    buf_append_uint32(&st->buffer,(uint32_t)st);
+    buf_append_uint32(&st->buffer,type);
     buf_append_string(&st->buffer,st->localname);
     buf_append_string(&st->buffer,st->remotename);
     memcpy(buf_append(&st->buffer,NONCELEN),st->localN,NONCELEN);
@@ -244,16 +245,16 @@ static bool_t unpick_msg(struct site *st, uint32_t type,
 {
     m->hashstart=msg->start;
     CHECK_AVAIL(msg,4);
-    m->dest=*(uint32_t *)buf_unprepend(msg,4);
+    m->dest=buf_unprepend_uint32(msg);
     CHECK_AVAIL(msg,4);
-    m->source=*(uint32_t *)buf_unprepend(msg,4);
+    m->source=buf_unprepend_uint32(msg);
     CHECK_TYPE(msg,type);
     CHECK_AVAIL(msg,2);
-    m->remlen=ntohs(*(uint16_t *)buf_unprepend(msg,2));
+    m->remlen=buf_unprepend_uint16(msg);
     CHECK_AVAIL(msg,m->remlen);
     m->remote=buf_unprepend(msg,m->remlen);
     CHECK_AVAIL(msg,2);
-    m->loclen=ntohs(*(uint16_t *)buf_unprepend(msg,2));
+    m->loclen=buf_unprepend_uint16(msg);
     CHECK_AVAIL(msg,m->loclen);
     m->local=buf_unprepend(msg,m->loclen);
     CHECK_AVAIL(msg,NONCELEN);
@@ -269,12 +270,12 @@ static bool_t unpick_msg(struct site *st, uint32_t type,
        return True;
     }
     CHECK_AVAIL(msg,2);
-    m->pklen=ntohs(*(uint16_t *)buf_unprepend(msg,2));
+    m->pklen=buf_unprepend_uint16(msg);
     CHECK_AVAIL(msg,m->pklen);
     m->pk=buf_unprepend(msg,m->pklen);
     m->hashlen=msg->start-m->hashstart;
     CHECK_AVAIL(msg,2);
-    m->siglen=ntohs(*(uint16_t *)buf_unprepend(msg,2));
+    m->siglen=buf_unprepend_uint16(msg);
     CHECK_AVAIL(msg,m->siglen);
     m->sig=buf_unprepend(msg,m->siglen);
     CHECK_EMPTY(msg);
@@ -322,15 +323,15 @@ static bool_t process_msg2(struct site *st, struct buffer_if *msg2,
     /* Check that the site names and our nonce have been sent
        back correctly, and then store our peer's nonce. */ 
     if (memcmp(m.remote,st->remotename,strlen(st->remotename)!=0)) {
-       slog(st,LOG_SECURITY,"msg2: bad B (remote site name)");
+       slog(st,LOG_SEC,"msg2: bad B (remote site name)");
        return False;
     }
     if (memcmp(m.local,st->localname,strlen(st->localname)!=0)) {
-       slog(st,LOG_SECURITY,"msg2: bad A (local site name)");
+       slog(st,LOG_SEC,"msg2: bad A (local site name)");
        return False;
     }
     if (memcmp(m.nL,st->localN,NONCELEN)!=0) {
-       slog(st,LOG_SECURITY,"msg2: bad nA (locally generated nonce)");
+       slog(st,LOG_SEC,"msg2: bad nA (locally generated nonce)");
        return False;
     }
     st->setup_session_id=m.source;
@@ -358,19 +359,19 @@ static bool_t process_msg3(struct site *st, struct buffer_if *msg3,
     /* Check that the site names and nonces have been sent back
        correctly */
     if (memcmp(m.remote,st->remotename,strlen(st->remotename)!=0)) {
-       slog(st,LOG_SECURITY,"msg3: bad A (remote site name)");
+       slog(st,LOG_SEC,"msg3: bad A (remote site name)");
        return False;
     }
     if (memcmp(m.local,st->localname,strlen(st->localname)!=0)) {
-       slog(st,LOG_SECURITY,"msg3: bad B (local site name)");
+       slog(st,LOG_SEC,"msg3: bad B (local site name)");
        return False;
     }
     if (memcmp(m.nR,st->remoteN,NONCELEN)!=0) {
-       slog(st,LOG_SECURITY,"msg3: bad nA (remotely generated nonce)");
+       slog(st,LOG_SEC,"msg3: bad nA (remotely generated nonce)");
        return False;
     }
     if (memcmp(m.nL,st->localN,NONCELEN)!=0) {
-       slog(st,LOG_SECURITY,"msg3: bad nB (locally generated nonce)");
+       slog(st,LOG_SEC,"msg3: bad nB (locally generated nonce)");
        return False;
     }
     
@@ -381,7 +382,7 @@ static bool_t process_msg3(struct site *st, struct buffer_if *msg3,
     /* Terminate signature with a '0' - cheating, but should be ok */
     m.sig[m.siglen]=0;
     if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
-       slog(st,LOG_SECURITY,"msg3 signature failed check!");
+       slog(st,LOG_SEC,"msg3 signature failed check!");
        return False;
     }
 
@@ -420,19 +421,19 @@ static bool_t process_msg4(struct site *st, struct buffer_if *msg4,
     /* Check that the site names and nonces have been sent back
        correctly */
     if (memcmp(m.remote,st->remotename,strlen(st->remotename)!=0)) {
-       slog(st,LOG_SECURITY,"msg4: bad B (remote site name)");
+       slog(st,LOG_SEC,"msg4: bad B (remote site name)");
        return False;
     }
     if (memcmp(m.local,st->localname,strlen(st->localname)!=0)) {
-       slog(st,LOG_SECURITY,"msg4: bad A (local site name)");
+       slog(st,LOG_SEC,"msg4: bad A (local site name)");
        return False;
     }
     if (memcmp(m.nR,st->remoteN,NONCELEN)!=0) {
-       slog(st,LOG_SECURITY,"msg4: bad nB (remotely generated nonce)");
+       slog(st,LOG_SEC,"msg4: bad nB (remotely generated nonce)");
        return False;
     }
     if (memcmp(m.nL,st->localN,NONCELEN)!=0) {
-       slog(st,LOG_SECURITY,"msg4: bad nA (locally generated nonce)");
+       slog(st,LOG_SEC,"msg4: bad nA (locally generated nonce)");
        return False;
     }
     
@@ -443,7 +444,7 @@ static bool_t process_msg4(struct site *st, struct buffer_if *msg4,
     /* Terminate signature with a '0' - cheating, but should be ok */
     m.sig[m.siglen]=0;
     if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
-       slog(st,LOG_SECURITY,"msg4 signature failed check!");
+       slog(st,LOG_SEC,"msg4 signature failed check!");
        return False;
     }
 
@@ -466,12 +467,12 @@ static bool_t generate_msg5(struct site *st)
     BUF_ALLOC(&st->buffer,"site:MSG5");
     /* We are going to add three words to the transformed message */
     buffer_init(&st->buffer,st->transform->max_start_pad+(4*3));
-    *(uint32_t *)buf_append(&st->buffer,4)=LABEL_MSG5;
+    buf_append_uint32(&st->buffer,LABEL_MSG5);
     st->new_transform->forwards(st->new_transform->st,&st->buffer,
                                &transform_err);
-    *(uint32_t *)buf_prepend(&st->buffer,4)=LABEL_MSG5;
-    *(uint32_t *)buf_prepend(&st->buffer,4)=(uint32_t)st;
-    *(uint32_t *)buf_prepend(&st->buffer,4)=st->setup_session_id;
+    buf_prepend_uint32(&st->buffer,LABEL_MSG5);
+    buf_prepend_uint32(&st->buffer,(uint32_t)st);
+    buf_prepend_uint32(&st->buffer,st->setup_session_id);
 
     st->retries=st->setup_retries;
     return True;
@@ -487,11 +488,11 @@ static bool_t unpick_msg0(struct site *st, struct buffer_if *msg0,
                          struct msg0 *m)
 {
     CHECK_AVAIL(msg0,4);
-    m->dest=*(uint32_t *)buf_unprepend(msg0,4);
+    m->dest=buf_unprepend_uint32(msg0);
     CHECK_AVAIL(msg0,4);
-    m->source=*(uint32_t *)buf_unprepend(msg0,4);
+    m->source=buf_unprepend_uint32(msg0);
     CHECK_AVAIL(msg0,4);
-    m->type=*(uint32_t *)buf_unprepend(msg0,4);
+    m->type=buf_unprepend_uint32(msg0);
     return True;
     /* Leaves transformed part of buffer untouched */
 }
@@ -507,13 +508,13 @@ static bool_t process_msg5(struct site *st, struct buffer_if *msg5,
     if (st->new_transform->reverse(st->new_transform->st,
                                   msg5,&transform_err)) {
        /* There's a problem */
-       slog(st,LOG_SECURITY,"process_msg5: transform: %s",transform_err);
+       slog(st,LOG_SEC,"process_msg5: transform: %s",transform_err);
        return False;
     }
     /* Buffer should now contain untransformed PING packet data */
     CHECK_AVAIL(msg5,4);
-    if ((*(uint32_t *)buf_unprepend(msg5,4))!=LABEL_MSG5) {
-       slog(st,LOG_SECURITY,"MSG5/PING packet contained invalid data");
+    if (buf_unprepend_uint32(msg5)!=LABEL_MSG5) {
+       slog(st,LOG_SEC,"MSG5/PING packet contained invalid data");
        return False;
     }
     CHECK_EMPTY(msg5);
@@ -527,12 +528,12 @@ static bool_t generate_msg6(struct site *st)
     BUF_ALLOC(&st->buffer,"site:MSG6");
     /* We are going to add three words to the transformed message */
     buffer_init(&st->buffer,st->transform->max_start_pad+(4*3));
-    *(uint32_t *)buf_append(&st->buffer,4)=LABEL_MSG6;
+    buf_append_uint32(&st->buffer,LABEL_MSG6);
     st->new_transform->forwards(st->new_transform->st,&st->buffer,
                                &transform_err);
-    *(uint32_t *)buf_prepend(&st->buffer,4)=LABEL_MSG6;
-    *(uint32_t *)buf_prepend(&st->buffer,4)=(uint32_t)st;
-    *(uint32_t *)buf_prepend(&st->buffer,4)=st->setup_session_id;
+    buf_prepend_uint32(&st->buffer,LABEL_MSG6);
+    buf_prepend_uint32(&st->buffer,(uint32_t)st);
+    buf_prepend_uint32(&st->buffer,st->setup_session_id);
 
     st->retries=1; /* Peer will retransmit MSG5 if necessary */
     return True;
@@ -549,13 +550,13 @@ static bool_t process_msg6(struct site *st, struct buffer_if *msg6,
     if (st->new_transform->reverse(st->new_transform->st,
                                   msg6,&transform_err)) {
        /* There's a problem */
-       slog(st,LOG_SECURITY,"process_msg6: transform: %s",transform_err);
+       slog(st,LOG_SEC,"process_msg6: transform: %s",transform_err);
        return False;
     }
     /* Buffer should now contain untransformed PING packet data */
     CHECK_AVAIL(msg6,4);
-    if ((*(uint32_t *)buf_unprepend(msg6,4))!=LABEL_MSG6) {
-       slog(st,LOG_SECURITY,"MSG6/PONG packet contained invalid data");
+    if (buf_unprepend_uint32(msg6)!=LABEL_MSG6) {
+       slog(st,LOG_SEC,"MSG6/PONG packet contained invalid data");
        return False;
     }
     CHECK_EMPTY(msg6);
@@ -584,11 +585,11 @@ static bool_t process_msg0(struct site *st, struct buffer_if *msg0,
     if (st->current_transform->reverse(st->current_transform->st,
                                       msg0,&transform_err)) {
        /* There's a problem */
-       slog(st,LOG_SECURITY,"transform: %s",transform_err);
+       slog(st,LOG_SEC,"transform: %s",transform_err);
        return False;
     }
     CHECK_AVAIL(msg0,4);
-    type=*(uint32_t *)buf_unprepend(msg0,4);
+    type=buf_unprepend_uint32(msg0);
     switch(type) {
     case LABEL_MSG9:
        /* Deliver to netlink layer */
@@ -596,7 +597,7 @@ static bool_t process_msg0(struct site *st, struct buffer_if *msg0,
        return True;
        break;
     default:
-       slog(st,LOG_SECURITY,"incoming message of type %08x (unknown)",type);
+       slog(st,LOG_SEC,"incoming message of type %08x (unknown)",type);
        break;
     }
     return False;
@@ -605,9 +606,9 @@ static bool_t process_msg0(struct site *st, struct buffer_if *msg0,
 static void dump_packet(struct site *st, struct buffer_if *buf,
                        struct sockaddr_in *addr, bool_t incoming)
 {
-    uint32_t dest=*(uint32_t *)buf->start;
-    uint32_t source=*(uint32_t *)(buf->start+4);
-    uint32_t msgtype=*(uint32_t *)(buf->start+8);
+    uint32_t dest=ntohl(*(uint32_t *)buf->start);
+    uint32_t source=ntohl(*(uint32_t *)(buf->start+4));
+    uint32_t msgtype=ntohl(*(uint32_t *)(buf->start+8));
 
     if (st->log_events & LOG_DUMP)
        log(st->log,0,"(%s,%s): %s: %08x<-%08x: %08x:",
@@ -887,12 +888,12 @@ static void site_outgoing(void *sst, void *cid, struct buffer_if *buf)
        a valid key and a valid address to send it to. */
     if (st->current_valid && st->peer_valid) {
        /* Transform it and send it */
-       *(uint32_t *)buf_prepend(buf,4)=LABEL_MSG9;
+       buf_prepend_uint32(buf,LABEL_MSG9);
        st->current_transform->forwards(st->current_transform->st,
                                        buf, &transform_err);
-       *(uint32_t *)buf_prepend(buf,4)=LABEL_MSG0;
-       *(uint32_t *)buf_prepend(buf,4)=(uint32_t)st;
-       *(uint32_t *)buf_prepend(buf,4)=st->remote_session_id;
+       buf_prepend_uint32(buf,LABEL_MSG0);
+       buf_prepend_uint32(buf,(uint32_t)st);
+       buf_prepend_uint32(buf,st->remote_session_id);
        st->comm->sendmsg(st->comm->st,buf,&st->peer);
        BUF_FREE(buf);
        return;
@@ -918,7 +919,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
                            struct sockaddr_in *source)
 {
     struct site *st=sst;
-    uint32_t dest=*(uint32_t *)buf->start;
+    uint32_t dest=ntohl(*(uint32_t *)buf->start);
 
     if (dest==0) {
        if (buf->size<(st->setupsiglen+8+NONCELEN)) return False;
@@ -971,7 +972,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
        return False; /* Not for us. */
     }
     if (dest==(uint32_t)st) {
-       uint32_t msgtype=*(uint32_t *)(buf->start+8);
+       uint32_t msgtype=ntohl(*(uint32_t *)(buf->start+8));
        /* Explicitly addressed to us */
        if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
        switch (msgtype) {
@@ -981,7 +982,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
        case LABEL_MSG1:
            /* Setup packet: should not have been explicitly addressed
               to us */
-           slog(st,LOG_SECURITY,"incoming explicitly addressed msg1");
+           slog(st,LOG_SEC,"incoming explicitly addressed msg1");
            break;
        case LABEL_MSG2:
            /* Setup packet: expected only in state SENTMSG1 */
@@ -990,7 +991,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
            } else if (process_msg2(st,buf,source))
                enter_state_sentmsg3(st);
            else {
-               slog(st,LOG_SECURITY,"invalid MSG2");
+               slog(st,LOG_SEC,"invalid MSG2");
            }
            break;
        case LABEL_MSG3:
@@ -1000,7 +1001,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
            } else if (process_msg3(st,buf,source))
                enter_state_sentmsg4(st);
            else {
-               slog(st,LOG_SECURITY,"invalid MSG3");
+               slog(st,LOG_SEC,"invalid MSG3");
            }
            break;
        case LABEL_MSG4:
@@ -1010,7 +1011,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
            } else if (process_msg4(st,buf,source))
                enter_state_sentmsg5(st);
            else {
-               slog(st,LOG_SECURITY,"invalid MSG4");
+               slog(st,LOG_SEC,"invalid MSG4");
            }
            break;
        case LABEL_MSG5:
@@ -1025,7 +1026,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
            } else if (process_msg5(st,buf,source)) {
                send_msg6(st);
            } else {
-               slog(st,LOG_SECURITY,"invalid MSG5");
+               slog(st,LOG_SEC,"invalid MSG5");
            }
            break;
        case LABEL_MSG6:
@@ -1036,7 +1037,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
                BUF_FREE(&st->buffer); /* Free message 5 */
                activate_new_key(st);
            } else {
-               slog(st,LOG_SECURITY,"invalid MSG6");
+               slog(st,LOG_SEC,"invalid MSG6");
            }
            break;
        case LABEL_MSG8:
@@ -1044,7 +1045,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf,
            slog(st,LOG_ERROR,"received a NAK");
            break;
        default:
-           slog(st,LOG_SECURITY,"received message of unknown type 0x%08x",
+           slog(st,LOG_SEC,"received message of unknown type 0x%08x",
                 msgtype);
            break;
        }
@@ -1116,7 +1117,7 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->wait_timeout=dict_read_number(dict,"wait-time",
                                      False,"site",loc,DEFAULT_WAIT_TIME);
     /* XXX should be configurable */
-    st->log_events=LOG_SECURITY|LOG_ERROR|
+    st->log_events=LOG_SEC|LOG_ERROR|
        LOG_ACTIVATE_KEY|LOG_TIMEOUT_KEY|LOG_SETUP_INIT|LOG_SETUP_TIMEOUT;
 
     st->tunname=safe_malloc(strlen(st->localname)+strlen(st->remotename)+5,
@@ -1124,6 +1125,7 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
 
     /* The information we expect to see in incoming messages of type 1 */
+    /* XXX fix this bit for unaligned access */
     st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
     st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
     *(uint32_t *)&(st->setupsig[0])=LABEL_MSG1;
index f94f5ae5571a19073017a3c8d5c16bb380c91beb..174beda7dd874cdd91117d3356f3ba12707eeb8d 100644 (file)
 #include "secnet.h"
 #include "util.h"
 #include "serpent.h"
+#include "unaligned.h"
 
 /* Required key length in bytes */
 #define REQUIRED_KEYLEN ((512+64+32)/8)
 
+#ifdef WORDS_BIGENDIAN
+static inline uint32_t byteswap(uint32_t a)
+{
+    return
+       ((a&0x000000ff)<<24) |
+       ((a&0x0000ff00)<<8) |
+       ((a&0x00ff0000)>>8) |
+       ((a&0xff000000)>>24);
+}
+#endif
+
 struct transform {
     closure_t cl;
     uint32_t line;
@@ -58,9 +70,9 @@ static bool_t transform_setkey(void *sst, uint8_t *key, uint32_t keylen)
 
     serpent_makekey(&ti->cryptkey,256,key);
     serpent_makekey(&ti->mackey,256,key+32);
-    ti->cryptiv=*(uint32_t *)(key+64);
-    ti->maciv=*(uint32_t *)(key+68);
-    ti->sendseq=*(uint32_t *)(key+72);
+    ti->cryptiv=ntohl(*(uint32_t *)(key+64));
+    ti->maciv=ntohl(*(uint32_t *)(key+68));
+    ti->sendseq=ntohl(*(uint32_t *)(key+72));
     ti->lastrecvseq=ti->sendseq;
     ti->keyed=True;
 
@@ -93,7 +105,7 @@ static uint32_t transform_forward(void *sst, struct buffer_if *buf,
     }
 
     /* Sequence number */
-    *(uint32_t *)buf_prepend(buf,4)=htonl(ti->sendseq);
+    buf_prepend_uint32(buf,ti->sendseq);
     ti->sendseq++;
 
     /* PKCS5, stolen from IWJ */
@@ -119,13 +131,26 @@ static uint32_t transform_forward(void *sst, struct buffer_if *buf,
        block encrypted once again. */
     for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
     {
+#ifdef WORDS_BIGENDIAN
+       macplain[0]=macacc[0]^byteswap(n[0]);
+       macplain[1]=macacc[1]^byteswap(n[1]);
+       macplain[2]=macacc[2]^byteswap(n[2]);
+       macplain[3]=macacc[3]^byteswap(n[3]);
+#else
        macplain[0]=macacc[0]^n[0];
        macplain[1]=macacc[1]^n[1];
        macplain[2]=macacc[2]^n[2];
        macplain[3]=macacc[3]^n[3];
+#endif
        serpent_encrypt(&ti->mackey,macplain,macacc);
     }
     serpent_encrypt(&ti->mackey,macacc,macacc);
+#ifdef WORDS_BIGENDIAN
+    macacc[0]=byteswap(macacc[0]);
+    macacc[1]=byteswap(macacc[1]);
+    macacc[2]=byteswap(macacc[2]);
+    macacc[3]=byteswap(macacc[3]);
+#endif
     memcpy(buf_append(buf,16),macacc,16);
 
     /* Serpent-CBC. We expand the ID as for CBCMAC, do the encryption,
@@ -139,15 +164,22 @@ static uint32_t transform_forward(void *sst, struct buffer_if *buf,
     p=iv;
     for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
     {
+#ifdef WORDS_BIGENDIAN
+       n[0]=byteswap(p[0]^n[0]);
+       n[1]=byteswap(p[1]^n[1]);
+       n[2]=byteswap(p[2]^n[2]);
+       n[3]=byteswap(p[3]^n[3]);
+#else
        n[0]=p[0]^n[0];
        n[1]=p[1]^n[1];
        n[2]=p[2]^n[2];
        n[3]=p[3]^n[3];
+#endif
        serpent_encrypt(&ti->cryptkey,n,n);
        p=n;
     }
 
-    *(uint32_t *)buf_prepend(buf,4)=ti->cryptiv;
+    buf_prepend_uint32(buf,ti->cryptiv);
     ti->cryptiv++;
 
     return 0;
@@ -175,17 +207,24 @@ static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
 
     /* CBC */
     memset(iv,0,16);
-    iv[0]=*(uint32_t *)buf_unprepend(buf,4);
+    iv[0]=buf_unprepend_uint32(buf);
     serpent_encrypt(&ti->cryptkey,iv,iv);
     /* XXX assert bufsize is multiple of blocksize */
     for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
     {
        pct[0]=n[0]; pct[1]=n[1]; pct[2]=n[2]; pct[3]=n[3];
        serpent_decrypt(&ti->cryptkey,n,n);
+#ifdef WORDS_BIGENDIAN
+       n[0]=byteswap(iv[0]^n[0]);
+       n[1]=byteswap(iv[1]^n[1]);
+       n[2]=byteswap(iv[2]^n[2]);
+       n[3]=byteswap(iv[3]^n[3]);
+#else
        n[0]=iv[0]^n[0];
        n[1]=iv[1]^n[1];
        n[2]=iv[2]^n[2];
        n[3]=iv[3]^n[3];
+#endif
        iv[0]=pct[0]; iv[1]=pct[1]; iv[2]=pct[2]; iv[3]=pct[3];
     }
 
@@ -199,13 +238,26 @@ static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
        block encrypted once again. */
     for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
     {
+#ifdef WORDS_BIGENDIAN
+       macplain[0]=macacc[0]^byteswap(n[0]);
+       macplain[1]=macacc[1]^byteswap(n[1]);
+       macplain[2]=macacc[2]^byteswap(n[2]);
+       macplain[3]=macacc[3]^byteswap(n[3]);
+#else
        macplain[0]=macacc[0]^n[0];
        macplain[1]=macacc[1]^n[1];
        macplain[2]=macacc[2]^n[2];
        macplain[3]=macacc[3]^n[3];
+#endif
        serpent_encrypt(&ti->mackey,macplain,macacc);
     }
     serpent_encrypt(&ti->mackey,macacc,macacc);
+#ifdef WORDS_BIGENDIAN
+    macacc[0]=byteswap(macacc[0]);
+    macacc[1]=byteswap(macacc[1]);
+    macacc[2]=byteswap(macacc[2]);
+    macacc[3]=byteswap(macacc[3]);
+#endif
     if (memcmp(macexpected,macacc,16)!=0) {
        *errmsg="invalid MAC";
        return 1;
@@ -230,7 +282,7 @@ static uint32_t transform_reverse(void *sst, struct buffer_if *buf,
 
     /* Sequence number must be within max_skew of lastrecvseq; lastrecvseq
        is only allowed to increase. */
-    seqnum=ntohl(*(uint32_t *)buf_unprepend(buf,4));
+    seqnum=buf_unprepend_uint32(buf);
     skew=seqnum-ti->lastrecvseq;
     if (skew<10) {
        /* Ok */
diff --git a/unaligned.h b/unaligned.h
new file mode 100644 (file)
index 0000000..45b0d3c
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef unaligned_h
+#define unaligned_h
+
+/* Parts of the secnet key-exchange protocol require access to
+   unaligned big-endian quantities in buffers. These macros provide
+   convenient access, even on architectures that don't support unaligned
+   accesses. */
+
+#define put_uint32(a,v) do { (a)[0]=(v)>>24; (a)[1]=((v)&0xff0000)>>16; \
+(a)[2]=((v)&0xff00)>>8; (a)[3]=(v)&0xff; } while(0)
+
+#define put_uint16(a,v) do {(a)[0]=((v)&0xff00)>>8; (a)[1]=(v)&0xff;} while(0)
+
+#define get_uint32(a) (((a)[0]<<24)|((a)[1]<<16)|((a)[2])<<8|(a)[3])
+
+#define get_uint16(a) (((a)[0]<<8)|(a)[1])
+
+#define buf_append_uint32(buf,v) do { uint8_t *c=buf_append((buf),4); \
+    put_uint32(c,(v)); } while(0)
+
+#define buf_append_uint16(buf,v) do { uint8_t *c=buf_append((buf),2); \
+       put_uint16(c,(v)); } while(0)
+
+#define buf_prepend_uint32(buf,v) do { uint8_t *c=buf_prepend((buf),4); \
+           put_uint32(c,(v)); } while(0)
+
+#define buf_prepend_uint16(buf,v) do { uint8_t *c=buf_prepend((buf),2); \
+               put_uint16(c,(v)); } while(0)
+
+#define buf_unappend_uint32(buf) ({uint8_t *c=buf_unappend((buf),4); \
+                   get_uint32(c);})
+
+#define buf_unappend_uint16(buf) ({uint8_t *c=buf_unappend((buf),2); \
+                       get_uint16(c);})
+
+#define buf_unprepend_uint32(buf) ({uint8_t *c=buf_unprepend((buf),4); \
+                       get_uint32(c);})
+
+#define buf_unprepend_uint16(buf) ({uint8_t *c=buf_unprepend((buf),2); \
+                       get_uint16(c);})
+
+#endif /* unaligned_h */
diff --git a/util.c b/util.c
index 19293834dc635c91c1a9db21d640090aab1a8af8..c652537704333f55ded4eb8890ece6f29d0d7f2b 100644 (file)
--- a/util.c
+++ b/util.c
 #include <errno.h>
 #include <syslog.h>
 #include <unistd.h>
-#include <values.h>
+#include <limits.h>
 #include <assert.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include "util.h"
 #include "secnet.h"
+#include "unaligned.h"
 
 #define MIN_BUFFER_SIZE 64
 #define DEFAULT_BUFFER_SIZE 4096
@@ -522,7 +523,7 @@ void buf_append_string(struct buffer_if *buf, string_t s)
     uint16_t len;
 
     len=strlen(s);
-    *(uint16_t *)buf_append(buf,2)=htons(len);
+    buf_append_uint16(buf,len);
     memcpy(buf_append(buf,len),s,len);
 }