Flash the Chrome EC lightbar when pf blocks a packet
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 131 lines 3.4 kB view raw
1/* 2 * Copyright (c) 2016 joshua stein <jcs@jcs.org> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17#include <sys/ioctl.h> 18#include <sys/socket.h> 19#include <err.h> 20#include <errno.h> 21#include <fcntl.h> 22#include <pcap.h> 23#include <pwd.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <time.h> 27#include <unistd.h> 28 29#ifdef __amd64__ 30#include <machine/chromeecvar.h> 31#else 32#error "this requires amd64" 33#endif 34 35int chromeec; 36time_t last_flash; 37 38void chromeec_set_seq(int); 39void chromeec_load_program(void); 40void have_packet(u_char *, const struct pcap_pkthdr *, const u_char *); 41 42int 43main(int argc, char **argv) 44{ 45 pcap_handler phandler = have_packet; 46 pcap_t *hpcap; 47 struct passwd *pw; 48 char errbuf[PCAP_ERRBUF_SIZE]; 49 50 if ((pw = getpwnam("nobody")) == NULL) 51 errx(1, "nobody?"); 52 endpwent(); 53 54 if ((hpcap = pcap_open_live("pflog0", 1, 1, 500, errbuf)) == NULL) 55 errx(1, "failed pcap_open_live(pflog0): %s", errbuf); 56 57 if (pcap_datalink(hpcap) != DLT_PFLOG) 58 errx(1, "invalid datalink type"); 59 60 if (ioctl(pcap_fileno(hpcap), BIOCLOCK) < 0) 61 err(1, "BIOCLOCK"); 62 63 if ((chromeec = open("/dev/chromeec", O_RDWR)) == -1) 64 err(1, "open /dev/chromeec"); 65 66 if (chroot("/var/empty") != 0 || chdir("/") != 0) 67 err(1, "suk"); 68 if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1 || 69 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) 70 err(1, "setresgid/setresuid"); 71 72 chromeec_load_program(); 73 last_flash = time(NULL); 74 75 while (1) { 76 if (pcap_dispatch(hpcap, 1, phandler, NULL) < 0) 77 errx(1, "%s", pcap_geterr(hpcap)); 78 } 79 80 return (0); 81} 82 83void chromeec_set_seq(int param) 84{ 85 if (ioctl(chromeec, CHROMEEC_IOC_LIGHTBAR_SET_SEQ, &param) < 0) 86 err(1, "ioctl"); 87} 88 89void chromeec_load_program(void) 90{ 91 struct chromeec_lightbar_program p = { 0 }; 92 int i = 0; 93 94 /* red */ 95 p.data[i++] = CHROMEEC_LIGHTBAR_OPCODE_SET_COLOR_SINGLE; 96 p.data[i++] = 0xf4; 97 p.data[i++] = 0xff; 98 99 /* ramp as fast as possible */ 100 p.data[i++] = CHROMEEC_LIGHTBAR_OPCODE_SET_RAMP_DELAY; 101 p.data[i++] = 0x00; 102 p.data[i++] = 0x00; 103 p.data[i++] = 0x00; 104 p.data[i++] = 0x01; 105 106 /* cycle once and end */ 107 p.data[i++] = CHROMEEC_LIGHTBAR_OPCODE_ON; 108 p.data[i++] = CHROMEEC_LIGHTBAR_OPCODE_CYCLE_ONCE; 109 p.data[i++] = CHROMEEC_LIGHTBAR_OPCODE_OFF; 110 p.data[i++] = CHROMEEC_LIGHTBAR_OPCODE_HALT; 111 112 p.size = i; 113 114 /* if the ec happens to be in SEQ_STOP it won't respond, so force it 115 * back into s0 */ 116 chromeec_set_seq(CHROMEEC_LIGHTBAR_SEQ_S0); 117 118 if (ioctl(chromeec, CHROMEEC_IOC_LIGHTBAR_SET_PROGRAM, &p) < 0) 119 err(1, "ioctl"); 120} 121 122void 123have_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 124{ 125 if (time(NULL) - last_flash <= 0) 126 return; 127 128 last_flash = time(NULL); 129 130 chromeec_set_seq(CHROMEEC_LIGHTBAR_SEQ_PROGRAM); 131}