Fatal trap 12 in binding V6 socket in FreeBSD 5.1-p2

Jan Mikael Melen jmgm at iki.fi
Fri Sep 5 03:06:23 PDT 2003


On Friday 05 September 2003 12:54, Simon L. Nielsen wrote:
> On 2003.09.05 12:51:14 +0300, Jan Mikael Melen wrote:
> > > I've included as an attachment a patch that I have used to fix the
> > > problem and allso as attached a short program which can be used to
> > > regenerate the problem in unpatched FreeBSD 5.1-p2.
> >
> > Oops.... Forgot the other attachment...
>
> The attachement at least didn't make it to the FreeBSD-net list.  This
> might be useful:
>
> http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/eresources.html#E
>RESOURCES-MAILFILTERING

Well let's put it in plain text because c-source files seems to be filtered 
away on freebsd-net list...

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <err.h>

static void
usage(char *progname) {
    fprintf(stderr, "Usage: %s ip port\n", progname);
    exit (1);
}

int main(int argc, char *argv[]) {

  int s1, s2, s3, len, ret, fromlen, i;
  char buf[1024];
  struct sockaddr_storage ss0;
  struct sockaddr_in6 *sin60 = (struct sockaddr_in6 *)&ss0;
  struct sockaddr_storage ss;
  char *progname = argv[0];
  char *scope;
    
  if (argc != 3)
    usage(progname);
  
  memset(&ss0, 0, sizeof(ss0));
  
  sin60->sin6_len = sizeof(struct sockaddr_in6);
  sin60->sin6_family = AF_INET6;
  sin60->sin6_port = htons(atoi(argv[2]));
    scope = strchr(argv[1], '%');
    if (scope) {
      *scope++ = 0;
      sin60->sin6_scope_id = atoi(scope);
    }
    ret = inet_pton(AF_INET6, argv[1], &sin60->sin6_addr.s6_addr);
    if (ret <= 0) {
        err(1, "%s: %s", progname, "inet_pton");
    }

    if(fork()) {

        for(i=0; i<2; i++) {
            sleep(1);
            
            s1 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
            if (s1 < 0) {
                err(1, "%s: %s", progname, "socket");
            }
            
            ret = connect(s1, (struct sockaddr *)&ss0, ss0.ss_len);
            if (ret < 0) {
                err(1, "%s: %s", progname, "connect");
            }
            
            len = sizeof(ss);
            ret = getsockname(s1, (struct sockaddr *)&ss, &len);
            if (ret < 0) {
                err(1, "%s: %s", progname, "getsockname");
            }
            
            ret = send(s1, &ss, ss.ss_len, 0);
            if (ret < 0) {
                err(1, "%s: %s", progname, "send");
            }
            
            close(s1);
        }
    } else {

      for(i=0; i<2; i++) {
        s2 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
        if (s2 < 0) {
            err(1, "%s: %s", progname, "socket");
        }

        ret = bind(s2, (struct sockaddr *)&ss0, ss0.ss_len);
        if (ret < 0) {
            err(1, "%s: %s", progname, "bind");
        }

        listen(s2, 5);

        fromlen = sizeof(ss);
        if((s3 = accept(s2, (struct sockaddr *)&ss, &fromlen)) > 0) {

            ret = recv(s3, buf, 1024, 0);
            if (ret < 0) {
               err(1, "%s: %s", progname, "recv");
            } 

            if (memcmp(&buf, &ss, ss.ss_len) != 0) {
                printf("accept->receive: [Failed]\n");
            }

        }

        len = sizeof(ss);
        ret = getpeername(s3, (struct sockaddr *)&ss, &len);
        if (ret < 0) {
            err(1, "%s: %s", progname, "getpeername");
        }

        if (memcmp(&buf, &ss, ss.ss_len) != 0) {
            printf("accept->getpeername: [Failed]\n");
        }

        close(s3);
        close(s2);
        sleep(1);
      }
    }
    
    return 1;
}



More information about the freebsd-net mailing list