]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
log.h:
authorJohannes Maximilian Kuehn <kuehn@ntp.org>
Wed, 10 Sep 2008 22:58:04 +0000 (22:58 +0000)
committerJohannes Maximilian Kuehn <kuehn@ntp.org>
Wed, 10 Sep 2008 22:58:04 +0000 (22:58 +0000)
  fixed missing timestamp for file logging
kod_management.c:
  Fixed the core dump when no kod file is specified
networking.c:
  Some fixes for broadcast mode
  remove filter reachable (no use for this function)
utilities.c:
  Added a function to convert a  struct sockaddr_storage to a string containing its hostname
crypto.c:
  Completeted auth md5 functions

bk: 48c850fcVp8qWyVmdYrAax-y6KW9mQ

12 files changed:
gsoc_sntp/crypto.c
gsoc_sntp/crypto.h
gsoc_sntp/header.h
gsoc_sntp/kod_management.c
gsoc_sntp/kod_management.h
gsoc_sntp/log.c
gsoc_sntp/log.h
gsoc_sntp/main.c
gsoc_sntp/networking.c
gsoc_sntp/networking.h
gsoc_sntp/utilities.c
gsoc_sntp/utilities.h

index 9fba3de878261452cb0a8bbdbe6c32726bb3f814..f3aea7fe96d97a48382b2cd4e670a6271d0d199d 100644 (file)
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #include "crypto.h"
 
+struct key *key_ptr;
 int key_cnt = 0;
 
+/* Generates a md5 digest of the ntp packet (exluding the MAC) concatinated
+ * with the key specified in keyid and compares this digest to the digest in
+ * the packet's MAC. If they're equal this function returns 1 (packet is 
+ * authentic) or else 0 (not authentic).
+ */
 int
 auth_md5 (
-               void *pkt_data,
+               char *pkt_data,
                int mac_size,
-               char *cmp_key,
-               int cmp_size
+               struct key *cmp_key
         )
 {
        register int a;
-       MD5Context ctx;
        char digest[16];
+       MD5_CTX ctx;
+
+       if(cmp_key->type != 'M')
+               return -1;
        
        MD5Init(&ctx);
-       unsigned char *digest_data = (unsigned char *) malloc(sizeof(char) * (LEN_PKT_NOMAC + cmp_size));
 
-       for(a=0; a<LEN_PKT_NOMAC; a++)
-               digest_data[a] = (unsigned char) pkt_data[a];
+       char *digest_data = (char *) malloc(sizeof(char) * (LEN_PKT_NOMAC + cmp_size));
 
-       for(a=0; a<cmp_size; a++)
-               digest_data[LEN_PKT_NOMAC + a] = (unsigned char) cmp_key[a];
+       for(a=0; a<LEN_PKT_NOMAC; a++)
+               digest_data[a] = pkt_data[a];
 
+       for(a=0; a<cmp_key->key_len; a++)
+               digest_data[LEN_PKT_NOMAC + a] = cmp_key->key_seq[a];
 
-       MD5Update(&ctx, digest_data, LEN_PKT_NOMAC + cmp_size);
-       MD5Final(digest, &ctx);
+       MD5Update(&ctx, (unsigned char *)digest_data, LEN_PKT_NOMAC + cmp_key->key_len);
+       MD5Final((unsigned char *)digest, &ctx);
 
        free(digest_data);
 
-       if(strncmp(cmp_key, digest, cmp_size) != 0) {
-               return 0;
-       }
-       else {
-               return 1;
-       }
+       for(a=0; a<16; a++)
+               if(digest[a] != pkt_data[LEN_PKT_MAC + a])
+                       return 0;
+
+       return 1;
 }
 
+/* Load keys from the specified keyfile into the key structures.
+ * Returns -1 if the reading failed, otherwise it returns the 
+ * number of keys it read
+ */
 int
 auth_init (
                char *keyfile,
-               struct key *keys
+               struct key **keys
                )
 {
+       printf("auth_init: %s\n", keyfile);
        char kbuf[96];
        FILE *keyf = fopen(keyfile, "r"); 
-       register int a, line_cnt;
+       register int a, line_cnt, line_limit;
        struct key *prev;
 
        if(keyf == NULL) {
-               /* Do something about it */
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp auth_init: Couldn't open key file %s for reading!\n", keyfile);
+
+               return -1;
        }
 
        line_cnt = 0;
+       
+       if(feof(keyf)) {
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp auth_init: Key file %s is empty!\n", keyfile);
+
+               return -1;
+       }
+
 
        while(!feof(keyf)) {
                struct key *act = (struct key *) malloc(sizeof(struct key));
+               line_limit = 0;
 
                fgets(kbuf, 96, keyf);
 
-               sscanf(fbuf, "%i %c %16s", act->key_id, act->type, act->key_seq);
+               for(a=0; a<strlen(kbuf) && a < 96; a++) {
+                       if(kbuf[a] == '#') {
+                               line_limit = a;
+                               a = 96;
+                       }
+               }
+
+               if(line_limit != 0)
+                       kbuf[line_limit] = '\0';
 
 #ifdef DEBUG
-               printf("auth_init: key_id %i type %c with key %s\n", act->key_id, act->type, act->key_seq);
+               printf("sntp auth_init: fgets: %s", kbuf);
 #endif
 
-               if(line_cnt == 0) {
-                       keys = act;
-                       prev = act;
-               }
-               else {
-                       prev->next = act;
-                       prev = act;
-               }
+               sscanf(kbuf, "%i %c %16s", &act->key_id, &act->type, act->key_seq);
+               act->key_len = strlen(key_seq);
+
+#ifdef DEBUG
+               printf("sntp auth_init: key_id %i type %c with key %s\n", act->key_id, act->type, act->key_seq);
+#endif
 
-               line_cnt++;
+               if(act->type != 0) {
+                       if(line_cnt == 0) {
+                               *keys = act;
+                               prev = act;
+                       }
+                       else {
+                               prev->next = act;
+                               act->next = NULL;
+                               prev = act;
+                       }
+
+                       line_cnt++;
+               }
        }
 
        fclose(keyf);
+       
+#ifdef DEBUG
+       STDLINE
+       printf("sntp auth_init: Read %i keys from file %s:\n", line_cnt, keyfile);
+
+       struct key *kptr = *keys;
+       for(a=0; a<line_cnt; a++) {
+               printf("key_id %i type %c with key %s (key length: %i)\n", kptr->key_id, 
+                               kptr->type, kptr->key_seq, kptr->key_len);
+               kptr = kptr->next;
+       }
+       STDLINE
+#endif
 
        key_cnt = line_cnt;
+       key_ptr = *keys;
 
        return line_cnt;
 }
 
