Esempio n. 1
0
static void debug_dump_getaddrinfo_args (const char *name, const char *serv,
                                         const struct addrinfo *hint)
{
    const char *sep;
    fprintf(stderr,
            "getaddrinfo(hostname %s, service %s,\n"
            "            hints { ",
            name ? name : "(null)", serv ? serv : "(null)");
    if (hint) {
        char buf[30];
        sep = "";
#define Z(FLAG) if (hint->ai_flags & AI_##FLAG) fprintf(stderr, "%s%s", sep, #FLAG), sep = "|"
        Z(CANONNAME);
        Z(PASSIVE);
#ifdef AI_NUMERICHOST
        Z(NUMERICHOST);
#endif
        if (sep[0] == 0)
            fprintf(stderr, "no-flags");
        if (hint->ai_family)
            fprintf(stderr, " %s", familyname(hint->ai_family, buf,
                                              sizeof(buf)));
        if (hint->ai_socktype)
            fprintf(stderr, " SOCK_%s", socktypename(hint->ai_socktype, buf,
                                                     sizeof(buf)));
        if (hint->ai_protocol)
            fprintf(stderr, " IPPROTO_%s", protoname(hint->ai_protocol, buf,
                                                     sizeof(buf)));
    } else
        fprintf(stderr, "(null)");
    fprintf(stderr, " }):\n");
}
Esempio n. 2
0
int
main(int argc, char **argv)
{
    struct sockaddr_in addr;
    struct pmaplist *list;
    struct rpcent *rpc;

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    addr.sin_port = htons(PMAPPORT);

    for (list = pmap_getmaps(&addr); list; list = list->pml_next) {
	rpc = getrpcbynumber((int) list->pml_map.pm_prog);
	printf("%10lu %4lu %5s %6lu  %s\n",
	       list->pml_map.pm_prog,
	       list->pml_map.pm_vers,
	       protoname(list->pml_map.pm_prot),
	       list->pml_map.pm_port,
	       rpc ? rpc->r_name : "");
    }
    return (fclose(stdout) ? (perror(argv[0]), 1) : 0);
}
Esempio n. 3
0
static void
ipv6cp_DecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type,
                    struct fsm_decode *dec)
{
  /* Deal with incoming PROTO_IPV6CP */
  struct ipv6cp *ipv6cp = fsm2ipv6cp(fp);
  int n;
  char tbuff[100];
  u_char ifid[IPV6CP_IFIDLEN], zero[IPV6CP_IFIDLEN];
  struct fsm_opt *opt;

  memset(zero, 0, IPV6CP_IFIDLEN);

