コード例 #1
0
ファイル: ether-wake.c プロジェクト: AllardJ/Tomato
int ether_wake_main(int argc UNUSED_PARAM, char **argv)
{
	const char *ifname = "eth0";
	char *pass;
	unsigned flags;
	unsigned char wol_passwd[6];
	int wol_passwd_sz = 0;
	int s;  /* Raw socket */
	int pktsize;
	unsigned char outpack[1000];

	struct ether_addr eaddr;
	struct whereto_t whereto;  /* who to wake up */

	/* handle misc user options */
	opt_complementary = "=1";
	flags = getopt32(argv, "bi:p:", &ifname, &pass);
	if (flags & 4) /* -p */
		wol_passwd_sz = get_wol_pw(pass, wol_passwd);
	flags &= 1; /* we further interested only in -b [bcast] flag */

	/* create the raw socket */
	s = make_socket();

	/* now that we have a raw socket we can drop root */
	/* xsetuid(getuid()); - but save on code size... */

	/* look up the dest mac address */
	get_dest_addr(argv[optind], &eaddr);

	/* fill out the header of the packet */
	pktsize = get_fill(outpack, &eaddr, flags /* & 1 OPT_BROADCAST */);

	bb_debug_dump_packet(outpack, pktsize);

	/* Fill in the source address, if possible. */
#ifdef __linux__
	{
		struct ifreq if_hwaddr;

		strncpy_IFNAMSIZ(if_hwaddr.ifr_name, ifname);
		ioctl_or_perror_and_die(s, SIOCGIFHWADDR, &if_hwaddr, "SIOCGIFHWADDR on %s failed", ifname);

		memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6);

# ifdef DEBUG
		{
			unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;
			printf("The hardware address (SIOCGIFHWADDR) of %s is type %d  "
				"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname,
				if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
				hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
		}
# endif
	}
#endif /* __linux__ */

	bb_debug_dump_packet(outpack, pktsize);

	/* append the password if specified */
	if (wol_passwd_sz > 0) {
		memcpy(outpack+pktsize, wol_passwd, wol_passwd_sz);
		pktsize += wol_passwd_sz;
	}

	bb_debug_dump_packet(outpack, pktsize);

	/* This is necessary for broadcasts to work */
	if (flags /* & 1 OPT_BROADCAST */) {
		if (setsockopt_broadcast(s) != 0)
			bb_perror_msg("SO_BROADCAST");
	}

#if defined(PF_PACKET)
	{
		struct ifreq ifr;
		strncpy_IFNAMSIZ(ifr.ifr_name, ifname);
		xioctl(s, SIOCGIFINDEX, &ifr);
		memset(&whereto, 0, sizeof(whereto));
		whereto.sll_family = AF_PACKET;
		whereto.sll_ifindex = ifr.ifr_ifindex;
		/* The manual page incorrectly claims the address must be filled.
		   We do so because the code may change to match the docs. */
		whereto.sll_halen = ETH_ALEN;
		memcpy(whereto.sll_addr, outpack, ETH_ALEN);
	}
#else
	whereto.sa_family = 0;
	strcpy(whereto.sa_data, ifname);
#endif
	xsendto(s, outpack, pktsize, (struct sockaddr *)&whereto, sizeof(whereto));
	if (ENABLE_FEATURE_CLEAN_UP)
		close(s);
	return EXIT_SUCCESS;
}
コード例 #2
0
int ether_wake_main(int argc, char *argv[])
{
	const char *ifname = "eth0";
	char *pass = NULL;
	unsigned long flags;
	unsigned char wol_passwd[6];
	int wol_passwd_sz = 0;

	int s;						/* Raw socket */
	int pktsize;
	unsigned char outpack[1000];

	struct ether_addr eaddr;
	struct whereto_t whereto;	/* who to wake up */

	/* handle misc user options */
	flags = getopt32(argc, argv, "bi:p:", &ifname, &pass);
	if (optind == argc)
		bb_show_usage();
	if (pass)
		wol_passwd_sz = get_wol_pw(pass, wol_passwd);

	/* create the raw socket */
	s = make_socket();

	/* now that we have a raw socket we can drop root */
	xsetuid(getuid());

	/* look up the dest mac address */
	get_dest_addr(argv[optind], &eaddr);

	/* fill out the header of the packet */
	pktsize = get_fill(outpack, &eaddr, flags /*& 1 [OPT_BROADCAST]*/);

	bb_debug_dump_packet(outpack, pktsize);

	/* Fill in the source address, if possible. */
#ifdef __linux__
	{
		struct ifreq if_hwaddr;

		strncpy(if_hwaddr.ifr_name, ifname, sizeof(if_hwaddr.ifr_name));
		if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0)
			bb_perror_msg_and_die("SIOCGIFHWADDR on %s failed", ifname);

		memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6);

