Skip to content

Commit 1c11489

Browse files
committed
Implement getfd() and inject() for pcap captures.
1 parent e7c99de commit 1c11489

1 file changed

Lines changed: 67 additions & 14 deletions

File tree

pcap.c

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,12 @@ static int lpcap_open_dead(lua_State *L)
251251
/*-
252252
-- cap = pcap.open_offline([fname])
253253
254-
- fname defaults to "-", stdin.
254+
fname defaults to "-", stdin.
255255
256256
Open a savefile to read packets from.
257257
258-
FIXME - in retrospect, fname defaulting to stdin causes unsuspecting users to
259-
think this API is hanging, when they don't actually have a pcap on stdin...
258+
Warning, fname defaulting to stdin causes unsuspecting users to
259+
think this API is hanging, when they don't actually have a pcap on stdin.
260260
*/
261261
static int lpcap_open_offline(lua_State *L)
262262
{
@@ -268,6 +268,25 @@ static int lpcap_open_offline(lua_State *L)
268268
}
269269

270270

271+
/*-
272+
-- cap:close()
273+
274+
Manually close a cap object, freeing it's resources (this will happen on
275+
garbage collection if not done explicitly).
276+
*/
277+
static int lpcap_close (lua_State *L)
278+
{
279+
pcap_t** cap = luaL_checkudata(L, 1, L_PCAP_REGID);
280+
281+
if(*cap)
282+
pcap_close(*cap);
283+
284+
*cap = NULL;
285+
286+
return 0;
287+
}
288+
289+
271290
/*-
272291
-- dumper = cap:dump_open([fname])
273292
@@ -344,10 +363,29 @@ static int lpcap_datalink(lua_State* L)
344363
{
345364
pcap_t* cap = checkpcap(L);
346365
lua_pushnumber(L, pcap_datalink(cap));
347-
348366
return 1;
349367
}
350368

369+
/*-
370+
-- fd = cap:getfd()
371+
372+
Get a selectable file descriptor number which can be used to wait for packets.
373+
374+
Returns the descriptor number on success, or nil if no such descriptor is
375+
available (see pcap_get_selectable_fd).
376+
*/
377+
static int lpcap_getfd(lua_State* L)
378+
{
379+
pcap_t* cap = checkpcap(L);
380+
int fd = pcap_get_selectable_fd(cap);
381+
if(fd < 0) {
382+
lua_pushnil(L);
383+
lua_pushstring(L, "not selectable");
384+
return 2;
385+
}
386+
lua_pushnumber(L, fd);
387+
return 1;
388+
}
351389

352390
/*-
353391
-- capdata, timestamp, wirelen = cap:next()
@@ -364,7 +402,7 @@ Returns capdata, timestamp, wirelen on sucess:
364402
- timestamp is in seconds, theoretically to microsecond accuracy
365403
- wirelen is the packets original length, the capdata may be shorter
366404
367-
Returns nil,emsg on falure, where emsg is:
405+
Returns nil,emsg on failure, where emsg is:
368406
369407
- "timeout", timeout on a live capture
370408
- "closed", no more packets to be read from a file
@@ -406,24 +444,32 @@ static int lpcap_next(lua_State* L)
406444
return luaL_error(L, "unreachable");
407445
}
408446

447+
409448
/*-
410-
-- cap:close()
449+
-- sent = cap:inject(packet)
411450
412-
Manually close a cap object, freeing it's resources (this will happen on
413-
garbage collection if not done explicitly).
451+
Injects packet.
452+
453+
Return is bytes sent on success, or nil,emsg on failure.
414454
*/
415-
static int lpcap_close (lua_State *L)
455+
static int lpcap_inject(lua_State* L)
416456
{
417-
pcap_t** cap = luaL_checkudata(L, 1, L_PCAP_REGID);
457+
pcap_t* cap = checkpcap(L);
458+
size_t datasz = 0;
459+
const char* data = luaL_checklstring(L, 2, &datasz);
418460

419-
if(*cap)
420-
pcap_close(*cap);
461+
int sent = pcap_inject(cap, data, datasz);
421462

422-
*cap = NULL;
463+
if (sent < 0) {
464+
return pusherr(L, cap);
465+
}
423466

424-
return 0;
467+
lua_pushinteger(L, sent);
468+
469+
return 1;
425470
}
426471

472+
427473
/* Wrap pcap_dumper_t */
428474

429475
static pcap_dumper_t* checkdumper(lua_State* L)
@@ -557,7 +603,14 @@ static const luaL_reg pcap_methods[] =
557603
{"dump_open", lpcap_dump_open},
558604
{"set_filter", lpcap_set_filter},
559605
{"datalink", lpcap_datalink},
606+
{"getfd", lpcap_getfd},
560607
{"next", lpcap_next},
608+
/* TODO - wt_pcap.c also had a next_nonblocking(), I'm not sure why a setnonblocking() wasn't sufficient */
609+
{"inject", lpcap_inject},
610+
611+
/* FIXME remove these once we don't need backwards compatibility */
612+
{"destroy", lpcap_close},
613+
{"get_selectable_fd", lpcap_getfd},
561614
{NULL, NULL}
562615
};
563616

0 commit comments

Comments
 (0)