Ignore:
Timestamp:
Nov 4, 2007, 3:16:40 AM (17 years ago)
Author:
Bruno Cornec
Message:

Update to busybox 1.7.2

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.5/mindi-busybox/networking/ether-wake.c

    r821 r1765  
    6666
    6767
    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>
    7968#include <netpacket/packet.h>
    8069#include <net/ethernet.h>
    81 #include <netdb.h>
    8270#include <netinet/ether.h>
    83 
    84 #ifdef __linux__
    8571#include <linux/if.h>
    86 #endif
    87 
    88 #include "busybox.h"
     72
     73#include "libbb.h"
    8974
    9075/* Note: PF_INET, SOCK_DGRAM, IPPROTO_UDP would allow SIOCGIFHWADDR to
     
    9479#ifdef PF_PACKET
    9580# 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)
    9782#else
    9883# 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)
    10085#endif
    10186
     
    10893    for (i = 0; i < pktsize; ++i) {
    10994        printf("%2.2x ", outpack[i]);
    110         if (i % 20 == 19) printf("\n");
     95        if (i % 20 == 19) puts("");
    11196    }
    11297    printf("\n\n");
    11398}
    11499#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*/
     110static 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
     126static 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
     152static 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
     181int ether_wake_main(int argc, char **argv);
     182int ether_wake_main(int argc, char **argv)
     183{
     184    const char *ifname = "eth0";
     185    char *pass;
     186    unsigned flags;
    127187    unsigned char wol_passwd[6];
    128188    int wol_passwd_sz = 0;
    129 
    130189    int s;                      /* Raw socket */
    131190    int pktsize;
     
    136195
    137196    /* 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 */
    142200        wol_passwd_sz = get_wol_pw(pass, wol_passwd);
     201    flags &= 1; /* we further interested only in -b [bcast] flag */
    143202
    144203    /* create the raw socket */
     
    146205
    147206    /* now that we have a raw socket we can drop root */
    148     xsetuid(getuid());
     207    /* xsetuid(getuid()); - but save on code size... */
    149208
    150209    /* look up the dest mac address */
     
    152211
    153212    /* 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 */);
    155214
    156215    bb_debug_dump_packet(outpack, pktsize);
     
    161220        struct ifreq if_hwaddr;
    162221
    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);
    166224
    167225        memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6);
     
    190248
    191249    /* 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)
    195252            bb_perror_msg("SO_BROADCAST");
    196253    }
     
    200257        struct ifreq ifr;
    201258        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);
    204260        memset(&whereto, 0, sizeof(whereto));
    205261        whereto.sll_family = AF_PACKET;
     
    214270    strcpy(whereto.sa_data, ifname);
    215271#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);
    222275    return EXIT_SUCCESS;
    223276}
    224 
    225 /* Convert the host ID string to a MAC address.
    226  * The string may be a:
    227  *    Host name
    228  *    IP address string
    229  *    MAC address string
    230 */
    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 #else
    243 # warning Need to implement ether_hostton() for uClibc
    244 #endif
    245     } else
    246         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     else
    257         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.