+/* Looks for the key with keyid key_id and sets the d_key pointer to the 
+ * address of the key. If no matching key is found the pointer is not touched.
+ */
+void
+get_key (
+               int key_id,
+               struct key **d_key
+               )
+{
+       register int a;
+       struct key *itr_key = key_ptr;
 
-
-
-
-
+       if(key_cnt == 0)
+               return;
+       
+       for(a=0; a<key_cnt && itr_key != NULL; a++) {
+               if(itr_key->key_id == key_id) {
+                       *d_key = itr_key;
+                       return;
+               }
        }
        
-       rewind(keyf);
-
-
-
+       return;
+}
index 126071893dab8c996518fcc8d17710204d5aa631..ff223c9b4bae4a4c0a77b2aaf543c91ee329e795 100644 (file)
@@ -1,19 +1,49 @@
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #ifndef CRYPTO_H
 #define CRYPTO_H
 
-#include <ntp_md5.h>
 #include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
 
-/* #include "sntp-opts.h" */
+#include <ntp_fp.h>
+#include <ntp.h>
+#include <ntp_md5.h>
+#include <ntp_stdlib.h>
+
+#include "utilities.h"
+#include "sntp-opts.h"
 
-int auth_md5(void *pkt_data, int mac_size, char *cmp_key, int cmp_size);
-int auth_init(char *keyfile, struct key *keys);
+
+/* #include "sntp-opts.h" */
 
 struct key {
-       unsigned int key_id;
+       int key_id;
+       int key_len;
        char type;
        char key_seq[16];
        struct key *next;
 };
 
+int auth_md5(char *pkt_data, int mac_size, char *cmp_key, int cmp_size);
+int auth_init(char *keyfile, struct key **keys);
+void get_key(int key_id, struct key **d_key);
+
+
 #endif
index 1a4b85dc05077a12fab130d191ec58cc8a35f07a..4e3fa9661a10c4120d0734480b7d0e3b9f93ebfc 100644 (file)
@@ -24,6 +24,8 @@ No changes should be needed for any system that is even remotely like Unix. */
 #    define SAVENAME "/etc/sntp.state" /* Stores the recovery state */
 #endif
 
+#define DEBUG
+
 
 
 /* Defined in main.c */
@@ -31,7 +33,7 @@ No changes should be needed for any system that is even remotely like Unix. */
 #define op_client           1          /* Behave as a challenge client */
 #define op_listen           2          /* Behave as a listening client */
 
-extern const char *argv0;
+/* extern const char *argv0;
 
 extern int verbose, operation;
 
@@ -41,7 +43,7 @@ extern void fatal (int syserr, const char *message, const char *insert);
 
 
 
-/* Defined in unix.c */
+ Defined in unix.c */
 
 extern void do_nothing (int seconds);
 
@@ -73,7 +75,7 @@ extern int read_socket (int which, void *packet, int length, int waiting);
 
 extern int flush_socket (int which);
 
-extern void close_socket (int which);
+/* extern void close_socket (int which); */
 
 
 
index 685a4c75c75ae2bd09f0adac1ace850376b95bdb..022d97093fc812ee316714f48a64a05742c0929e 100644 (file)
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 /* TODO check for memory leaks */
 #include <string.h>
 
@@ -12,6 +29,9 @@ struct kod_entry *kod_db;
 FILE *db_s;
 
 
