ether-wake: close bug 1317. Reorder fuctions to avoid

forward refs while at it
This commit is contained in:
Denis Vlasenko 2007-04-16 23:16:37 +00:00
parent 7d4c44e1b1
commit 198714c0dd

View File

@ -97,20 +97,93 @@ void bb_debug_dump_packet(unsigned char *outpack, int pktsize)
printf("\n\n"); printf("\n\n");
} }
#else #else
# define bb_debug_msg(fmt, args...) # define bb_debug_msg(fmt, args...) ((void)0)
# define bb_debug_dump_packet(outpack, pktsize) # define bb_debug_dump_packet(outpack, pktsize) ((void)0)
#endif #endif
static inline void get_dest_addr(const char *arg, struct ether_addr *eaddr); /* Convert the host ID string to a MAC address.
static inline int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast); * The string may be a:
static inline int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd); * Host name
* IP address string
* MAC address string
*/
static void get_dest_addr(const char *hostid, struct ether_addr *eaddr)
{
struct ether_addr *eap;
eap = ether_aton(hostid);
if (eap) {
*eaddr = *eap;
bb_debug_msg("The target station address is %s\n\n", ether_ntoa(eaddr));
#if !defined(__UCLIBC__)
} else if (ether_hostton(hostid, eaddr) == 0) {
bb_debug_msg("Station address for hostname %s is %s\n\n", hostid, ether_ntoa(eaddr));
#endif
} else
bb_show_usage();
}
static int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast)
{
int i;
unsigned char *station_addr = eaddr->ether_addr_octet;
memset(pkt, 0xff, 6);
if (!broadcast)
memcpy(pkt, station_addr, 6);
pkt += 6;
memcpy(pkt, station_addr, 6); /* 6 */
pkt += 6;
*pkt++ = 0x08; /* 12 */ /* Or 0x0806 for ARP, 0x8035 for RARP */
*pkt++ = 0x42; /* 13 */
memset(pkt, 0xff, 6); /* 14 */
for (i = 0; i < 16; ++i) {
pkt += 6;
memcpy(pkt, station_addr, 6); /* 20,26,32,... */
}
return 20 + 16*6; /* length of packet */
}
static int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd)
{
unsigned passwd[6];
int byte_cnt, i;
/* handle MAC format */
byte_cnt = sscanf(ethoptarg, "%2x:%2x:%2x:%2x:%2x:%2x",
&passwd[0], &passwd[1], &passwd[2],
&passwd[3], &passwd[4], &passwd[5]);
/* handle IP format */
// FIXME: why < 4?? should it be < 6?
if (byte_cnt < 4)
byte_cnt = sscanf(ethoptarg, "%u.%u.%u.%u",
&passwd[0], &passwd[1], &passwd[2], &passwd[3]);
if (byte_cnt < 4) {
bb_error_msg("cannot read Wake-On-LAN pass");
return 0;
}
// TODO: check invalid numbers >255??
for (i = 0; i < byte_cnt; ++i)
wol_passwd[i] = passwd[i];
bb_debug_msg("password: %2.2x %2.2x %2.2x %2.2x (%d)\n\n",
wol_passwd[0], wol_passwd[1], wol_passwd[2], wol_passwd[3],
byte_cnt);
return byte_cnt;
}
int ether_wake_main(int argc, char **argv); int ether_wake_main(int argc, char **argv);
int ether_wake_main(int argc, char **argv) int ether_wake_main(int argc, char **argv)
{ {
const char *ifname = "eth0"; const char *ifname = "eth0";
char *pass = NULL; char *pass = NULL;
unsigned long flags; unsigned flags;
unsigned char wol_passwd[6]; unsigned char wol_passwd[6];
int wol_passwd_sz = 0; int wol_passwd_sz = 0;
@ -138,7 +211,7 @@ int ether_wake_main(int argc, char **argv)
get_dest_addr(argv[optind], &eaddr); get_dest_addr(argv[optind], &eaddr);
/* fill out the header of the packet */ /* fill out the header of the packet */
pktsize = get_fill(outpack, &eaddr, flags /*& 1 [OPT_BROADCAST]*/); pktsize = get_fill(outpack, &eaddr, flags & 1 /* OPT_BROADCAST */);
bb_debug_dump_packet(outpack, pktsize); bb_debug_dump_packet(outpack, pktsize);
@ -148,7 +221,7 @@ int ether_wake_main(int argc, char **argv)
struct ifreq if_hwaddr; struct ifreq if_hwaddr;
strncpy(if_hwaddr.ifr_name, ifname, sizeof(if_hwaddr.ifr_name)); strncpy(if_hwaddr.ifr_name, ifname, sizeof(if_hwaddr.ifr_name));
if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0) if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) != 0)
bb_perror_msg_and_die("SIOCGIFHWADDR on %s failed", ifname); bb_perror_msg_and_die("SIOCGIFHWADDR on %s failed", ifname);
memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6); memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6);
@ -176,8 +249,8 @@ int ether_wake_main(int argc, char **argv)
bb_debug_dump_packet(outpack, pktsize); bb_debug_dump_packet(outpack, pktsize);
/* This is necessary for broadcasts to work */ /* This is necessary for broadcasts to work */
if (flags /*& 1 [OPT_BROADCAST]*/) { if (flags & 1 /* OPT_BROADCAST */) {
if (setsockopt_broadcast(s) < 0) if (setsockopt_broadcast(s) != 0)
bb_perror_msg("SO_BROADCAST"); bb_perror_msg("SO_BROADCAST");
} }
@ -185,7 +258,7 @@ int ether_wake_main(int argc, char **argv)
{ {
struct ifreq ifr; struct ifreq ifr;
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) if (ioctl(s, SIOCGIFINDEX, &ifr) != 0)
bb_perror_msg_and_die("SIOCGIFINDEX"); bb_perror_msg_and_die("SIOCGIFINDEX");
memset(&whereto, 0, sizeof(whereto)); memset(&whereto, 0, sizeof(whereto));
whereto.sll_family = AF_PACKET; whereto.sll_family = AF_PACKET;
@ -200,81 +273,7 @@ int ether_wake_main(int argc, char **argv)
strcpy(whereto.sa_data, ifname); strcpy(whereto.sa_data, ifname);
#endif #endif
xsendto(s, outpack, pktsize, (struct sockaddr *)&whereto, sizeof(whereto)); xsendto(s, outpack, pktsize, (struct sockaddr *)&whereto, sizeof(whereto));
close(s); if (ENABLE_FEATURE_CLEAN_UP)
close(s);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/* Convert the host ID string to a MAC address.
* The string may be a:
* Host name
* IP address string
* MAC address string
*/
static inline void get_dest_addr(const char *hostid, struct ether_addr *eaddr)
{
struct ether_addr *eap;
eap = ether_aton(hostid);
if (eap) {
*eaddr = *eap;
bb_debug_msg("The target station address is %s\n\n", ether_ntoa(eaddr));
#if !defined(__UCLIBC__)
} else if (ether_hostton(hostid, eaddr) == 0) {
bb_debug_msg("Station address for hostname %s is %s\n\n", hostid, ether_ntoa(eaddr));
#endif
} else
bb_show_usage();
}
static inline int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast)
{
int offset, i;
unsigned char *station_addr = eaddr->ether_addr_octet;
if (broadcast)
memset(pkt+0, 0xff, 6);
else
memcpy(pkt, station_addr, 6);
memcpy(pkt+6, station_addr, 6);
pkt[12] = 0x08; /* Or 0x0806 for ARP, 0x8035 for RARP */
pkt[13] = 0x42;
offset = 14;
memset(pkt+offset, 0xff, 6);
offset += 6;
for (i = 0; i < 16; ++i) {
memcpy(pkt+offset, station_addr, 6);
offset += 6;
}
return offset;
}
static inline int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd)
{
int passwd[6];
int byte_cnt, i;
/* handle MAC format */
byte_cnt = sscanf(ethoptarg, "%2x:%2x:%2x:%2x:%2x:%2x",
&passwd[0], &passwd[1], &passwd[2],
&passwd[3], &passwd[4], &passwd[5]);
/* handle IP format */
if (byte_cnt < 4)
byte_cnt = sscanf(ethoptarg, "%d.%d.%d.%d",
&passwd[0], &passwd[1], &passwd[2], &passwd[3]);
if (byte_cnt < 4) {
bb_error_msg("cannot read Wake-On-LAN pass");
return 0;
}
for (i = 0; i < byte_cnt; ++i)
wol_passwd[i] = passwd[i];
bb_debug_msg("password: %2.2x %2.2x %2.2x %2.2x (%d)\n\n",
wol_passwd[0], wol_passwd[1], wol_passwd[2], wol_passwd[3],
byte_cnt);
return byte_cnt;
}