/*- - ptag = n:ipv4{len=int, protocol=int, src=ipaddr, dst=ipaddr, payload=str, ptag=int, options=ip_options} ptag is optional, defaults to creating a new protocol block options is optional */ static int lnet_ipv4 (lua_State *L) { libnet_t** ud = luaL_checkudata(L, 1, L_NET_REGID); luaL_argcheck(L, *ud, 1, "net has been destroyed"); int len = v_arg_integer(L, 2, "len"); // FIXME - should be optional! int tos = 0; int id = 0; int offset = 0; int ttl = 64; int protocol = v_arg_integer(L, 2, "protocol"); int cksum = 0; // 0 is a flag requesting libnet to fill in correct cksum const char* src = v_arg_string(L, 2, "src"); const char* dst = v_arg_string(L, 2, "dst"); size_t payloadsz = 0; const char* payload = v_arg_lstring(L, 2, "payload", &payloadsz, ""); int ptag = lnet_arg_ptag(L, 2); int options_ptag = 0; size_t optionsz = 0; const char* options = v_arg_lstring(L, 2, "options", &optionsz, ""); if(payloadsz == 0) { payload = NULL; } #ifdef NET_DUMP printf("net ipv4 src %s dst %s len %d payloadsz %lu ptag %d optionsz %lu\n", src, dst, len, payloadsz, ptag, optionsz); #endif uint32_t src_n = check_ip_pton(L, src, "src"); uint32_t dst_n = check_ip_pton(L, dst, "dst"); if(ptag) { /* Modifying exist IPv4 packet, so find the preceeding options block (we * _always_ push an options block, perhaps empty, to make this easy). */ libnet_pblock_t* p = libnet_pblock_find(*ud, ptag); if(!p) return check_error(L, *ud, -1); options_ptag = p->prev->ptag; } #ifdef NET_DUMP printf(" options_ptag %d optionsz %lu\n", options_ptag, optionsz); #endif options_ptag = libnet_build_ipv4_options((uint8_t*) options, optionsz, *ud, options_ptag); check_error(L, *ud, options_ptag); ptag = libnet_build_ipv4(len, tos, id, offset, ttl, protocol, cksum, src_n, dst_n, (uint8_t*) payload, payloadsz, *ud, ptag); check_error(L, *ud, ptag); lua_pushinteger(L, ptag); return 1; }
/*- - ptag = n:eth{src=ethmac, dst=ethmac, type=int, payload=str, ptag=int} type is optional, defaults to IP ptag is optional, defaults to creating a new protocol block */ static int lnet_eth (lua_State *L) { libnet_t** ud = luaL_checkudata(L, 1, L_NET_REGID); luaL_argcheck(L, *ud, 1, "net has been destroyed"); const char* src = v_arg_string(L, 2, "src"); const char* dst = v_arg_string(L, 2, "dst"); int type = v_arg_integer_opt(L, 2, "type", ETHERTYPE_IP); size_t payloadsz = 0; const char* payload = v_arg_lstring(L, 2, "payload", &payloadsz, ""); int ptag = lnet_arg_ptag(L, 2); if(payloadsz == 0) { payload = NULL; } #ifdef NET_DUMP printf("net eth src %s dst %s type %d payloadsz %lu ptag %d\n", src, dst, type, payloadsz, ptag); #endif eth_addr_t src_n = check_eth_pton(L, src, "src"); eth_addr_t dst_n = check_eth_pton(L, dst, "dst"); ptag = libnet_build_ethernet(dst_n.data, src_n.data, type, (uint8_t*)payload, payloadsz, *ud, ptag); check_error(L, *ud, ptag); lua_pushinteger(L, ptag); return 1; }
static const uint8_t* checklbuffer(lua_State* L, int argt, const char* field, uint32_t* size) { size_t payloadsz = 0; const char* payload = v_arg_lstring(L, argt, field, &payloadsz, ""); if(payloadsz == 0) { payload = NULL; } *size = payloadsz; return (const uint8_t*) payload; }
/*- - ptag = net:udp{src=NUM, dst=NUM, len=NUM, payload=STR, ptag=int} Build UDP packet inside net context. ptag is optional, defaults to creating a new protocol block */ static int lnet_udp (lua_State *L) { libnet_t** ud = luaL_checkudata(L, 1, L_NET_REGID); luaL_argcheck(L, *ud, 1, "net has been destroyed"); int src = v_arg_integer(L, 2, "src"); int dst = v_arg_integer(L, 2, "dst"); size_t payloadsz = 0; const char* payload = v_arg_lstring(L, 2, "payload", &payloadsz, ""); int len = v_arg_integer_opt(L, 2, "len", LIBNET_UDP_H + payloadsz); int cksum = 0; int ptag = lnet_arg_ptag(L, 2); if(payloadsz == 0) { payload = NULL; } ptag = libnet_build_udp(src, dst, len, cksum, (uint8_t*)payload, payloadsz, *ud, ptag); check_error(L, *ud, ptag); lua_pushinteger(L, ptag); return 1; }
static const char* v_arg_string(lua_State* L, int argt, const char* field) { return v_arg_lstring(L, argt, field, NULL, NULL); }