예제 #1
0
// NewTPacket returns a new TPacket object for reading packets off the wire.
// Its behavior may be modified by passing in any/all of afpacket.Opt* to this
// function.
// If this function succeeds, the user should be sure to Close the returned
// TPacket when finished with it.
func NewTPacket(opts ...interface{}) (h *TPacket, err error) {
	h = &TPacket{}
	if h.opts, err = parseOptions(opts...); err != nil {
		return nil, err
	}
	fd, err := C.socket(C.AF_PACKET, C.int(h.opts.socktype), C.int(C.htons(C.ETH_P_ALL)))
	if err != nil {
		return nil, err
	}
	h.fd = fd
	if h.opts.iface != "" {
		if err = h.bindToInterface(h.opts.iface); err != nil {
			goto errlbl
		}
	}
	if err = h.setRequestedTPacketVersion(); err != nil {
		goto errlbl
	}
	if err = h.setUpRing(); err != nil {
		goto errlbl
	}
	// Clear stat counter from socket
	if err = h.InitSocketStats(); err != nil {
		goto errlbl
	}
	runtime.SetFinalizer(h, (*TPacket).Close)
	return h, nil
errlbl:
	h.Close()
	return nil, err
}
예제 #2
0
파일: port_cgo.go 프로젝트: hkwi/gopenflow
func (self NamedPort) Ethernet() (PortEthernetProperty, error) {
	switch self.hatype {
	case 0:
		return PortEthernetProperty{}, nil
	case syscall.ARPHRD_ETHER:
		// pass
	default:
		return PortEthernetProperty{}, fmt.Errorf("%s not an ether", self.name)
	}

	cname := C.CString(self.name)
	defer C.free(unsafe.Pointer(cname))

	fd := C.socket(C.AF_INET, C.SOCK_DGRAM, 0)
	defer C.close(fd)

	state := PortEthernetProperty{}

	ecmd := C.struct_ethtool_cmd{cmd: C.ETHTOOL_GSET}
	if r, err := C.ethtool_cmd_call(fd, cname, &ecmd); err != nil {
		return state, fmt.Errorf("ethtool for %s: %s", self.name, err.Error())
	} else if r != 0 {
		return state, fmt.Errorf("ethtool_cmd_call error")
	} else {
		for k, v := range supportedSpeed {
			if ecmd.supported&k != 0 && v > state.MaxSpeed {
				state.MaxSpeed = v
			}
		}
		state.Supported = 0
		for k, v := range supportedConvert {
			if ecmd.supported&k != 0 {
				state.Supported |= v
			}
		}
		state.Advertised = 0
		state.Peer = 0
		for k, v := range advertisedConvert {
			if ecmd.advertising&k != 0 {
				state.Advertised |= v
			}
			if ecmd.lp_advertising&k != 0 {
				state.Peer |= v
			}
		}

		var curr uint32
		switch C.ethtool_cmd_speed(&ecmd) {
		case C.SPEED_10:
			state.CurrSpeed = 10000
			switch ecmd.duplex {
			case C.DUPLEX_HALF:
				curr |= ofp4.OFPPF_10MB_HD
			case C.DUPLEX_FULL:
				curr |= ofp4.OFPPF_10MB_FD
			default:
				curr |= ofp4.OFPPF_OTHER
			}
		case C.SPEED_100:
			state.CurrSpeed = 100000
			switch ecmd.duplex {
			case C.DUPLEX_HALF:
				curr |= ofp4.OFPPF_100MB_HD
			case C.DUPLEX_FULL:
				curr |= ofp4.OFPPF_100MB_FD
			default:
				curr |= ofp4.OFPPF_OTHER
			}
		case C.SPEED_1000:
			state.CurrSpeed = 1000000
			switch ecmd.duplex {
			case C.DUPLEX_HALF:
				curr |= ofp4.OFPPF_1GB_HD
			case C.DUPLEX_FULL:
				curr |= ofp4.OFPPF_1GB_FD
			default:
				curr |= ofp4.OFPPF_OTHER
			}
		case C.SPEED_10000:
			state.CurrSpeed = 1000000
			switch ecmd.duplex {
			case C.DUPLEX_FULL:
				curr |= ofp4.OFPPF_10GB_FD
			default:
				curr |= ofp4.OFPPF_OTHER
			}
		default:
			curr |= ofp4.OFPPF_OTHER
		}
		switch ecmd.port {
		case C.PORT_TP:
			curr |= ofp4.OFPPF_COPPER
		case C.PORT_FIBRE:
			curr |= ofp4.OFPPF_FIBER
		}
		if ecmd.autoneg != C.AUTONEG_DISABLE {
			curr |= ofp4.OFPPF_AUTONEG
		}
		state.Curr = curr
	}
	return state, nil
}