  while (end - cp >= (int)sizeof(opt->hdr)) {
    if ((opt = fsm_readopt(&cp)) == NULL)
      break;

    snprintf(tbuff, sizeof tbuff, " %s[%d]", protoname(opt->hdr.id),
             opt->hdr.len);

    switch (opt->hdr.id) {
    case TY_TOKEN:
      memcpy(ifid, opt->data, IPV6CP_IFIDLEN);
      log_Printf(LogIPV6CP, "%s 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", tbuff,
		 ifid[0], ifid[1], ifid[2], ifid[3], ifid[4], ifid[5], ifid[6], ifid[7]);

      switch (mode_type) {
      case MODE_REQ:
        ipv6cp->peer_tokenreq = 1;
        ipv6cp_ValidateInterfaceID(ipv6cp, ifid, dec);
        break;

      case MODE_NAK:
        if (memcmp(ifid, zero, IPV6CP_IFIDLEN) == 0) {
          log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE,
		     "0x0000000000000000: Unacceptable IntefaceID!\n");
          fsm_Close(&ipv6cp->fsm);
        } else if (memcmp(ifid, ipv6cp->his_ifid, IPV6CP_IFIDLEN) == 0) {
          log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE,
		     "0x%02x%02x%02x%02x%02x%02x%02x%02x: "
		     "Unacceptable IntefaceID!\n",
		     ifid[0], ifid[1], ifid[2], ifid[3],
		     ifid[4], ifid[5], ifid[6], ifid[7]);
        } else if (memcmp(ifid, ipv6cp->my_ifid, IPV6CP_IFIDLEN) != 0) {
          n = 100;
	  while (n && !ipcp_SetIPv6address(ipv6cp, ifid, ipv6cp->his_ifid)) {
	    do {
	      n--;
	      SetInterfaceID(ifid, 1);
	    } while (n && memcmp(ifid, ipv6cp->his_ifid, IPV6CP_IFIDLEN) == 0);
	  }

          if (n == 0) {
            log_Printf(log_IsKept(LogIPV6CP) ? LogIPV6CP : LogPHASE,
                       "0x0000000000000000: Unacceptable IntefaceID!\n");
            fsm_Close(&ipv6cp->fsm);
          } else {
	    log_Printf(LogIPV6CP, "%s changing IntefaceID: "
		       "0x%02x%02x%02x%02x%02x%02x%02x%02x "
		       "--> 0x%02x%02x%02x%02x%02x%02x%02x%02x\n", tbuff,
		       ipv6cp->my_ifid[0], ipv6cp->my_ifid[1],
		       ipv6cp->my_ifid[2], ipv6cp->my_ifid[3],
		       ipv6cp->my_ifid[4], ipv6cp->my_ifid[5],
		       ipv6cp->my_ifid[6], ipv6cp->my_ifid[7],
		       ifid[0], ifid[1], ifid[2], ifid[3],
		       ifid[4], ifid[5], ifid[6], ifid[7]);
            memcpy(ipv6cp->my_ifid, ifid, IPV6CP_IFIDLEN);
            bundle_AdjustFilters(fp->bundle, &ipv6cp->myaddr, NULL);
          }
        }
        break;

      case MODE_REJ:
        ipv6cp->his_reject |= (1 << opt->hdr.id);
        break;
      }
      break;

    default:
      if (mode_type != MODE_NOP) {
        ipv6cp->my_reject |= (1 << opt->hdr.id);
        fsm_rej(dec, opt);
      }
      break;
    }
  }

  if (mode_type != MODE_NOP) {
    if (mode_type == MODE_REQ && !ipv6cp->peer_tokenreq) {
      if (dec->rejend == dec->rej && dec->nakend == dec->nak) {
        /*
         * Pretend the peer has requested a TOKEN.
         * We do this to ensure that we only send one NAK if the only
         * reason for the NAK is because the peer isn't sending a
         * TY_TOKEN REQ.  This stops us from repeatedly trying to tell
         * the peer that we have to have an IP address on their end.
         */
        ipv6cp->peer_tokenreq = 1;
      }
      memset(ifid, 0, IPV6CP_IFIDLEN);
      ipv6cp_ValidateInterfaceID(ipv6cp, ifid, dec);
    }
    fsm_opt_normalise(dec);
  }
}
Esempio n. 4
0
static void
CcpDecodeConfig(struct fsm *fp, u_char *cp, u_char *end, int mode_type,
                struct fsm_decode *dec)
{
  /* Deal with incoming data */
  struct ccp *ccp = fsm2ccp(fp);
  int f;
  const char *disp;
  struct fsm_opt *opt;

  if (mode_type == MODE_REQ)
    ccp->in.algorithm = -1;	/* In case we've received two REQs in a row */

