ERL_NIF_TERM vert_make_resource(ErlNifEnv *env, VERT_RESOURCE *vp, ERL_NIF_TERM type) { ERL_NIF_TERM res = {0}; if (vp->res == NULL) { enif_release_resource(vp); return verterr(env); } res = enif_make_resource(env, vp); enif_release_resource(vp); return enif_make_tuple2(env, atom_ok, enif_make_tuple4(env, atom_resource, type, enif_make_ref(env), res)); }
static ERL_NIF_TERM nif_pcap_open_live(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary device = {0}; int snaplen = 0; int promisc = 0; int to_ms = 0; char errbuf[PCAP_ERRBUF_SIZE] = {0}; EWPCAP_STATE *ep = NULL; ERL_NIF_TERM res = {0}; ERL_NIF_TERM ref = {0}; if (!enif_inspect_iolist_as_binary(env, argv[0], &device)) return enif_make_badarg(env); if (!enif_get_int(env, argv[1], &snaplen)) return enif_make_badarg(env); if (!enif_get_int(env, argv[2], &promisc)) return enif_make_badarg(env); if (!enif_get_int(env, argv[3], &to_ms)) return enif_make_badarg(env); /* NULL terminate the device name */ if (device.size > 0 && !enif_realloc_binary(&device, device.size+1)) return enif_make_tuple2(env, atom_error, atom_enomem); device.data[device.size-1] = '\0'; ep = enif_alloc_resource(EWPCAP_RESOURCE, sizeof(EWPCAP_STATE)); if (ep == NULL) return enif_make_tuple2(env, atom_error, atom_enomem); /* "any" is a Linux only virtual dev */ ep->p = pcap_open_live((device.size == 0 ? "any" : (char *)device.data), snaplen, promisc, to_ms, errbuf); if (ep->p == NULL) return enif_make_tuple2(env, atom_error, enif_make_string(env, errbuf, ERL_NIF_LATIN1)); ep->datalink = pcap_datalink(ep->p); (void)enif_self(env, &ep->pid); ep->term_env = enif_alloc_env(); if (ep->term_env == NULL) { pcap_close(ep->p); return enif_make_tuple2(env, atom_error, atom_enomem); } ep->ref = enif_make_ref(ep->term_env); ref = enif_make_copy(env, ep->ref); res = enif_make_resource(env, ep); enif_release_resource(ep); return enif_make_tuple2(env, atom_ok, enif_make_tuple3(env, atom_ewpcap_resource, ref, res)); }
static ERL_NIF_TERM nif_pcap_open_live(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary device = {0}; int snaplen = 0; int promisc = 0; int to_ms = 0; int buffer_size = 0; int rfmon = 0; char errbuf[PCAP_ERRBUF_SIZE] = {0}; EWPCAP_STATE *ep = NULL; ERL_NIF_TERM res = {0}; ERL_NIF_TERM ref = {0}; if (!enif_inspect_iolist_as_binary(env, argv[0], &device)) return enif_make_badarg(env); if (!enif_get_int(env, argv[1], &snaplen)) return enif_make_badarg(env); if (!enif_get_int(env, argv[2], &promisc)) return enif_make_badarg(env); if (!enif_get_int(env, argv[3], &to_ms)) return enif_make_badarg(env); if (!enif_get_int(env, argv[4], &buffer_size)) return enif_make_badarg(env); if (!enif_get_int(env, argv[5], &rfmon)) return enif_make_badarg(env); /* NULL terminate the device name */ if (device.size > 0) { if (!enif_realloc_binary(&device, device.size+1)) return enif_make_tuple2(env, atom_error, atom_enomem); device.data[device.size-1] = '\0'; } ep = enif_alloc_resource(EWPCAP_RESOURCE, sizeof(EWPCAP_STATE)); if (ep == NULL) return enif_make_tuple2(env, atom_error, atom_enomem); /* "any" is a Linux only virtual dev */ ep->p = pcap_create((device.size == 0 ? "any" : (char *)device.data), errbuf); if (ep->p == NULL) return enif_make_tuple2(env, atom_error, enif_make_string(env, errbuf, ERL_NIF_LATIN1)); /* Set the snaplen */ (void)pcap_set_snaplen(ep->p, snaplen); /* Set promiscuous mode */ (void)pcap_set_promisc(ep->p, promisc); /* Set timeout */ (void)pcap_set_timeout(ep->p, to_ms); /* Set buffer size */ if (buffer_size > 0) (void)pcap_set_buffer_size(ep->p, buffer_size); /* Set monitor mode */ if (pcap_can_set_rfmon(ep->p) == 1) (void)pcap_set_rfmon(ep->p, rfmon); /* Return failure on error and warnings */ if (pcap_activate(ep->p) != 0) { pcap_close(ep->p); return enif_make_tuple2(env, atom_error, enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1)); } ep->datalink = pcap_datalink(ep->p); (void)enif_self(env, &ep->pid); ep->term_env = enif_alloc_env(); if (ep->term_env == NULL) { pcap_close(ep->p); return enif_make_tuple2(env, atom_error, atom_enomem); } ep->ref = enif_make_ref(ep->term_env); ref = enif_make_copy(env, ep->ref); res = enif_make_resource(env, ep); enif_release_resource(ep); return enif_make_tuple2(env, atom_ok, enif_make_tuple3(env, atom_ewpcap_resource, ref, res)); }
static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { int i; int sint; unsigned uint; long slong; unsigned long ulong; ErlNifSInt64 sint64; ErlNifUInt64 uint64; double d; ERL_NIF_TERM atom, ref1, ref2; sint = INT_MIN; do { if (!test_int(env,sint)) { goto error; } sint += ~sint / 3 + 1; } while (sint < 0); sint = INT_MAX; do { if (!test_int(env,sint)) { goto error; } sint -= sint / 3 + 1; } while (sint >= 0); slong = LONG_MIN; do { if (!test_long(env,slong)) { goto error; } slong += ~slong / 3 + 1; } while (slong < 0); slong = LONG_MAX; do { if (!test_long(env,slong)) { goto error; } slong -= slong / 3 + 1; } while (slong >= 0); sint64 = ((ErlNifSInt64)1 << 63); /* INT64_MIN */ do { if (!test_int64(env,sint64)) { goto error; } sint64 += ~sint64 / 3 + 1; } while (sint64 < 0); sint64 = ((ErlNifUInt64)1 << 63) - 1; /* INT64_MAX */ do { if (!test_int64(env,sint64)) { goto error; } sint64 -= sint64 / 3 + 1; } while (sint64 >= 0); uint = UINT_MAX; for (;;) { if (!test_uint(env,uint)) { goto error; } if (uint == 0) break; uint -= uint / 3 + 1; } ulong = ULONG_MAX; for (;;) { if (!test_ulong(env,ulong)) { goto error; } if (ulong == 0) break; ulong -= ulong / 3 + 1; } uint64 = (ErlNifUInt64)-1; /* UINT64_MAX */ for (;;) { if (!test_uint64(env,uint64)) { goto error; } if (uint64 == 0) break; uint64 -= uint64 / 3 + 1; } if (MAX_SMALL < INT_MAX) { /* 32-bit */ for (i=-10 ; i <= 10; i++) { if (!test_int(env,MAX_SMALL+i)) { goto error; } } for (i=-10 ; i <= 10; i++) { if (!test_int(env,MIN_SMALL+i)) { goto error; } } for (i=-10 ; i <= 10; i++) { if (!test_uint(env,MAX_SMALL+i)) { goto error; } } } assert((MAX_SMALL < INT_MAX) == (MIN_SMALL > INT_MIN)); for (i=-10 ; i < 10; i++) { if (!test_long(env,MAX_SMALL+i) || !test_ulong(env,MAX_SMALL+i) || !test_long(env,MIN_SMALL+i) || !test_int64(env,MAX_SMALL+i) || !test_uint64(env,MAX_SMALL+i) || !test_int64(env,MIN_SMALL+i)) { goto error; } if (MAX_SMALL < INT_MAX) { if (!test_int(env,MAX_SMALL+i) || !test_uint(env,MAX_SMALL+i) || !test_int(env,MIN_SMALL+i)) { goto error; } } } for (d=3.141592e-100 ; d < 1e100 ; d *= 9.97) { if (!test_double(env,d) || !test_double(env,-d)) { goto error; } } if (!enif_make_existing_atom(env,"nif_SUITE", &atom, ERL_NIF_LATIN1) || !enif_is_identical(atom,enif_make_atom(env,"nif_SUITE"))) { fprintf(stderr, "nif_SUITE not an atom?\r\n"); goto error; } for (i=2; i; i--) { if (enif_make_existing_atom(env,"nif_SUITE_pink_unicorn", &atom, ERL_NIF_LATIN1)) { fprintf(stderr, "pink unicorn exist?\r\n"); goto error; } } ref1 = enif_make_ref(env); ref2 = enif_make_ref(env); if (!enif_is_ref(env,ref1) || !enif_is_ref(env,ref2) || enif_is_identical(ref1,ref2) || enif_compare(ref1,ref2)==0) { fprintf(stderr, "strange refs?\r\n"); goto error; } return enif_make_atom(env,"ok"); error: return enif_make_atom(env,"error"); }
static ERL_NIF_TERM make_term_ref(struct make_term_info* mti, int n) { return enif_make_ref(mti->dst_env); }