예제 #1
1
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)
		}

	}

}
예제 #2
0
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)
			}
		}
	}
}
예제 #3
0
파일: fd_unix.go 프로젝트: hfeeki/go
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
}
예제 #4
0
파일: gnl2go.go 프로젝트: kobolog/gorb
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
}
예제 #5
0
파일: fd.go 프로젝트: rapgamer/golang-china
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
}
예제 #6
0
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
}
예제 #7
0
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
}
예제 #8
0
파일: fd_unix.go 프로젝트: duhaibo0404/go-1
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
}
예제 #9
0
// 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)
			}
		}
	}

}
예제 #10
0
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
}
예제 #11
0
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
}
예제 #12
0
파일: trace.go 프로젝트: mag-/gtr
// 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)
	}
}
예제 #13
0
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)
	}
}
예제 #14
0
// 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[:]))
				}
			}
		}
	}

}
예제 #15
0
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
}
예제 #16
0
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
}
예제 #17
0
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
}
예제 #18
0
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)
		}
	}
}
예제 #19
0
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
}
예제 #20
0
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
	}
}
예제 #21
0
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)
}
예제 #22
0
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
}
예제 #23
0
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)
}
예제 #24
0
// 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)
}
예제 #25
0
// 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)
}
예제 #26
0
파일: unixsock.go 프로젝트: 8l/go-learn
// 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
}
예제 #27
0
// 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)
}
예제 #28
0
파일: genl_ctrl.go 프로젝트: qmsk/nlgo
// 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
}
예제 #29
0
파일: nl_linux.go 프로젝트: rossj/docker
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)
}
예제 #30
0
파일: udpsock.go 프로젝트: 8l/go-learn
// 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
}