  while (end >= cp + sizeof(opt->hdr)) {
    if ((opt = fsm_readopt(&cp)) == NULL)
      break;

    for (f = NALGORITHMS-1; f > -1; f--)
      if (algorithm[f]->id == opt->hdr.id)
        break;

    disp = f == -1 ? "" : (*algorithm[f]->Disp)(opt);
    if (disp == NULL)
      disp = "";

    log_Printf(LogCCP, " %s[%d] %s\n", protoname(opt->hdr.id),
               opt->hdr.len, disp);

    if (f == -1) {
      /* Don't understand that :-( */
      if (mode_type == MODE_REQ) {
        ccp->my_reject |= (1 << opt->hdr.id);
        fsm_rej(dec, opt);
      }
    } else {
      struct ccp_opt *o;

      switch (mode_type) {
      case MODE_REQ:
        if (IsAccepted(ccp->cfg.neg[algorithm[f]->Neg]) &&
            (*algorithm[f]->Usable)(fp) &&
            ccp->in.algorithm == -1) {
          memcpy(&ccp->in.opt, opt, opt->hdr.len);
          switch ((*algorithm[f]->i.Set)(fp->bundle, &ccp->in.opt, &ccp->cfg)) {
          case MODE_REJ:
            fsm_rej(dec, &ccp->in.opt);
            break;
          case MODE_NAK:
            fsm_nak(dec, &ccp->in.opt);
            break;
          case MODE_ACK:
            fsm_ack(dec, &ccp->in.opt);
            ccp->his_proto = opt->hdr.id;
            ccp->in.algorithm = (int)f;		/* This one'll do :-) */
            break;
          }
        } else {
          fsm_rej(dec, opt);
        }
        break;
      case MODE_NAK:
        for (o = ccp->out.opt; o != NULL; o = o->next)
          if (o->val.hdr.id == opt->hdr.id)
            break;
        if (o == NULL)
          log_Printf(LogCCP, "%s: Warning: Ignoring peer NAK of unsent"
                     " option\n", fp->link->name);
        else {
          memcpy(&o->val, opt, opt->hdr.len);
          if ((*algorithm[f]->o.Set)(fp->bundle, &o->val, &ccp->cfg) ==
              MODE_ACK)
            ccp->my_proto = algorithm[f]->id;
          else {
            ccp->his_reject |= (1 << opt->hdr.id);
            ccp->my_proto = -1;
            if (algorithm[f]->Required(fp)) {
              log_Printf(LogWARN, "%s: Cannot understand peers (required)"
                         " %s negotiation\n", fp->link->name,
                         protoname(algorithm[f]->id));
              fsm_Close(&fp->link->lcp.fsm);
            }
          }
        }
        break;
      case MODE_REJ:
        ccp->his_reject |= (1 << opt->hdr.id);
        ccp->my_proto = -1;
        if (algorithm[f]->Required(fp)) {
          log_Printf(LogWARN, "%s: Peer rejected (required) %s negotiation\n",
                     fp->link->name, protoname(algorithm[f]->id));
          fsm_Close(&fp->link->lcp.fsm);
        }
        break;
      }
    }
  }

