Пример #1
0
/* ________________________________________________________________________ */
int nslookup_main(int argc, char **argv)
{
	struct hostent *host;

	/*
	* initialize DNS structure _res used in printing the default
	* name server and in the explicit name server option feature.
	*/
	
	res_init();

	/*
	* We allow 1 or 2 arguments. 
	* The first is the name to be looked up and the second is an 
	* optional DNS server with which to do the lookup. 
	* More than 3 arguments is an error to follow the pattern of the
	* standard nslookup
	*/

	if (argc < 2 || *argv[1]=='-' || argc > 3) 
		bb_show_usage();
	else if(argc == 3) 
		set_default_dns(argv[2]);

	server_print();
	if (is_ip_address(argv[1])) {
		host = gethostbyaddr_wrapper(argv[1]);
	} else {
		host = xgethostbyname(argv[1]);
	}
	hostent_fprint(host, "Name:  ");
	return EXIT_SUCCESS;
}
Пример #2
0
static void init_RemoteLog(void)
{

	struct sockaddr_in remoteaddr;
	struct hostent *hostinfo;
	int len = sizeof(remoteaddr);

	memset(&remoteaddr, 0, len);

	remotefd = socket(AF_INET, SOCK_DGRAM, 0);

	if (remotefd < 0) {
		bb_error_msg_and_die("cannot create socket");
	}

	hostinfo = xgethostbyname(RemoteHost);

	remoteaddr.sin_family = AF_INET;
	remoteaddr.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
	remoteaddr.sin_port = htons(RemotePort);

	/* Since we are using UDP sockets, connect just sets the default host and port
	 * for future operations
	 */
	if (0 != (connect(remotefd, (struct sockaddr *) &remoteaddr, len))) {
		bb_error_msg_and_die("cannot connect to remote host %s:%d", RemoteHost,
						  RemotePort);
	}

}
Пример #3
0
HTTPConnection * HTTPConnection_new_client(const char * host, uint16_t port) {
  struct in_addr ip_address;
  if (! inet_aton(host, &ip_address)) {
    /* it's a host name */
    if (xgethostbyname(host, &ip_address) != 0) {
      return NULL;
    }
  }

  SOCKET s = socket(PF_INET, SOCK_STREAM, 0);
  if (s == INVALID_SOCKET) {
    return NULL;
  }

  struct sockaddr_in a;
  a.sin_family = AF_INET;
  a.sin_port = htons(port);
  a.sin_addr = ip_address;

  if (connect(s, (struct sockaddr *) &a, sizeof(a)) < 0) {
    closesocket(s);
    return NULL;
  }

  return HTTPConnection_new(s);
}
Пример #4
0
void bb_lookup_host(struct sockaddr_in *s_in, const char *host)
{
	struct hostent *he;

	memset(s_in, 0, sizeof(struct sockaddr_in));
	s_in->sin_family = AF_INET;
	he = xgethostbyname(host);
	memcpy(&(s_in->sin_addr), he->h_addr_list[0], he->h_length);
}
Пример #5
0
static struct in_addr getserver(char * host)
{
	struct in_addr addr;

	struct hostent * he;
	he = xgethostbyname(host);
	memcpy(&addr, he->h_addr, sizeof addr);

	TRACE(1, ("addr: %s\n", inet_ntoa(addr)));

	return addr;
}
Пример #6
0
static void init_RemoteLog(void)
{
	memset(&remoteaddr, 0, sizeof(remoteaddr));
	remotefd = socket(AF_INET, SOCK_DGRAM, 0);

	if (remotefd < 0) {
		bb_error_msg("cannot create socket");
	}

	remoteaddr.sin_family = AF_INET;
	remoteaddr.sin_addr = *(struct in_addr *) *(xgethostbyname(RemoteHost))->h_addr_list;
	remoteaddr.sin_port = htons(RemotePort);
}
Пример #7
0
static void init_RemoteLog(void)
{
	memset(&remoteaddr, 0, sizeof(remoteaddr));
	remotefd = socket(AF_INET, SOCK_DGRAM, 0);

	if (remotefd < 0) {
          /* BRCM begin */
          if ((local_logging == FALSE) && (circular_logging == FALSE))
		bb_error_msg_and_die("cannot create socket");
          else
                bb_perror_msg("cannot create socket");
          /* BRCM end */
	}

	remoteaddr.sin_family = AF_INET;
	remoteaddr.sin_addr = *(struct in_addr *) *(xgethostbyname(RemoteHost))->h_addr_list;
	remoteaddr.sin_port = htons(RemotePort);
}
Пример #8
0
static void tlist_add(char *str)
{
	char *hostname;
	int port;
	
	struct hostent *host;
	TListNode n = NEW(TListNode);

	hostname = str;
	if((str = strchr(hostname, ':')) != NULL) {
		*str++ = '\0';
		port = atoi(str);
	} else
		port = DEFAULT_TRACKER_PORT;

	memset(&(n->sin), '\0', sizeof(struct sockaddr_in));

	if((n->sin.sin_addr.s_addr = inet_addr(hostname)) < 0) {
		if((host = xgethostbyname(hostname)) == NULL)
			goto err;

		memcpy(&n->sin.sin_addr, host->h_addr, host->h_length);
		xfree(host);
	}

	n->sin.sin_family = AF_INET;
	n->sin.sin_port = htons(port);

	if((n->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0)
		goto err;

	n->l = tlist;
	tlist = n;
	tlist_count++;

	return;
err:
	log("!!! Couldn't resolve tracker: %s", hostname);
	xfree(n);
}
Пример #9
0
static void             /* not inline */
send_probe(int seq, int ttl)
{
	struct opacket *op = outpacket;
	struct ip *ip = &op->ip;
	struct udphdr *up = &op->udp;
	int i;
	struct timezone tz;
#if defined (DMP_TRACEROUTE_1)
	int dataSize = datalen -12; /* Minus some parameters' length in struct opacket*/
#endif
	ip->ip_off = 0;
	ip->ip_hl = sizeof(*ip) >> 2;
	ip->ip_p = IPPROTO_UDP;
#if defined (DMP_TRACEROUTE_1)
	ip->ip_len = dataSize;
#else
	ip->ip_len = datalen;
#endif	
	ip->ip_ttl = ttl;
	ip->ip_v = IPVERSION;
	ip->ip_id = htons(ident+seq);

	up->source = htons(ident);
	up->dest = htons(port+seq);
#if defined (DMP_TRACEROUTE_1)
	up->len = htons((u_short)(dataSize - sizeof(struct ip)));
#else
	up->len = htons((u_short)(datalen - sizeof(struct ip)));
#endif	
	up->check = 0;

	op->seq = seq;
	op->ttl = ttl;
	(void) gettimeofday(&op->tv, &tz);

#if defined (DMP_TRACEROUTE_1)
	i = sendto(sndsock, (char *)outpacket, dataSize, 0, &whereto,
		sizeof(struct sockaddr));
#else
	i = sendto(sndsock, (char *)outpacket, datalen, 0, &whereto,
		sizeof(struct sockaddr));
#endif
#if defined (DMP_TRACEROUTE_1)
	if (i < 0 || i != dataSize)  {
#else
	if (i < 0 || i != datalen)  {
#endif
		if (i<0)
			perror("sendto");
#if defined (DMP_TRACEROUTE_1)
		printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
			dataSize, i);
#else
		printf("traceroute: wrote %s %d chars, ret=%d\n", hostname,
			datalen, i);
#endif			
		(void) fflush(stdout);
	}
}


int
#ifndef CONFIG_TRACEROUTE
main(int argc, char *argv[])
#else
traceroute_main(int argc, char *argv[])
#endif
{
	extern char *optarg;
	extern int optind;
	struct hostent *hp;
	struct sockaddr_in from, *to;
	int ch, i, on, probe, seq, tos, ttl;

	int options = 0;                /* socket options */
	char *source = 0;
	int nprobes = 3;
#if defined(AEI_VDSL_CUSTOMER_QWEST_Q2000)
	int ttl_set_flag = 0;
#endif
#if defined(AEI_VDSL_CUSTOMER_NCS)
	int failcount = 0;
#endif
#if defined(DMP_TRACEROUTE_1)
	unsigned int repTime;
	char strRepTime[16];
	TraceRouteDataMsgBody traceRouteInfo;
	memset(&traceRouteInfo, 0 , sizeof(TraceRouteDataMsgBody));
	TraceRouteDataMsgBody *pTraceRouteInfo = &traceRouteInfo;
	cmsMsg_init(EID_TRACEROUTE, &msgHandle);
#endif
	on = 1;
	seq = tos = 0;
	to = (struct sockaddr_in *)&whereto;
	while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF)
		switch(ch) {
		case 'd':
#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
			options |= SO_DEBUG;
#endif
			break;
		case 'm':
			max_ttl = atoi(optarg);
#if defined(AEI_VDSL_CUSTOMER_QWEST_Q2000)
			ttl_set_flag = 1;
#endif
			if (max_ttl <= 1)
				bb_error_msg_and_die("max ttl must be >1.");
			break;
		case 'n':
			nflag++;
			break;
		case 'p':
			port = atoi(optarg);
			if (port < 1)
				bb_error_msg_and_die("port must be >0.");
			break;
		case 'q':
			nprobes = atoi(optarg);
			if (nprobes < 1)
				bb_error_msg_and_die("nprobes must be >0.");
			break;
		case 'r':
			options |= SO_DONTROUTE;
			break;
		case 's':
			/*
			 * set the ip source address of the outbound
			 * probe (e.g., on a multi-homed host).
			 */
			source = optarg;
			break;
		case 't':
			tos = atoi(optarg);
			if (tos < 0 || tos > 255)
				bb_error_msg_and_die("tos must be 0 to 255.");
			break;
		case 'v':
#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
			verbose++;
#endif
			break;
		case 'w':
			waittime = atoi(optarg);
			if (waittime <= 1)
				bb_error_msg_and_die("wait must be >1 sec.");
			break;
		default:
			bb_show_usage();
		}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		bb_show_usage();

	setlinebuf (stdout);

	memset(&whereto, 0, sizeof(struct sockaddr));
#if defined(DMP_TRACEROUTE_1)
	hp = gethostbyname(*argv);
	if (*++argv)
	{
		requesterId = atoi(*argv);		
	}
	if (hp == NULL)
	{
		AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_CannotResolveHostName);
		bb_herror_msg_and_die("%s", *--argv);
	}
