static void function (struct channel * channel, flag_t flags) { struct message message; signed length; while ((length = readpacket (channel, &message, sizeof (message))) >= 0) { if (!length) { continue; } if (_allclr (flags, HPAV_SILENCE)) { MMEPeek (&message, length, stdout); } if (_anyset (flags, HPAV_VERBOSE)) { hexdump (&message, 0, length, stdout); } } return; }
int main (int argc, char const * argv []) { extern struct channel channel; struct message message; static char const * optv [] = { "i:qt:v", PUTOPTV_S_DIVINE, "Qualcomm Atheros HomePlug AV Packet Monitor", #if defined (WINPCAP) "i s\thost interface is (s) [" CHANNEL_ETHDEVICE "]", #else "i n\thost interface is (n) [" LITERAL (CHANNEL_ETHNUMBER) "]", #endif "q\tsuppress normal output", "t n\tread timeout is (n) milliseconds [" LITERAL (CHANNEL_TIMEOUT) "]", "v\tverbose messages on stdout", (char const *) (0) }; flag_t flags = (flag_t)(0); signed length; signed c; if (getenv (PLCDEVICE)) { #if defined (WINPCAP) channel.ifindex = atoi (getenv (PLCDEVICE)); #else channel.ifname = strdup (getenv (PLCDEVICE)); #endif } optind = 1; while ((c = getoptv (argc, argv, optv)) != -1) { switch (c) { case 'i': #if defined (WIN32) channel.ifindex = atoi (optarg); #else channel.ifname = optarg; #endif break; case 'q': _setbits (flags, HPAV_SILENCE); break; case 't': channel.timeout = (unsigned)(uintspec (optarg, 0, UINT_MAX)); break; case 'v': _setbits (flags, HPAV_VERBOSE); break; default: break; } } argc -= optind; argv += optind; openchannel (&channel); while ((length = readpacket (&channel, &message, sizeof (message))) >= 0) { if (length > 0) { if (_allclr (flags, HPAV_SILENCE)) { MMEPeek (&message, length, stdout); } if (_anyset (flags, HPAV_VERBOSE)) { hexdump (&message, 0, length, stdout); } } } closechannel (&channel); return (0); }
int main (int argc, char const * argv []) { struct sigaction sa; struct ifreq ifreq; struct sockaddr_ll sockaddr = { PF_PACKET, htons (ETH_P_HPAV), 0x0000, ARPHRD_ETHER, PACKET_OTHERHOST, ETHER_ADDR_LEN, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; static char const * optv [] = { "di:qv", PUTOPTV_S_DIVINE, "Qualcomm Atheros HomePlug AV Packet Daemon", "d\trun in background as daemon", "i s\thost interface is (s) [" ETHDEVICE "]", "q\tsuppress normal output", "v\tverbose messages on stdout", (char const *) (0) }; uint8_t packet [ETHER_MAX_LEN]; flag_t state = (flag_t)(0); flag_t flags = (flag_t)(0); sock_t fd = -1; signed c; memset (&ifreq, 0, sizeof (ifreq)); memcpy (ifreq.ifr_name, ETHDEVICE, sizeof (ETHDEVICE)); if (getenv (PLCDEVICE)) { memcpy (ifreq.ifr_name, getenv (PLCDEVICE), sizeof (ifreq.ifr_name)); } optind = 1; while ((c = getoptv (argc, argv, optv)) != -1) { switch ((char) (c)) { case 'd': _setbits (flags, HPAVD_DAEMON); break; case 'i': memcpy (ifreq.ifr_name, optarg, sizeof (ifreq.ifr_name)); break; case 'q': _setbits (flags, HPAVD_SILENCE); break; case 'v': _setbits (flags, HPAVD_VERBOSE); break; default: break; } } argc -= optind; argv += optind; if (geteuid ()) { error (1, EPERM, ERROR_NOTROOT); } if (_anyset (flags, HPAVD_DAEMON)) { pid_t pid = fork (); if (pid < 0) { error (1, errno, "razzlefrats!"); } if (pid > 0) { exit (0); } } memset (&sa, 0, sizeof (struct sigaction)); sa.sa_handler = terminate; sigaction (SIGTERM, &sa, (struct sigaction *)(0)); sigaction (SIGQUIT, &sa, (struct sigaction *)(0)); sigaction (SIGTSTP, &sa, (struct sigaction *)(0)); sigaction (SIGINT, &sa, (struct sigaction *)(0)); sigaction (SIGHUP, &sa, (struct sigaction *)(0)); if ((fd = socket (sockaddr.sll_family, SOCK_RAW, sockaddr.sll_protocol)) == -1) { error (1, errno, "Can't create socket for %s", ifreq.ifr_name); } if (ioctl (fd, SIOCGIFFLAGS, &ifreq) < 0) { error (1, errno, "Can't read %s device state", ifreq.ifr_name); } state = ifreq.ifr_flags; _setbits (ifreq.ifr_flags, (IFF_UP | IFF_BROADCAST)); _clrbits (ifreq.ifr_flags, (IFF_MULTICAST | IFF_ALLMULTI | IFF_PROMISC)); if (ioctl (fd, SIOCSIFFLAGS, &ifreq) < 0) { error (1, errno, "Can't change %s device state", ifreq.ifr_name); } if (ioctl (fd, SIOCGIFINDEX, &ifreq) == -1) { error (1, errno, "Can't get %s interface index", ifreq.ifr_name); } sockaddr.sll_ifindex = ifreq.ifr_ifindex; if (ioctl (fd, SIOCGIFHWADDR, &ifreq) == -1) { error (1, errno, "Can't get %s hardware address", ifreq.ifr_name); } memcpy (sockaddr.sll_addr, ifreq.ifr_ifru.ifru_hwaddr.sa_data, sizeof (sockaddr.sll_addr)); if (bind (fd, (struct sockaddr *) (&sockaddr), sizeof (struct sockaddr_ll)) == -1) { error (1, errno, "Can't bind socket to %s", ifreq.ifr_name); } while (!done) { signed length = recvfrom (fd, packet, sizeof (packet), 0, (struct sockaddr *) (0), (socklen_t *)(0)); if (length > 0) { if (_allclr (flags, HPAVD_SILENCE)) { MMEPeek (&packet, length, stdout); } if (_anyset (flags, HPAVD_VERBOSE)) { hexdump (&packet, 0, length, stdout); } } } ifreq.ifr_flags = state; if (ioctl (fd, SIOCSIFFLAGS, &ifreq) < 0) { error (1, errno, "Can't restore %s device state", ifreq.ifr_name); } close (fd); return (0); }