// 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 }
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 }
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) }
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 }
// 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 }
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 }
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 }
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) }
// 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 }
// 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 }