  if (mode_type != MODE_NOP) {
    fsm_opt_normalise(dec);
    if (dec->rejend != dec->rej || dec->nakend != dec->nak) {
      if (ccp->in.state == NULL) {
        ccp->his_proto = -1;
        ccp->in.algorithm = -1;
      }
    }
  }
}
Esempio n. 5
0
/*  Called when CCP has reached the OPEN state */
static int
CcpLayerUp(struct fsm *fp)
{
  /* We're now up */
  struct ccp *ccp = fsm2ccp(fp);
  struct ccp_opt **o;
  unsigned f, fail;

  for (f = fail = 0; f < NALGORITHMS; f++)
    if (IsEnabled(ccp->cfg.neg[algorithm[f]->Neg]) &&
        (*algorithm[f]->Required)(&ccp->fsm) &&
        (ccp->in.algorithm != (int)f || ccp->out.algorithm != (int)f)) {
      /* Blow it all away - we haven't negotiated a required algorithm */
      log_Printf(LogWARN, "%s: Failed to negotiate (required) %s\n",
                 fp->link->name, protoname(algorithm[f]->id));
      fail = 1;
    }

  if (fail) {
    ccp->his_proto = ccp->my_proto = -1;
    fsm_Close(fp);
    fsm_Close(&fp->link->lcp.fsm);
    return 0;
  }

  log_Printf(LogCCP, "%s: LayerUp.\n", fp->link->name);

  if (ccp->in.state == NULL && ccp->in.algorithm >= 0 &&
      ccp->in.algorithm < (int)NALGORITHMS) {
    ccp->in.state = (*algorithm[ccp->in.algorithm]->i.Init)
      (fp->bundle, &ccp->in.opt);
    if (ccp->in.state == NULL) {
      log_Printf(LogERROR, "%s: %s (in) initialisation failure\n",
                fp->link->name, protoname(ccp->his_proto));
      ccp->his_proto = ccp->my_proto = -1;
      fsm_Close(fp);
      return 0;
    }
  }

  o = &ccp->out.opt;
  if (ccp->out.algorithm > 0)
    for (f = 0; f < (unsigned)ccp->out.algorithm; f++)
      if (IsEnabled(ccp->cfg.neg[algorithm[f]->Neg]))
	o = &(*o)->next;

  if (ccp->out.state == NULL && ccp->out.algorithm >= 0 &&
      ccp->out.algorithm < (int)NALGORITHMS) {
    ccp->out.state = (*algorithm[ccp->out.algorithm]->o.Init)
      (fp->bundle, &(*o)->val);
    if (ccp->out.state == NULL) {
      log_Printf(LogERROR, "%s: %s (out) initialisation failure\n",
                fp->link->name, protoname(ccp->my_proto));
      ccp->his_proto = ccp->my_proto = -1;
      fsm_Close(fp);
      return 0;
    }
  }

  fp->more.reqs = fp->more.naks = fp->more.rejs = ccp->cfg.fsm.maxreq * 3;

  log_Printf(LogCCP, "%s: Out = %s[%d], In = %s[%d]\n",
            fp->link->name, protoname(ccp->my_proto), ccp->my_proto,
            protoname(ccp->his_proto), ccp->his_proto);

  return 1;
}
Esempio n. 6
0
int
ccp_ReportStatus(struct cmdargs const *arg)
{
  struct ccp_opt **o;
  struct link *l;
  struct ccp *ccp;
  int f;

  l = command_ChooseLink(arg);
  ccp = &l->ccp;

  prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, ccp->fsm.name,
                State2Nam(ccp->fsm.state));
  if (ccp->fsm.state == ST_OPENED) {
    prompt_Printf(arg->prompt, " My protocol = %s, His protocol = %s\n",
                  protoname(ccp->my_proto), protoname(ccp->his_proto));
    prompt_Printf(arg->prompt, " Output: %ld --> %ld,  Input: %ld --> %ld\n",
                  ccp->uncompout, ccp->compout,
                  ccp->compin, ccp->uncompin);
  }

  if (ccp->in.algorithm != -1)
    prompt_Printf(arg->prompt, "\n Input Options:  %s\n",
                  (*algorithm[ccp->in.algorithm]->Disp)(&ccp->in.opt));

  if (ccp->out.algorithm != -1) {
    o = &ccp->out.opt;
    for (f = 0; f < ccp->out.algorithm; f++)
      if (IsEnabled(ccp->cfg.neg[algorithm[f]->Neg]))
        o = &(*o)->next;
    prompt_Printf(arg->prompt, " Output Options: %s\n",
                  (*algorithm[ccp->out.algorithm]->Disp)(&(*o)->val));
  }

  prompt_Printf(arg->prompt, "\n Defaults: ");
  prompt_Printf(arg->prompt, "FSM retry = %us, max %u Config"
                " REQ%s, %u Term REQ%s\n", ccp->cfg.fsm.timeout,
                ccp->cfg.fsm.maxreq, ccp->cfg.fsm.maxreq == 1 ? "" : "s",
                ccp->cfg.fsm.maxtrm, ccp->cfg.fsm.maxtrm == 1 ? "" : "s");
  prompt_Printf(arg->prompt, "           deflate windows: ");
  prompt_Printf(arg->prompt, "incoming = %d, ", ccp->cfg.deflate.in.winsize);
  prompt_Printf(arg->prompt, "outgoing = %d\n", ccp->cfg.deflate.out.winsize);
#ifndef NODES
  prompt_Printf(arg->prompt, "           MPPE: ");
  if (ccp->cfg.mppe.keybits)
    prompt_Printf(arg->prompt, "%d bits, ", ccp->cfg.mppe.keybits);
  else
    prompt_Printf(arg->prompt, "any bits, ");
  switch (ccp->cfg.mppe.state) {
  case MPPE_STATEFUL:
    prompt_Printf(arg->prompt, "stateful");
    break;
  case MPPE_STATELESS:
    prompt_Printf(arg->prompt, "stateless");
    break;
  case MPPE_ANYSTATE:
    prompt_Printf(arg->prompt, "any state");
    break;
  }
  prompt_Printf(arg->prompt, "%s\n",
                ccp->cfg.mppe.required ? ", required" : "");