#else
	hp = xgethostbyname(*argv);
#endif
			to->sin_family = hp->h_addrtype;
	memcpy(&to->sin_addr, hp->h_addr, hp->h_length);
			hostname = (char *)hp->h_name;
	if (*++argv)
		datalen = atoi(*argv);
#if defined (DMP_TRACEROUTE_1)
	if (datalen == 0)
	{
		datalen = 40; /*Default data length*/
	}
#endif		
	if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket))
		bb_error_msg_and_die("packet size must be 0 <= s < %d.",
		    MAXPACKET - sizeof(struct opacket));
	datalen += sizeof(struct opacket);
	outpacket = (struct opacket *)xmalloc((unsigned)datalen);
	memset(outpacket, 0, datalen);
	outpacket->ip.ip_dst = to->sin_addr;
	outpacket->ip.ip_tos = tos;
#if defined(DMP_TRACEROUTE_1)
	outpacket->ip.ip_tos = (outpacket->ip.ip_tos)<<2;
#endif
	outpacket->ip.ip_v = IPVERSION;
	outpacket->ip.ip_id = 0;

	ident = (getpid() & 0xffff) | 0x8000;

	if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
		bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);

	s = create_icmp_socket();

#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
	if (options & SO_DEBUG)
		(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
				  (char *)&on, sizeof(on));
#endif
	if (options & SO_DONTROUTE)
		(void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,
				  (char *)&on, sizeof(on));
#ifdef SO_SNDBUF
	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
		       sizeof(datalen)) < 0)
		bb_perror_msg_and_die("SO_SNDBUF");
#endif
#ifdef IP_HDRINCL
	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
		       sizeof(on)) < 0)
		bb_perror_msg_and_die("IP_HDRINCL");
#endif
#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
	if (options & SO_DEBUG)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
				  (char *)&on, sizeof(on));
#endif
	if (options & SO_DONTROUTE)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
				  (char *)&on, sizeof(on));

	if (source) {
		memset(&from, 0, sizeof(struct sockaddr));
		from.sin_family = AF_INET;
		from.sin_addr.s_addr = inet_addr(source);
		if (from.sin_addr.s_addr == -1)
			bb_error_msg_and_die("unknown host %s", source);
		outpacket->ip.ip_src = from.sin_addr;
#ifndef IP_HDRINCL
		if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)
			bb_perror_msg_and_die("bind");
#endif
	}

	fprintf(stderr, "traceroute to %s (%s)", hostname,
		inet_ntoa(to->sin_addr));
	if (source)
		fprintf(stderr, " from %s", source);
	fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);

	for (ttl = 1; ttl <= max_ttl; ++ttl) {
		u_long lastaddr = 0;
		int got_there = 0;
		int unreachable = 0;

#if defined(DMP_TRACEROUTE_1)
		pTraceRouteInfo->routeHopsNumberOfEntries++;	
#endif
		printf("%2d ", ttl);
		for (probe = 0; probe < nprobes; ++probe) {
			int cc, reset_timer;
			struct timeval t1, t2;
			struct timezone tz;
			struct ip *ip;

			(void) gettimeofday(&t1, &tz);
			send_probe(++seq, ttl);
			reset_timer = 1;
			while ((cc = wait_for_reply(s, &from, reset_timer)) != 0) {
				(void) gettimeofday(&t2, &tz);
				if ((i = packet_ok(packet, cc, &from, seq))) {
					reset_timer = 1;
					if (from.sin_addr.s_addr != lastaddr) {
						print(packet, cc, &from);
						lastaddr = from.sin_addr.s_addr;
					}
					printf("  %g ms", deltaT(&t1, &t2));
#if defined(DMP_TRACEROUTE_1)
					struct icmp *hopIcp;
					int hopHlen;
					struct ip *hopIp;
					hopIp = (struct ip *) packet;
					hopHlen = hopIp->ip_hl << 2;
					hopIcp = (struct icmp *)(packet + hopHlen);
					repTime = ((int)(t2.tv_sec - t1.tv_sec) * 1000 + (int)(t2.tv_usec - t1.tv_usec) / 1000);
					sprintf(strRepTime, "%d,", repTime);
					pTraceRouteInfo->responseTime+=repTime; 
					pTraceRouteInfo->routeHops[ttl-1].hopErrorCode = hopIcp->icmp_code;
					sprintf(pTraceRouteInfo->routeHops[ttl-1].hopHost, "%s", inet_ntoa(from.sin_addr));
					sprintf(pTraceRouteInfo->routeHops[ttl-1].hopHostAddress, "%s", inet_ntoa(from.sin_addr));	
					strcat(pTraceRouteInfo->routeHops[ttl-1].hopRTTimes, strRepTime);		
#endif
					switch(i - 1) {
					case ICMP_UNREACH_PORT:
						ip = (struct ip *)packet;
						if (ip->ip_ttl <= 1)
							printf(" !");
						++got_there;
						break;
					case ICMP_UNREACH_NET:
						++unreachable;
						printf(" !N");
						break;
					case ICMP_UNREACH_HOST:
						++unreachable;
						printf(" !H");
						break;
					case ICMP_UNREACH_PROTOCOL:
						++got_there;
						printf(" !P");
						break;
					case ICMP_UNREACH_NEEDFRAG:
						++unreachable;
						printf(" !F");
						break;
					case ICMP_UNREACH_SRCFAIL:
						++unreachable;
						printf(" !S");
						break;
					}
					break;
				} else
					reset_timer = 0;
			}
			if (cc == 0)
			{
#if defined(AEI_VDSL_CUSTOMER_NCS)
				failcount++;
#endif
				printf(" *");
			}
#if defined(AEI_VDSL_CUSTOMER_NCS)
            		else
				failcount=0;
#endif
			(void) fflush(stdout);
		}
		putchar('\n');
		if (got_there || (unreachable && unreachable >= nprobes-1))
		{
#if defined(DMP_TRACEROUTE_1)		
			if (got_there)
			{
				AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Complete);
			}
			else if (unreachable && unreachable >= nprobes-1)
			{
				AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_MaxHopCountExceeded);
			}
