func (t *Listener) readRAWSocket() { // AF_INET can't capture outgoing packets, must change to use AF_PACKET // https://github.com/golang/go/issues/7653 // http://www.binarytides.com/packet-sniffer-code-in-c-using-linux-sockets-bsd-part-2/ proto := (syscall.ETH_P_ALL<<8)&0xff00 | syscall.ETH_P_ALL>>8 // change to Big-Endian order fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, proto) if err != nil { log.Fatal("socket: ", err) } defer syscall.Close(fd) if t.addr != "" && t.addr != "0.0.0.0" { ifi, err := net.InterfaceByName(t.addr) if err != nil { log.Fatal("interfacebyname: ", err) } lla := syscall.SockaddrLinklayer{Protocol: uint16(proto), Ifindex: ifi.Index} if err := syscall.Bind(fd, &lla); err != nil { log.Fatal("bind: ", err) } } var src_ip string var dest_ip string buf := make([]byte, 65536) for { n, _, err := syscall.Recvfrom(fd, buf, 0) if err != nil { log.Println("Error:", err) continue } if n <= 0 { continue } packet := gopacket.NewPacket(buf[:n], layers.LayerTypeEthernet, gopacket.Default) if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { tcp, _ := tcpLayer.(*layers.TCP) src_ip = packet.NetworkLayer().NetworkFlow().Src().String() dest_ip = packet.NetworkLayer().NetworkFlow().Dst().String() t.parsePacket(src_ip, dest_ip, tcp) } } }
func (w *Watcher) readAllEvents() { buf := make([]byte, syscall.Getpagesize()) listener, _ := w.listener.(*netlinkListener) for { if w.isDone() { return } nr, _, err := syscall.Recvfrom(listener.sock, buf, 0) if err != nil { w.Error <- err continue } if nr < syscall.NLMSG_HDRLEN { w.Error <- syscall.EINVAL continue } msgs, _ := syscall.ParseNetlinkMessage(buf[:nr]) for _, m := range msgs { if m.Header.Type == syscall.NLMSG_DONE { w.handleEventAll(m.Data) } } } }
func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { fd.rio.Lock() defer fd.rio.Unlock() if err := fd.incref(false); err != nil { return 0, nil, err } defer fd.decref() for { n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0) if err == syscall.EAGAIN { err = errTimeout if fd.rdeadline >= 0 { if err = fd.pollServer.WaitRead(fd); err == nil { continue } } } if err != nil { n = 0 } break } if err != nil && err != io.EOF { err = &OpError{"read", fd.net, fd.laddr, err} } return }
func (nlSock *NLSocket) recv() ([]GNLMessage, error) { buff := make([]byte, 16384) var msgsList []GNLMessage for { n, _, err := syscall.Recvfrom(nlSock.Sd, buff, 0) if err != nil { return nil, err } resp := buff[:n] for len(resp) > 0 { rmsg, data, err := DeserializeNLMsg(resp) if err != nil { return nil, err } if len(msgsList) == 0 && rmsg.Flags&0x2 == 0 { return []GNLMessage{rmsg}, nil } else if rmsg.Family == DoneMessageType { return msgsList, nil } msgsList = append(msgsList, rmsg) resp = data } } return msgsList, nil }
func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err os.Error) { if fd == nil || fd.sysfile == nil { return 0, nil, os.EINVAL } fd.rio.Lock() defer fd.rio.Unlock() fd.incref() defer fd.decref() if fd.rdeadline_delta > 0 { fd.rdeadline = pollserver.Now() + fd.rdeadline_delta } else { fd.rdeadline = 0 } var oserr os.Error for { var errno int n, sa, errno = syscall.Recvfrom(fd.sysfd, p, 0) if errno == syscall.EAGAIN && fd.rdeadline >= 0 { pollserver.WaitRead(fd) continue } if errno != 0 { n = 0 oserr = os.Errno(errno) } break } if oserr != nil { err = &OpError{"read", fd.net, fd.laddr, oserr} } return }
func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { if err := fd.readLock(); err != nil { return 0, nil, err } defer fd.readUnlock() if err := fd.pd.PrepareRead(); err != nil { return 0, nil, &OpError{"read", fd.net, fd.laddr, err} } for { n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0) if err != nil { n = 0 if err == syscall.EAGAIN { if err = fd.pd.WaitRead(); err == nil { continue } } } err = chkReadErr(n, err, fd) break } if err != nil && err != io.EOF { err = &OpError{"read", fd.net, fd.laddr, err} } return }
func (fd *netFD) ReadFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { if fd == nil || fd.sysfile == nil { return 0, nil, os.EINVAL } fd.rio.Lock() defer fd.rio.Unlock() fd.incref() defer fd.decref() for { n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0) if err == syscall.EAGAIN { if fd.rdeadline >= 0 { pollserver.WaitRead(fd) continue } err = errTimeout } if err != nil { n = 0 } break } if err != nil { err = &OpError{"read", fd.net, fd.laddr, err} } return }
func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) { if err := fd.readLock(); err != nil { return 0, nil, err } defer fd.readUnlock() if err := fd.pd.prepareRead(); err != nil { return 0, nil, err } for { n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0) if err != nil { n = 0 if err == syscall.EAGAIN { if err = fd.pd.waitRead(); err == nil { continue } } } err = fd.eofError(n, err) break } if _, ok := err.(syscall.Errno); ok { err = os.NewSyscallError("recvfrom", err) } return }
// Receives messages from Kernel and forwards to channels func Getreply(s *NetlinkSocket, done <-chan bool, msgchan chan string, errchan chan error) { for { rb := make([]byte, MAX_AUDIT_MESSAGE_LENGTH) nr, _, err := syscall.Recvfrom(s.fd, rb, 0) if isDone(msgchan, errchan, done) { return } if err != nil { log.Println("Error While Recieving !!") errchan <- err continue } if nr < syscall.NLMSG_HDRLEN { log.Println("Message Too Short!!") errchan <- syscall.EINVAL continue } rb = rb[:nr] msgs, err := ParseAuditNetlinkMessage(rb) if err != nil { log.Println("Not Parsed Successfuly !!") errchan <- err continue } for _, m := range msgs { //Decide on various message Types //Add more message Types if m.Header.Type == syscall.NLMSG_DONE { log.Println("Done") } else if m.Header.Type == syscall.NLMSG_ERROR { err := int32(nativeEndian().Uint32(m.Data[0:4])) if err == 0 { //Acknowledgement from kernel log.Println("Ack") } else { log.Println("NLMSG_ERROR") } } else if m.Header.Type == AUDIT_GET { log.Println("AUDIT_GET") } else if m.Header.Type == AUDIT_FIRST_USER_MSG { log.Println("AUDIT_FIRST_USER_MSG") } else if m.Header.Type == AUDIT_SYSCALL { msgchan <- ("type=SYSCALL " + "msg=" + string(m.Data[:])) } else if m.Header.Type == AUDIT_CWD { msgchan <- ("type=CWD " + "msg=" + string(m.Data[:])) } else if m.Header.Type == AUDIT_PATH { msgchan <- ("type=PATH " + "msg=" + string(m.Data[:])) } else if m.Header.Type == AUDIT_EOE { // log.Println("Event Ends ", string(m.Data[:])) } else if m.Header.Type == AUDIT_CONFIG_CHANGE { msgchan <- ("type=CONFIG_CHANGE " + "msg=" + string(m.Data[:])) } else { log.Println("Unknown: ", m.Header.Type) } } } }
func (nl *NetlinkSocket) RecvMessages(sz, sockflags int) ([]NetlinkMessage, error) { buf := make([]byte, sz) rsz, _, err := syscall.Recvfrom(nl.sfd, buf, sockflags) if err != nil { return nil, err } if rsz < syscall.NLMSG_HDRLEN { return nil, syscall.EINVAL } msgList, err := syscall.ParseNetlinkMessage(buf[:rsz]) if err != nil { return nil, err } ret := []NetlinkMessage{} for _, msg := range msgList { msg := NetlinkMessage(msg) logf("received: %+v\n", msg) ret = append(ret, msg) } return ret, nil }
func traceOne(addr *syscall.SockaddrInet4, ttl int) *ReturnArgs { cli, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) if err != nil { exitWithError(err) } srv, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP) if err != nil { exitWithError(err) } defer syscall.Close(cli) defer syscall.Close(srv) // set ttl, stolen from somewhere else... // https://github.com/aeden/traceroute/blob/master/traceroute.go#L195 if err := syscall.SetsockoptInt(cli, syscall.SOL_IP, syscall.IP_TTL, ttl); err != nil { exitWithError(err) } // set timeout, stolen from somewhere else... // https://github.com/aeden/traceroute/blob/master/traceroute.go#L197 tv := syscall.NsecToTimeval(1e6 * TIMEOUT) if err := syscall.SetsockoptTimeval(srv, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv); err != nil { exitWithError(err) } if err := syscall.Bind(srv, toAddr(HOST, RECV_PORT)); err != nil { exitWithError(err) } rr := &ReturnArgs{} start := time.Now() if err := syscall.Sendto(cli, makeICMP(), 0, addr); err != nil { return rr } buf := make([]byte, 512) _, from, err := syscall.Recvfrom(srv, buf, 0) if err != nil { return rr } rr.elapsed = float64(time.Since(start).Nanoseconds()) / 1e6 t, c := parseICMP(buf) if t == 3 && c == 3 { // Destination port unreachable, type==3 && code==3 rr.done = true } else if t != 11 { // Time Exceeded, type==11 && code in (0,1) return rr } rr.ok = true rr.ip = toStr(from) addrs, err := net.LookupAddr(rr.ip) if err != nil { rr.addr = rr.ip } else { rr.addr = addrs[0] } return rr }
// Traceroute executes traceroute to given destination, using options from TracerouteOptions // and sending updates to chan c // // Outbound packets are UDP packets and inbound packets are ICMP. // // Returns an error or nil if no error occurred func Traceroute(dest *net.IPAddr, options *TracerouteOptions, c chan TraceUpdate) (err error) { var destAddr [4]byte copy(destAddr[:], dest.IP.To4()) socketAddr, err := getSocketAddr() if err != nil { return } timeoutMs := (int64)(options.TimeoutMs) tv := syscall.NsecToTimeval(1000 * 1000 * timeoutMs) ttl := 1 for { // Set up receiving socket recvSocket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP) if err != nil { log.Fatal("Cannot setup receive socket, please run as root or with CAP_NET_RAW permissions") return err } // Set up sending socket sendSocket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) if err != nil { log.Fatal("Cannot setup sending socket") return err } start := time.Now() syscall.SetsockoptInt(sendSocket, 0x0, syscall.IP_TTL, ttl) syscall.SetsockoptTimeval(recvSocket, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv) syscall.Bind(recvSocket, &syscall.SockaddrInet4{Port: options.Port, Addr: socketAddr}) syscall.Sendto(sendSocket, []byte{0x0}, 0, &syscall.SockaddrInet4{Port: options.Port, Addr: destAddr}) var p = make([]byte, options.PacketSize) n, from, err := syscall.Recvfrom(recvSocket, p, 0) elapsed := time.Since(start) if err == nil { currAddr := from.(*syscall.SockaddrInet4).Addr hop := TraceUpdate{Success: true, Address: currAddr, N: n, ElapsedTime: elapsed, TTL: ttl} currHost, err := net.LookupAddr(hop.addressString()) if err == nil { hop.Host = currHost[0] } // Send update c <- hop ttl += 1 // We reached the destination if ttl > options.MaxTTL || currAddr == destAddr { ttl = 1 } } else { c <- TraceUpdate{Success: false, TTL: ttl} ttl += 1 } syscall.Close(recvSocket) syscall.Close(sendSocket) } }
func receiveICMP(result chan icmpEvent) { // Set up the socket to receive inbound packets sock, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP) if err != nil { result <- makeICMPErrorEvent(&icmpEvent{}, fmt.Errorf("%v. Did you forget to run as root?", err)) return } err = syscall.Bind(sock, &syscall.SockaddrInet4{}) if err != nil { result <- makeICMPErrorEvent(&icmpEvent{}, err) return } var pkt = make([]byte, 1024) for { event := icmpEvent{} _, from, err := syscall.Recvfrom(sock, pkt, 0) if err != nil { result <- makeICMPErrorEvent(&event, err) return } reader := bytes.NewReader(pkt) var ip IPHeader var icmp ICMPHeader var tcp TCPHeader err = binary.Read(reader, binary.BigEndian, &ip) if ip.Protocol != syscall.IPPROTO_ICMP { break } ipheaderlen := (ip.VerHdrLen & 0xf) * 4 reader = bytes.NewReader(pkt[ipheaderlen:]) err = binary.Read(reader, binary.BigEndian, &icmp) if icmp.Type != 11 || icmp.Code != 0 { break } err = binary.Read(reader, binary.BigEndian, &ip) if ip.Protocol != syscall.IPPROTO_TCP { break } err = binary.Read(reader, binary.BigEndian, &tcp) event.localAddr.IP = append(event.localAddr.IP, ip.SourceIP[:]...) event.localPort = int(tcp.SrcPort) // fill in the remote endpoint deatils on the event struct event.remoteAddr, _, _ = ToIPAddrAndPort(from) result <- makeICMPEvent(&event, icmpTTLExpired) } }
// Receives messages from Kernel and forwards to channels func Getreply(s *NetlinkSocket, done <-chan bool, msgchan chan string, errchan chan error) { for { rb := make([]byte, MAX_AUDIT_MESSAGE_LENGTH) nr, _, err := syscall.Recvfrom(s.fd, rb, 0) if isDone(msgchan, errchan, done) { return } if err != nil { log.Println("Error While Recieving !!") errchan <- err continue } if nr < syscall.NLMSG_HDRLEN { log.Println("Message Too Short!!") errchan <- syscall.EINVAL continue } rb = rb[:nr] msgs, err := ParseAuditNetlinkMessage(rb) if err != nil { log.Println("Not Parsed Successfuly !!") errchan <- err continue } for _, m := range msgs { //Decide on various message Types if m.Header.Type == syscall.NLMSG_DONE { log.Println("Done") } else if m.Header.Type == syscall.NLMSG_ERROR { err := int32(nativeEndian().Uint32(m.Data[0:4])) if err == 0 { //Acknowledgement from kernel log.Println("Ack") } else { log.Println("NLMSG_ERROR") } } else if m.Header.Type == uint16(AUDIT_EOE) { // log.Println("Event Ends ", string(m.Data[:])) } else if m.Header.Type == uint16(AUDIT_GET) { log.Println("AUDIT_GET") } else if m.Header.Type == uint16(AUDIT_FIRST_USER_MSG) { log.Println("AUDIT_FIRST_USER_MSG") } else { Type := auditConstant(m.Header.Type) if Type.String() == "auditConstant("+strconv.Itoa(int(m.Header.Type))+")" { log.Println("Unknown: ", m.Header.Type) } else { msgchan <- ("type=" + Type.String()[6:] + " msg=" + string(m.Data[:])) } } } } }
func receive() (arpDatagram, time.Time, error) { buffer := make([]byte, 128) n, _, err := syscall.Recvfrom(sock, buffer, 0) if err != nil { return arpDatagram{}, time.Now(), err } // skip 14 bytes ethernet header return parseArpDatagram(buffer[14:n]), time.Now(), nil }
func (nl *NetlinkSocket) RecvMessagesRaw(sz, sockflags int) ([]byte, error) { buf := make([]byte, sz) rsz, _, err := syscall.Recvfrom(nl.sfd, buf, sockflags) if err != nil { return nil, err } return buf[:rsz], nil }
func Hop(port, ttl int, IP_addr net.IP) (*Hop_ret, error) { ret_addr := net.IPv4(0, 0, 0, 0) success := false // make sockets send_udp_s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) if err != nil { return nil, err } recv_icmp_s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP) if err != nil { return nil, err } //editing TTL value for outgoing IPv4 packets if err := syscall.SetsockoptInt(send_udp_s, syscall.SOL_IP, syscall.IP_TTL, ttl); err != nil { return nil, err } tv := syscall.NsecToTimeval(1000 * 1000 * TIME_OUT_MS) syscall.SetsockoptTimeval(recv_icmp_s, syscall.SOL_SOCKET, syscall.SO_RCVTIMEO, &tv) defer syscall.Close(send_udp_s) defer syscall.Close(recv_icmp_s) //connect sockets if err := syscall.Bind(recv_icmp_s, &syscall.SockaddrInet4{Port: port, Addr: [4]byte{137, 224, 226, 47}}); err != nil { return nil, err } //send udp-packet var IP [4]byte copy(IP[:], IP_addr.To4()) if err := syscall.Sendto(send_udp_s, []byte{0x42, 0x42}, 0, &syscall.SockaddrInet4{Port: 1337, Addr: IP}); err != nil { return nil, err } //receive ICMP recv_buffer := make([]byte, 4096) _, _, err = syscall.Recvfrom(recv_icmp_s, recv_buffer, 0) if err == nil { header, err := ipv4.ParseHeader(recv_buffer) if err != nil { log.Errorf("%q", err) } success = true ret_addr = header.Src } else { //time out success = false ret_addr = net.IPv4(0, 0, 0, 0) //log.Errorf("%q", err) } //resolve (timeout) errors, retry or return false... return &Hop_ret{Addr: ret_addr, TTL: ttl, success: success}, nil }
func main() { flag.Parse() args := flag.Args() if flag.NArg() != 1 { usage() } f, err := os.Create(args[0]) if err != nil { log.Fatal(err) } defer func() { if err := f.Close(); err != nil { log.Fatal(err) } }() pw := pcap.NewWriter(f) defer func() { if err := pw.Close(); err != nil { log.Fatal(err) } }() hdr := &pcap.Header{ SnapLen: maxSnapLen, LinkType: pcap.LINKTYPE_ETHERNET, } if err := pw.WriteHeader(hdr); err != nil { log.Fatal(err) } fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, htons(syscall.ETH_P_ALL)) if err != nil { log.Fatal(err) } var buf [maxSnapLen]byte for { n, _, err := syscall.Recvfrom(fd, buf[:], 0) if err != nil { log.Fatal(err) } sec, usec := currTime() record := &pcap.RecordHeader{TsSec: uint32(sec), TsUsec: uint32(usec), CapLen: uint32(n), Len: uint32(n)} if err := pw.WriteRecordHeader(record); err != nil { log.Fatal(err) } if _, err = pw.Write(buf[:n]); err != nil { log.Fatal(err) } } }
func NewRtHub() (*RtHub, error) { self := &RtHub{ sock: NlSocketAlloc(), lock: &sync.Mutex{}, unilock: &sync.Mutex{}, multicast: make(map[uint32][]NetlinkListener), } if err := NlConnect(self.sock, syscall.NETLINK_ROUTE); err != nil { NlSocketFree(self.sock) return nil, err } go func() { for { buf := make([]byte, syscall.Getpagesize()) if n, _, err := syscall.Recvfrom(self.sock.Fd, buf, syscall.MSG_TRUNC); err != nil { if e, ok := err.(syscall.Errno); ok && e.Temporary() { continue } break } else if msgs, err := syscall.ParseNetlinkMessage(buf[:n]); err != nil { break } else { for _, msg := range msgs { multi := func() []NetlinkListener { self.lock.Lock() defer self.lock.Unlock() var ret []NetlinkListener for _, s := range self.multicast { ret = append(ret, s...) } return ret }() if msg.Header.Seq == self.uniseq { if self.unicast != nil { self.unicast.NetlinkListen(msg) } switch msg.Header.Type { case syscall.NLMSG_DONE, syscall.NLMSG_ERROR: self.unilock.Unlock() } } if msg.Header.Seq == 0 { for _, proc := range multi { proc.NetlinkListen(msg) } } } } } log.Print("rt hub loop exit") }() return self, nil }
func (k *PosixKernel) Recvfrom(fd co.Fd, buf co.Buf, size co.Len, flags int, from co.Buf, fromlen co.Len) uint64 { p := make([]byte, size) if n, _, err := syscall.Recvfrom(int(fd), p, flags); err != nil { // TODO: need kernel.Pack() so we can pack a sockaddr into from if err := buf.Pack(p); err != nil { return UINT64_MAX // FIXME } return uint64(n) } else { return UINT64_MAX // FIXME } }
func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) { rb := make([]byte, syscall.Getpagesize()) nr, _, err := syscall.Recvfrom(s.fd, rb, 0) if err != nil { return nil, err } if nr < syscall.NLMSG_HDRLEN { return nil, ErrShortResponse } rb = rb[:nr] return syscall.ParseNetlinkMessage(rb) }
func (w *Worker) recvPacket(socket int) ([]byte, int) { //time.Sleep(time.Duration(time.Millisecond * 100)) RecvBuf := make([]byte, 52) var RecvLen int //var from net.TCPAddr var RecvErr error RecvLen, _, RecvErr = syscall.Recvfrom(socket, RecvBuf, 0) if RecvErr != nil { fmt.Printf("%s", RecvErr.Error()) } return RecvBuf, RecvLen }
func (self *NetLinkSocket) Receive() (*ProcEvent, error) { rb := make([]byte, 76) nr, _, err := syscall.Recvfrom(self.fd, rb, 0) if err != nil { return nil, err } if nr < syscall.NLMSG_HDRLEN { return nil, ErrShortResponse } rb = rb[:nr] return parseProcEvent(rb) }
// Receive is a wrapper for recieving from netlink socket and return an array of NetlinkMessage func (s *NetlinkConnection) Receive(bytesize int, block int) ([]NetlinkMessage, error) { rb := make([]byte, bytesize) nr, _, err := syscall.Recvfrom(s.fd, rb, 0|block) if err != nil { return nil, errors.Wrap(err, "recvfrom failed") } if nr < syscall.NLMSG_HDRLEN { return nil, errors.Wrap(err, "message length shorter than expected") } rb = rb[:nr] return parseAuditNetlinkMessage(rb) }
// Wrapper for Recvfrom func (s *NetlinkConnection) Receive(bytesize int, block int) ([]NetlinkMessage, error) { rb := make([]byte, bytesize) nr, _, err := syscall.Recvfrom(s.fd, rb, 0|block) if err != nil { return nil, err } if nr < syscall.NLMSG_HDRLEN { return nil, syscall.EINVAL } rb = rb[:nr] return parseAuditNetlinkMessage(rb) }
// ReadFromUnix reads a packet from c, copying the payload into b. // It returns the number of bytes copied into b and the return address // that was on the packet. // // ReadFromUnix can be made to time out and return err == os.EAGAIN // after a fixed time limit; see SetTimeout and SetReadTimeout. func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err os.Error) { if !c.ok() { return 0, nil, os.EINVAL } n, sa, errno := syscall.Recvfrom(c.fd.fd, b, 0) if errno != 0 { err = os.Errno(errno) } switch sa := sa.(type) { case *syscall.SockaddrUnix: addr = &UnixAddr{sa.Name, c.fd.proto == syscall.SOCK_DGRAM} } return }
// Wrapper for Recvfrom func (s *NetlinkSocket) Receive(bytesize int, block int) ([]syscall.NetlinkMessage, error) { rb := make([]byte, bytesize) nr, _, err := syscall.Recvfrom(s.fd, rb, 0|block) //nr, _, err := syscall.Recvfrom(s, rb, syscall.MSG_PEEK|syscall.MSG_DONTWAIT) if err != nil { return nil, err } if nr < syscall.NLMSG_HDRLEN { return nil, syscall.EINVAL } rb = rb[:nr] return ParseAuditNetlinkMessage(rb) }
// genl_ctrl_probe_by_name is not exposed in the original libnl func GenlCtrlProbeByName(sk *NlSock, name string) (AttrMap, error) { if err := GenlSendSimple(sk, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, CTRL_VERSION, syscall.NLM_F_DUMP); err != nil { return AttrMap{}, err } var ret AttrMap err := func() error { for { buf := make([]byte, syscall.Getpagesize()) if nn, _, err := syscall.Recvfrom(sk.Fd, buf, syscall.MSG_TRUNC); err != nil { return err } else if nn > len(buf) { return NLE_MSG_TRUNC } else { buf = buf[:nn] } if msgs, err := syscall.ParseNetlinkMessage(buf); err != nil { return err } else { for _, msg := range msgs { switch msg.Header.Type { case GENL_ID_CTRL: genl := (*GenlMsghdr)(unsafe.Pointer(&msg.Data[0])) switch genl.Cmd { case CTRL_CMD_NEWFAMILY: if attrs, err := CtrlPolicy.Parse(msg.Data[GENL_HDRLEN:]); err != nil { return err } else if info, ok := attrs.(AttrMap); !ok { // shold not happen } else if value := info.Get(CTRL_ATTR_FAMILY_NAME); value == nil { // should not happen by kernel } else if string(value.(NulString)) == name { ret = info } default: return fmt.Errorf("unexpected command") } case syscall.NLMSG_DONE: return nil case syscall.NLMSG_ERROR: return fmt.Errorf("NlMsgerr=%s", (*syscall.NlMsgerr)(unsafe.Pointer(&msg.Data[0]))) default: return fmt.Errorf("unexpected NlMsghdr=%s", msg.Header) } } } } }() return ret, err }
func (s *NetlinkSocket) Receive() ([]syscall.NetlinkMessage, error) { if s.fd < 0 { return nil, fmt.Errorf("Receive called on a closed socket") } rb := make([]byte, syscall.Getpagesize()) nr, _, err := syscall.Recvfrom(s.fd, rb, 0) if err != nil { return nil, err } if nr < syscall.NLMSG_HDRLEN { return nil, fmt.Errorf("Got short response from netlink") } rb = rb[:nr] return syscall.ParseNetlinkMessage(rb) }
// ReadFromUDP reads a UDP packet from c, copying the payload into b. // It returns the number of bytes copied into b and the return address // that was on the packet. // // ReadFromUDP can be made to time out and return err == os.EAGAIN // after a fixed time limit; see SetTimeout and SetReadTimeout. func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err os.Error) { if !c.ok() { return 0, nil, os.EINVAL } n, sa, errno := syscall.Recvfrom(c.fd.fd, b, 0) if errno != 0 { err = os.Errno(errno) } switch sa := sa.(type) { case *syscall.SockaddrInet4: addr = &UDPAddr{&sa.Addr, sa.Port} case *syscall.SockaddrInet6: addr = &UDPAddr{&sa.Addr, sa.Port} } return }