Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/networking/ether-wake.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/networking/ether-wake.c
r821 r1770 66 66 67 67 68 #include <unistd.h>69 #include <stdlib.h>70 #include <stdio.h>71 #include <errno.h>72 #include <ctype.h>73 #include <string.h>74 75 #include <sys/socket.h>76 #include <sys/types.h>77 #include <sys/ioctl.h>78 #include <features.h>79 68 #include <netpacket/packet.h> 80 69 #include <net/ethernet.h> 81 #include <netdb.h>82 70 #include <netinet/ether.h> 83 84 #ifdef __linux__85 71 #include <linux/if.h> 86 #endif 87 88 #include "busybox.h" 72 73 #include "libbb.h" 89 74 90 75 /* Note: PF_INET, SOCK_DGRAM, IPPROTO_UDP would allow SIOCGIFHWADDR to … … 94 79 #ifdef PF_PACKET 95 80 # define whereto_t sockaddr_ll 96 # define make_socket() bb_xsocket(PF_PACKET, SOCK_RAW, 0)81 # define make_socket() xsocket(PF_PACKET, SOCK_RAW, 0) 97 82 #else 98 83 # define whereto_t sockaddr 99 # define make_socket() bb_xsocket(AF_INET, SOCK_PACKET, SOCK_PACKET)84 # define make_socket() xsocket(AF_INET, SOCK_PACKET, SOCK_PACKET) 100 85 #endif 101 86 … … 108 93 for (i = 0; i < pktsize; ++i) { 109 94 printf("%2.2x ", outpack[i]); 110 if (i % 20 == 19) p rintf("\n");95 if (i % 20 == 19) puts(""); 111 96 } 112 97 printf("\n\n"); 113 98 } 114 99 #else 115 # define bb_debug_msg(fmt, args...) 116 # define bb_debug_dump_packet(outpack, pktsize) 117 #endif 118 119 static inline void get_dest_addr(const char *arg, struct ether_addr *eaddr); 120 static inline int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast); 121 static inline int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd); 122 123 int etherwake_main(int argc, char *argv[]) 124 { 125 char *ifname = "eth0", *pass = NULL; 126 unsigned long flags; 100 # define bb_debug_msg(fmt, args...) ((void)0) 101 # define bb_debug_dump_packet(outpack, pktsize) ((void)0) 102 #endif 103 104 /* Convert the host ID string to a MAC address. 105 * The string may be a: 106 * Host name 107 * IP address string 108 * MAC address string 109 */ 110 static void get_dest_addr(const char *hostid, struct ether_addr *eaddr) 111 { 112 struct ether_addr *eap; 113 114 eap = ether_aton(hostid); 115 if (eap) { 116 *eaddr = *eap; 117 bb_debug_msg("The target station address is %s\n\n", ether_ntoa(eaddr)); 118 #if !defined(__UCLIBC__) 119 } else if (ether_hostton(hostid, eaddr) == 0) { 120 bb_debug_msg("Station address for hostname %s is %s\n\n", hostid, ether_ntoa(eaddr)); 121 #endif 122 } else 123 bb_show_usage(); 124 } 125 126 static int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast) 127 { 128 int i; 129 unsigned char *station_addr = eaddr->ether_addr_octet; 130 131 memset(pkt, 0xff, 6); 132 if (!broadcast) 133 memcpy(pkt, station_addr, 6); 134 pkt += 6; 135 136 memcpy(pkt, station_addr, 6); /* 6 */ 137 pkt += 6; 138 139 *pkt++ = 0x08; /* 12 */ /* Or 0x0806 for ARP, 0x8035 for RARP */ 140 *pkt++ = 0x42; /* 13 */ 141 142 memset(pkt, 0xff, 6); /* 14 */ 143 144 for (i = 0; i < 16; ++i) { 145 pkt += 6; 146 memcpy(pkt, station_addr, 6); /* 20,26,32,... */ 147 } 148 149 return 20 + 16*6; /* length of packet */ 150 } 151 152 static int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd) 153 { 154 unsigned passwd[6]; 155 int byte_cnt, i; 156 157 /* handle MAC format */ 158 byte_cnt = sscanf(ethoptarg, "%2x:%2x:%2x:%2x:%2x:%2x", 159 &passwd[0], &passwd[1], &passwd[2], 160 &passwd[3], &passwd[4], &passwd[5]); 161 /* handle IP format */ 162 // FIXME: why < 4?? should it be < 6? 163 if (byte_cnt < 4) 164 byte_cnt = sscanf(ethoptarg, "%u.%u.%u.%u", 165 &passwd[0], &passwd[1], &passwd[2], &passwd[3]); 166 if (byte_cnt < 4) { 167 bb_error_msg("cannot read Wake-On-LAN pass"); 168 return 0; 169 } 170 // TODO: check invalid numbers >255?? 171 for (i = 0; i < byte_cnt; ++i) 172 wol_passwd[i] = passwd[i]; 173 174 bb_debug_msg("password: %2.2x %2.2x %2.2x %2.2x (%d)\n\n", 175 wol_passwd[0], wol_passwd[1], wol_passwd[2], wol_passwd[3], 176 byte_cnt); 177 178 return byte_cnt; 179 } 180 181 int ether_wake_main(int argc, char **argv); 182 int ether_wake_main(int argc, char **argv) 183 { 184 const char *ifname = "eth0"; 185 char *pass; 186 unsigned flags; 127 187 unsigned char wol_passwd[6]; 128 188 int wol_passwd_sz = 0; 129 130 189 int s; /* Raw socket */ 131 190 int pktsize; … … 136 195 137 196 /* handle misc user options */ 138 flags = bb_getopt_ulflags(argc, argv, "bi:p:", &ifname, &pass); 139 if (optind == argc) 140 bb_show_usage(); 141 if (pass) 197 opt_complementary = "=1"; 198 flags = getopt32(argv, "bi:p:", &ifname, &pass); 199 if (flags & 4) /* -p */ 142 200 wol_passwd_sz = get_wol_pw(pass, wol_passwd); 201 flags &= 1; /* we further interested only in -b [bcast] flag */ 143 202 144 203 /* create the raw socket */ … … 146 205 147 206 /* now that we have a raw socket we can drop root */ 148 xsetuid(getuid());207 /* xsetuid(getuid()); - but save on code size... */ 149 208 150 209 /* look up the dest mac address */ … … 152 211 153 212 /* fill out the header of the packet */ 154 pktsize = get_fill(outpack, &eaddr, flags /* & 1 [OPT_BROADCAST]*/);213 pktsize = get_fill(outpack, &eaddr, flags /* & 1 OPT_BROADCAST */); 155 214 156 215 bb_debug_dump_packet(outpack, pktsize); … … 161 220 struct ifreq if_hwaddr; 162 221 163 strcpy(if_hwaddr.ifr_name, ifname); 164 if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0) 165 bb_perror_msg_and_die("SIOCGIFHWADDR on %s failed", ifname); 222 strncpy(if_hwaddr.ifr_name, ifname, sizeof(if_hwaddr.ifr_name)); 223 ioctl_or_perror_and_die(s, SIOCGIFHWADDR, &if_hwaddr, "SIOCGIFHWADDR on %s failed", ifname); 166 224 167 225 memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6); … … 190 248 191 249 /* This is necessary for broadcasts to work */ 192 if (flags /*& 1 [OPT_BROADCAST]*/) { 193 int one = 1; 194 if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (void *)&one, sizeof(one)) < 0) 250 if (flags /* & 1 OPT_BROADCAST */) { 251 if (setsockopt_broadcast(s) != 0) 195 252 bb_perror_msg("SO_BROADCAST"); 196 253 } … … 200 257 struct ifreq ifr; 201 258 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); 202 if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) 203 bb_perror_msg_and_die("SIOCGIFINDEX"); 259 xioctl(s, SIOCGIFINDEX, &ifr); 204 260 memset(&whereto, 0, sizeof(whereto)); 205 261 whereto.sll_family = AF_PACKET; … … 214 270 strcpy(whereto.sa_data, ifname); 215 271 #endif 216 217 if (sendto(s, outpack, pktsize, 0, (struct sockaddr *)&whereto, sizeof(whereto)) < 0) 218 bb_perror_msg(bb_msg_write_error); 219 220 close(s); 221 272 xsendto(s, outpack, pktsize, (struct sockaddr *)&whereto, sizeof(whereto)); 273 if (ENABLE_FEATURE_CLEAN_UP) 274 close(s); 222 275 return EXIT_SUCCESS; 223 276 } 224 225 /* Convert the host ID string to a MAC address.226 * The string may be a:227 * Host name228 * IP address string229 * MAC address string230 */231 static inline void get_dest_addr(const char *hostid, struct ether_addr *eaddr)232 {233 struct ether_addr *eap;234 235 eap = ether_aton(hostid);236 if (eap) {237 *eaddr = *eap;238 bb_debug_msg("The target station address is %s\n\n", ether_ntoa(eaddr));239 #if !defined(__UCLIBC__)240 } else if (ether_hostton(hostid, eaddr) == 0) {241 bb_debug_msg("Station address for hostname %s is %s\n\n", hostid, ether_ntoa(eaddr));242 #else243 # warning Need to implement ether_hostton() for uClibc244 #endif245 } else246 bb_show_usage();247 }248 249 static inline int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast)250 {251 int offset, i;252 unsigned char *station_addr = eaddr->ether_addr_octet;253 254 if (broadcast)255 memset(pkt+0, 0xff, 6);256 else257 memcpy(pkt, station_addr, 6);258 memcpy(pkt+6, station_addr, 6);259 pkt[12] = 0x08; /* Or 0x0806 for ARP, 0x8035 for RARP */260 pkt[13] = 0x42;261 offset = 14;262 263 memset(pkt+offset, 0xff, 6);264 offset += 6;265 266 for (i = 0; i < 16; ++i) {267 memcpy(pkt+offset, station_addr, 6);268 offset += 6;269 }270 271 return offset;272 }273 274 static inline int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd)275 {276 int passwd[6];277 int byte_cnt, i;278 279 /* handle MAC format */280 byte_cnt = sscanf(ethoptarg, "%2x:%2x:%2x:%2x:%2x:%2x",281 &passwd[0], &passwd[1], &passwd[2],282 &passwd[3], &passwd[4], &passwd[5]);283 /* handle IP format */284 if (byte_cnt < 4)285 byte_cnt = sscanf(ethoptarg, "%d.%d.%d.%d",286 &passwd[0], &passwd[1], &passwd[2], &passwd[3]);287 if (byte_cnt < 4) {288 bb_error_msg("Unable to read the Wake-On-LAN pass");289 return 0;290 }291 292 for (i = 0; i < byte_cnt; ++i)293 wol_passwd[i] = passwd[i];294 295 bb_debug_msg("password: %2.2x %2.2x %2.2x %2.2x (%d)\n\n",296 wol_passwd[0], wol_passwd[1], wol_passwd[2], wol_passwd[3],297 byte_cnt);298 299 return byte_cnt;300 }
Note:
See TracChangeset
for help on using the changeset viewer.