#include #include #include #include "extra-ipprotos.h" #include "rpc-portmap.h" #include "ip.h" #include "rpc.h" #include "xdr.h" #include "util.h" #include "vars.h" #define PROC_NULL 0 #define PROC_SET 1 #define PROC_UNSET 2 #define PROC_GETPORT 3 #define PROC_DUMP 4 #define PROC_CALLIT 5 typedef struct pmap PMAP; typedef struct call CALL; struct pmap { unsigned long int pm_prog; unsigned long int pm_vers; unsigned long int pm_prot; unsigned long int pm_port; } ; struct call { unsigned long int dsthost; PMAP pmap; } ; static void dump_pmap(const char *tag, int ignmask, PMAP *pmp) #define IGN_PROG 0x1 #define IGN_VERS 0x2 #define IGN_PROT 0x4 #define IGN_PORT 0x8 { unsigned long int pm_prog; unsigned long int pm_vers; unsigned long int pm_prot; unsigned long int pm_port; need(16,"portmapper (prog,vers,prot,port) tuple"); printx(pkt,4); pm_prog = get32(0); printf("%spm_prog",tag); if (ignmask & IGN_PROG) { printf(" (ignored)"); } else { const char *prog_name; printf(" = %lu",pm_prog); prog_name = rpc_prog_name(pm_prog); if (prog_name) printf(" [%s]",prog_name); } printf("\n"); consume(4); printx(pkt,4); pm_vers = get32(0); printf("%spm_vers",tag); if (ignmask & IGN_VERS) { printf(" (ignored)"); } else { printf(" = %lu",pm_vers); } printf("\n"); consume(4); printx(pkt,4); pm_prot = get32(0); printf("%spm_prot",tag); if (ignmask & IGN_PROT) { printf(" (ignored)"); } else { printf(" = %lu",pm_prot); switch (pm_prot) { case IPPROTO_ICMP: printf(" [ICMP]"); break; case IPPROTO_IGMP: printf(" [IGMP]"); break; case IPPROTO_GGP: printf(" [GGP]"); break; case IPPROTO_TCP: printf(" [TCP]"); break; case IPPROTO_EGP: printf(" [EGP]"); break; case IPPROTO_PUP: printf(" [PUP]"); break; case IPPROTO_UDP: printf(" [UDP]"); break; case IPPROTO_IDP: printf(" [IDP]"); break; case IPPROTO_HELLO: printf(" [HELLO]"); break; case IPPROTO_ND: printf(" [ND]"); break; } } printf("\n"); consume(4); printx(pkt,4); pm_port = get32(0); printf("%spm_port",tag); if (ignmask & IGN_PORT) { printf(" (ignored)"); } else { printf(" = %lu",pm_port); } printf("\n"); consume(4); if (pmp) { pmp->pm_prog = pm_prog; pmp->pm_vers = pm_vers; pmp->pm_prot = pm_prot; pmp->pm_port = pm_port; } } void *dumprpc_portmap(RPCDUMP_ARGS) { switch (op) { case DO_CALL: printx(pkt,0); switch (proc) { case PROC_NULL: printf("portmap NULL request\n"); break; case PROC_SET: printf("portmap SET request\n"); dump_pmap("",0,0); break; case PROC_UNSET: printf("portmap UNSET request\n"); { CALL *c; c = malloc(sizeof(CALL)); dump_pmap("",IGN_PROT|IGN_PORT,&c->pmap); c->dsthost = ip_dst; return(c); } break; case PROC_GETPORT: printf("portmap GETPORT request\n"); { CALL *c; c = malloc(sizeof(CALL)); dump_pmap("",IGN_PORT,&c->pmap); c->dsthost = ip_dst; return(c); } break; case PROC_DUMP: printf("portmap DUMP request\n"); /* PMAPPROC_DUMP() RETURNS (struct pmaplist *) */ /* struct pmaplist { struct pmap pml_map; struct pmaplist *pml_next; }; */ break; case PROC_CALLIT: printf("portmap CALLIT request\n"); { unsigned int prog; unsigned int vers; unsigned int proc; unsigned int arglen; const char *pname; need(16,"portmap CALLIT arguments"); prog = get32(0); vers = get32(4); proc = get32(8); arglen = get32(12); printx(pkt,4); printf("Program %u",prog); pname = rpc_prog_name(prog); if (pname) printf(" [%s]",pname); printf("\n"); consume(4); printx(pkt,4); printf("Program version %u\n",vers); consume(4); printx(pkt,4); printf("Procedure %u\n",proc); consume(4); printx(pkt,4); printf("Argument length %u\n",arglen); consume(4); need(arglen,"encoded CALLIT arguments"); } break; default: printf("portmap request, unknown proc %u\n",proc); break; } return(0); break; case DO_REPLY: printx(pkt,0); switch (proc) { case PROC_NULL: printf("portmap NULL reply\n"); break; case PROC_SET: printf("portmap SET reply\n"); dump_xdr_bool("succeeded",0); break; case PROC_UNSET: printf("portmap UNSET reply\n"); { int ok; dump_xdr_bool("succeeded",&ok); if (ok) { rpc_portcache_unset(ip_src,((CALL *)token)->pmap.pm_prog); if (((CALL *)token)->dsthost != ip_src) { rpc_portcache_unset(((CALL *)token)->dsthost,((CALL *)token)->pmap.pm_prog); } } } break; case PROC_GETPORT: printf("portmap GETPORT reply\n"); { unsigned long int v; need(4,"portmap GETPORT reply value"); printx(pkt,4); v = get32(0); printf("port = %lu",v); if (v == 0) printf(" (failure)"); printf("\n"); consume(4); rpc_portcache_set(ip_src,v,((CALL *)token)->pmap.pm_prog); if (((CALL *)token)->dsthost != ip_src) { rpc_portcache_set(((CALL *)token)->dsthost,v,((CALL *)token)->pmap.pm_prog); } } break; case PROC_DUMP: printf("portmap DUMP reply\n"); /* PMAPPROC_DUMP() RETURNS (struct pmaplist *) */ /* struct pmaplist { struct pmap pml_map; struct pmaplist *pml_next; }; */ break; case PROC_CALLIT: printf("portmap CALLIT reply\n"); /* PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) RETURNS (port, string<>); */ /* usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); */ break; default: printf("portmap reply, unknown proc %u\n",proc); break; } break; case DO_FREE: free(token); break; } return(0); }