#endif
			return 0;
		}
#if defined(AEI_VDSL_CUSTOMER_NCS)
#if defined(AEI_VDSL_CUSTOMER_QWEST_Q2000)
		if (failcount >= nprobes*2&&ttl_set_flag==0)
#else
		if (failcount >= nprobes*2)
#endif
		{
#if defined(DMP_TRACEROUTE_1)
			AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_MaxHopCountExceeded);
#endif
			return 0;
		}	
#endif
	}
#if defined(DMP_TRACEROUTE_1)
	AEI_sendTraceRouteEventMessage(pTraceRouteInfo, Error_MaxHopCountExceeded);
#endif

	return 0;
}
int hostname_main(int argc UNUSED_PARAM, char **argv)
{
	enum {
		OPT_d = 0x1,
		OPT_f = 0x2,
		OPT_i = 0x4,
		OPT_s = 0x8,
		OPT_F = 0x10,
		OPT_dfi = 0x7,
	};

	unsigned opts;
	char *buf;
	char *hostname_str;

#if ENABLE_LONG_OPTS
	applet_long_options =
		"domain\0"     No_argument "d"
		"fqdn\0"       No_argument "f"
	//Enable if seen in active use in some distro:
	//	"long\0"       No_argument "f"
	//	"ip-address\0" No_argument "i"
	//	"short\0"      No_argument "s"
	//	"verbose\0"    No_argument "v"
		"file\0"       No_argument "F"
		;

#endif
	/* dnsdomainname from net-tools 1.60, hostname 1.100 (2001-04-14),
	 * supports hostname's options too (not just -v as manpage says) */
	opts = getopt32(argv, "dfisF:v", &hostname_str);
	argv += optind;
	buf = safe_gethostname();
	if (applet_name[0] == 'd') /* dnsdomainname? */
		opts = OPT_d;

	if (opts & OPT_dfi) {
		/* Cases when we need full hostname (or its part) */
		struct hostent *hp;
		char *p;

		hp = xgethostbyname(buf);
		p = strchrnul(hp->h_name, '.');
		if (opts & OPT_f) {
			puts(hp->h_name);
		} else if (opts & OPT_s) {
			*p = '\0';
			puts(hp->h_name);
		} else if (opts & OPT_d) {
			if (*p)
				puts(p + 1);
		} else /*if (opts & OPT_i)*/ {
			if (hp->h_length == sizeof(struct in_addr)) {
				struct in_addr **h_addr_list = (struct in_addr **)hp->h_addr_list;
				while (*h_addr_list) {
					printf(h_addr_list[1] ? "%s " : "%s", inet_ntoa(**h_addr_list));
					h_addr_list++;
				}
				bb_putchar('\n');
			}
		}
	} else if (opts & OPT_s) {
		strchrnul(buf, '.')[0] = '\0';
		puts(buf);
	} else if (opts & OPT_F) {
		/* Set the hostname */
		do_sethostname(hostname_str, 1);
	} else if (argv[0]) {
		/* Set the hostname */
		do_sethostname(argv[0], 0);
	} else {
		/* Just print the current hostname */
		puts(buf);
	}

	if (ENABLE_FEATURE_CLEAN_UP)
		free(buf);
	return EXIT_SUCCESS;
}
Пример #11
0
int sendmail_main(int argc UNUSED_PARAM, char **argv)
{
	char *opt_connect = opt_connect;
	char *opt_from = NULL;
	char *s;
	llist_t *list = NULL;
	char *host = sane_address(safe_gethostname());
	unsigned nheaders = 0;
	int code;
	enum {
		HDR_OTHER = 0,
		HDR_TOCC,
		HDR_BCC,
	} last_hdr = 0;
	int check_hdr;
	int has_to = 0;

	enum {
	//--- standard options
		OPT_t = 1 << 0,         // read message for recipients, append them to those on cmdline
		OPT_f = 1 << 1,         // sender address
		OPT_o = 1 << 2,         // various options. -oi IMPLIED! others are IGNORED!
		OPT_i = 1 << 3,         // IMPLIED!
	//--- BB specific options
		OPT_w = 1 << 4,         // network timeout
		OPT_H = 1 << 5,         // use external connection helper
		OPT_S = 1 << 6,         // specify connection string
		OPT_a = 1 << 7,         // authentication tokens
		OPT_v = 1 << 8,         // verbosity
	};

	// init global variables
	INIT_G();

	// save initial stdin since body is piped!
	xdup2(STDIN_FILENO, 3);
	G.fp0 = xfdopen_for_read(3);

	// parse options
	// -v is a counter, -H and -S are mutually exclusive, -a is a list
	opt_complementary = "vv:w+:H--S:S--H:a::";
	// N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect
	// -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility,
	// it is still under development.
	opts = getopt32(argv, "tf:o:iw:H:S:a::v", &opt_from, NULL,
			&timeout, &opt_connect, &opt_connect, &list, &verbose);
	//argc -= optind;
	argv += optind;

	// process -a[upm]<token> options
	if ((opts & OPT_a) && !list)
		bb_show_usage();
	while (list) {
		char *a = (char *) llist_pop(&list);
		if ('u' == a[0])
			G.user = xstrdup(a+1);
		if ('p' == a[0])
			G.pass = xstrdup(a+1);
		// N.B. we support only AUTH LOGIN so far
		//if ('m' == a[0])
		//	G.method = xstrdup(a+1);
	}
	// N.B. list == NULL here
	//bb_info_msg("OPT[%x] AU[%s], AP[%s], AM[%s], ARGV[%s]", opts, au, ap, am, *argv);

	// connect to server

	// connection helper ordered? ->
	if (opts & OPT_H) {
		const char *args[] = { "sh", "-c", opt_connect, NULL };
		// plug it in
		launch_helper(args);
		// Now:
		// our stdout will go to helper's stdin,
		// helper's stdout will be available on our stdin.

		// Wait for initial server message.
		// If helper (such as openssl) invokes STARTTLS, the initial 220
		// is swallowed by helper (and not repeated after TLS is initiated).
		// We will send NOOP cmd to server and check the response.
		// We should get 220+250 on plain connection, 250 on STARTTLSed session.
		//
		// The problem here is some servers delay initial 220 message,
		// and consider client to be a spammer if it starts sending cmds
		// before 220 reached it. The code below is unsafe in this regard:
		// in non-STARTTLSed case, we potentially send NOOP before 220
		// is sent by server.
		// Ideas? (--delay SECS opt? --assume-starttls-helper opt?)
		code = smtp_check("NOOP", -1);
		if (code == 220)
			// we got 220 - this is not STARTTLSed connection,
			// eat 250 response to our NOOP
			smtp_check(NULL, 250);
		else
		if (code != 250)
			bb_error_msg_and_die("SMTP init failed");
	} else {
		// vanilla connection
		int fd;
		// host[:port] not explicitly specified? -> use $SMTPHOST
		// no $SMTPHOST? -> use localhost
		if (!(opts & OPT_S)) {
			opt_connect = getenv("SMTPHOST");
			if (!opt_connect)
				opt_connect = (char *)"127.0.0.1";
		}
		// do connect
		fd = create_and_connect_stream_or_die(opt_connect, 25);
		// and make ourselves a simple IO filter
		xmove_fd(fd, STDIN_FILENO);
		xdup2(STDIN_FILENO, STDOUT_FILENO);

		// Wait for initial server 220 message
		smtp_check(NULL, 220);
	}

	// we should start with modern EHLO
	if (250 != smtp_checkp("EHLO %s", host, -1))
		smtp_checkp("HELO %s", host, 250);

	// perform authentication
	if (opts & OPT_a) {
		smtp_check("AUTH LOGIN", 334);
		// we must read credentials unless they are given via -a[up] options
		if (!G.user || !G.pass)
			get_cred_or_die(4);
		encode_base64(NULL, G.user, NULL);
		smtp_check("", 334);
		encode_base64(NULL, G.pass, NULL);
		smtp_check("", 235);
	}

	// set sender
	// N.B. we have here a very loosely defined algorythm
	// since sendmail historically offers no means to specify secrets on cmdline.
	// 1) server can require no authentication ->
	//	we must just provide a (possibly fake) reply address.
	// 2) server can require AUTH ->
	//	we must provide valid username and password along with a (possibly fake) reply address.
	//	For the sake of security username and password are to be read either from console or from a secured file.
	//	Since reading from console may defeat usability, the solution is either to read from a predefined
	//	file descriptor (e.g. 4), or again from a secured file.

	// got no sender address? use auth name, then UID username as a last resort
	if (!opt_from) {
		opt_from = xasprintf("%s@%s",
		                     G.user ? G.user : xuid2uname(getuid()),
		                     xgethostbyname(host)->h_name);
	}
	free(host);

	smtp_checkp("MAIL FROM:<%s>", opt_from, 250);

	// process message

	// read recipients from message and add them to those given on cmdline.
	// this means we scan stdin for To:, Cc:, Bcc: lines until an empty line
	// and then use the rest of stdin as message body
	code = 0; // set "analyze headers" mode
	while ((s = xmalloc_fgetline(G.fp0)) != NULL) {
 dump:
		// put message lines doubling leading dots
		if (code) {
			// escape leading dots
			// N.B. this feature is implied even if no -i (-oi) switch given
			// N.B. we need to escape the leading dot regardless of
			// whether it is single or not character on the line
			if ('.' == s[0] /*&& '\0' == s[1] */)
				bb_putchar('.');
			// dump read line
			send_r_n(s);
			free(s);
			continue;
		}

		// analyze headers
		// To: or Cc: headers add recipients
		check_hdr = (0 == strncasecmp("To:", s, 3));
		has_to |= check_hdr;
		if (opts & OPT_t) {
			if (check_hdr || 0 == strncasecmp("Bcc:" + 1, s, 3)) {
				rcptto_list(s+3);
				last_hdr = HDR_TOCC;
				goto addheader;
			}
			// Bcc: header adds blind copy (hidden) recipient
			if (0 == strncasecmp("Bcc:", s, 4)) {
				rcptto_list(s+4);
				free(s);
				last_hdr = HDR_BCC;
				continue; // N.B. Bcc: vanishes from headers!
			}
		}
		check_hdr = (list && isspace(s[0]));
		if (strchr(s, ':') || check_hdr) {
			// other headers go verbatim
			// N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines.
			// Continuation is denoted by prefixing additional lines with whitespace(s).
			// Thanks (stefan.seyfried at googlemail.com) for pointing this out.
			if (check_hdr && last_hdr != HDR_OTHER) {
				rcptto_list(s+1);
				if (last_hdr == HDR_BCC)
					continue;
					// N.B. Bcc: vanishes from headers!
			} else {
				last_hdr = HDR_OTHER;
			}
 addheader:
			// N.B. we allow MAX_HEADERS generic headers at most to prevent attacks
			if (MAX_HEADERS && ++nheaders >= MAX_HEADERS)
				goto bail;
			llist_add_to_end(&list, s);
		} else {
			// a line without ":" (an empty line too, by definition) doesn't look like a valid header
			// so stop "analyze headers" mode
 reenter:
			// put recipients specified on cmdline
			check_hdr = 1;
			while (*argv) {
				char *t = sane_address(*argv);
				rcptto(t);
				//if (MAX_HEADERS && ++nheaders >= MAX_HEADERS)
				//	goto bail;
				if (!has_to) {
					const char *hdr;

					if (check_hdr && argv[1])
						hdr = "To: %s,";
					else if (check_hdr)
						hdr = "To: %s";
					else if (argv[1])
						hdr = "To: %s," + 3;
					else
						hdr = "To: %s" + 3;
					llist_add_to_end(&list,
							xasprintf(hdr, t));
					check_hdr = 0;
				}
				argv++;
			}
			// enter "put message" mode
			// N.B. DATA fails iff no recipients were accepted (or even provided)
			// in this case just bail out gracefully
			if (354 != smtp_check("DATA", -1))
				goto bail;
			// dump the headers
			while (list) {
				send_r_n((char *) llist_pop(&list));
			}
			// stop analyzing headers
			code++;
			// N.B. !s means: we read nothing, and nothing to be read in the future.
			// just dump empty line and break the loop
			if (!s) {
				send_r_n("");
				break;
			}
			// go dump message body
			// N.B. "s" already contains the first non-header line, so pretend we read it from input
			goto dump;
		}
	}
	// odd case: we didn't stop "analyze headers" mode -> message body is empty. Reenter the loop
	// N.B. after reenter code will be > 0
	if (!code)
		goto reenter;

	// finalize the message
	smtp_check(".", 250);
 bail:
	// ... and say goodbye
	smtp_check("QUIT", 221);
	// cleanup
	if (ENABLE_FEATURE_CLEAN_UP)
		fclose(G.fp0);

	return EXIT_SUCCESS;
}
Пример #12
0
int nc_main(int argc, char **argv)
{
    int do_listen = 0, lport = 0, tmpfd, opt, sfd, x;
    char buf[BUFSIZ];
#ifdef GAPING_SECURITY_HOLE
    char * pr00gie = NULL;
#endif

    struct sockaddr_in address;
    struct hostent *hostinfo;

    fd_set readfds, testfds;

    while ((opt = getopt(argc, argv, "lp:")) > 0) {
        switch (opt) {
        case 'l':
            do_listen++;
            break;
        case 'p':
            lport = atoi(optarg);
            break;
#ifdef GAPING_SECURITY_HOLE
        case 'e':
            pr00gie = optarg;
            break;
#endif
        default:
            show_usage();
        }
    }

#ifdef GAPING_SECURITY_HOLE
    if (pr00gie) {
        /* won't need stdin */
        close (fileno(stdin));
    }
#endif /* GAPING_SECURITY_HOLE */


    if ((do_listen && optind != argc) || (!do_listen && optind + 2 != argc))
        show_usage();

    if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        perror_msg_and_die("socket");
    x = 1;
    if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1)
        perror_msg_and_die ("reuseaddr failed");
    address.sin_family = AF_INET;

    if (lport != 0) {
        memset(&address.sin_addr, 0, sizeof(address.sin_addr));
        address.sin_port = htons(lport);

        if (bind(sfd, (struct sockaddr *) &address, sizeof(address)) < 0)
            perror_msg_and_die("bind");
    }

    if (do_listen) {
        socklen_t addrlen = sizeof(address);

        if (listen(sfd, 1) < 0)
            perror_msg_and_die("listen");

        if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0)
            perror_msg_and_die("accept");

        close(sfd);
        sfd = tmpfd;
    } else {
        hostinfo = xgethostbyname(argv[optind]);

        address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
        address.sin_port = htons(atoi(argv[optind+1]));

        if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0)
            perror_msg_and_die("connect");
    }

