wins.c

Go to the documentation of this file.
00001 
00002 /*
00003   * Copyright (C) 2004 by Jean Pierre Gauthier. All rights reserved.
00004   *
00005   * Redistribution and use in source and binary forms, with or without
00006   * modification, are permitted provided that the following conditions
00007   * are met:
00008   *
00009   * 1. Redistributions of source code must retain the above copyright
00010   *    notice, this list of conditions and the following disclaimer.
00011   * 2. Redistributions in binary form must reproduce the above copyright
00012   *    notice, this list of conditions and the following disclaimer in the
00013   *    documentation and/or other materials provided with the distribution.
00014   * 3. Neither the name of the copyright holders nor the names of
00015   *    contributors may be used to endorse or promote products derived
00016   *    from this software without specific prior written permission.
00017   *
00018   * THIS SOFTWARE IS PROVIDED BY <YOUR NAME> AND CONTRIBUTORS
00019   * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00020   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00021   * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <YOUR NAME>
00022   * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00023   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00024   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00025   * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00026   * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00028   * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00029   * SUCH DAMAGE.
00030   */
00031 
00032 /* ********************************************************* */
00033 /* 
00034 Netbios WINS (RFC 1002) Name Query. 
00035 Only Query Request Client Routine sending/Positive Name Query Response receiving
00036 are implemented. 
00037 When the Netbios Name Query request UDP datagram is on the ethernet network, asking 
00038 "Who is 'name'?", NutWinsNameQuery answers with the specified 'ipaddr' Ethernut IP address. 
00039 Answer to Microsoft Windows/Internet Explorer calls by "http://name" command line
00040 (and even directly "name" as command line if "name" is not a shared folder). 
00041 
00042 Launch for example :
00043 THREAD(wins_deamon, arg)
00044 {
00045 NutWinsNameQuery  (  "myboard", inet_addr(MYIP) ) ;
00046 } 
00047 */
00048 /* ********************************************************* */
00049 
00050 #include <cfg/os.h>
00051 #include <string.h>
00052 
00053 #include <sys/heap.h>
00054 #include <sys/socket.h>
00055 #include <sys/sock_var.h>
00056 #include <sys/types.h>
00057 #include <pro/wins.h>
00058 #include <netinet/in.h>
00059 #ifdef NUTDEBUG
00060 #include <stdio.h>
00061 #endif
00062 
00063 extern int toupper(int);
00064 /* ********************************************************* */
00065 
00070 
00071 typedef struct {
00072     u_short id;
00073     u_short flags;
00074     u_short quests;
00075     u_short answers;
00076     u_short authrr;
00077     u_short addrr;
00078     u_char namelen;
00079     u_char name[33];
00080     u_short type;
00081     u_short class;              /* end of request */
00082     u_long ttl;
00083     u_short len_rep;
00084     u_char node_flags;
00085     u_char node_type;
00086     u_long ip_addr;             /* end of answer */
00087 } WINSHEADER;
00088 
00089 
00090 /* ********************************************************* */
00091 /* name : netbios label (15 chars max), ipaddr : network ordered IP address bytes */
00092 int NutWinsNameQuery(char * name, u_long ipaddr)
00093 {
00094     WINSHEADER *pkt = NULL;
00095     u_char *encoded = NULL;
00096     UDPSOCKET *sock;
00097     u_long raddr;
00098     u_short rport;
00099     u_char car;
00100     int i, j;
00101     if (strlen(name) > 15)
00102         return -1;
00103     if (((pkt = NutHeapAllocClear(sizeof(WINSHEADER))) == NULL) ||      /* */
00104         ((encoded = NutHeapAllocClear(33)) == NULL) ||  /* */
00105         ((sock = NutUdpCreateSocket(137)) == 0) /* NETBIOS UDP port */
00106         ) {
00107         if (pkt != NULL)
00108             NutHeapFree(pkt);
00109         if (encoded != NULL)
00110             NutHeapFree(encoded);
00111         return -1;
00112     }
00113     j = 0;
00114     for (i = 0; i < 16; i++) {  /* label  'compression' */
00115         car = toupper(i < strlen(name) ? name[i] : ' ');
00116         if (i == 15)
00117             car = 0;
00118         encoded[j] = (car >> 4) + 'A';
00119         encoded[j + 1] = (car & 0xf) + 'A';
00120         j += 2;
00121     }
00122     encoded[j] = 0;
00123      /* printf("local compressed name=\n%s \n", encoded); */
00124     for (;;) {                  /* infinite loop / Netbios deamon */
00125         NutUdpReceiveFrom(sock, &raddr, &rport, pkt, sizeof(WINSHEADER), 0);
00126         /* RFC1002 Name Query Request verification */
00127         if (((ntohs(pkt->flags) & 0xf800) != 0) ||      /* */
00128             (ntohs(pkt->quests) != 1) ||        /* */
00129             (pkt->namelen != 0x20) ||   /* */
00130             (ntohs(pkt->type) != 32) || /* */
00131             (ntohs(pkt->class) != 1) || /* */
00132             (strcmp((char *)pkt->name, (char *)encoded)))
00133             continue;           /* bad request, try again */
00134          /* printf("Name=%s recognized\r\n", name); */
00135         /* build RFC1002 Positive Name Query Response */
00136         pkt->flags = htons(0x8580);     /* Response flags */
00137         pkt->answers = htons(1);
00138         pkt->ttl = htonl((u_long) 60);  /* 60 seconds validity */
00139         pkt->len_rep = htons(6);
00140         pkt->node_flags = pkt->node_type = pkt->quests = 0;     /* B-type node, etc... */
00141         pkt->ip_addr = ipaddr;  /* Returned IP Address, end of answer */
00142         NutUdpSendTo(sock, raddr, 137, pkt, sizeof(WINSHEADER));        /* send to netbios port */
00143         memset(pkt, 0, sizeof(WINSHEADER));
00144     }
00145 }
00146 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/