package util import ( "crypto/rand" "encoding/base32" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/google/gopacket/pcapgo" log "github.com/sirupsen/logrus" "hash/adler32" "io/ioutil" "net" "os" "strconv" "strings" "time" ) // WritePcap writes the provided data to a given pcap file func WritePcap(file string, data []byte) { f, err := os.Create(file) if err != nil { log.Errorf("Error writing pcap file %s", file) } defer f.Close() r, err := pcapgo.NewNgWriter(f, layers.LinkTypeEthernet) if err != nil { log.Errorf("Error writing pcap file %s", file) } defer r.Flush() ci := gopacket.CaptureInfo{ Timestamp: time.Now(), CaptureLength: len(data), Length: len(data), } err = r.WritePacket(ci, data) } // WriteBinary writes the provided data to a given binary file func WriteBinary(file string, data []byte) { if err := ioutil.WriteFile(file, data, 0644); err != nil { log.Errorf("Error writing binary file %s", file) } } func WritePIDFile(filename string) { if filename == "" { return } if err := ioutil.WriteFile(filename, []byte(strconv.Itoa(os.Getpid()) + "\n"), 0644); err != nil { log.Errorf("Error writing PID file %s", filename) } } func GenerateMac(customMAC string) net.HardwareAddr { if customMAC != "" { ret, _ := net.ParseMAC(customMAC) return ret } buf := make([]byte, 6) var mac net.HardwareAddr if _, err := rand.Read(buf); err != nil { log.Error("Error generating random mac") ret, _ := net.ParseMAC("52:54:00:12:34:aa") return ret } // Set local bit, ensure unicast address buf[0] = (buf[0] | 2) & 0xfe mac = append(mac, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]) return mac } func GenerateXID() []byte { buf := make([]byte, 4) if _, err := rand.Read(buf); err != nil { log.Error("Error generating random xid") return []byte{36, 23, 250, 224} // chosen by fair dice roll // guaranteed to be random --> https://xkcd.com/221/ } return buf } func GenerateUId(path string) string { adl := adler32.Checksum([]byte(path)) byt := make([]byte, 4) for i := uint32(0); i < 4; i++ { byt[i] = byte((adl >> (8 * i)) & 0xff) } b32 := base32.StdEncoding.EncodeToString(byt) return strings.ReplaceAll(b32, "=", "") } // If is a helper type to form expressive ternary expressions being the // concatenation of a type conversion and a method call such as: // // i := If(cond).Int(a, b) // // For details, see https://stackoverflow.com/a/59375088/1705598 type If bool // If returns a if c is true, b otherwise. func (c If) If(a, b interface{}) interface{} { if c { return a } return b } // MAC returns a if c is true, b otherwise. func (c If) MAC(a, b net.HardwareAddr) net.HardwareAddr { if c { return a } return b } // IP returns a if c is true, b otherwise. func (c If) IP(a, b net.IP) net.IP { if c { return a } return b }