Subversion Repositories planix.SVN

Rev

Blame | Last modification | View Log | RSS feed

#include <u.h>
#include <libc.h>
#include <ip.h>
#include <thread.h>
#include "netbios.h"

static char *hmsg = "headers";
int chatty = 1;

void
warning(char *fmt, ...)
{
        char err[128];
        va_list arg;

        va_start(arg, fmt);
        vseprint(err, err+sizeof(err), fmt, arg);
        va_end(arg);
        syslog(1, "netbios-ns", err);
        if (chatty)
                print("%s\n", err);
}

static int
udpannounce(void)
{
        int data, ctl;
        char dir[64];
        char datafile[64+6];

        /* get a udp port */
        ctl = announce("udp!*!netbios-ns", dir);
        if(ctl < 0){
                warning("can't announce on netbios-ns udp port");
                return -1;
        }
        snprint(datafile, sizeof(datafile), "%s/data", dir);

        /* turn on header style interface */
        if(write(ctl, hmsg, strlen(hmsg)) , 0)
                abort(); /* hmsg */;
        data = open(datafile, ORDWR);
        if(data < 0){
                close(ctl);
                warning("can't announce on dns udp port");
                return -1;
        }

        close(ctl);
        return data;
}

#define BROADCAST 1


void
listen137(void *)
{       
        for (;;) {
                uchar msg[Udphdrsize + 576];
                int len = read(fd137, msg, sizeof(msg));
                if (len < 0)
                        break;
                if (len >= Udphdrsize) {
                        NbnsMessage *s;
                        Udphdr *uh;
                        uchar *p;

                        uh = (Udphdr*)msg;
                        p = msg + Udphdrsize;
                        len -= Udphdrsize;
                        s = nbnsconvM2S(p, len);
                        if (s) {
                                print("%I:%d -> %I:%d\n", uh->raddr, nhgets(uh->rport), uh->laddr, nhgets(uh->lport));
                                nbnsdumpmessage(s);
                                if (s->response) {
                                        NbnsTransaction *t;
                                        qlock(&transactionlist);
                                        for (t = transactionlist.head; t; t = t->next)
                                                if (t->id == s->id)
                                                        break;
                                        if (t) {
                                                sendp(t->c, s);
                                        }
                                        else
                                                nbnsmessagefree(&s);
                                        qunlock(&transactionlist);
                                }
                                else
                                        nbnsmessagefree(&s);
                        }
                }
        }
}

void
usage(void)
{
        fprint(2, "usage: %s [-u ipaddr] name\n", argv0);
        exits("usage");
}

void
threadmain(int argc, char **argv)
{
        int broadcast = 1, i, listen137thread, rv;
        char *ip;
        uchar ipaddr[IPaddrlen], serveripaddr[IPaddrlen];
        NbName nbname;

        ARGBEGIN {
        case 'u':
                broadcast = 0;
                ip = EARGF(usage());
                if (parseip(serveripaddr, ip) == -1)
                        sysfatal("bad ip address %s", ip);
                break;
        default:
                usage();
        } ARGEND;

        if (argc == 0)
                usage();

        nbmknamefromstring(nbname, argv[0]);

        ipifc = readipifc("/net", nil, 0);
        if (ipifc == nil || ipifc->lifc == nil)
                sysfatal("no network interface");
        fmtinstall('I', eipfmt);
        ipmove(bcastaddr, ipifc->lifc->ip);
        for (i = 0; i < IPaddrlen; i++)
                bcastaddr[i] |= ~ipifc->lifc->mask[i];
        print("broadcasting to %I\n", bcastaddr);
//      setnetmtpt("/net");
        fd137 = udpannounce();
        listen137thread = proccreate(listen137, nil, 16384);
        rv = nbnsaddname(broadcast ? nil : serveripaddr, nbname, 3000, ipifc->lifc->ip);
        if (rv != 0)
                print("error code %d\n", rv);
        else
                print("%I\n", ipaddr);
        nbnsalarmend();
        threadint(listen137thread);
}