예제 #1
0
파일: pfring.go 프로젝트: jcantrill/geard
// WritePacketData uses the ring to send raw packet data to the interface.
func (r *Ring) WritePacketData(data []byte) error {
	buf := (*C.char)(unsafe.Pointer(&data[0]))
	if rv := C.pfring_send(r.cptr, buf, C.u_int(len(data)), 1); rv != 0 {
		return fmt.Errorf("Unable to send packet data, got error code %d", rv)
	}
	return nil
}
예제 #2
0
func oidWrite(dst *C.asn_oid_t, value SnmpValue) SnmpError {
	uintArray := value.GetUint32s()
	if ASN_MAXOIDLEN <= len(uintArray) {
		return Errorf(SNMP_CODE_FAILED, "oid is too long, maximum size is %d, oid is %s", ASN_MAXOIDLEN, value.String())
	}

	for i, subOid := range uintArray {
		dst.subs[i] = C.asn_subid_t(subOid)
	}
	dst.len = C.u_int(len(uintArray))
	return nil
}
예제 #3
0
func (pdu *V2CPDU) encodePDU(bs []byte, is_dump bool) ([]byte, SnmpError) {
	internal := newNativePdu()
	C.snmp_pdu_init(internal)
	defer func() {
		C.snmp_pdu_free(internal)
		releaseNativePdu(internal)
	}()

	internal.error_status = C.int32_t(pdu.error_status)
	if SNMP_PDU_GETBULK == pdu.op {
		if pdu.variableBindings.Len() < pdu.non_repeaters {
			internal.error_status = C.int32_t(pdu.variableBindings.Len())
		} else {
			internal.error_status = C.int32_t(pdu.non_repeaters)
		}

		if pdu.max_repetitions > 0 {
			internal.error_index = C.int32_t(pdu.max_repetitions)
		} else {
			internal.error_index = C.int32_t(1)
		}
	}

	err := strcpy(&internal.community[0], MAX_COMMUNITY_LEN, pdu.community)
	if nil != err {
		return nil, newError(SNMP_CODE_FAILED, err, "copy community")
	}

	internal.engine.max_msg_size = C.int32_t(pdu.maxMsgSize)
	internal.request_id = C.int32_t(pdu.requestId)
	internal.pdu_type = C.u_int(pdu.op)
	internal.version = uint32(pdu.version)

	err = encodeBindings(internal, pdu.GetVariableBindings())

	if nil != err {
		return nil, newError(SNMP_CODE_FAILED, err, "encode bindings")
	}

	if is_test {
		debug_init_secparams(internal)
	} else {
		C.snmp_pdu_init_secparams(internal)
	}

	if is_dump {
		C.snmp_pdu_dump(internal)
	}

	return encodeNativePdu(bs, internal)
}
예제 #4
0
파일: pcap.go 프로젝트: ldnvnbl/gopacket
func bpfInstructionFilter(bpfInstructions []BPFInstruction) (bpf _Ctype_struct_bpf_program, err error) {
	if len(bpfInstructions) < 1 {
		return bpf, errors.New("bpfInstructions must not be empty")
	}

	if len(bpfInstructions) > MaxBpfInstructions {
		return bpf, fmt.Errorf("bpfInstructions must not be larger than %d", MaxBpfInstructions)
	}

	bpf.bf_len = C.u_int(len(bpfInstructions))
	cbpfInsns := C.calloc(C.size_t(len(bpfInstructions)), C.size_t(unsafe.Sizeof(bpfInstructions[0])))

	copy((*[bpfInstructionBufferSize]BPFInstruction)(cbpfInsns)[0:len(bpfInstructions)], bpfInstructions)
	bpf.bf_insns = (*_Ctype_struct_bpf_insn)(cbpfInsns)

	return
}
예제 #5
0
파일: pfring.go 프로젝트: jcantrill/geard
// ReadPacketDataTo reads packet data into a user-supplied buffer.
// This function ignores snaplen and instead reads up to the length of the
// passed-in slice.
// The number of bytes read into data will be returned in ci.CaptureLength.
func (r *Ring) ReadPacketDataTo(data []byte) (ci gopacket.CaptureInfo, err error) {
	// This tricky buf_ptr points to the start of our slice data, so pfring_recv
	// will actually write directly into our Go slice.  Nice!
	r.mu.Lock()
	r.buf_ptr = (*C.u_char)(unsafe.Pointer(&data[0]))
	result := NextResult(C.pfring_recv(r.cptr, &r.buf_ptr, C.u_int(len(data)), &r.pkthdr, 1))
	if result != NextOk {
		err = result
		r.mu.Unlock()
		return
	}
	ci.Timestamp = time.Unix(int64(r.pkthdr.ts.tv_sec),
		int64(r.pkthdr.ts.tv_usec)*1000) // convert micros to nanos
	ci.CaptureLength = int(r.pkthdr.caplen)
	ci.Length = int(r.pkthdr.len)
	r.mu.Unlock()
	return
}
예제 #6
0
파일: bdb.go 프로젝트: zqc115322536/gobdb
func (db *DB) set(key, value []byte, flags int) error {
	db.lk.Lock()
	defer db.lk.Unlock()

	k := C.str{unsafe.Pointer(&key[0]), C.size_t(len(key))}
	v := C.str{unsafe.Pointer(&value[0]), C.size_t(len(value))}

	n, err := C.db_put(db.db, &k, &v, C.u_int(flags))

	switch {
	case n < 0:
		return err
	case n > 0:
		return ErrKeyAlreadyExists(string(key))
	}

	return nil
}
예제 #7
0
func encodeBindings(internal *C.snmp_pdu_t, vbs *VariableBindings) SnmpError {
	if SNMP_MAX_BINDINGS < vbs.Len() {
		return Errorf(SNMP_CODE_FAILED, "bindings too long, SNMP_MAX_BINDINGS is %d, variableBindings is %d",
			SNMP_MAX_BINDINGS, vbs.Len())
	}

	for i, vb := range vbs.All() {
		err := oidWrite(&internal.bindings[i].oid, &vb.Oid)
		if nil != err {
			internal.nbindings = C.u_int(i) + 1 // free
			return err
		}

		if nil == vb.Value {
			internal.bindings[i].syntax = uint32(SNMP_SYNTAX_NULL)
			continue
		}

		internal.bindings[i].syntax = uint32(vb.Value.GetSyntax())
		switch vb.Value.GetSyntax() {
		case SNMP_SYNTAX_NULL:
		case SNMP_SYNTAX_INTEGER:
			C.snmp_value_put_int32(&internal.bindings[i].v, C.int32_t(vb.Value.GetInt32()))
		case SNMP_SYNTAX_OCTETSTRING:
			send_bytes := vb.Value.GetBytes()
			if nil != send_bytes && 0 != len(send_bytes) {
				C.snmp_value_put_octets(&internal.bindings[i].v, unsafe.Pointer(&send_bytes[0]), C.u_int(len(send_bytes)))
			} else {
				C.snmp_value_put_octets(&internal.bindings[i].v, nil, C.u_int(0))
			}
		case SNMP_SYNTAX_OID:
			err = oidWrite(C.snmp_value_get_oid(&internal.bindings[i].v), vb.Value)
			if nil != err {
				internal.nbindings = C.u_int(i) + 1 // free
				return err
			}
		case SNMP_SYNTAX_IPADDRESS:
			send_bytes := vb.Value.GetBytes()
			if 4 != len(send_bytes) {
				internal.nbindings = C.u_int(i) + 1 // free
				return Errorf(SNMP_CODE_FAILED, "ip address is error, it's length is %d, excepted length is 4, value is %s",
					len(send_bytes), vb.Value.String())
			}
			C.snmp_value_put_ipaddress(&internal.bindings[i].v, C.u_char(send_bytes[0]),
				C.u_char(send_bytes[1]), C.u_char(send_bytes[2]), C.u_char(send_bytes[3]))
		case SNMP_SYNTAX_COUNTER:
			C.snmp_value_put_uint32(&internal.bindings[i].v, C.uint32_t(vb.Value.GetUint32()))
		case SNMP_SYNTAX_GAUGE:
			C.snmp_value_put_uint32(&internal.bindings[i].v, C.uint32_t(vb.Value.GetUint32()))
		case SNMP_SYNTAX_TIMETICKS:
			C.snmp_value_put_uint32(&internal.bindings[i].v, C.uint32_t(vb.Value.GetUint32()))
		case SNMP_SYNTAX_COUNTER64:
			uint64_to_counter64(vb.Value.GetUint64(), &internal.bindings[i].v)
			//cs := C.CString(s)
			//defer C.free(unsafe.Pointer(cs))
			//C.snmp_value_put_uint64_str(&internal.bindings[i].v, cs)
			//C.snmp_value_put_uint64(&internal.bindings[i].v, C.uint64_t(vb.Value.GetUint64()))
		default:
			internal.nbindings = C.u_int(i) + 1 // free
			return Errorf(SNMP_CODE_FAILED, "unsupported type - %v", vb.Value)
		}
	}
	internal.nbindings = C.u_int(vbs.Len())
	return nil
}
예제 #8
0
func (pdu *V3PDU) encodePDU(bs []byte, is_dump bool) ([]byte, SnmpError) {
	internal := newNativePdu()
	C.snmp_pdu_init(internal)
	defer func() {
		C.snmp_pdu_free(internal)
		releaseNativePdu(internal)
	}()
	internal.request_id = C.int32_t(pdu.requestId)
	internal.pdu_type = C.u_int(pdu.op)
	internal.version = uint32(SNMP_V3)
	internal.error_status = C.int32_t(pdu.error_status)

	if SNMP_PDU_GETBULK == pdu.op {
		if pdu.variableBindings.Len() < pdu.non_repeaters {
			internal.error_status = C.int32_t(pdu.variableBindings.Len())
		} else {
			internal.error_status = C.int32_t(pdu.non_repeaters)
		}

		if pdu.max_repetitions > 0 {
			internal.error_index = C.int32_t(pdu.max_repetitions)
		} else {
			internal.error_index = C.int32_t(1)
		}
	}

	if pdu.identifier < 0 {
		internal.identifier = C.int32_t(pdu.requestId)
	} else {
		internal.identifier = C.int32_t(pdu.identifier)
	}
	internal.flags = 0

	if nil == pdu.contextEngine {
		internal.context_engine_len = C.uint32_t(0)
	} else {
		err := memcpy(&internal.context_engine[0], SNMP_ENGINE_ID_LEN, pdu.contextEngine)
		if nil != err {
			return nil, context_engine_failed //newError(SNMP_CODE_FAILED, err, "copy context_engine failed")
		}
		internal.context_engine_len = C.uint32_t(len(pdu.contextEngine))
	}

	err := strcpy(&internal.context_name[0], SNMP_CONTEXT_NAME_LEN, pdu.contextName)
	if nil != err {
		return nil, context_name_failed //newError(SNMP_CODE_FAILED, err, "copy context_name failed")
	}

	if nil != pdu.engine {
		err = memcpy(&internal.engine.engine_id[0], SNMP_ENGINE_ID_LEN, pdu.engine.engine_id)
		if nil != err {
			return nil, engine_id_failed //newError(SNMP_CODE_FAILED, err, "copy engine_id failed")
		}
		internal.engine.engine_len = C.uint32_t(len(pdu.engine.engine_id))
		internal.engine.engine_boots = C.int32_t(pdu.engine.engine_boots)
		internal.engine.engine_time = C.int32_t(pdu.engine.engine_time)
	}

	if 0 == pdu.maxMsgSize {
		pdu.maxMsgSize = *maxPDUSize
	}
	internal.engine.max_msg_size = C.int32_t(pdu.maxMsgSize)

	internal.security_model = SNMP_SECMODEL_USM
	if nil == pdu.securityModel {
		return nil, security_model_is_nil //newError(SNMP_CODE_FAILED, nil, "security model is nil")
	}
	err = pdu.securityModel.Write(&internal.user)
	if nil != err {
		return nil, newError(SNMP_CODE_FAILED, err, "fill security model failed")
	}

	err = encodeBindings(internal, pdu.GetVariableBindings())
	if nil != err {
		return nil, newError(SNMP_CODE_FAILED, err, "fill encode bindings failed")
	}

	if is_test {
		debug_init_secparams(internal)
	} else {
		C.snmp_pdu_init_secparams(internal)
	}

	if is_dump {
		C.snmp_pdu_dump(internal)
	}
	return encodeNativePdu(bs, internal)
}
예제 #9
0
파일: pfring.go 프로젝트: jcantrill/geard
// SetCluster sets which cluster the ring should be part of, and the cluster
// type to use.
func (r *Ring) SetCluster(cluster int, typ ClusterType) error {
	if rv := C.pfring_set_cluster(r.cptr, C.u_int(cluster), C.cluster_type(typ)); rv != 0 {
		return fmt.Errorf("Unable to set cluster, got error code %d", rv)
	}
	return nil
}
예제 #10
0
// Performs the actual xdr decode via some C helper functions and libganglia.
func xdrDecode(lock sync.Locker, buf []byte) (msg Message, nbytes int, err error) {
	var xdr *C.XDR
	var cbuf *C.char

	lock.Lock()
	defer lock.Unlock()

	xdr = (*C.XDR)(C.malloc(C.XDR_size))
	defer C.free(unsafe.Pointer(xdr))
	buflen := len(buf)
	if buflen > GANGLIA_MAX_MESSAGE_LEN {
		buflen = GANGLIA_MAX_MESSAGE_LEN
	} else if buflen == 0 {
		panic("empty buffer")
	}

	cbuf = (*C.char)(C.calloc(1, C.size_t(GANGLIA_MAX_MESSAGE_LEN)))
	if cbuf == nil {
		panic("out of memory calling C.calloc")
	}
	defer C.free(unsafe.Pointer(cbuf))
	if buflen > 0 {
		C.memcpy(unsafe.Pointer(cbuf), unsafe.Pointer(&buf[0]), C.size_t(buflen))
	}

	C.xdrmem_create(xdr, cbuf, C.u_int(GANGLIA_MAX_MESSAGE_LEN), C.XDR_DECODE)
	defer C.helper_destroy_xdr(xdr)

	if cbuf != nil {
		// perform the actual decode
		var fmsg *C.Ganglia_metadata_msg
		var vmsg *C.Ganglia_value_msg
		var mf *C.Ganglia_msg_formats

		fmsg = (*C.Ganglia_metadata_msg)(C.malloc(C.Ganglia_metadata_msg_size))
		if fmsg == nil {
			panic("out of memory allocating for decoding ganglia xdr msg")
		}
		vmsg = (*C.Ganglia_value_msg)(C.malloc(C.Ganglia_metadata_val_size))
		if vmsg == nil {
			panic("out of memory allocating for decoding ganglia xdr value")
		}
		defer C.free(unsafe.Pointer(fmsg))
		defer C.free(unsafe.Pointer(vmsg))

		mf = (*C.Ganglia_msg_formats)(C.calloc(1, C.size_t(unsafe.Sizeof(*mf))))
		if mf == nil {
			panic("out of memory allocating for ganglia msg formats")
		}
		defer C.free(unsafe.Pointer(mf))
		if !xdrBool(C.helper_init_xdr(xdr, mf)) {
			err = XDRDecodeFailure
			return
		}
		defer C.helper_uninit_xdr(xdr, mf)
		nbytes = int(C.helper_perform_xdr(xdr, fmsg, vmsg, mf))
		if nbytes > 0 {
			var info *MetricInfo
			var metric_id *C.Ganglia_metric_id

			id := MsgFormat(*mf)
			// log.Printf("XDR bytes=%v id=%v", nbytes,id)
			switch id {
			case GMETADATA_REQUEST:
				greq := C.Ganglia_metadata_msg_u_grequest(fmsg)
				msg = &MetadataReq{
					gangliaMsg: gangliaMsg{formatIdentifier: id},
					MetricIdentifier: &MetricIdentifier{
						Host:   C.GoString(greq.metric_id.host),
						Name:   C.GoString(greq.metric_id.name),
						Spoof:  xdrBool(greq.metric_id.spoof),
						Exists: true,
					},
				}
				C.helper_free_xdr(xdr, mf, unsafe.Pointer(fmsg))
			case GMETADATA_FULL:
				gfull := C.Ganglia_metadata_msg_u_gfull(fmsg)
				var extra_metadata_keys []KeyValueMetadata
				if int(gfull.metric.metadata.metadata_len) > 0 {
					exLen := int(gfull.metric.metadata.metadata_len)
					extra_metadata := &extraMetadata{
						values:  make([]string, exLen),
						mapping: make(map[string][]byte),
					}
					hdr := &reflect.SliceHeader{Data: uintptr(unsafe.Pointer(gfull.metric.metadata.metadata_val)),
						Len: exLen,
						Cap: exLen}
					extra := *(*[]C.Ganglia_extra_data)(unsafe.Pointer(hdr))
					for i, val := range extra {
						key := C.GoString(val.name)
						extra_metadata.values[i] = C.GoString(val.data)
						extra_metadata.mapping[key] = []byte(extra_metadata.values[i])
						extra_metadata_keys = append(extra_metadata_keys, &extraMetadataKey{
							key:  key,
							data: extra_metadata})
					}
				}
				mid := &MetricIdentifier{
					Host:   C.GoString(gfull.metric_id.host),
					Name:   C.GoString(gfull.metric_id.name),
					Spoof:  xdrBool(gfull.metric_id.spoof),
					Exists: true,
				}
				msg = &MetadataDef{
					gangliaMsg:       gangliaMsg{formatIdentifier: id},
					MetricIdentifier: mid,
					metric: Metadata{
						Type:      C.GoString(gfull.metric._type),
						Name:      C.GoString(gfull.metric.name),
						Units:     C.GoString(gfull.metric.units),
						Tmax:      uint(gfull.metric.tmax),
						Dmax:      uint(gfull.metric.dmax),
						Slope:     Slope(gfull.metric.slope),
						metric_id: mid,
						extra:     extra_metadata_keys,
					},
				}
				//log.Printf("DEBUG: metadata name=%v/%v type=%v",mid.Name,msg.MetricId().Name,
				//            msg.GetMetadata().Type)
				C.helper_free_xdr(xdr, mf, unsafe.Pointer(fmsg))
			case GMETRIC_STRING:
				gstr := C.Ganglia_value_msg_u_gstr(vmsg)
				metric_id = &gstr.metric_id
				info = &MetricInfo{
					Value:  C.GoString(gstr.str),
					Format: C.GoString(gstr.fmt),
				}
			case GMETRIC_USHORT:
				gus := C.Ganglia_value_msg_u_gu_short(vmsg)
				metric_id = &gus.metric_id
				f := C.GoString(gus.fmt)
				info = &MetricInfo{
					Value:  uint16(gus.us),
					Format: f,
				}
			case GMETRIC_SHORT:
				gss := C.Ganglia_value_msg_u_gs_short(vmsg)
				metric_id = &gss.metric_id
				f := C.GoString(gss.fmt)
				info = &MetricInfo{
					Value:  int16(gss.ss),
					Format: f,
				}
			case GMETRIC_UINT:
				gint := C.Ganglia_value_msg_u_gu_int(vmsg)
				metric_id = &gint.metric_id
				f := C.GoString(gint.fmt)
				info = &MetricInfo{
					Value:  uint32(gint.ui),
					Format: f,
				}
			case GMETRIC_INT:
				gint := C.Ganglia_value_msg_u_gs_int(vmsg)
				metric_id = &gint.metric_id
				f := C.GoString(gint.fmt)
				info = &MetricInfo{
					Value:  int32(gint.si),
					Format: f,
				}
				fallthrough
			case GMETRIC_FLOAT:
				gflt := C.Ganglia_value_msg_u_gf(vmsg)
				metric_id = &gflt.metric_id
				info = &MetricInfo{
					Value:  float32(gflt.f),
					Format: C.GoString(gflt.fmt),
				}
			case GMETRIC_DOUBLE:
				gdbl := C.Ganglia_value_msg_u_gd(vmsg)
				metric_id = &gdbl.metric_id
				info = &MetricInfo{
					Value:  float64(gdbl.d),
					Format: C.GoString(gdbl.fmt),
				}
			default:
				log.Printf("XDR value decode failure, unsupported metric %v", id)
				C.helper_free_xdr(xdr, mf, unsafe.Pointer(vmsg))
			}
			if err == nil && info != nil {
				if metric_id != nil {
					info.Spoof = xdrBool(metric_id.spoof)
					if metric_id.host != nil {
						info.Host = []byte(C.GoString(metric_id.host))
					}
					if metric_id.name != nil {
						info.Name = []byte(C.GoString(metric_id.name))
					}
				}
				msg, err = NewMetric(id, *info)
				C.helper_free_xdr(xdr, mf, unsafe.Pointer(vmsg))
			}
		}
	}
	// log.Printf("xdr bytes consumed: %v",nbytes)
	if err == nil && msg != nil && !msg.HasMetadata() {
		md, err := MetadataServer.Lookup(msg)
		if err == nil {
			if md == nil {
				panic("bad metadata from metadata server")
			}
			msg.(*gmetric).metadata = md
			//log.Printf("SET MD for msg %v to %v",msg.(*gmetric).Name,msg.GetMetadata().Type)
		}
	}
	return
}