Mail delivery failed: returning message to sender

Mail Delivery System Mailer-Daemon at pop.de
Mon Aug 21 13:21:55 GMT 2000


This message was created automatically by mail delivery software.

A message that you sent could not be delivered to all of its recipients. The
following address(es) failed:

  tc-wedel.de!monscheu at s023250.tk.tc-wedel.de:
    SMTP error from remote mailer after RCPT TO:
    <tc-wedel.de!monscheu at s023250.tk.tc-wedel.de>:
    host 195.222.202.30 [195.222.202.30]:
    550 relaying to <tc-wedel.de!monscheu at s023250.tk.tc-wedel.de> prohibited by administrator

------ This is a copy of the message, including all the headers. ------

Return-path: <samba-ntdom at samba.org>
Received: from zwitter-nt.hamburg.pop.de ([192.168.1.3] helo=smtpshield.pop.de)
	by virus.pop.de with smtp (Exim 3.02 #1)
	id 13QrWU-00072w-00
	for tc-wedel.de!monscheu at s023250.tk.tc-wedel.de; Mon, 21 Aug 2000 15:21:54 +0200
Received: FROM virus.pop.de BY smtpshield.pop.de ; Fri Aug 21 15:23:44 1998 +0100
Received: from [195.222.210.68] (helo=uucp.hamburg.pop.de)
	by virus.pop.de with esmtp (Exim 3.02 #1)
	id 13QrWT-00072r-00
	for tc-wedel.de!monscheu at s023250.tk.tc-wedel.de; Mon, 21 Aug 2000 15:21:53 +0200
Received: from [203.17.0.92] (helo=samba.org)
	by uucp.hamburg.pop.de with esmtp (Exim 2.054 #1)
	id 13QrWL-000669-00
	for tc-wedel.de!monscheu at s023250.tk.tc-wedel.de; Mon, 21 Aug 2000 15:21:47 +0200
Received: from localhost ([127.0.0.1]:31216 "HELO ") by samba.org with SMTP
	id <S27794170AbQHUNWu>; Mon, 21 Aug 2000 23:22:50 +1000
Message-Id: <39A12C19.52256496 at fy.chalmers.se>
Errors-To: listproc-errors at samba.org
Reply-To: appro at fy.chalmers.se
Originator: samba-ntdom at samba.org
Sender: samba-ntdom at samba.org
Precedence: bulk
From:   Andy Polyakov <appro at fy.chalmers.se>
To:     Multiple recipients of list SAMBA-NTDOM <samba-ntdom at samba.org>
Subject: comments on following (I called it msn_tunnel.c)?
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Listprocessor-Version: 6.0d -- ListProcessor by Anastasios Kotsikonas
X-URL:  http://lists.samba.org/
X-Comment: Discussion of NT domain controller support in Samba
X-Mailer: Mozilla 4.08C-SGI [en] (X11; U; IRIX 6.5 IP32)
Date:   Mon, 21 Aug 2000 23:22:50 +1000

/*
 * I've got tired from trying to get browsing in MSN (Microsoft
 * Neigborhood) work through a router. I even started giving up the
 * belief that it's actually possible... I mean to get one domain
 * working is no problem, but arbitrary mixture of workgroups,
 * domains and OSes seem to be a subject for "Mission Impossible"
 * manuscript writers.
 *
 * So I came up with this crazy idea to tunnel the MSN broadcast
 * traffic between two subnets. The idea can't be simpler. I pick up
 * MSN broadcast traffic off RAW_UDP socket, meaning that I get IP-
 * and UDP-headers along. Then I ship this whole packet to a relay
 * in the other subnet as payload of an UDP packet. Relay does
 * nothing but replaces destination address with local broadcast and
 * simply injects the raw packet (i.e. with the *original*
 * destination address and stuff) into the local wire. Works like a
 * charm! Well, there is one thing that actually doesn't work (at
 * least when the relay runs on a Solaris box). To be specific
 * smbclient isn't capable to resolve names with broadcast... The
 * catch is that bound RAW_UDP socket delivers only datagrams with
 * the *same* destination and source port number. Both Windows and
 * SAMBA nmbd do send such datagrams, but not smbclient:-(
 *
 * Note that the program was written for Solaris and I at this point
 * have no idea if it would work under any other OS.
 *
 * This program is naturally provided "AS IS" with no warranties of
 * any kind.
 *
 * Copyright (c) 2000 Andy Polyakov <appro at fy.chalmers.se>
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <inet/common.h>
#include <netdb.h>
#include <fcntl.h>

struct ip_hdr {
#if defined(_LITTLE_ENDIAN)
    unsigned int ihl:4;
    unsigned int version:4;
#elif defined(_BIG_ENDIAN)
    unsigned int version:4;
    unsigned int ihl:4;
#else
#error "undefined ENDIANness"
#endif
    unsigned char  tos;
    unsigned short tot_len, id, frag_off;
    unsigned char  ttl,     protocol;
    unsigned short check;
    unsigned int   saddr, daddr;
};

struct udp_hdr {
    unsigned short sport,dport,len,check;
};

#define MSN_137   htons(137)
#define MSN_138   htons(138)
#define MSN_RELAY htons(1001)
#define MSN_MTU   1500 /* as large as Ethernet MTU */

main (int argc, char **argv)
{ int raw_udp137,raw_udp138,raw_out,udp,one=1,nrelays,i;
  struct sockaddr_in _addr,*relays;
  struct in_addr bcast;
  struct hostent *hp;
  pid_t pid;

  if (argc < 3)
    fprintf (stderr,"Usage: %s <broadcast-address> <relay-host> ...\n",argv[0]),
    exit (1);

  if ((bcast.s_addr = inet_addr (argv[1])) == (in_addr_t)-1)
  { if (!(hp = gethostbyname (argv[1])))
      fprintf (stderr,"%s: unable to gethostbyname(\"%s\"): %s\n",
                       argv[0],argv[1],strerror(errno)),
      exit (errno);
    if (hp->h_addrtype != AF_INET) /* well, not supposed to return anything else */
      fprintf (stderr,"%s: only IPv4 is supported.\n",argv[0]),
      exit (1);
    memcpy (&(bcast.s_addr),hp->h_addr_list[0],sizeof(bcast.s_addr));
  }

  nrelays = argc-2;
  if ((relays = malloc (nrelays*sizeof(relays[0]))) == NULL)
    fprintf (stderr,"%s: unable to allocate few bytes\n",argv[0]),
    exit(1);

  for (i=0;i<nrelays;i++)
  { if ((relays[i].sin_addr.s_addr = inet_addr (argv[2+i])) == (in_addr_t)-1)
    { if (!(hp = gethostbyname (argv[2+i])))
        fprintf (stderr,"%s: unable to gethostbyname(\"%s\"): %s\n",
                         argv[0],argv[2+i],strerror(errno)),
        exit (errno);
      if (hp->h_addrtype != AF_INET) /* see comment above */
        fprintf (stderr,"%s: only IPv4 is supported\n",argv[0]),
        exit (1);
      memcpy (&(relays[i].sin_addr.s_addr),hp->h_addr_list[0],sizeof(relays[0].sin_addr.s_addr));
    }
    relays[i].sin_family = AF_INET;
    relays[i].sin_port   = MSN_RELAY;
  }


  if ((raw_out = socket (AF_INET,SOCK_RAW,IPPROTO_RAW)) == -1)
    fprintf (stderr,"%s: unable to create IPPROTO_RAW socket: %s\n",
                     argv[0],strerror(errno)),
    exit (errno);

  setsockopt (raw_out,SOL_SOCKET,SO_BROADCAST,(char *)&one,sizeof(one));


  if ((raw_udp137 = socket (AF_INET,SOCK_RAW,IPPROTO_UDP)) == -1)
    fprintf (stderr,"%s: unable to create IPPROTO_UDP socket: %s\n",
                     argv[0],strerror(errno)),
    exit (errno);

  setsockopt (raw_udp137,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));

  _addr.sin_family = AF_INET;
  _addr.sin_addr.s_addr = INADDR_ANY;
  _addr.sin_port   = MSN_137;

  if (bind (raw_udp137,(struct sockaddr *)&_addr,sizeof(_addr)) == -1)
    fprintf (stderr,"%s: unable to bind IPPROTO_UDP socket: %s\n",
                     argv[0],strerror(errno)),
    exit (errno);


  if ((raw_udp138 = socket (AF_INET,SOCK_RAW,IPPROTO_UDP)) == -1)
    fprintf (stderr,"%s: unable to create IPPROTO_UDP socket: %s\n",
                     argv[0],strerror(errno)),
    exit (errno);

  setsockopt (raw_udp138,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));

  _addr.sin_family = AF_INET;
  _addr.sin_addr.s_addr = INADDR_ANY;
  _addr.sin_port   = MSN_138;

  if (bind (raw_udp138,(struct sockaddr *)&_addr,sizeof(_addr)) == -1)
    fprintf (stderr,"%s: unable to bind IPPROTO_UDP socket: %s\n",
                     argv[0],strerror(errno)),
    exit (errno);


  if ((udp = socket (AF_INET,SOCK_DGRAM,0)) == -1)
    fprintf (stderr,"%s: unable to cread SOCK_DGRAM socket: %s\n",
                    argv[0],strerror(errno)),
    exit (errno);

  setsockopt (udp,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));

  _addr.sin_family = AF_INET;
  _addr.sin_addr.s_addr = INADDR_ANY;
  _addr.sin_port   = MSN_RELAY;

  if (bind (udp,(struct sockaddr *)&_addr,sizeof(_addr)) == -1)
    fprintf (stderr,"%s: unable to bind SOCK_DGRAM socket: %s\n",
                    argv[0],strerror(errno));


  /*
   * Daemonize...
   */
  if ((pid = fork()) < 0)
    fprintf (stderr,"%s: unable to fork: %s\n",argv[0],strerror(errno)),
    exit (errno);
  else if (pid)
    exit (0);

  close (2), close (1), close (0);
  i = open ("/dev/null", O_RDWR);
  dup2 (i,1), dup2 (i,2);
  setsid();


  while (1)
  { struct pollfd fds [3];
    unsigned int buf[MSN_MTU/sizeof(unsigned int)];
    struct ip_hdr *ip = (struct ip_hdr *)buf;
    int numfd,len,_alen,tail,fd;

    _alen=sizeof(_addr);

    fds[0].fd = raw_udp137;
    fds[1].fd = raw_udp138;
    fds[2].fd = udp;
    fds[0].events = fds[1].events = fds[2].events = POLLIN;

    numfd = poll (fds,sizeof(fds)/sizeof(fds[0]),-1);

    for (i=0;numfd>0 && i<(sizeof(fds)/sizeof(fds[0]));i++)
    {
      if (fds[i].revents & POLLIN)
      { numfd--;
        fd = fds[i].fd;
        /* broadcasts on UDP port 137, relay 'em */
        if	((fd == raw_udp137 || fd == raw_udp138)
		&& (len = recv (fd,(void *)buf,sizeof(buf),0)) > 0
		)
        { if ((tail = ntohs(ip->tot_len) + ip->ihl*4 - len) > 0)
          { /*
             * I'll discard packets larger than MSN_MTU till I figure a
             * better way... I fetch it without polling for more data
             * because the IP layer *has* collected all the fragments.
             */
            do     len = recv (fd,(void *)buf,sizeof(buf),0);
            while (len>0 && (tail-=len)>0);
          }
          else if (ip->ttl > 1 && ip->daddr == bcast.s_addr)
          { /*
             * Despite what manual says RAW_IP replaces tot_len with
             * the size of (reassembled) payload and we have to fix
             * it up to make it look real.
             */
            ip->tot_len = htons(len);
            for (i=0;i<nrelays;i++)
              sendto (udp,(void *)buf,len,0,
                     (struct sockaddr *)relays+i,sizeof(struct sockaddr_in));
          }
        }
        /* unicast from relay, broadcast the payload */
        else if	(fd == udp
		&& (len = recvfrom (fd,(void *)buf,sizeof(buf),0,
			(struct sockaddr *)&_addr,&_alen)) > 0
		)
        { struct udp_hdr *udp = (struct udp_hdr *)(buf+ip->ihl);

          for (i=0;i<nrelays;i++)
            if (_addr.sin_addr.s_addr == relays[i].sin_addr.s_addr)
              break;
 
          if (i < nrelays /* we listen only to the hosts we relay to ourselves */
	      && _addr.sin_port == MSN_RELAY
	      /* some sanity check... */
              && ip->version == 4
              && ip->tot_len == htons(len)
              && ip->protocol == IPPROTO_UDP
              && (udp->dport == MSN_137 || udp->dport == MSN_138)
             )
          {
	    /*
	     * drop TTL in order to prevent relaying it back as
	     * we ourselves are going to "hear" it too...
	     */
            ip->ttl = 1;
	    ip->daddr = bcast.s_addr;
            sendto (raw_out,(void *)buf,len,0,
                    /*
		     * Following arguments are meaningless (at least
		     * in Solaris), but have be present. So we simply
		     * pick _addr...
		     */
                    (struct sockaddr *)&_addr,sizeof(_addr));
          }
        }
      }
    }
  }
}




More information about the samba-ntdom mailing list