#ifdef GAPING_SECURITY_HOLE
    /* -e given? */
    if (pr00gie) {
        dup2(sfd, 0);
        close(sfd);
        dup2 (0, 1);
        dup2 (0, 2);
        execl (pr00gie, pr00gie, NULL);
        /* Don't print stuff or it will go over the wire.... */
        _exit(-1);
    }
#endif /* GAPING_SECURITY_HOLE */


    FD_ZERO(&readfds);
    FD_SET(sfd, &readfds);
    FD_SET(STDIN_FILENO, &readfds);

    while (1) {
        int fd;
        int ofd;
        int nread;

        testfds = readfds;

        if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0)
            perror_msg_and_die("select");

        for (fd = 0; fd < FD_SETSIZE; fd++) {
            if (FD_ISSET(fd, &testfds)) {
                if ((nread = safe_read(fd, buf, sizeof(buf))) < 0)
                    perror_msg_and_die("read");

                if (fd == sfd) {
                    if (nread == 0)
                        exit(0);
                    ofd = STDOUT_FILENO;
                } else {
                    if (nread == 0)
                        shutdown(sfd, 1);
                    ofd = sfd;
                }

                if (full_write(ofd, buf, nread) < 0)
                    perror_msg_and_die("write");
            }
        }
    }
}
Пример #13
0
int nc_main(int argc, char **argv)
{
	int do_listen = 0, lport = 0, delay = 0, wsecs = 0, tmpfd, opt, sfd, x;

#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
	char *pr00gie = NULL;
#endif

	struct sockaddr_in address;
	struct hostent *hostinfo;

	fd_set readfds, testfds;

	while ((opt = getopt(argc, argv, "lp:i:e:w:")) > 0) {
		switch (opt) {
			case 'l':
				do_listen++;
				break;
			case 'p':
				lport = bb_lookup_port(optarg, "tcp", 0);
				break;
			case 'i':
				delay = atoi(optarg);
				break;
#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
			case 'e':
				pr00gie = optarg;
				break;
#endif
			case 'w':
				wsecs = atoi(optarg);
				break;
			default:
				bb_show_usage();
		}
	}

	if ((do_listen && optind != argc) || (!do_listen && optind + 2 != argc))
		bb_show_usage();

	sfd = bb_xsocket(AF_INET, SOCK_STREAM, 0);
	x = 1;
	if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1)
		bb_perror_msg_and_die("reuseaddr");
	address.sin_family = AF_INET;

	if (wsecs) {
		signal(SIGALRM, timeout);
		alarm(wsecs);
	}

	if (lport != 0) {
		memset(&address.sin_addr, 0, sizeof(address.sin_addr));
		address.sin_port = lport;

		bb_xbind(sfd, (struct sockaddr *) &address, sizeof(address));
	}

	if (do_listen) {
		socklen_t addrlen = sizeof(address);

		bb_xlisten(sfd, 1);
		if ((tmpfd = accept(sfd, (struct sockaddr *) &address, &addrlen)) < 0)
			bb_perror_msg_and_die("accept");

		close(sfd);
		sfd = tmpfd;
	} else {
		hostinfo = xgethostbyname(argv[optind]);

		address.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
		address.sin_port = bb_lookup_port(argv[optind+1], "tcp", 0);

		if (connect(sfd, (struct sockaddr *) &address, sizeof(address)) < 0)
			bb_perror_msg_and_die("connect");
	}

	if (wsecs) {
		alarm(0);
		signal(SIGALRM, SIG_DFL);
	}

