[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [lwip-users] Netbios nameresolving for lwip
From: |
bonny gijzen |
Subject: |
RE: [lwip-users] Netbios nameresolving for lwip |
Date: |
Tue, 9 Dec 2008 12:42:57 +0100 |
Just
go to commandline and do 'ping myhostname' and Windows will translate for
you.
Regards Bonny,
Hi Oliver
Great code!!
I want to try it in my embedded system, with freertos and lwip
How i can discovery my board on the net using windows? (i need to find
quickly ip assigned using dhcp starting from NETBIOS name)
Or is it necessary sw like this:
Bye,
Piero
2008/12/6 Oliver Schindler
<address@hidden>
Hi
there,
i'm quite new in this list, so didn't know, if this topic was
handled before ...
.. anyway, I'm using the lwip on an Arm9 together with
FreeRtos and it's working
smooth like anything. There was only one
little naggi thing for me, because the counterpart of my
SW is hosted in
the windows-world, and this speaks only netbios for nameresolving.
I'm in
the need of using DHCP, so there is no chance to contact my Arm-board through
a
static IP. To keep long terms short, i wrote a little piece of SW which
does the name-resolving
for a netbios-name request and sends back the
current IP-Adress.
Maybe it's of any use for someone ... If the maintainer
of the lwip find it
somehow usefull, it can also be a part of the lwip.
It consists of a c- and h -file and a part for
the
lwip-opts.
The init is quite simple, jut give a pointer of
your host-name, and pointer for the namelength and a
pointer for your
networkinterface. The last one is needed to get the IP-adress for the
interface, so
this will work also in cooperation with DHCP. The
maximumlength for the hostname is 32 chars, this
is the restriction from
netbios.
Thanks for your great work and c.u. soon,
Oliver
/*
----------------------------------
---------- NBNS options
-----------
----------------------------------
*/
/**
* LWIP_NBNS==1: Turn
on NetBiosNameService module. UDP must be available for NBNS
*
transport.
*/
#ifndef LWIP_NBNS
#define LWIP_NBNS
0
#endif
/** NBNS use a local buffer if
NBNS_USES_STATIC_BUF=0, a static one if
NBNS_USES_STATIC_BUF=1, or a dynamic one if
NBNS_USES_STATIC_BUF=2.
The buffer will be of size
NBNS_MSG_SIZE */
#ifndef NBNS_USES_STATIC_BUF
#define
NBNS_USES_STATIC_BUF
1
#endif
/** NBNS message max. size. Default value is RFC compliant.
*/
#ifndef NBNS_MSG_SIZE
#define NBNS_MSG_SIZE
512
#endif
/** NBNS
client port address */
#ifndef NBNS_CLIENT_PORT
#define NBNS_CLIENT_PORT
137
#endif
/**
*
@file
* NBNS - host name to NetBios
resolver.
*
*/
/**
* This file
implements a simple NetBios Server for the HostName.
* All other
NetBios querys are ignored
* by Oliver Schindler November
2008
* uIP version Copyright (c) 2002-2003, Adam
Dunkels.
* All rights reserved.
*
* Redistribution
and use in source and binary forms, with or without
* modification,
are permitted provided that the following conditions
* are
met:
* 1. Redistributions of source code must retain the above
copyright
* notice, this list of conditions and the
following disclaimer.
* 2. Redistributions in binary form must
reproduce the above copyright
* notice, this list of
conditions and the following disclaimer in the
*
documentation and/or other materials provided with the
distribution.
* 3. The name of the author may not be used to endorse
or promote
* products derived from this software without
specific prior
* written
permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS
IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*
*
* NBNS.H
*
* The
NetbiosNameService waiting on UDP-Port 137 for a NBNS-Query.
* If
this Query matches with the HostName, a respond is send.
* All other
NetBios Telegramms are ignored. ( like Samba, PrinterServices , etc.
)
*/
/*-----------------------------------------------------------------------------
*
RFC 1001 - Protocol Standard for a NetBIOS Service on a TCP/UDP Transport:
Concepts and methods
* RFC 1002 - Protocol standard for a NetBIOS
service on a TCP/UDP transport: Detailed
specifications
*----------------------------------------------------------------------------*/
#ifndef
__LWIP_NBNS_H__
#define __LWIP_NBNS_H__
#include
"lwip/opt.h"
#if LWIP_NBNS /* don't build if not configured for use in
lwipopts.h */
void
nbns_init(u8_t* Hostname,u8_t* Hostname_Len, struct netif
*netif);
/* Values of the opcode field */
#define OPCODE_R
0x8000
/*OPCODE 1-4 Operation
specifier:
0 = query
5 = registration
6 =
release
7 = WACK
8 = refresh */
#define
OPCODE_MASK 0x7800
#define
OPCODE_QUERY 0x0000
#define
OPCODE_REGISTRATION 0x2800
#define OPCODE_RELEASE
0x3000
#define OPCODE_WACK
0x3800
#define OPCODE_REFRESH
0x4000
/* NM_FLAGS subfield bits
*/
#define NM_AA_BIT 0x0400 /*
Authoritative Answer */
#define NM_TR_BIT
0x0200 /* TRuncation flag */
#define NM_RD_BIT
0x0100 /* Recursion Desired
*/
#define NM_RA_BIT 0x0080 /*
Recursion Available */
#define NM_B_BIT
0x0010 /* Broadcast flag */
/* Return
Codes */
#define RCODE_POS_RSP 0x0000 /* Positive
Response */
#define RCODE_FMT_ERR 0x0001
/* Format Error */
#define RCODE_SRV_ERR
0x0002 /* Server failure
*/
#define RCODE_NAM_ERR 0x0003 /* Name Not Found
*/
#define RCODE_IMP_ERR 0x0004 /*
Unsupported request */
#define RCODE_RFS_ERR 0x0005
/* Refused */
#define
RCODE_ACT_ERR 0x0006 /* Active error
*/
#define RCODE_CFT_ERR 0x0007 /* Name in
conflict */
#define RCODE_MASK
0x0007 /* Mask
*/
/* Used to set the record count fields. */
#define
QUERYREC 0x1000 /* Query Record
*/
#define ANSREC
0x0100 /* Answer Record */
#define
NSREC 0x0010 /* NS Rec (never
used) */
#define ADDREC
0x0001 /* Additional Record */
/* RDATA
NB_FLAGS. */
#define GROUP_BIT 0x8000 /* Group
indicator */
#define ONT_B
0x0000 /* Broadcast node */
#define ONT_P
0x2000 /* Point-to-point node */
#define
ONT_M 0x4000 /* Mixed mode node
*/
#define ONT_H 0x6000 /*
MS Hybrid mode node */
#define ONT_MASK 0x6000
/* Mask
*/
/* RDATA NAME_FLAGS. */
#define DRG
0x0100 /* Deregister.
*/
#define CNF 0x0800 /*
Conflict. */
#define ACT
0x0400 /* Active.
*/
#define PRM
0x0200 /* Permanent.
*/
#endif /* LWIP_DNS */
#endif /* __LWIP_DNS_H__
*/
/**
* @file
* NBNS - host name to NetBios
resolver.
*
*/
/**
* This file
implements a simple NetBios Server for the HostName.
* All other
NetBios querys are ignored
* by Oliver Schindler November
2008
* uIP version Copyright (c) 2002-2003, Adam
Dunkels.
* All rights reserved.
*
* Redistribution
and use in source and binary forms, with or without
* modification,
are permitted provided that the following conditions
* are
met:
* 1. Redistributions of source code must retain the above
copyright
* notice, this list of conditions and the
following disclaimer.
* 2. Redistributions in binary form must
reproduce the above copyright
* notice, this list of
conditions and the following disclaimer in the
*
documentation and/or other materials provided with the
distribution.
* 3. The name of the author may not be used to endorse
or promote
* products derived from this software without
specific prior
* written
permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS
IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*
*
* NBNS.C
*
* The
NetbiosNameService waiting on UDP-Port 137 for a NBNS-Query.
* If
this Query matches with the HostName, a resond is send.
* All other
NetBios Telegramms are ignored. ( like Samba, PrinterServices , etc.
)
*/
/*-----------------------------------------------------------------------------
*
RFC 1001 - Protocol Standard for a NetBIOS Service on a TCP/UDP Transport:
Concepts and methods
* RFC 1002 - Protocol standard for a NetBIOS
service on a TCP/UDP transport: Detailed
specifications
*----------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------------
*
Includes
*----------------------------------------------------------------------------*/
#include
"lwip/opt.h"
#if LWIP_NBNS /* don't build if not configured for use in
lwipopts.h */
#if LWIP_UDP
#include "lwip/udp.h"
#include
"lwip/mem.h"
#include "lwip/nbns.h"
#include
<string.h>
#include <stdlib.h>
/** NBNS server port
address */
#ifndef NBNS_CLIENT_PORT
#define NBNS_CLIENT_PORT
137
#endif
#define NETBIOS_NAME_LEN
32
#if
(NBNS_USES_STATIC_BUF == 1)
static u8_t
pHostname[NETBIOS_NAME_LEN];
#endif /* (NBNS_USES_STATIC_BUF == 1)
*/
/** NBNS message header */
#ifdef
PACK_STRUCT_USE_INCLUDES
# include
"arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct nbns_hdr
{
u16_t id;
u16_t flags;
u16_t
numquestions;
u16_t numanswers;
u16_t
numauthrr;
u16_t numextrarr;
}
PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef PACK_STRUCT_USE_INCLUDES
#
include "arch/epstruct.h"
#endif
/** NBNS rdata field
*/
#ifdef PACK_STRUCT_USE_INCLUDES
# include
"arch/bpstruct.h"
#endif
PACK_STRUCT_BEGIN
struct nbns_rdata
{
u16_t len;
u16_t nbflags;
struct ip_addr
addr;
} PACK_STRUCT_STRUCT;
PACK_STRUCT_END
#ifdef
PACK_STRUCT_USE_INCLUDES
# include
"arch/epstruct.h"
#endif
/* forward declarations */
static
void nbns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr
*addr, u16_t
port);
/*-----------------------------------------------------------------------------
*
Globales
*----------------------------------------------------------------------------*/
/*
NBNS variables */
static struct udp_pcb
*nbns_pcb;
struct netif *pnetif=NULL;
static u8_t*
pnbns_hostname=NULL;
u8_t*
pnbns_hostname_len=NULL;
/**
* Initialize the resolver: set up
the UDP pcb
*/
void
nbns_init(u8_t*
Hostname,u8_t* Hostname_Len, struct netif
*netif)
{
LWIP_DEBUGF(NBNS_DEBUG, ("nbns_init:
initializing\n"));
pnbns_hostname_len=Hostname_Len;
if
(*pnbns_hostname_len>NETBIOS_NAME_LEN) {
LWIP_DEBUGF(NBNS_DEBUG, ("nbns_init:ERROR Hostname should be max 32
chars \n"));
return;
}
pnbns_hostname=Hostname;
pnetif=
netif;
/* if nbns client not yet initialized... */
if
(nbns_pcb == NULL) {
nbns_pcb = udp_new();
if (nbns_pcb != NULL) {
/* initialize NBNS
client */
udp_bind(nbns_pcb, IP_ADDR_ANY,
NBNS_CLIENT_PORT);
udp_recv(nbns_pcb, nbns_recv,
NULL);
}
}
}
static
u8_t
nbns_compare_name(u8_t *query, u8_t *response,u8_t
len)
{
u8_t i;
for (i=0;i<len;i++) {
if (*response==0){
return 1;
}
if (*query==0){
return 1;
}
if (tolower(query[i])!=tolower(response[i])) {
return 1;
}
}
return 0;
}
#define
NBNS_TTL_POS sizeof(struct nbns_hdr)+1+NETBIOS_NAME_LEN+1+2+2
#define
NBNS_RDATA_POS NBNS_TTL_POS + 4
#define NBNS_MSGLEN_QUERY_RESPONSE 70
// NBNS_RDATA_POS+sizeof(struct nbns_rdata)
/**
* Receive
input function for NBNS query packets arriving for the NameService UDP
pcb.
*
* @params see udp.h
*/
static
void
nbns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct
ip_addr *addr, u16_t port)
{
err_t err;
u16_t
unique_id,i;
char c1,c2;
char *pNamefield;
struct
nbns_hdr *hdr;
struct nbns_rdata* rdata ;
u16_t*
ttl1,*ttl2;
struct pbuf *prep;
u16_t nquestions,
nanswers,opcode,nm_flags,rcode,name_len;
#if (NBNS_USES_STATIC_BUF ==
0)
u8_t
pHostname[NETBIOS_NAME_LEN];
#endif /* (NBNS_USES_STATIC_BUF == 0)
*/
#if (NBNS_USES_STATIC_BUF == 2)
u8_t* pHostname;
#endif /*
(NBNS_USES_STATIC_BUF == 2)
*/
LWIP_UNUSED_ARG(arg);
LWIP_UNUSED_ARG(pcb);
/*
is the nbns message too big ? */
if (p->tot_len >
NBNS_MSG_SIZE) {
LWIP_DEBUGF(NBNS_DEBUG, ("nbns_recv: pbuf too
big\n"));
/* free pbuf and return */
goto
memerr1;
}
/* is the nbns message big enough ?
*/
if (p->tot_len < (1+NETBIOS_NAME_LEN+1+2+2+sizeof(struct
nbns_hdr))) {
LWIP_DEBUGF(NBNS_DEBUG, ("nbns_recv: pbuf too
small\n"));
/* free pbuf and return */
goto
memerr1;
}
#if (NBNS_USES_STATIC_BUF == 2)
pHostname
= mem_malloc(NETBIOS_NAME_LEN);
if (pHostname == NULL) {
LWIP_DEBUGF(NBNS_DEBUG, ("nbns_recv: mem_malloc
error\n"));
/* free pbuf and return */
goto memerr2;
}
#endif /*
(NBNS_USES_STATIC_BUF == 2) */
/* The content of the Telegramm is
only decoded for information purpses.
Later we use a copy of
the orignal message */
hdr = (struct
nbns_hdr*)p->payload;
unique_id = htons(hdr->id);
/* this is a unique ID , which has to be sent back */
/*
We only care about the question(s) and the answers. The authrr
and the extrarr are simply discarded. */
nquestions = htons(hdr->numquestions);
nanswers =
htons(hdr->numanswers);
/* Decode what the client wants from
us */
opcode = htons(hdr->flags)
& 0xf800;
nm_flags =
htons(hdr->flags) & 0x03f0;
rcode
= htons(hdr->flags) &
0x000f;
if (opcode & OPCODE_R ) { /* This is a response
packet, so don't care about */
/*
deallocate memory and return */
goto
memerr2;
}
switch (opcode & OPCODE_MASK)
{
case OPCODE_QUERY:
/*
There is someone looking for a host with a certain name ... */
break;
case
OPCODE_REGISTRATION:
case OPCODE_RELEASE:
case OPCODE_WACK:
case OPCODE_REFRESH:
default:
/* Nothing of interest for us
*/
/* deallocate memory and return
*/
goto memerr2;
break; /* just for the compiler ....
*/
}
pNamefield=((u8_t*)p->payload)+sizeof(struct
nbns_hdr);
name_len=pNamefield[0];
if
(name_len!=NETBIOS_NAME_LEN) {
/* Hmm ,
this is not a netbios name ... */
goto
memerr2;
}
memset
(pHostname,0,NETBIOS_NAME_LEN);
pNamefield++;
/* Decode
the hostname */
for (i=0;i<name_len;i+=2) {
c1=(pNamefield[i]&0x3f)-1;
c2=(pNamefield[i+1]&0x3f)-1;
pHostname[i/2]=(c1<<4)+(c2);
}
if
(!nbns_compare_name(pHostname,pnbns_hostname,*pnbns_hostname_len)) {
/* Hey , this is ours .. we have to send a reply
*/
LWIP_DEBUGF(NBNS_DEBUG,
("nbns_recv: Got a query for our hostname\n"));
/* reallocate of pbuf isn't implemented to grow, so we have
allocate a
new buffer ,to have
space for our IP-Adress */
prep =
pbuf_alloc(PBUF_TRANSPORT, NBNS_MSGLEN_QUERY_RESPONSE,
PBUF_RAM);
/* clone the original
message, for the transport_id,hostname and flags*/
pbuf_copy_partial(p, prep->payload, p->tot_len,
0);
/* set pointers for the
different parts in the message */
hdr =
(struct nbns_hdr*)prep->payload;
/* ttl is 32-bit, but we can't guarantee that is aligned on a 32 bit
boundary,
so split it up into two
halves */
ttl1 =
(u16_t*)(((u8_t*)prep->payload)+NBNS_TTL_POS);
ttl2 =
(u16_t*)(((u8_t*)prep->payload)+NBNS_TTL_POS+2);
/* This is were our IP-Adress goes to */
rdata = (struct nbns_rdata*)
(((u8_t*)prep->payload)+NBNS_RDATA_POS);
/* Set the response Flag, and the number of answers
*/
opcode=OPCODE_R+OPCODE_QUERY;
nm_flags=NM_AA_BIT+NM_RD_BIT;
rcode=RCODE_POS_RSP; /* Positive respones */
hdr->flags =ntohs(opcode+nm_flags+rcode);
hdr->numquestions=ntohs(0);
hdr->numanswers =ntohs(1);
*ttl1=ntohs(0);
*ttl2=ntohs(0); /* Infinite time to live
*/
rdata->len=ntohs(2+sizeof(struct
ip_addr));
rdata->nbflags=ntohs(ONT_B); /*
Broadcast Node */
memcpy((unsigned
char*)&rdata->addr,(unsigned
char*)&pnetif->ip_addr,sizeof(struct ip_addr));
/* It's better to answer on the port , we got the
query, maybe some strange
port-translation is in between */
err =
udp_sendto(nbns_pcb, prep, addr,port/* NBNS_CLIENT_PORT*/);
/* cleaning up */
pbuf_free(prep);
}
/* deallocate
memory and return */
//goto memerr2;
memerr2:
#if
(NBNS_USES_STATIC_BUF == 2)
/* free Hostname buffer
*/
if(pHostname!=NULL){
mem_free(pHostname);
}
#endif
/* (NBNS_USES_STATIC_BUF == 2) */
memerr1:
/* free pbuf
*/
pbuf_free(p);
return;
}
#else
#error
"UDP is needed !"
#endif
#endif /* LWIP_NBNS
*/
_______________________________________________
lwip-users
mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/lwip-users