#endif

  prompt_Printf(arg->prompt, "\n           DEFLATE:    %s\n",
                command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE]));
  prompt_Printf(arg->prompt, "           PREDICTOR1: %s\n",
                command_ShowNegval(ccp->cfg.neg[CCP_NEG_PRED1]));
  prompt_Printf(arg->prompt, "           DEFLATE24:  %s\n",
                command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE24]));
#ifndef NODES
  prompt_Printf(arg->prompt, "           MPPE:       %s\n",
                command_ShowNegval(ccp->cfg.neg[CCP_NEG_MPPE]));
#endif
  return 0;
}
Esempio n. 7
0
/*
 * Transfer the file or directory in target[].
 * rname is the name of the file on the remote host.
 */
int 
sendf (char *rname, int opts)
{
	struct subcmd *sc;
	struct stat stb;
	int sizerr, f, u, len;
	off_t i;
	DIR *d;
	struct dirent *dp;
	char *otp, *cp;
	extern struct subcmd *subcmds;
	char	buf[BUFSIZ];
	static char uname[15], group[15];

	if (debug)
		 printf("sendf(%s, %x)\n", rname, opts);

	if (except(target))
		return;
	if ((opts & FOLLOW ? stat(target, &stb) : lstat(target, &stb)) < 0) {
		advise (target, "Can't stat");
		return;
	}
	if ((u = update(rname, opts, &stb)) == 0) {
		if ((stb.st_mode & S_IFMT) == S_IFREG && stb.st_nlink > 1)
			 savelink(&stb, opts);
		return;
	}

	if (pw == NULL || pw->pw_uid != stb.st_uid)
		if ((pw = getpwuid(stb.st_uid)) == NULL) {
			log(lfp, "%s: no password entry for uid \n", target);
			pw = NULL;
			 sprintf(uname, ":%d", stb.st_uid);
		}
	if (gr == NULL || gr->gr_gid != stb.st_gid)
		if ((gr = getgrgid(stb.st_gid)) == NULL) {
			log(lfp, "%s: no name for group %d\n", target);
			gr = NULL;
			 sprintf(group, ":%d", stb.st_gid);
		}
	if (u == 1) {
#ifdef UW
		if (opts & NOINSTALL) {
			log(lfp, "does not exist, did not install: %s\n", target);
			goto dospecial;
		}
#endif UW
		if (opts & VERIFY) {
			log(lfp, "need to install: %s\n", target);
			goto dospecial;
		}
		log(lfp, "installing: %s\n", target);
		opts &= ~(COMPARE|REMOVE);
	}

	switch (stb.st_mode & S_IFMT) {
	case S_IFDIR:
		if ((d = opendir(target)) == NULL) {
			advise (target, "Can't open directory");
			return;
		}
		if (transfer (stb.st_mode & S_IFMT, opts,
					  stb.st_mode & 07777, (off_t)0, (time_t)0,
					  protoname (), protogroup (),
					  rname, "") < 0) {
			 closedir (d);
			return;
		}

		if (opts & REMOVE)
			 rmchk(opts);

		otp = tp;
		len = tp - target;
		while (dp = readdir(d)) {
			if (!strcmp(dp->d_name, ".") ||
					!strcmp(dp->d_name, ".."))
				continue;
			if (len + 1 + (int)strlen(dp->d_name) >= BUFSIZ - 1) {
				advise (NULLCP, "%s/%s name too long",
						target, dp->d_name);
				continue;
			}
			tp = otp;
			*tp++ = '/';
			cp = dp->d_name;
			while (*tp++ = *cp++)
				;
			tp--;
			sendf(dp->d_name, opts);
		}
		 closedir(d);
		 terminate (S_IFDIR, OK);
		tp = otp;
		*tp = '\0';
		return;

	case S_IFLNK:
		if (u != 1)
			opts |= COMPARE;
		if (stb.st_nlink > 1) {
			struct linkbuf *lp;

			if ((lp = savelink(&stb, opts)) != NULL) {
				if (*lp -> target == 0)
					 strcpy (buf, lp -> pathname);
				else	 sprintf (buf, "%s/%s",
											lp -> target,
											lp -> pathname);
				 transfer ((unsigned short)0, opts,
								 (unsigned short)0, (off_t)0,
								 (time_t)0, "", "",
								 rname, buf);
				return;
			}
		}
		sizerr = (readlink(target, buf, BUFSIZ) != stb.st_size);
		if (debug)
			 printf("readlink = %.*s\n", stb.st_size, buf);
		if (transfer (stb.st_mode & S_IFMT, opts, stb.st_mode & 07777,
					  stb.st_size, stb.st_mtime,
					  protoname (), protogroup (), rname,
					  buf) < 0)
			return;
		goto done;

	case S_IFREG:
		break;

	default:
		advise (NULLCP, "%s: not a file or directory", target);
		return;
	}

	if (u == 2) {
		if (opts & VERIFY) {
			log(lfp, "need to update: %s\n", target);
			goto dospecial;
		}
		log(lfp, "updating: %s\n", target);
	}

	if (stb.st_nlink > 1) {
		struct linkbuf *lp;

		if ((lp = savelink(&stb, opts)) != NULL) {
			if (*lp -> target == 0)
				 strcpy (buf, lp -> pathname);
			else	 sprintf (buf, "%s/%s",
										lp -> target,
										lp -> pathname);
			 transfer ((unsigned short)0, opts,
							 (unsigned short)0, (off_t)0,
							 (time_t)0, "", "",
							 rname, buf);
			return;
		}
	}

	if ((f = open(target, O_RDONLY, 0)) < 0) {
		advise (target, "Can't open file");
		return;
	}
	if ( transfer ((unsigned short)S_IFREG, opts, stb.st_mode & 07777,
				   stb.st_size,
				   stb.st_mtime, protoname (), protogroup (),
				   rname, "") < 0) {
		 close (f);
		return;
	}
	sizerr = 0;
	for (i = 0; i < stb.st_size; i += sizeof tranbuf) {
		int amt = sizeof tranbuf;
		if (i + amt > stb.st_size)
			amt = stb.st_size - i;
		if (sizerr == 0 && read(f, tranbuf, amt) != amt)
			sizerr = 1;
		if (tran_data (tranbuf, amt) == NOTOK)
			break;
	}
	 close(f);
	if (sizerr) {
		advise (NULLCP, "%s: file changed size", target);
		if (terminate (S_IFREG, NOTOK) < 0)
			return;
	} else {
		if (terminate (S_IFREG, OK) < 0)
			return;
	}
done:
	if (opts & COMPARE)
		return;
dospecial:
	for (sc = subcmds; sc != NULL; sc = sc->sc_next) {
		if (sc->sc_type != SPECIAL)
			continue;
#ifdef UW
		if (opts & NOINSTALL)  /* don't do specials associated with
					  non-installation notices */
			continue;
#endif UW
		if (sc->sc_args != NULL && !inlist(sc->sc_args, target))
			continue;
		log(lfp, "special \"%s\"\n", sc->sc_name);
		if (opts & VERIFY)
			continue;
		 sprintf(buf, "FILE=%s;export FILE;%s",
					   target, sc->sc_name);
		 runspecial (buf);

	}
}
Esempio n. 8
0
int main (int argc, char *argv[])
{
    struct addrinfo *ap, *ap2;
    int err, numerichost = 0, numericserv = 0;
    char *hname, *port = 0, *sep;
    struct addrinfo hints;

    whoami = strrchr(argv[0], '/');
    if (whoami == 0)
        whoami = argv[0];
    else
        whoami = whoami+1;

    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = 0;
    hints.ai_socktype = 0;

    hname = 0;
    hints.ai_family = 0;

    if (argc == 1)
        usage ();

    while (++argv, --argc > 0) {
        char *arg;
        arg = *argv;

        if (*arg != '-')
            hname = arg;
        else if (arg[1] == 0 || arg[2] != 0)
            usage ();
        else
            switch (arg[1]) {
            case 'u':
                hints.ai_protocol = IPPROTO_UDP;
                break;
            case 't':
                hints.ai_protocol = IPPROTO_TCP;
                break;
            case 'R':
                hints.ai_protocol = IPPROTO_RAW;
                break;
            case 'I':
                hints.ai_protocol = IPPROTO_ICMP;
                break;
            case 'd':
                hints.ai_socktype = SOCK_DGRAM;
                break;
            case 's':
                hints.ai_socktype = SOCK_STREAM;
                break;
            case 'r':
                hints.ai_socktype = SOCK_RAW;
                break;
            case 'p':
                if (argv[1] == 0 || argv[1][0] == 0 || argv[1][0] == '-')
                    usage ();
                port = argv[1];
                argc--, argv++;
                break;
            case '4':
                hints.ai_family = AF_INET;
                break;
#ifdef AF_INET6
            case '6':
                hints.ai_family = AF_INET6;
                break;
#endif
            case 'N':
                numerichost = 1;
                break;
            case 'n':
                numericserv = 1;
                break;
            case 'P':
                hints.ai_flags |= AI_PASSIVE;
                break;
            default:
                usage ();
            }
    }

    if (hname && !numerichost)
        hints.ai_flags |= AI_CANONNAME;
    if (numerichost) {
#ifdef AI_NUMERICHOST
        hints.ai_flags |= AI_NUMERICHOST;
#else
        fprintf(stderr, "AI_NUMERICHOST not defined on this platform\n");
        exit(1);
#endif
    }
    if (numericserv) {
#ifdef AI_NUMERICSERV
        hints.ai_flags |= AI_NUMERICSERV;
#else
        fprintf(stderr, "AI_NUMERICSERV not defined on this platform\n");
        exit(1);
#endif
    }

    printf("getaddrinfo(hostname %s, service %s,\n"
           "            hints { ",
           hname ? hname : "(null)", port ? port : "(null)");
    sep = "";
#define Z(FLAG) if (hints.ai_flags & AI_##FLAG) printf("%s%s", sep, #FLAG), sep = "|"
    Z(CANONNAME);
    Z(PASSIVE);
#ifdef AI_NUMERICHOST
    Z(NUMERICHOST);
#endif
#ifdef AI_NUMERICSERV
    Z(NUMERICSERV);
#endif
    if (sep[0] == 0)
        printf ("no-flags");
    if (hints.ai_family)
        printf(" %s", familyname(hints.ai_family));
    if (hints.ai_socktype)
        printf(" SOCK_%s", socktypename(hints.ai_socktype));
    if (hints.ai_protocol)
        printf(" IPPROTO_%s", protoname(hints.ai_protocol));
    printf(" }):\n");

    err = getaddrinfo(hname, port, &hints, &ap);
    if (err) {
        printf("\terror => %s\n", eaistr(err));
        return 1;
    }

    for (ap2 = ap; ap2; ap2 = ap2->ai_next) {
        char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
        /* If we don't do this, even AIX's own getnameinfo will reject
           the sockaddr structures.  The sa_len field doesn't get set
           either, on AIX, but getnameinfo won't complain.  */
        if (ap2->ai_addr->sa_family == 0) {
            printf("BAD: sa_family zero! fixing...\n");
            ap2->ai_addr->sa_family = ap2->ai_family;
        } else if (ap2->ai_addr->sa_family != ap2->ai_family) {
            printf("BAD: sa_family != ai_family! fixing...\n");
            ap2->ai_addr->sa_family = ap2->ai_family;
        }
        if (getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof(hbuf),
                        pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
            strlcpy(hbuf, "...", sizeof(hbuf));
            strlcpy(pbuf, "...", sizeof(pbuf));
        }
        printf("%p:\n"
               "\tfamily = %s\tproto = %-4s\tsocktype = %s\n",
               (void *) ap2, familyname(ap2->ai_family),
               protoname (ap2->ai_protocol),
               socktypename (ap2->ai_socktype));
        if (ap2->ai_canonname) {
            if (ap2->ai_canonname[0])
                printf("\tcanonname = %s\n", ap2->ai_canonname);
            else
                printf("BAD: ai_canonname is set but empty!\n");
        } else if (ap2 == ap && (hints.ai_flags & AI_CANONNAME)) {
            printf("BAD: first ai_canonname is null!\n");
        }
        printf("\taddr = %-28s\tport = %s\n", hbuf, pbuf);

        err = getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof (hbuf),
                          pbuf, sizeof(pbuf), NI_NAMEREQD);
        if (err)
            printf("\tgetnameinfo(NI_NAMEREQD): %s\n", eaistr(err));
        else
            printf("\tgetnameinfo => %s, %s\n", hbuf, pbuf);
    }
    freeaddrinfo(ap);
    return 0;
}
Esempio n. 9
0
static int dummy_portmap(int sock, FILE *portmap_file)
{
	struct sockaddr_in sin;
	int pktlen, addrlen;
	unsigned char pkt[65536];	/* Max UDP packet size */
	/* RPC UDP packets do not include TCP fragment size */
	struct rpc_call *rpc = (struct rpc_call *) &pkt[-4];
	struct rpc_auth *cred;
	struct rpc_auth *vrf;
	struct portmap_args *args;
	struct portmap_reply rply;

	for (;;) {
		addrlen = sizeof sin;
		pktlen = recvfrom(sock, &pkt, sizeof pkt, 0,
				  (struct sockaddr *)&sin, &addrlen);

		if (pktlen < 0) {
			if (errno == EINTR)
				continue;

			return -1;
		}

		/* +4 to skip the TCP fragment header */
		if (pktlen + 4 < sizeof(struct portmap_call))
			continue;	/* Bad packet */

		if (rpc->hdr.udp.msg_type != htonl(RPC_CALL))
			continue;	/* Bad packet */

		memset(&rply, 0, sizeof rply);

		rply.rpc.hdr.udp.xid = rpc->hdr.udp.xid;
		rply.rpc.hdr.udp.msg_type = htonl(RPC_REPLY);

		cred = (struct rpc_auth *) &rpc->cred_flavor;
		if (rpc->rpc_vers != htonl(2)) {
			rply.rpc.reply_state = htonl(REPLY_DENIED);
			/* state <- RPC_MISMATCH == 0 */
		} else if (rpc->program != htonl(PORTMAP_PROGRAM)) {
			rply.rpc.reply_state = htonl(PROG_UNAVAIL);
		} else if (rpc->prog_vers != htonl(2)) {
			rply.rpc.reply_state = htonl(PROG_MISMATCH);
		} else if (!(vrf = get_auth(cred)) ||
			   (char *)vrf > (char *)pkt + pktlen - 8 - sizeof(*args) ||
			   !(args = get_auth(vrf)) ||
			   (char *)args > (char *)pkt + pktlen - sizeof(*args) ||
			   check_cred(cred) || check_vrf(vrf)) {
			/* Can't deal with credentials data; the kernel
			   won't send them */
			rply.rpc.reply_state = htonl(SYSTEM_ERR);
		} else {
			switch (ntohl(rpc->proc)) {
			case PMAP_PROC_NULL:
				break;
			case PMAP_PROC_SET:
				if (args->proto == htonl(IPPROTO_TCP) ||
				    args->proto == htonl(IPPROTO_UDP)) {
					if (portmap_file)
						fprintf(portmap_file,
							"%u %u %s %u\n",
							ntohl(args->program),
							ntohl(args->version),
							protoname(args->proto),
							ntohl(args->port));
					rply.port = htonl(1);	/* TRUE = success */
				}
				break;
			case PMAP_PROC_UNSET:
				rply.port = htonl(1);	/* TRUE = success */
				break;
			case PMAP_PROC_GETPORT:
				break;
			case PMAP_PROC_DUMP:
				break;
			default:
				rply.rpc.reply_state = htonl(PROC_UNAVAIL);
				break;
			}
		}

		sendto(sock, &rply.rpc.hdr.udp, sizeof rply - 4, 0,
		       (struct sockaddr *)&sin, addrlen);
	}
}