# ifdef DEBUG
		{
			unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;
			printf("The hardware address (SIOCGIFHWADDR) of %s is type %d  "
				   "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname,
				   if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
				   hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
		}
# endif
	}
#endif /* __linux__ */

	bb_debug_dump_packet(outpack, pktsize);

	/* append the password if specified */
	if (wol_passwd_sz > 0) {
		memcpy(outpack+pktsize, wol_passwd, wol_passwd_sz);
		pktsize += wol_passwd_sz;
	}

	bb_debug_dump_packet(outpack, pktsize);

	/* This is necessary for broadcasts to work */
	if (flags /*& 1 [OPT_BROADCAST]*/) {
		if (setsockopt_broadcast(s) < 0)
			bb_perror_msg("SO_BROADCAST");
	}

#if defined(PF_PACKET)
	{
		struct ifreq ifr;
		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
		if (ioctl(s, SIOCGIFINDEX, &ifr) == -1)
			bb_perror_msg_and_die("SIOCGIFINDEX");
		memset(&whereto, 0, sizeof(whereto));
		whereto.sll_family = AF_PACKET;
		whereto.sll_ifindex = ifr.ifr_ifindex;
		/* The manual page incorrectly claims the address must be filled.
		   We do so because the code may change to match the docs. */
		whereto.sll_halen = ETH_ALEN;
		memcpy(whereto.sll_addr, outpack, ETH_ALEN);
	}
#else
	whereto.sa_family = 0;
	strcpy(whereto.sa_data, ifname);