#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
	/* -e given? */
	if (pr00gie) {
		dup2(sfd, 0);
		close(sfd);
		dup2(0, 1);
		dup2(0, 2);
		execl(pr00gie, pr00gie, NULL);
		/* Don't print stuff or it will go over the wire.... */
		_exit(-1);
	}
#endif /* CONFIG_NC_GAPING_SECURITY_HOLE */

	FD_ZERO(&readfds);
	FD_SET(sfd, &readfds);
	FD_SET(STDIN_FILENO, &readfds);

	while (1) {
		int fd;
		int ofd;
		int nread;

		testfds = readfds;

		if (select(FD_SETSIZE, &testfds, NULL, NULL, NULL) < 0)
			bb_perror_msg_and_die("select");

		for (fd = 0; fd < FD_SETSIZE; fd++) {
			if (FD_ISSET(fd, &testfds)) {
				if ((nread = safe_read(fd, bb_common_bufsiz1,
					sizeof(bb_common_bufsiz1))) < 0)
				{
					bb_perror_msg_and_die(bb_msg_read_error);
				}

				if (fd == sfd) {
					if (nread == 0)
						exit(0);
					ofd = STDOUT_FILENO;
				} else {
					if (nread <= 0) {
						shutdown(sfd, 1 /* send */ );
						close(STDIN_FILENO);
						FD_CLR(STDIN_FILENO, &readfds);
					}
					ofd = sfd;
				}

				if (bb_full_write(ofd, bb_common_bufsiz1, nread) < 0)
					bb_perror_msg_and_die(bb_msg_write_error);
				if (delay > 0) {
					sleep(delay);
				}
			}
		}
	}
}
Пример #14
0
int hostname_main(int argc, char **argv)
{
	int opt;
	int type = 0;
	struct hostent *hp;
	char *filename = NULL;
	char buf[255];
	char *p = NULL;

	if (argc < 1)
		bb_show_usage();

        while ((opt = getopt(argc, argv, "dfisF:")) > 0) {
                switch (opt) {
		case 'd':
		case 'f':
		case 'i':
		case 's':
			type = opt;
			break;
		case 'F':
			filename = optarg;
			break;
		default:
			bb_show_usage();
		}
	}

	/* Output in desired format */
	if (type != 0) {
		gethostname(buf, 255);
		hp = xgethostbyname(buf);
		p = strchr(hp->h_name, '.');
		if (type == 'f') {
			puts(hp->h_name);
		} else if (type == 's') {
			if (p != NULL) {
				*p = 0;
			}
			puts(hp->h_name);
		} else if (type == 'd') {
			if (p) puts(p + 1);
		} else if (type == 'i') {
			while (hp->h_addr_list[0]) {
				printf("%s ", inet_ntoa(*(struct in_addr *) (*hp->h_addr_list++)));
			}
			printf("\n");
		}
	}
	/* Set the hostname */
	else if (filename != NULL) {
		do_sethostname(filename, 1);
	} else if (optind < argc) {
		do_sethostname(argv[optind], 0);
	}
	/* Or if all else fails,
	 * just print the current hostname */
	 else {
		gethostname(buf, 255);
		puts(buf);
	}
	return(0);
}
Пример #15
0
void log_remote_message(syslogd_remote_config_t *remote, const char *msg)
{
	remote_info_t *info;

	debug_printf("log_remote_message(remote=%p, msg=%s)", remote, msg);
	debug_printf("host=%s", remote->host);

	if (remote_socket == -1) {
		remote_socket = socket(AF_INET, SOCK_DGRAM, 0);
		if (remote_socket < 0) {
			bb_perror_msg_and_die("syslogd: cannot create socket");
		}
	}

	if (!remote->common.priv) {
		struct hostent *hostinfo = 0;

		if (remote->host) {
			debug_printf("Getting ip address for server: %s", remote->host);

			hostinfo = xgethostbyname(remote->host);

			debug_printf("Got hostinfo=%p", hostinfo);
		}

		if (!hostinfo || !hostinfo->h_addr_list) {
			debug_printf("Disabling remote target because we couldn't resolve %s", remote->host);
			remote->common.level = LOG_NONE;
			return;
		}

		debug_printf("Allocating priv");

		remote->common.priv = info = malloc(sizeof(*info));

		memset(&info->saremote, 0, sizeof(info->saremote));

		debug_printf("Creating socket");

		debug_printf("Setting up saremote");

		info->saremote.sin_family = AF_INET;
		debug_printf("%s:%d", __FILE__, __LINE__);
		info->saremote.sin_addr = *(struct in_addr *) *hostinfo->h_addr_list;
		debug_printf("%s:%d", __FILE__, __LINE__);
		info->saremote.sin_port = htons(remote->port);
		debug_printf("%s:%d", __FILE__, __LINE__);
	}
	else {
		debug_printf("%s:%d", __FILE__, __LINE__);
		info = (remote_info_t *)remote->common.priv;
	}
		debug_printf("%s:%d", __FILE__, __LINE__);

	for (;;) {
		debug_printf("%s:%d", __FILE__, __LINE__);
		if (-1 == sendto(remote_socket, msg, strlen(msg), 0, (struct sockaddr *)&info->saremote, sizeof(info->saremote))) {
			time_t now;
			static time_t last_message_time = 0;
		debug_printf("%s:%d", __FILE__, __LINE__);

			if (errno == EINTR) {
		debug_printf("%s:%d", __FILE__, __LINE__);
				continue;
			}
		debug_printf("%s:%d", __FILE__, __LINE__);

			/*
			 * Throttle these messages so that we don't get one after
			 * every message if the network is down
			 */
			now = time(0);
			if (now - last_message_time > MIN_ERRMSG_INTERVAL) {
				debug_printf("syslogd: cannot write to remote file handle on %s:%d - %m\n",
					remote->host, remote->port);

				debug_printf("host=%s", remote->host);
				debug_printf("port=%d", remote->port);

				syslog_local_message("syslogd: cannot write to remote file handle on %s:%d - %m\n",
					remote->host, remote->port);
				last_message_time = now;
			}
		}
		debug_printf("%s:%d", __FILE__, __LINE__);
		break;
	}
}
Пример #16
0
traceroute_main(int argc, char *argv[])
#endif
{
	extern char *optarg;
	extern int optind;
	struct hostent *hp;
	struct sockaddr_in from, *to;
	int ch, i, on, probe, seq, tos, ttl;

	int options = 0;                /* socket options */
	char *source = 0;
	int nprobes = 3;

	on = 1;
	seq = tos = 0;
	to = (struct sockaddr_in *)&whereto;
	while ((ch = getopt(argc, argv, "dm:np:q:rs:t:w:v")) != EOF)
		switch(ch) {
		case 'd':
#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
			options |= SO_DEBUG;
#endif
			break;
		case 'm':
			max_ttl = atoi(optarg);
			if (max_ttl <= 1)
				bb_error_msg_and_die("max ttl must be >1.");
			break;
		case 'n':
			nflag++;
			break;
		case 'p':
			port = atoi(optarg);
			if (port < 1)
				bb_error_msg_and_die("port must be >0.");
			break;
		case 'q':
			nprobes = atoi(optarg);
			if (nprobes < 1)
				bb_error_msg_and_die("nprobes must be >0.");
			break;
		case 'r':
			options |= SO_DONTROUTE;
			break;
		case 's':
			/*
			 * set the ip source address of the outbound
			 * probe (e.g., on a multi-homed host).
			 */
			source = optarg;
			break;
		case 't':
			tos = atoi(optarg);
			if (tos < 0 || tos > 255)
				bb_error_msg_and_die("tos must be 0 to 255.");
			break;
		case 'v':
#ifdef CONFIG_FEATURE_TRACEROUTE_VERBOSE
			verbose++;
#endif
			break;
		case 'w':
			waittime = atoi(optarg);
			if (waittime <= 1)
				bb_error_msg_and_die("wait must be >1 sec.");
			break;
		default:
			bb_show_usage();
		}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		bb_show_usage();

	setlinebuf (stdout);

	memset(&whereto, 0, sizeof(struct sockaddr));
	hp = xgethostbyname(*argv);
			to->sin_family = hp->h_addrtype;
	memcpy(&to->sin_addr, hp->h_addr, hp->h_length);
			hostname = (char *)hp->h_name;
	if (*++argv)
		datalen = atoi(*argv);
	if (datalen < 0 || datalen >= MAXPACKET - sizeof(struct opacket))
		bb_error_msg_and_die("packet size must be 0 <= s < %d.",
		    MAXPACKET - sizeof(struct opacket));
	datalen += sizeof(struct opacket);
	outpacket = (struct opacket *)xmalloc((unsigned)datalen);
	memset(outpacket, 0, datalen);
	outpacket->ip.ip_dst = to->sin_addr;
	outpacket->ip.ip_tos = tos;
	outpacket->ip.ip_v = IPVERSION;
	outpacket->ip.ip_id = 0;

	ident = (getpid() & 0xffff) | 0x8000;

	if ((sndsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
		bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);

	s = create_icmp_socket();

#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
	if (options & SO_DEBUG)
		(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
				  (char *)&on, sizeof(on));
#endif
	if (options & SO_DONTROUTE)
		(void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE,
				  (char *)&on, sizeof(on));
#ifdef SO_SNDBUF
	if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, (char *)&datalen,
		       sizeof(datalen)) < 0)
		bb_perror_msg_and_die("SO_SNDBUF");
