W dniu 12.03.2019 o 15:19, Otto Moerbeek pisze:
On Tue, Mar 12, 2019 at 02:02:15PM +0100, Otto Moerbeek wrote:

On Mon, Mar 11, 2019 at 05:11:56PM +0100, Otto Moerbeek wrote:

I was going to test your diff but it does not apply. Your mailer seems
to convert spaces and or tabs to funny char sequences. Please fix
(test by mailing to yourself and applying with patch(1)) and resend,

        -Otto

So I reworked the diff to apply and use the proper formatting
(regulart sapces and tabs instead of UTF-8 non breaking spaces).

I also fixed a case of parsing IPv6 addresses.

Anyone willing to ok?
And now also with a lexer bug fixed.  Earlier I thougt it was an order
dependency in the clauses. But is was an order dependency in comment
lines and empty lines.

        -Otto


Index: conf.y
===================================================================
RCS file: /cvs/src/usr.sbin/sasyncd/conf.y,v
retrieving revision 1.19
diff -u -p -r1.19 conf.y
--- conf.y      9 Apr 2017 02:40:24 -0000       1.19
+++ conf.y      12 Mar 2019 14:16:23 -0000
@@ -30,8 +30,10 @@
  #include <sys/types.h>
  #include <sys/stat.h>
  #include <sys/socket.h>
+#include <arpa/inet.h>
  #include <ctype.h>
  #include <fcntl.h>
+#include <ifaddrs.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
@@ -48,6 +50,7 @@ struct cfgstate       cfgstate;
  int   conflen = 0;
  char  *confbuf, *confptr;
+int check_peer_addr(const char *);
  int   yyparse(void);
  int   yylex(void);
  void  yyerror(const char *);
@@ -172,17 +175,8 @@ setting            : INTERFACE STRING
                | PEER STRING
                {
                        struct syncpeer *peer;
-                       int              duplicate = 0;
- for (peer = LIST_FIRST(&cfgstate.peerlist); peer;
-                            peer = LIST_NEXT(peer, link))
-                               if (strcmp($2, peer->name) == 0) {
-                                       duplicate++;
-                                       break;
-                               }
-                       if (duplicate)
-                               free($2);
-                       else {
+                       if (check_peer_addr($2)) {
                                peer = calloc(1, sizeof *peer);
                                if (!peer) {
                                        log_err("config: calloc(1, %lu) "
@@ -191,10 +185,11 @@ setting           : INTERFACE STRING
                                        YYERROR;
                                }
                                peer->name = $2;
-                       }
-                       LIST_INSERT_HEAD(&cfgstate.peerlist, peer, link);
-                       cfgstate.peercnt++;
-                       log_msg(2, "config: add peer %s", peer->name);
+                               LIST_INSERT_HEAD(&cfgstate.peerlist, peer, 
link);
+                               cfgstate.peercnt++;
+                               log_msg(2, "config: add peer %s", peer->name);
+                       } else
+                               free($2);
                }
                | LISTEN ON STRING af port
                {
@@ -284,6 +279,72 @@ match(char *token)
  }
int
+check_peer_addr(const char *peer_addr)
+{
+       int valid = 1;
+       short peer_family = AF_UNSPEC;
+       struct ifaddrs *ifap = NULL, *ifa;
+       struct syncpeer *peer;
+       struct sockaddr_in sa;
+       struct sockaddr_in6 sa6;
+
+       if (inet_pton(AF_INET, peer_addr, &sa.sin_addr) == 1)
+               peer_family = AF_INET;
+
+       if (peer_family == AF_UNSPEC && inet_pton(AF_INET6, peer_addr,
+           &sa6.sin6_addr) == 1)
+               peer_family = AF_INET6;
+
+       if (peer_family == AF_UNSPEC) {
+               log_msg(2, "config: skip unparseable peer %s", peer_addr);
+               valid = 0;
+       }
+
+       if (valid && getifaddrs(&ifap) == 0) {
+               for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+                       if (!ifa->ifa_addr || ifa->ifa_addr->sa_family !=
+                           peer_family)
+                               continue;
+
+                       switch (ifa->ifa_addr->sa_family) {
+                       case AF_INET:
+                               if (memcmp(&sa.sin_addr,
+                                   &((struct sockaddr_in 
*)ifa->ifa_addr)->sin_addr,
+                                   sizeof(struct in_addr)) == 0)
+                                       valid = 0;
+                               break;
+                       case AF_INET6:
+                               if (memcmp(&sa6.sin6_addr,
+                                   &((struct sockaddr_in6 
*)ifa->ifa_addr)->sin6_addr,
+                                   sizeof(struct in6_addr)) == 0)
+                                       valid = 0;
+                               break;
+                       }
+
+                       if (!valid) {
+                               log_msg(2, "config: skip local peer %s",
+                                   peer_addr);
+                               break;
+                       }
+               }
+               freeifaddrs(ifap);
+       }
+
+       if (valid) {
+               for (peer = LIST_FIRST(&cfgstate.peerlist); peer;
+                       peer = LIST_NEXT(peer, link)) {
+                       if (strcmp(peer_addr, peer->name) == 0) {
+                               log_msg(2, "config: skip duplicate peer %s",
+                                   peer_addr);
+                               valid = 0;
+                       }
+               }
+       }
+
+       return valid;
+}
+
+int
  yylex(void)
  {
        char *p;
@@ -325,7 +386,7 @@ yylex(void)
        /* Numerical token? */
        if (isdigit(*confptr)) {
                for (p = confptr; *p; p++)
-                       if (*p == '.') /* IP address, or bad input */
+                       if (*p == '.' || *p == ':') /* IP address, or bad input 
*/
                                goto is_string;
                v = (int)strtol(confptr, (char **)NULL, 10);
                yylval.val = v;
@@ -397,6 +458,9 @@ conf_parse_file(char *cfgfile)
                if (*s == '#') {
                        while (*s != '\n' && s < buf + conflen)
                                s++;
+                       while (*s == '\n' && s < buf + conflen)
+                               s++;
+                       s--;
                        continue;
                }
                if (d == buf && isspace(*s))


Hi all,

What are the next steps to push it forward ?

Best regards
M.K.

Reply via email to