#endif

	if (sendto(s, outpack, pktsize, 0, (struct sockaddr *)&whereto, sizeof(whereto)) < 0)
		bb_perror_msg(bb_msg_write_error);

	close(s);

	return EXIT_SUCCESS;
}
コード例 #3
0
ファイル: ether-wake.c プロジェクト: jens-maus/cuxd
int main(int argc, char *argv[])
{
	char *ifname = "eth0";
	int one = 1;				/* True, for socket options. */
	int s;						/* Raw socket */
	int errflag = 0, verbose = 0, do_version = 0;
	int perm_failure = 0;
	int i, c, pktsize;
#if defined(PF_PACKET)
	struct sockaddr_ll whereto;
#else
	struct sockaddr whereto;	/* who to wake up */
#endif
	struct ether_addr eaddr;

	while ((c = getopt(argc, argv, "bDi:p:uvV")) != -1)
		switch (c) {
		case 'b': opt_broadcast++;	break;
		case 'D': debug++;			break;
		case 'i': ifname = optarg;	break;
		case 'p': get_wol_pw(optarg); break;
		case 'u': printf(usage_msg); return 0;
		case 'v': verbose++;		break;
		case 'V': do_version++;		break;
		case '?':
			errflag++;
		}
	if (verbose || do_version)
		printf("%s\n", version_msg);
	if (errflag) {
		fprintf(stderr, brief_usage_msg);
		return 3;
	}

	if (optind == argc) {
		fprintf(stderr, "Specify the Ethernet address as 00:11:22:33:44:55.\n");
		return 3;
	}

	/* Note: PF_INET, SOCK_DGRAM, IPPROTO_UDP would allow SIOCGIFHWADDR to
	   work as non-root, but we need SOCK_PACKET to specify the Ethernet
	   destination address. */
#if defined(PF_PACKET)
	s = socket(PF_PACKET, SOCK_RAW, 0);
#else
	s = socket(AF_INET, SOCK_PACKET, SOCK_PACKET);
#endif
	if (s < 0) {
		if (errno == EPERM)
			fprintf(stderr, "ether-wake: This program must be run as root.\n");
		else
			perror("ether-wake: socket");
		perm_failure++;
	}
	/* Don't revert if debugging allows a normal user to get the raw socket. */
	setuid(getuid());

	/* We look up the station address before reporting failure so that
	   errors may be reported even when run as a normal user.
	*/
	if (get_dest_addr(argv[optind], &eaddr) != 0)
		return 3;
	if (perm_failure && ! debug)
		return 2;

	pktsize = get_fill(outpack, &eaddr);

	/* Fill in the source address, if possible.
	   The code to retrieve the local station address is Linux specific. */
	if (! opt_no_src_addr) {
		struct ifreq if_hwaddr;
		char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;

		strcpy(if_hwaddr.ifr_name, ifname);
		if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0) {
			fprintf(stderr, "SIOCGIFHWADDR on %s failed: %s\n", ifname,
					strerror(errno));
			/* Magic packets still work if our source address is bogus, but
			   we fail just to be anal. */
			return 1;
		}
		memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6);

		if (verbose) {
			printf("The hardware address (SIOCGIFHWADDR) of %s is type %d  "
				   "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n", ifname,
				   if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
				   hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
		}
	}

	if (wol_passwd_sz > 0) {
		memcpy(outpack+pktsize, wol_passwd, wol_passwd_sz);
		pktsize += wol_passwd_sz;
	}

	if (verbose > 1) {
		printf("The final packet is: ");
		for (i = 0; i < pktsize; i++)
			printf(" %2.2x", outpack[i]);
		printf(".\n");
	}

	/* This is necessary for broadcasts to work */
	if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&one, sizeof(one)) < 0)
		perror("setsockopt: SO_BROADCAST");

#if defined(PF_PACKET)
	{
		struct ifreq ifr;
		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
		if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) {
			fprintf(stderr, "SIOCGIFINDEX on %s failed: %s\n", ifname,
					strerror(errno));
			return 1;
		}
		memset(&whereto, 0, sizeof(whereto));
		whereto.sll_family = AF_PACKET;
		whereto.sll_ifindex = ifr.ifr_ifindex;
		/* The manual page incorrectly claims the address must be filled.
		   We do so because the code may change to match the docs. */
		whereto.sll_halen = ETH_ALEN;
		memcpy(whereto.sll_addr, outpack, ETH_ALEN);

	}
#else
	whereto.sa_family = 0;
	strcpy(whereto.sa_data, ifname);
#endif

	if ((i = sendto(s, outpack, pktsize, 0, (struct sockaddr *)&whereto,
					sizeof(whereto))) < 0)
		perror("sendto");
	else if (debug)
		printf("Sendto worked ! %d.\n", i);

#ifdef USE_SEND
	if (bind(s, (struct sockaddr *)&whereto, sizeof(whereto)) < 0)
		perror("bind");
	else if (send(s, outpack, 100, 0) < 0)
		perror("send");
#endif
#ifdef USE_SENDMSG
	{
		struct msghdr msghdr = { 0,};
		struct iovec iovector[1];
		msghdr.msg_name = &whereto;
		msghdr.msg_namelen = sizeof(whereto);
		msghdr.msg_iov = iovector;
		msghdr.msg_iovlen = 1;
		iovector[0].iov_base = outpack;
		iovector[0].iov_len = pktsize;
		if ((i = sendmsg(s, &msghdr, 0)) < 0)
			perror("sendmsg");
		else if (debug)
			printf("sendmsg worked, %d (%d).\n", i, errno);
	}
#endif

	return 0;
}