#endif
#ifdef IP_HDRINCL
	if (setsockopt(sndsock, IPPROTO_IP, IP_HDRINCL, (char *)&on,
		       sizeof(on)) < 0)
		bb_perror_msg_and_die("IP_HDRINCL");
#endif
#ifdef CONFIG_FEATURE_TRACEROUTE_SO_DEBUG
	if (options & SO_DEBUG)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DEBUG,
				  (char *)&on, sizeof(on));
#endif
	if (options & SO_DONTROUTE)
		(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
				  (char *)&on, sizeof(on));

	if (source) {
		memset(&from, 0, sizeof(struct sockaddr));
		from.sin_family = AF_INET;
		from.sin_addr.s_addr = inet_addr(source);
		if (from.sin_addr.s_addr == -1)
			bb_error_msg_and_die("unknown host %s", source);
		outpacket->ip.ip_src = from.sin_addr;
#ifndef IP_HDRINCL
		if (bind(sndsock, (struct sockaddr *)&from, sizeof(from)) < 0)
			bb_perror_msg_and_die("bind");
#endif
	}

	fprintf(stderr, "traceroute to %s (%s)", hostname,
		inet_ntoa(to->sin_addr));
	if (source)
		fprintf(stderr, " from %s", source);
	fprintf(stderr, ", %d hops max, %d byte packets\n", max_ttl, datalen);

	for (ttl = 1; ttl <= max_ttl; ++ttl) {
		u_long lastaddr = 0;
		int got_there = 0;
		int unreachable = 0;

		printf("%2d ", ttl);
		for (probe = 0; probe < nprobes; ++probe) {
			int cc, reset_timer;
			struct timeval t1, t2;
			struct timezone tz;
			struct ip *ip;

			(void) gettimeofday(&t1, &tz);
			send_probe(++seq, ttl);
			reset_timer = 1;
			while ((cc = wait_for_reply(s, &from, reset_timer)) != 0) {
				(void) gettimeofday(&t2, &tz);
				if ((i = packet_ok(packet, cc, &from, seq))) {
					reset_timer = 1;
					if (from.sin_addr.s_addr != lastaddr) {
						print(packet, cc, &from);
						lastaddr = from.sin_addr.s_addr;
					}
					printf("  %g ms", deltaT(&t1, &t2));
					switch(i - 1) {
					case ICMP_UNREACH_PORT:
						ip = (struct ip *)packet;
						if (ip->ip_ttl <= 1)
							printf(" !");
						++got_there;
						break;
					case ICMP_UNREACH_NET:
						++unreachable;
						printf(" !N");
						break;
					case ICMP_UNREACH_HOST:
						++unreachable;
						printf(" !H");
						break;
					case ICMP_UNREACH_PROTOCOL:
						++got_there;
						printf(" !P");
						break;
					case ICMP_UNREACH_NEEDFRAG:
						++unreachable;
						printf(" !F");
						break;
					case ICMP_UNREACH_SRCFAIL:
						++unreachable;
						printf(" !S");
						break;
					}
					break;
				} else
					reset_timer = 0;
			}
			if (cc == 0)
				printf(" *");
			(void) fflush(stdout);
		}
		putchar('\n');
		if (got_there || unreachable >= nprobes-1)
			return 0;
	}

	return 0;
}
Пример #17
0
int tftp_main(int argc, char **argv)
{
	struct hostent *host = NULL;
	const char *localfile = NULL;
	const char *remotefile = NULL;
	int port;
	int cmd = 0;
	int fd = -1;
	int flags = 0;
	int result;
	int blocksize = TFTP_BLOCKSIZE_DEFAULT;

	/* figure out what to pass to getopt */

#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
	char *sblocksize = NULL;
#define BS "b:"
#define BS_ARG , &sblocksize
#else
#define BS
#define BS_ARG
#endif

#ifdef CONFIG_FEATURE_TFTP_GET
#define GET "g"
#define GET_COMPL ":g"
#else
#define GET
#define GET_COMP
#endif

#ifdef CONFIG_FEATURE_TFTP_PUT
#define PUT "p"
#define PUT_COMPL ":p"
#else
#define PUT
#define PUT_COMPL
#endif

#if defined(CONFIG_FEATURE_TFTP_GET) && defined(CONFIG_FEATURE_TFTP_PUT)
	bb_opt_complementally = GET_COMPL PUT_COMPL ":?g--p:p--g";
#elif defined(CONFIG_FEATURE_TFTP_GET) || defined(CONFIG_FEATURE_TFTP_PUT)
	bb_opt_complementally = GET_COMPL PUT_COMPL;
#else
	/* XXX: may be should #error ? */
#endif

	
	cmd = bb_getopt_ulflags(argc, argv, GET PUT "l:r:" BS, 
				&localfile, &remotefile BS_ARG);
#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
	if(sblocksize) {
		blocksize = atoi(sblocksize);
		if (!tftp_blocksize_check(blocksize, 0)) {
			return EXIT_FAILURE;
		}
	}
#endif

	cmd &= (tftp_cmd_get | tftp_cmd_put);
#ifdef CONFIG_FEATURE_TFTP_GET
	if(cmd == tftp_cmd_get)
		flags = O_WRONLY | O_CREAT | O_TRUNC;
#endif
#ifdef CONFIG_FEATURE_TFTP_PUT
	if(cmd == tftp_cmd_put)
		flags = O_RDONLY;
#endif

	if(localfile == NULL)
	    localfile = remotefile;
	if(remotefile == NULL)
	    remotefile = localfile;
	/* XXX: I corrected this, but may be wrong too. vodz */
	if(localfile==NULL || strcmp(localfile, "-") == 0) {
	    fd = fileno((cmd==tftp_cmd_get)? stdout : stdin);
	} else if (fd==-1) {
	    fd = open(localfile, flags, 0644);
	}
	if (fd < 0) {
		bb_perror_msg_and_die("local file");
	}

	/* XXX: argv[optind] and/or argv[optind + 1] may be NULL! */
	host = xgethostbyname(argv[optind]);
	port = bb_lookup_port(argv[optind + 1], "udp", 69);

#ifdef CONFIG_FEATURE_TFTP_DEBUG
	fprintf(stderr, "using server \"%s\", remotefile \"%s\", "
		"localfile \"%s\".\n",
		inet_ntoa(*((struct in_addr *) host->h_addr)),
		remotefile, localfile);
#endif

	result = tftp(cmd, host, remotefile, fd, port, blocksize);

#ifdef CONFIG_FEATURE_CLEAN_UP
	if (!(fd == STDOUT_FILENO || fd == STDIN_FILENO)) {
	    close(fd);
	}
#endif
	return(result);
}
Пример #18
0
int tftp_main(int argc, char **argv)
{
	struct hostent *host = NULL;
	char *localfile = NULL;
	char *remotefile = NULL;
	int port;
	int cmd = 0;
	int fd = -1;
	int flags = 0;
	int opt;
	int result;
	int blocksize = TFTP_BLOCKSIZE_DEFAULT;

	/* figure out what to pass to getopt */

#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
#define BS "b:"
#else
#define BS
#endif

#ifdef CONFIG_FEATURE_TFTP_GET
#define GET "g"
#else
#define GET 
#endif

#ifdef CONFIG_FEATURE_TFTP_PUT
#define PUT "p"
#else
#define PUT 
#endif

	while ((opt = getopt(argc, argv, BS GET PUT "l:r:")) != -1) {
		switch (opt) {
#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
		case 'b':
			blocksize = atoi(optarg);
			if (!tftp_blocksize_check(blocksize, 0)) {
                                return EXIT_FAILURE;
			}
			break;
#endif
#ifdef CONFIG_FEATURE_TFTP_GET
		case 'g':
			cmd = tftp_cmd_get;
			flags = O_WRONLY | O_CREAT;
			break;
#endif
#ifdef CONFIG_FEATURE_TFTP_PUT
		case 'p':
			cmd = tftp_cmd_put;
			flags = O_RDONLY;
			break;
#endif
		case 'l': 
			localfile = bb_xstrdup(optarg);
			break;
		case 'r':
			remotefile = bb_xstrdup(optarg);
			break;
		}
	}

	if ((cmd == 0) || (optind == argc)) {
		bb_show_usage();
	}
	if(localfile && strcmp(localfile, "-") == 0) {
	    fd = fileno((cmd==tftp_cmd_get)? stdout : stdin);
	}
	if(localfile == NULL)
	    localfile = remotefile;
	if(remotefile == NULL)
	    remotefile = localfile;
	if (fd==-1) {
	    fd = open(localfile, flags, 0644);
	}
	if (fd < 0) {
		bb_perror_msg_and_die("local file");
	}

	host = xgethostbyname(argv[optind]);
	port = bb_lookup_port(argv[optind + 1], "udp", 69);

#ifdef CONFIG_FEATURE_TFTP_DEBUG
	printf("using server \"%s\", remotefile \"%s\", "
		"localfile \"%s\".\n",
		inet_ntoa(*((struct in_addr *) host->h_addr)),
		remotefile, localfile);
#endif

	result = tftp(cmd, host, remotefile, fd, port, blocksize);

#ifdef CONFIG_FEATURE_CLEAN_UP
	if (!(fd == fileno(stdout) || fd == fileno(stdin))) {
	    close(fd);
	}
#endif
	return(result);
}
Пример #19
0
static int
tftpd_daemon (char *directory, char *address, int port)
{
  struct tftphdr *tp;
  struct sockaddr_in from;
  struct sockaddr_in myaddr;
  struct sockaddr_in bindaddr;
  int fd = -1;
  int peer;
  int rv;
  int n;
  pid_t pid;
  int i = 1;

  char buf[TFTP_BLOCKSIZE_DEFAULT + 4];
  struct iovec iov = { buf, sizeof buf };
  struct cmsghdr *cmsg;
  char *ctrl = (char *)xmalloc(MAXCTRLSIZE);
  struct msghdr msg = { (void*)&from, sizeof from, &iov, 1, (void*)ctrl, MAXCTRLSIZE, 0};
  struct in_pktinfo *info = NULL;

   daemon(0,1);
  if ((fd = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
    perror_msg_and_die ("socket");
  memset (&bindaddr, 0, sizeof (bindaddr));
  bindaddr.sin_family = AF_INET;
  bindaddr.sin_addr.s_addr = INADDR_ANY;
  bindaddr.sin_port = htons (port);
  if (address != NULL)
    {
      struct hostent *hostent;
      hostent = xgethostbyname (address);
      if (!hostent || hostent->h_addrtype != AF_INET)
	perror_msg_and_die ("cannot resolve local bind address");
      memcpy (&bindaddr.sin_addr, hostent->h_addr, hostent->h_length);
    }
  // set option for getting the to ip address.
  setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &i, sizeof(i));

  if (bind (fd, (struct sockaddr *) &bindaddr, sizeof (bindaddr)) < 0)
    perror_msg_and_die ("daemon bind failed");
  /* This means we don't want to wait() for children */
  signal (SIGCHLD, SIG_IGN);
  while (1)
    {
      fd_set readset;
      memset(buf,0,TFTP_BLOCKSIZE_DEFAULT + 4);
      memset (&myaddr, 0, sizeof (myaddr));
      FD_ZERO (&readset);
      FD_SET (fd, &readset);
      /* Never time out, we're in standalone mode */
      rv = select (fd + 1, &readset, NULL, NULL, NULL);
      if (rv == -1 && errno == EINTR)
	continue;		/* Signal caught, reloop */
      if (rv == -1)
	perror_msg_and_die ("select loop");
      if (rv == 0)
	{
	  bb_error_msg ("We shouldn't be timeing out!");
	  exit (0);		/* Timeout, return to inetd */
	}

      n = recvmsg (fd, &msg, MSG_WAITALL);
      if (n <= 0)
      {
          printf("*** error recvmsg n=%d\n", n);
          break;
      }
//printf("incoming_ip=%s, n=%d\n", inet_ntoa(from.sin_addr), n);
	for(cmsg=CMSG_FIRSTHDR(&msg); cmsg != NULL;cmsg =CMSG_NXTHDR(&msg,cmsg)) {
		if (cmsg->cmsg_type == IP_PKTINFO){
		    info = (struct in_pktinfo *)CMSG_DATA(cmsg);
//            printf("sepc_dst=%s, ipi_addr=%s\n", inet_ntoa(info->ipi_spec_dst),inet_ntoa(info->ipi_addr));
            break;
		}
    }
    free(ctrl);
  /* Process the request */
  myaddr.sin_family = AF_INET;
  myaddr.sin_port = htons (0);	/* we want a new local port */
  myaddr.sin_addr = getLanIp();

  if (myaddr.sin_addr.s_addr != info->ipi_spec_dst.s_addr)
    memcpy (&myaddr.sin_addr, &bindaddr.sin_addr,sizeof bindaddr.sin_addr);

      /* Now that we have read the request packet from the UDP
         socket, we fork and go back to listening to the socket. */
    pid = FORK ();
    if (pid < 0)
	    perror_msg_and_die ("cannot fork");
    if (pid == 0)
	    break;			/* Child exits the while(1), parent continues to loop */
    }

  /* Close file descriptors we don't need */
  // brcm close (fd);

  /* Get a socket.  This has to be done before the chroot() (/dev goes away) */
  peer = socket (AF_INET, SOCK_DGRAM, 0);
  if (peer < 0)
    perror_msg_and_die ("socket");
  if (chroot ("."))
    perror_msg_and_die ("chroot");
  from.sin_family = AF_INET;

  /* Process the request */
  if (bind (peer, (struct sockaddr *) &myaddr, sizeof myaddr) < 0)
    perror_msg_and_die ("daemon-child bind");

//printf("after bind. my_ip=%s*****\n", inet_ntoa(myaddr.sin_addr));

  if (connect (peer, (struct sockaddr *) &from, sizeof from) < 0)
    perror_msg_and_die ("daemon-child connect");
  tp = (struct tftphdr *) buf;

//printf("after connect \n");

  int accessMode = bcmCheckEnable("tftp", from.sin_addr);
//printf("accessmode = %d\n", accessMode);
  if (accessMode == CLI_ACCESS_DISABLED) 
  {
    close(peer);
    exit(0);
  }
  if (accessMode == CLI_ACCESS_REMOTE) 
  {
    glbIfName[0] = '\0';
    if ((bcmGetIntfNameSocket(peer, glbIfName) != 0) || glbIfName[0] == '\0') 
    {
      printf("Failed to get remote ifc name!\n");
      close(peer);
      exit(0);
    }
  }
//printf("socket ifname = %s\n", glbIfName);
  
  tp->th_opcode = ntohs (tp->th_opcode);

  switch(tp->th_opcode)
  {
  	case RRQ:
	    tftpd_send (peer, tp, n, TFTP_BLOCKSIZE_DEFAULT);
	    break;
	case WRQ:
	    tftpd_receive (peer, tp, n, TFTP_BLOCKSIZE_DEFAULT);
	    break;
  }
  exit (0);
}