+/*
+ * Search for a KOD entry
+ */
 int
 search_entry (
                char *hostname,
@@ -22,7 +42,7 @@ search_entry (
        struct kod_entry *sptr = kod_db;
 
        for(a=0; a<entryc && sptr; a++) {
-               if(strcmp(sptr->hostname, hostname)) 
+               if(!strcmp(sptr->hostname, hostname)) 
                        resc++;
 
                sptr = sptr->next;
@@ -32,7 +52,7 @@ search_entry (
 
        b=0;
        for(a=0; a<entryc && sptr; a++) {
-               if(strcmp(sptr->hostname, hostname)) {
+               if(!strcmp(sptr->hostname, hostname)) {
                        dst[b] = sptr;
                        b++;
                }
@@ -162,7 +182,7 @@ kod_init_kod_db (
 
        db_s = fopen(db_file, "r");
 
-       if(db_file == NULL) {
+       if(db_s == NULL) {
                char msg[80];
 
                snprintf(msg, 80, "kod_init_kod_db(): Cannot open KOD db file %s", db_file);
@@ -175,7 +195,8 @@ kod_init_kod_db (
                log_msg(msg, 2);
        }
 
-       printf("Starting to read KOD file %s...\n", db_file);
+       if(ENABLED_OPT(NORMALVERBOSE)) 
+               printf("Starting to read KOD file %s...\n", db_file);
        /* First let's see how many entries there are and check for right syntax */
 
        while(!feof(db_s)) {
index fcb22d048ac6f5ecf28bef9f34417d40aedb4df6..e1c6cc71d0e93cd91259ce598ec838656d795a47 100644 (file)
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #ifndef KOD_MANAGEMENT_H
 #define KOD_MANAGEMENT_H
 
@@ -13,7 +30,7 @@ int kod_entry_exists (char *search_str);
 
 void add_entry (char *hostname, char *type);
 void delete_entry (char *hostname, char *type);
-void init_kod_db (char *db_file);
+void kod_init_kod_db (char *db_file);
 void write_kod_db (void);
 void kod_atexit (void);
 
index e511b986f2b1849bfb5b4152464410ca0b84e428..ed62b67a73e7d4ad579079dcdcdb903096fc228f 100644 (file)
@@ -1,4 +1,20 @@
-/* Add timestamps to file logging!!! */
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #include "log.h"
 #include "sntp-opts.h"
 
@@ -10,7 +26,11 @@ FILE *log_file;
 
 void log_msg(char *message, char type) {
        if(init) {
-               fprintf(log_file, message);
+               time_t cur_time = time(NULL);
+               char *timestamp = ctime(&cur_time);
+
+               fprintf(log_file, "%s: %s\n", timestamp, message);
+               fflush(log_file);
        }
        else {
                switch(type) {
@@ -33,8 +53,10 @@ void log_msg(char *message, char type) {
 
 void debug_msg(char *message) {
        if(HAVE_OPT(FILELOG)) {
-               fprintf(stderr, message);
-               fprintf(stderr, "\n");
+               time_t cur_time = time(NULL);
+               char *timestamp = ctime(&cur_time);
+
+               fprintf(stderr, "%s: %s\n", timestamp, message);
        }
        else {
                syslog(LOG_DEBUG | LOG_PERROR | LOG_CONS, message);
@@ -42,7 +64,6 @@ void debug_msg(char *message) {
 }
 
 void init_log(char *logfile) {
-       printf("INIT IST KRIEEEEEG %s!!!\n", logfile);
        log_file = fopen(logfile, "a");
        
        if(log_file == NULL) {
index a17a5227b8d11844df3ceaa3641a839c58811b81..0a8026297274204085105b3b6ab69b509aa1d75f 100644 (file)
@@ -1,3 +1,20 @@
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #ifndef LOG_H
 #define LOG_H
 
@@ -5,9 +22,10 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-
-#include <syslog.h>
 #include <stdarg.h>
+#include <syslog.h>
+#include <time.h>
+
 
 void log_msg(char *message, char type);
 void debug_msg(char *message);
index d0be5f873aebfb31d8e2d792195ac1f8c5bceac7..6c18d5fa66e2ebd0da4cd419a337396204c0082a 100644 (file)
@@ -1,33 +1,32 @@
-#include <ntp_fp.h>
+#include <isc/result.h>
+#include <l_stdlib.h>
 #include <ntp.h>
+#include <ntp_fp.h>
 #include <ntp_stdlib.h>
 #include <ntp_unixtime.h>
-#include <l_stdlib.h>
-#include <isc/result.h>
 #include <stdio.h>
 
 #include <sntp-opts.h>
 
+#include "crypto.h"
 #include "kod_management.h"
 #include "networking.h"
 #include "utilities.h"
 #include "log.h"
 
-#define DEBUG
 
 int ai_fam_pref;
 volatile int debug;
 char adr_buf[INET6_ADDRSTRLEN];
 
+struct key *keys = NULL;
 
 void set_li_vn_mode (struct pkt *spkt, char leap, char version, char mode); 
 int sntp_main (int argc, char **argv);
 int on_wire (struct addrinfo *host);
-void set_li_vn_mode (struct pkt *spkt, char leap, char version, char mode);
 int set_time (double offset);
 
 
-
 int 
 main (
                int argc,
@@ -37,6 +36,9 @@ main (
        return sntp_main(argc, argv);
 }
 
+/*
+ * The actual main function.
+ */
 int  
 sntp_main (
                int argc, 
@@ -60,7 +62,7 @@ sntp_main (
                else if(ENABLED_OPT(IPV6))
                        ai_fam_pref = AF_INET6;
                else 
-                       ai_fam_pref = NULL;
+                       ai_fam_pref = 0;
        }
 
        log_msg("Started sntp", 0);
@@ -82,10 +84,12 @@ sntp_main (
        if(HAVE_OPT(KOD)) {
                kod_init_kod_db((char *)OPT_ARG(KOD));
        }
-       else {
-               kod_init_kod_db("sntp.kod");
+
+       if(HAVE_OPT(KEYFILE)) {
+               auth_init((char *)OPT_ARG(KEYFILE), keys);
        }
 
+
        /* Considering employing a variable that prevents functions of doing anything until 
         * everything is initialized properly 
         */
@@ -157,12 +161,13 @@ on_wire (
 
                error = GETTIMEOFDAY(&tv_xmt, (struct timezone *)NULL);
 
+               tv_xmt.tv_sec += JAN_1970;
+
 #ifdef DEBUG
-               printf("Current time sec: %i msec: %i\n\n", (unsigned int) tv_xmt.tv_sec, 
+               printf("sntp on_wire: Current time sec: %i msec: %i\n", (unsigned int) tv_xmt.tv_sec, 
                                (unsigned int) tv_xmt.tv_usec);
 #endif
 
-               tv_xmt.tv_sec += JAN_1970;
                TVTOTS(&tv_xmt, &xmt);
                HTONL_FP(&xmt, &(x_pkt->xmt));
 
@@ -183,6 +188,8 @@ on_wire (
                else
                        sw_case = rpktl;
 
+               printf("sw_case: %i\n", sw_case);
+
                switch(sw_case) {
                        case SERVER_UNUSEABLE:
                                return -1;
index f0841c60f5f24eccb967e40255dc678fe38c62ce..c76d37bbbbc0129417d05cb5070a77b0ac6c2e08 100644 (file)
@@ -1,8 +1,21 @@
-#include "sntp-opts.h" 
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #include "networking.h"
-#include "header.h"
-#include "utilities.h"
-#include "log.h"
 
 char adr_buf[INET6_ADDRSTRLEN];
 
@@ -33,7 +46,7 @@ resolve_hosts (
                tres[a] = (struct addrinfo **) malloc(sizeof(struct addrinfo));
 
 #ifdef DEBUG
-               printf("Starting host resolution for %s...\n", hosts[a]); 
+               printf("sntp resolve_hosts: Starting host resolution for %s...\n", hosts[a]); 
 #endif
 
                struct addrinfo hints, *dres;
@@ -41,7 +54,7 @@ resolve_hosts (
 
                memset(&hints, 0, sizeof(hints));
 
-               if(pref_family == NULL)
+               if(pref_family == 0)
                        hints.ai_family = PF_UNSPEC;
                else 
                        hints.ai_family = pref_family;
@@ -125,14 +138,16 @@ create_socket (
 {
        *rsock = socket(dest->ss_family, SOCK_DGRAM, 0);
 
-#ifdef DEBUG
        if(*rsock == -1)
-               printf("Failed to create UDP socket with family %i\n", dest->ss_family);
-#endif
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("Failed to create UDP socket with family %i\n", dest->ss_family);
 
 }
 
-/* If there's nothing more to do here we might need this function */
+/* If there's nothing more to do here we might need this function 
+ * Originally I thought about doing some broad-/multicast related
+ * cleaning up here. 
+ */
 void 
 close_socket (
                SOCKET rsock
@@ -151,28 +166,31 @@ sendpkt (
        )
 {
 #ifdef DEBUG
+       printf("sntp sendpkt: Packet data:\n");
        pkt_output(pkt, len, stdout);
-       getnameinfo((struct sockaddr *) dest, dest->ss_len, adr_buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
-
-       printf("\nSending packet to %s...\n", adr_buf);
 #endif
 
-       int cc = sendto(rsock, (char *)pkt, len, 0, (struct sockaddr *)dest, dest->ss_len);
+       if(ENABLED_OPT(NORMALVERBOSE)) {
+               getnameinfo((struct sockaddr *) dest, SOCKLEN(dest), adr_buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
+
+               printf("sntp sendpkt: Sending packet to %s...\n", adr_buf);
+       }
+
+       int cc = sendto(rsock, (char *)pkt, len, 0, (struct sockaddr *)dest, SOCKLEN(dest));
 
        if (cc == SOCKET_ERROR) {
 #ifdef DEBUG
-               printf("Socket error: %i. Couldn't send packet!\n", cc);
+               printf("sntp sendpkt: Socket error: %i. Couldn't send packet!\n", cc);
 #endif
 
                if (errno != EWOULDBLOCK && errno != ENOBUFS) {
 
                }
        }
-#ifdef DEBUG
        else {
-               printf("Packet sent.\n");
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("Packet sent.\n");
        }
-#endif
 }
 
 /* Receive raw data */
@@ -181,25 +199,25 @@ recvdata (
                SOCKET rsock,
                struct sockaddr_storage *sender,
                char *rdata,
-               size_t rdata_length
+               int rdata_length
         )
 {
        socklen_t slen = SOCKLEN(&rsock);
 
 #ifdef DEBUG
-       printf("Trying to receive data from...\n");
+       printf("sntp recvdata: Trying to receive data from...\n");
 #endif
 
        int recvc = recvfrom(rsock, rdata, rdata_length, 0, 
                        (struct sockaddr *) sender, &slen);
 #ifdef DEBUG
-       printf("recvfrom returned...\n");
+       printf("sntp recvdata: recvfrom returned...\n");
 #endif
 
 #ifdef DEBUG
 
        if(recvc > 0) {
-               getnameinfo((struct sockaddr *)sender, sender->ss_len, adr_buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
+               getnameinfo((struct sockaddr *)sender, SOCKLEN(sender), adr_buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
 
                printf("Received %i bytes from %s:\n", recvc, adr_buf);
 
@@ -216,14 +234,322 @@ recvdata (
 /* Receive data from broadcast. Couldn't finish that. Need to do some digging
  * here, especially for protocol independence and IPv6 multicast */
 int 
-recvbcst (
+recv_bcst_data (
+               SOCKET rsock,
+               char *rdata,
+               int rdata_len,
+               struct sockaddr_storage *sas,
+               struct sockaddr_storage *ras
+        )
+{
+       struct timeval timeout_tv;
+       fd_set bcst_fd;
+
+       int btrue = 1;
+       int recv_bytes = 0;
+
+        
+       setsockopt(rsock, SOL_SOCKET, SO_REUSEADDR, &btrue, sizeof(btrue));
+
+       if(sas->ss_family == AF_INET) {
+               struct sockaddr_in sin;
+               struct ip_mreq mdevadr;
+       
+               sin.sin_family = AF_INET;
+               sin.sin_addr.s_addr = htonl(INADDR_ANY);
+               sin.sin_port = htons(123);
+
+               if(bind(rsock, (struct sockaddr *) sas, SOCKLEN(sas)) < 0) {}
+
+
+               if(setsockopt(rsock, IPPROTO_IP, IP_MULTICAST_LOOP, &btrue, sizeof(btrue)) < 0) {
+                       /* some error message regarding setting up multicast loop */
+                       return BROADCAST_FAILED;
+           }
+
+               char *buf = ss_to_str(sas);
+
+               mdevadr.imr_multiaddr.s_addr = inet_addr(buf); 
+               mdevadr.imr_interface.s_addr = htonl(INADDR_ANY);
+
+               if(mdevadr.imr_multiaddr.s_addr == -1) {
+                       if(ENABLED_OPT(NORMALVERBOSE)) {
+                               printf("sntp recv_bcst_data: %s is not a broad-/multicast address, aborting...\n", buf);
+                       }
+                       
+                       return BROADCAST_FAILED;
+               }
+
+               free(buf);
+
+               if (setsockopt(rsock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mdevadr, sizeof(mdevadr)) < 0) {
+                       if(ENABLED_OPT(NORMALVERBOSE)) {
+                               char *buf = ss_to_str(sas);
+
+                               printf("sntp recv_bcst_data: Couldn't add IP membership for %s\n", buf);
+                               
+                               free(buf);
+
+                               return BROADCAST_FAILED;
+                       }
+               }
+       }
+       else if(sas->ss_family == AF_INET6) {
+               struct sockaddr_in6 sin6;
+               struct ipv6_mreq mdevadr;
+
+               sin6.sin6_family = AF_INET6;
+               sin6.sin6_addr = in6addr_any;
+               sin6.sin6_port = htons(123);
+
+               if(bind(rsock, (struct sockaddr *) sas, sizeof(sas)) < 0) {
+                       if(ENABLED_OPT(NORMALVERBOSE))
+                               printf("sntp recv_bcst_data: Couldn't bind() address.\n");
+               }
+
+               if(setsockopt(rsock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &btrue, sizeof (btrue)) < 0) {
+                       /* some error message regarding setting up multicast loop */
+                       return BROADCAST_FAILED;
+           }
+
+               mdevadr.ipv6mr_multiaddr = *((struct in6_addr *) sas);
+               /* FIXME    hat value for ipv6mr_interface?  Use utilities for sock to char op*/
+               /* mdevadr.ipv6mr_interface = in6addr_any; */ 
+                                                                                                                
+               if(!IN6_IS_ADDR_MULTICAST((struct in6_addr *) &mdevadr.ipv6mr_multiaddr)) {
+                       if(ENABLED_OPT(NORMALVERBOSE)) {
+                               char *buf = ss_to_str(sas); 
+
+                               printf("sntp recv_bcst_data: %s is not a broad-/multicast address, aborting...\n", buf);
+                               
+                               free(buf);
+                       }
+                       
+                       return BROADCAST_FAILED;
+               }
+
+               if (setsockopt(rsock, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mdevadr, sizeof(mdevadr)) < 0) {
+                       if(ENABLED_OPT(NORMALVERBOSE)) {
+                               char *buf = ss_to_str(sas); 
+
+                               printf("sntp recv_bcst_data: Couldn't join group for %s\n", buf);
+                               
+                               free(buf);
+
+                               return BROADCAST_FAILED;
+                       }
+               }
+       }
+       
+       FD_ZERO(&bcst_fd);
+       FD_SET(rsock, &bcst_fd);
+
+       if(ENABLED_OPT(TIMEOUT)) 
+               timeout_tv.tv_sec = (int) OPT_ARG(TIMEOUT);
+       else 
+               timeout_tv.tv_sec = 60;
+       
+       switch(select(rsock + 1, &bcst_fd, 0, 0, &timeout_tv)) {
+               FD_CLR(rsock, &bcst_fd);
+               
+               case -1: 
+                       if(ENABLED_OPT(NORMALVERBOSE)) 
+                               printf("sntp recv_bcst_data: select() returned -1, an error occured, aborting.\n");
+
+                       return BROADCAST_FAILED;
+                       break;
+
+               case 0:
+                       if(ENABLED_OPT(NORMALVERBOSE))
+                               printf("sntp recv_bcst_data: select() reached timeout (%i sec), aborting.\n", timeout_tv.tv_sec);
+
+                       return BROADCAST_FAILED;
+                       break;
+
+               default:
+                       socklen_t ss_len = SOCKLEN(ras);
+                       recv_bytes = recvfrom(rsock, rdata, rdata_len, 0, (struct sockaddr *) ras, (socklen_t *) &ss_len);
+       }
+
+       if(recv_bytes == -1) {
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp recv_bcst_data: Failed to receive from broad-/multicast\n");
+
+               return BROADCAST_FAILED;
+       }
+
+       if(sas->ss_family == AF_INET) 
+               setsockopt(rsock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &btrue, sizeof(btrue));
+       else if(sas->ss_family == AF_INET6)
+               setsockopt(rsock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &btrue, sizeof(btrue));
+               
+       return recv_bytes;
+}
+
+int 
+recv_bcst_pkt (
                SOCKET rsock,
                struct pkt *rpkt,
                struct sockaddr_storage *sas
-        )
+               )
 {
+       struct sockaddr_storage sender;
+       register int a;
+       int is_authentic, has_mac, orig_pkt_len;
+
+       char *rdata = (char *) malloc(sizeof(char) * 256);
+
+       int pkt_len = recv_bcst_data(rsock, rdata, 256, sas, &sender);
+
+
+       if(pkt_len < 0)
+               return BROADCAST_FAILED;
 
-       return 0;
+       /* No MAC, no authentication */
+       if(pkt_len == LEN_PKT_NOMAC)
+               has_mac = 0;
+
+       /* If there's more than just the NTP packet it should be a MAC */       
+       else if(pkt_len > LEN_PKT_NOMAC) 
+               has_mac = pkt_len - LEN_PKT_NOMAC;
+       else
+               if(ENABLED_OPT(NORMALVERBOSE)) {
+                       printf("sntp recv_bcst_pkt: Funny packet length: %i. Discarding package.\n", pkt_len);
+                       return PACKET_UNUSEABLE;
+               }
+
+       /* Packet too big */
+       if(pkt_len > LEN_PKT_NOMAC + MAX_MAC_LEN) {
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp recv_bcst_pkt: Received packet is too big (%i bytes), trying again to get a useable packet\n", 
+                                       pkt_len);
+
+               return PACKET_UNUSEABLE;
+       }
+       
+       orig_pkt_len = pkt_len;
+       pkt_len = min(pkt_len, sizeof(struct pkt));
+
+       /* Let's copy the received data to the packet structure */
+       for(a=0; a<pkt_len; a++) 
+               if(a < orig_pkt_len)
+                       ((char *)rpkt)[a] = rdata[a];
+               else
+                       ((char *)rpkt)[a] = 0;
+
+       free(rdata);
+
+       /* MAC could be useable for us */
+       if(has_mac) {
+               /* Two more things that the MAC must conform to */
+               if(has_mac > MAX_MAC_LEN || has_mac % 4 != 0) {
+                       is_authentic = 0; /* Or should we discard this packet? */
+               }
+               else  {
+                       if(has_mac == MAX_MAC_LEN) {
+                               struct key *pkt_key = NULL;
+
+                               /* Look for the key used by the server in the specified keyfile
+                                * and if existent, fetch it or else leave the pointer untouched */
+                               get_key(rpkt->mac[0], &pkt_key);
+
+                               /* Seems like we've got a key with matching keyid */
+                               if(pkt_key != NULL) {
+                                       /* Generate a md5sum of the packet with the key from our keyfile
+                                        * and compare those md5sums */
+                                       if(!auth_md5((char *) rpkt, has_mac, pkt_key)) {
+                                               if(ENABLED_OPT(AUTHENTICATION)) {
+                                                       /* We want a authenticated packet */
+                                                       if(ENABLED_OPT(NORMALVERBOSE)) {
+                                                               char *hostname = ss_to_str(sas);
+                                                               printf("sntp recv_bcst_pkt: Broadcast packet received from %s is not authentic. Will discard this packet.\n", 
+                                                                               hostname);
+
+                                                               free(hostname);
+                                                       }
+                                                       return SERVER_AUTH_FAIL;
+                                               }
+                                               else {
+                                                       /* We don't know if the user wanted authentication so let's 
+                                                        * use it anyways */
+                                                       if(ENABLED_OPT(NORMALVERBOSE)) {
+                                                               char *hostname = ss_to_str(sas);
+                                                               printf("sntp recv_bcst_pkt: Broadcast packet received from %s is not authentic. Authentication not enforced.\n", 
+                                                                               hostname);
+
+                                                               free(hostname);
+                                                       }
+
+                                                       is_authentic = 0;
+                                               }
+                                       }
+                                       else {
+                                               /* Yay! Things worked out! */
+                                               if(ENABLED_OPT(NORMALVERBOSE)) {
+                                                       char *hostname = ss_to_str(sas);
+                                                       printf("sntp recv_bcst_pkt: Broadcast packet received from %s successfully authenticated using key id %i.\n", 
+                                                                       hostname, rpkt->mac[0]);
+
+                                                       free(hostname);
+                                               }
+
+                                               is_authentic = 1;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /* Check for server's ntp version */
+       if(PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION ||
+               PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) {
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp recv_bcst_pkt: Packet shows wrong version (%i)\n", 
+                                       PKT_VERSION(rpkt->li_vn_mode));
+
+               return SERVER_UNUSEABLE;
+       } 
+
+       /* We want a server to sync with */
+       if(PKT_MODE(rpkt->li_vn_mode) != MODE_BROADCAST
+                && PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE) {
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp recv_bcst_pkt: mode %d stratum %i\n",
+                          PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);
+
+               return SERVER_UNUSEABLE;
+       }
+
+       if(rpkt->stratum == STRATUM_PKT_UNSPEC) {
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp recv_bcst_pkt: Stratum unspecified, going to check for KOD (stratum: %i)\n", rpkt->stratum);
+
+               char *ref_char = (char *) &rpkt->refid;
+               
+               /* If it's a KOD packet we'll just use the KOD information */
+               if(ref_char[0] != 'X') {
+                       if(strncmp(ref_char, "DENY", 4))
+                               return KOD_DEMOBILIZE;
+
+                       if(strncmp(ref_char, "RSTR", 4))
+                               return KOD_DEMOBILIZE;
+
+                       if(strncmp(ref_char, "RATE", 4))
+                               return KOD_RATE;
+
+                       /* There are other interesting kiss codes which might be interesting for authentication */
+               }
+       }
+
+       /* If the server is not synced it's not really useable for us */
+       if(PKT_LEAP(rpkt->li_vn_mode) == LEAP_NOTINSYNC) {
+               if(ENABLED_OPT(NORMALVERBOSE)) 
+                       printf("recv_bcst_pkt: Server not in sync, skipping this server\n");
+
+               return SERVER_UNUSEABLE;
+       }
+
+       return pkt_len;
 }
 
 
@@ -238,19 +564,19 @@ recvpkt (
                struct pkt *spkt
        )
 {
+       struct sockaddr_storage sender;
+       char *rdata, done;
+
        register int a;
-       int has_mac, is_authentic;
+       int has_mac, is_authentic, orig_pkt_len;
 
        l_fp org;
 
 
-       struct sockaddr_storage sender;
-       char *rdata, done;
-
        /* Much space, just to be sure */
        rdata = (char *) malloc(sizeof(char) * 512);
 
-       int pkt_length = recvdata(rsock, &sender, rdata, 512);
+       int pkt_len = recvdata(rsock, &sender, rdata, 512);
 
        if(!done) {
                /* Do something about it, first check for a maximum length of ntp packets,
@@ -258,36 +584,42 @@ recvpkt (
                 */
        }
        
-       pkt_length = min(pkt_length, sizeof(struct pkt));
-       
-       for(a=0; a<pkt_length; a++) 
-               ((unsigned char *) rpkt)[a] = rdata[a];
-
        /* Some checks to see if that packet is intended for us */
 
        /* No MAC, no authentication */
-       if(pkt_length == LEN_PKT_NOMAC)
+       if(pkt_len == LEN_PKT_NOMAC)
                has_mac = 0;
 
        /* If there's more than just the NTP packet it should be a MAC */       
-       else if(pkt_length > LEN_PKT_NOMAC) 
-               has_mac = pkt_length - LEN_PKT_NOMAC;
+       else if(pkt_len > LEN_PKT_NOMAC) 
+               has_mac = pkt_len - LEN_PKT_NOMAC;
        
-       else
-               if(debug) {
-                       fprintf(stderr, "recvpkt: Funny packet length: %i. Discarding package.\n", pkt_length);
+       else {
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp recvpkt: Funny packet length: %i. Discarding package.\n", pkt_len);
+
                        return PACKET_UNUSEABLE;
-               }
+       }
 
        /* Packet too big */
-       if(pkt_length > LEN_PKT_MAC) {
+       if(pkt_len > LEN_PKT_MAC) {
                if(ENABLED_OPT(NORMALVERBOSE))
                        printf("sntp recvpkt: Received packet is too big (%i bytes), trying again to get a useable packet\n", 
-                                       pkt_length);
+                                       pkt_len);
 
                return PACKET_UNUSEABLE;
        }
 
+       orig_pkt_len = pkt_len;
+       pkt_len = min(pkt_len, sizeof(struct pkt));
+       
+       for(a=0; a<pkt_len; a++) 
+               /* FIXME! */
+               if(a < orig_pkt_len)
+                       ((char *) rpkt)[a] = rdata[a];
+               else
+                       ((char *) rpkt)[a] = 0;
+
        /* MAC could be useable for us */
        if(has_mac) {
                /* Two more things that the MAC must conform to */
@@ -295,42 +627,105 @@ recvpkt (
                        is_authentic = 0; /* Or should we discard this packet? */
                }
                else  {
-                       /* Do auth stuff */
+                       if(has_mac == MAX_MAC_LEN) {
+                               struct key *pkt_key = NULL;
+                               
+                               /*
+                                * Look for the key used by the server in the specified keyfile
+                                * and if existent, fetch it or else leave the pointer untouched 
+                                */
+                               get_key(rpkt->mac[0], &pkt_key);
+
+                               /* Seems like we've got a key with matching keyid */
+                               if(pkt_key != NULL) {
+                                       /*
+                                        * Generate a md5sum of the packet with the key from our keyfile
+                                        * and compare those md5sums 
+                                        */
+                                       if(!auth_md5((char *) rpkt, has_mac, pkt_key)) {
+                                               if(ENABLED_OPT(AUTHENTICATION)) {
+                                                       /* We want a authenticated packet */
+                                                       if(ENABLED_OPT(NORMALVERBOSE)) {
+                                                               char *hostname = ss_to_str(sas);
+                                                               printf("sntp recvpkt: Broadcast packet received from %s is not authentic. Will discard this packet.\n", 
+                                                                               hostname);
+
+                                                               free(hostname);
+                                                       }
+                                                       return SERVER_AUTH_FAIL;
+                                               }
+                                               else {
+                                                       /* 
+                                                        * We don't know if the user wanted authentication so let's 
+                                                        * use it anyways 
+                                                        */
+                                                       if(ENABLED_OPT(NORMALVERBOSE)) {
+                                                               char *hostname = ss_to_str(sas);
+                                                               printf("sntp recvpkt: Broadcast packet received from %s is not authentic. Authentication not enforced.\n", 
+                                                                               hostname);
+
+                                                               free(hostname);
+                                                       }
+
+                                                       is_authentic = 0;
+                                               }
+                                       }
+                                       else {
+                                               /* Yay! Things worked out! */
+                                               if(ENABLED_OPT(NORMALVERBOSE)) {
+                                                       char *hostname = ss_to_str(sas);
+                                                       printf("sntp recvpkt: Broadcast packet received from %s successfully authenticated using key id %i.\n", 
+                                                                       hostname, rpkt->mac[0]);
+
+                                                       free(hostname);
+                                               }
+
+                                               is_authentic = 1;
+                                       }
+                               }
+                       }
                }
        }
 
        /* Check for server's ntp version */
        if(PKT_VERSION(rpkt->li_vn_mode) < NTP_OLDVERSION ||
                PKT_VERSION(rpkt->li_vn_mode) > NTP_VERSION) {
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp recvpkt: Packet got wrong version (%i)\n", PKT_VERSION(rpkt->li_vn_mode));
+
                return SERVER_UNUSEABLE;
        } 
 
        /* We want a server to sync with */
        if(PKT_MODE(rpkt->li_vn_mode) != MODE_SERVER
                 && PKT_MODE(rpkt->li_vn_mode) != MODE_PASSIVE) {
-#ifdef DEBUG
+               if(ENABLED_OPT(NORMALVERBOSE))
                        printf("sntp recvpkt: mode %d stratum %i\n",
                           PKT_MODE(rpkt->li_vn_mode), rpkt->stratum);
-#endif
+
                return SERVER_UNUSEABLE;
        }
 
+       /* Stratum is unspecified (0) check what's going on */
        if(rpkt->stratum == STRATUM_PKT_UNSPEC) {
                if(ENABLED_OPT(NORMALVERBOSE))
                        printf("sntp recvpkt: Stratum unspecified, going to check for KOD (stratum: %i)\n", rpkt->stratum);
 
 
                char *ref_char = (char *) &rpkt->refid;
+
+               if(ENABLED_OPT(NORMALVERBOSE)) 
+                       printf("sntp recvpkt: Packet refid: %c%c%c%c\n", ref_char[0], ref_char[1], ref_char[2], ref_char[3]);
                
                /* If it's a KOD packet we'll just use the KOD information */
                if(ref_char[0] != 'X') {
-                       if(strncmp(ref_char, "DENY", 4))
+                       if(!strncmp(ref_char, "DENY", 4))
                                return KOD_DEMOBILIZE;
 
-                       if(strncmp(ref_char, "RSTR", 4))
+                       if(!strncmp(ref_char, "RSTR", 4))
                                return KOD_DEMOBILIZE;
 
-                       if(strncmp(ref_char, "RATE", 4))
+                       if(!strncmp(ref_char, "RATE", 4))
                                return KOD_RATE;
 
                        /* There are other interesting kiss codes which might be interesting for authentication */
@@ -345,20 +740,26 @@ recvpkt (
                return SERVER_UNUSEABLE;
        }
 
-
        /*
         * Decode the org timestamp and make sure we're getting a response
         * to our last request. 
         */
-       NTOHL_FP(&rpkt->org, &org);
-       if (!L_ISEQU(&org, &spkt->xmt)) {
-               if (debug)
-                       printf("receive: pkt.org and peer.xmt differ\n");
+
+#ifdef DEBUG
+       printf("rpkt->org:\n");
+       l_fp_output(&rpkt->org, stdout);
+       printf("spkt->xmt:\n");
+       l_fp_output(&spkt->xmt, stdout);
+#endif
+       
+       if (!L_ISEQU(&rpkt->org, &spkt->xmt)) {
+               if(ENABLED_OPT(NORMALVERBOSE))
+                       printf("sntp recvpkt: pkt.org and peer.xmt differ\n");
                
                return PACKET_UNUSEABLE;
        }
 
-       return pkt_length;
+       return pkt_len;
 }
 
 /*
@@ -388,41 +789,3 @@ is_reachable (
        closesocket(sockfd);
        return 1;
 }
-
-int 
-filter_reachable (
-               struct addrinfo **res,
-               int resc
-               )
-{
-       register int a, b;
-       int filter_elements = 0;
-
-       int *index = (int *) malloc(sizeof(int) * resc);
-       
-       for(a=0, b=0; a<resc; a++) {
-               if(is_reachable(res[a])) {
-                       index[b] = a;
-                       b++;
-               }
-       }
-
-       struct addrinfo **cpyres = (struct addrinfo **) malloc(sizeof(struct addrinfo *) * b);
-
-       filter_elements = b+1;
-
-       for(a=0; a<filter_elements; a++) 
-               cpyres[a] = res[index[a]];
-
-
-       for(a=0, b=0; a<resc; a++) {
-               if(a == index[b]) 
-                       b++;
-               else 
-                       freeaddrinfo(res[a]);
-       }
-
-       res = cpyres;
-
-       return filter_elements;
-}
index 2b5e2d26e1c28367e5431a8b88e008b1f9dd1c42..2e3d1ae8ac68c2c5292d8e3708a6dde804640e32 100644 (file)
@@ -1,22 +1,50 @@
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #ifndef NETWORKING_H
 #define NETWORKING_H
 
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
 #include <strings.h>   
 #include <errno.h>
 #include <config.h>
 #include <unistd.h>
-
+#include <sys/types.h>
+#include <sys/socket.h>
 
 #include <ntp_stdlib.h>
 #include <ntp_machine.h>
+#include <ntp_unixtime.h>
 #include <ntp_fp.h>
 #include <ntp.h>
 
+#include "log.h"
+#include "sntp-opts.h" 
+#include "utilities.h"
+
+/* FIXME To be replaced by the constants in ntp.h */
 #define SERVER_UNUSEABLE -1 /* Skip server */
 #define PACKET_UNUSEABLE -2 /* Discard packet and try to get a useable packet again if not tried too often */
 #define SERVER_AUTH_FAIL -3 /* Authentication failed, act upon settings */
 #define KOD_DEMOBILIZE -4   /* KOD packet with code DENY or RSTR, stop all communication and save KOD information */
 #define KOD_RATE -5        /* KOD packet with code RATE, reduce poll intervall */
+#define BROADCAST_FAILED -6
 
 
 /* From ntpdate.c */
@@ -30,11 +58,13 @@ void close_socket (SOCKET rsock);
 
 void sendpkt (SOCKET rsock, struct sockaddr_storage *dest, struct pkt *pkt, int len);
 
-int recvdata (SOCKET rsock, struct sockaddr_storage *sender, char *rdata, size_t rdata_length);
+int recvdata (SOCKET rsock, struct sockaddr_storage *sender, char *rdata, int rdata_len);
 
 int recvpkt (SOCKET rsock, struct pkt *rpkt, struct pkt *spkt);
 
-int recvbcst (SOCKET rsock, struct pkt *rpkt, struct sockaddr_storage *sas);
+int recv_bcst_data (SOCKET rsock, char *rdata, int rdata_len, struct sockaddr_storage *sas, struct sockaddr_storage *ras);
+
+int recv_bcst_pkt (SOCKET rsock, struct pkt *rpkt, struct sockaddr_storage *sas);
 
 /* Shortened peer structure. Not absolutely necessary yet */
 struct speer {
index d6e712243069c7f8db216488e70278459f3fa9b5..722f397c9bb230de93a0d00207702d506d7c3117 100644 (file)
@@ -1,5 +1,25 @@
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #include "utilities.h"
 
+/* Display a NTP packet in hex with leading address offset 
+ * e.g. offset: value, 0: ff 1: fe ... 255: 00
+ */ 
 void 
 pkt_output (
                struct pkt *dpkg,
@@ -28,6 +48,8 @@ pkt_output (
        fprintf(output, HLINE);
 }
 
+/* Output a long floating point value in hex in the style described above 
+ */
 void
 l_fp_output (
                l_fp *ts,
@@ -46,6 +68,8 @@ l_fp_output (
 
 }
 
+/* Output a long floating point value in binary in the style described above
+ */
 void 
 l_fp_output_bin (
                l_fp *ts,
@@ -81,6 +105,8 @@ l_fp_output_bin (
        fprintf(output, HLINE);
 }
 
+/* Output a long floating point value in decimal in the style described above
+ */
 void
 l_fp_output_dec (
                l_fp *ts,
@@ -99,6 +125,9 @@ l_fp_output_dec (
 
 }
 
+/* Convert a struct addrinfo to a string containing the address in style
+ * of inet_ntoa
+ */
 char *
 addrinfo_to_str (
                struct addrinfo *addr
@@ -111,3 +140,20 @@ addrinfo_to_str (
 
        return buf;
 }
+
+/* Convert a struct sockaddr_storage to a string containing the address in
+ * style of inet_ntoa
+ */
+char *
+ss_to_str (
+               struct sockaddr_storage *saddr
+               )
+{
+       char *buf = (char *) malloc(sizeof(char) * INET6_ADDRSTRLEN);
+
+       getnameinfo((struct sockaddr *) saddr, SOCKLEN(saddr), buf,
+                       INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
+
+
+       return buf;
+}
index c943f121eeab88053b1867635b9688bccd87506f..db26db83ec2bc6bc0ab8cbf6b0a1ef8158063170 100644 (file)
@@ -1,3 +1,37 @@
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Copyright (C) 2008  Johannes Maximilian Kühn
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #ifndef UTILITIES_H
 #define UTILITIES_H
 
@@ -18,5 +52,6 @@ void l_fp_output_bin (l_fp *ts, FILE *output);
 void l_fp_output_dec (l_fp *ts, FILE *output);
 
 char *addrinfo_to_str (struct addrinfo *addr);
+char *ss_to_str (struct sockaddr_storage *saddr);
 
 #endif