Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * sunrpc portmapper
 */
#include "all.h"

typedef struct Portmap  Portmap;
struct Portmap
{
        int     prog;
        int     vers;
        int     protocol;
        int     port;
};

Portmap map[] = {
        100003, 2, IPPROTO_UDP, 2049,   /* nfs v2 */
//      100003, 3, IPPROTO_UDP, 2049,   /* nfs v3 */
        100005, 1, IPPROTO_UDP, 2049,   /* mount */
        150001, 2, IPPROTO_UDP, 1111,   /* pcnfsd v2 */
        150001, 1, IPPROTO_UDP, 1111,   /* pcnfsd v1 */
        0, 0, 0, 0,
};

static void     pmapinit(int, char**);
static int      pmapnull(int, Rpccall*, Rpccall*);
static int      pmapset(int, Rpccall*, Rpccall*);
static int      pmapunset(int, Rpccall*, Rpccall*);
static int      pmapgetport(int, Rpccall*, Rpccall*);
static int      pmapdump(int, Rpccall*, Rpccall*);
static int      pmapcallit(int, Rpccall*, Rpccall*);

static Procmap pmapproc[] = {
        0, pmapnull,
        1, pmapset,
        2, pmapunset,
        3, pmapgetport,
        4, pmapdump,
        5, pmapcallit,
        0, 0
};

int     myport = 111;

Progmap progmap[] = {
        100000, 2, pmapinit, pmapproc,
        0, 0, 0,
};

void
main(int argc, char *argv[])
{
        server(argc, argv, myport, progmap);
}

static
void
pmapinit(int argc, char **argv)
{
        ARGBEGIN{
        default:
                if(argopt(ARGC()) < 0)
                        sysfatal("usage: %s %s", argv0, commonopts);
                break;
        }ARGEND;
        clog("portmapper init\n");
}

static int
pmapnull(int n, Rpccall *cmd, Rpccall *reply)
{
        USED(n, cmd, reply);
        return 0;
}

static int
pmapset(int n, Rpccall *cmd, Rpccall *reply)
{
        uchar *dataptr = reply->results;

        if(n != 16)
                return garbage(reply, "bad count");
        USED(cmd);
        PLONG(FALSE);
        return dataptr - (uchar *)reply->results;
}

static int
pmapunset(int n, Rpccall *cmd, Rpccall *reply)
{
        uchar *dataptr = reply->results;

        if(n != 16)
                return garbage(reply, "bad count");
        USED(cmd);
        PLONG(TRUE);
        return dataptr - (uchar *)reply->results;
}

static int
pmapgetport(int n, Rpccall *cmd, Rpccall *reply)
{
        int prog, vers, prot;
        uchar *argptr = cmd->args;
        uchar *dataptr = reply->results;
        Portmap *mp;

        clog("get port\n");

        if(n != 16)
                return garbage(reply, "bad count");
        prog = GLONG();
        vers = GLONG();
        prot = GLONG();
        chat("host=%I, port=%ld: ", cmd->host, cmd->port);
        chat("getport: %d, %d, %d...", prog, vers, prot);
        for(mp=map; mp->prog>0; mp++)
                if(prog == mp->prog && vers == mp->vers &&
                   prot == mp->protocol)
                        break;
        chat("%d\n", mp->port);
        PLONG(mp->port);
        return dataptr - (uchar *)reply->results;
}

static int
pmapdump(int n, Rpccall *cmd, Rpccall *reply)
{
        uchar *dataptr = reply->results;
        Portmap *mp;

        if(n != 0)
                return garbage(reply, "bad count");
        USED(cmd);
        for(mp=map; mp->prog>0; mp++){
                PLONG(1);
                PLONG(mp->prog);
                PLONG(mp->vers);
                PLONG(mp->protocol);
                PLONG(mp->port);
        }
        PLONG(0);
        return dataptr - (uchar *)reply->results;
}

static int
pmapcallit(int n, Rpccall *cmd, Rpccall *reply)
{
        int prog, vers, proc;
        uchar *argptr = cmd->args;
        uchar *dataptr = reply->results;
        Portmap *mp;

        if(n < 12)
                return garbage(reply, "bad count");
        prog = GLONG();
        vers = GLONG();
        proc = GLONG();
        chat("host=%I, port=%ld: ", cmd->host, cmd->port);
        chat("callit: %d, %d, %d...", prog, vers, proc);
        for(mp=map; mp->prog>0; mp++)
                if(prog == mp->prog && vers == mp->vers &&
                   proc == 0)
                        break;
        if(mp->port == 0){
                chat("ignored\n");
                return -1;
        }
        chat("%d\n", mp->port);
        PLONG(mp->port);
        PLONG(0);
        return dataptr - (uchar *)reply->results;
}