예제 #1
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;
}
예제 #2
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;
}