95639e91bb483c661caf7d4b0354e73780c8b776
[rrq/newlisp-ftw.git] / socket-sniff.lsp
1 #!/usr/bin/newlisp
2 #
3 # Open a raw socket to sniff an interface; output to stdout
4
5 (signal 2 (fn (x) (exit 0)))
6
7 (context 'LIBC6)
8 (constant 'library "/lib/x86_64-linux-gnu/libc.so.6")
9 (import library "ioctl" "int" "int" "long" "void*" )
10 (import library "perror" "void" "char*" )
11 (import library "fdopen" "void*" "int" "char*" )
12 (import library "setbuf" "void" "void*" "void*" )
13 (import library "ntohs" "int" "int" )
14 (import library "htons" "int" "int" )
15 (import library "inet_addr" "void*" "void*")
16 (import library "socket" "int" "int" "int" "int")
17 (import library "setsockopt" "int" "int" "int" "int" "void*" "int")
18 (import library "perror" "void" "char*")
19 (setf bind-socket (import library "bind" "int" "int" "void*" "int"))
20
21 (define (die)
22   (perror (join (map string (args)) " "))
23   (exit 1))
24
25 (letex ((AF_INET 2)
26         (SOCK_RAW 10)
27         (IPPROTO_RAW (htons 0x0800))
28         (SOL_SOCKET 1)
29         (SO_BINDTODEVICE 25)
30         (SO_BROADCAST 6)
31         (SIZEOF_struct_sockaddr 16)
32         )
33   (define (raw-socket)
34     (socket AF_INET SOCK_RAW IPPROTO_RAW))
35
36   (define (bind-to-device FD IFACE)
37     (when (!= (setsockopt FD SOL_SOCKET SO_BINDTODEVICE IFACE (length IFACE)))
38       (die "setsockopt bind"))
39     (when (!= (setsockopt FD SOL_SOCKET SO_BROADCAST (pack "lu" 1) 4))
40       (die "setsockopt broadcast"))
41     0)
42
43   ) ; end letex
44
45 (context MAIN)
46
47 (setf IFACE (main-args -1) FD (LIBC6:raw-socket) )
48
49 (when (< FD)
50   (LIBC6:die "socket"))
51
52 (when (!= (LIBC6:bind-to-device FD IFACE))
53   (LIBC6:die "bind-to-device"))
54
55 (LIBC6:setbuf (LIBC6:fdopen 1 "w") 0)
56
57 (while (> (setf N (read FD BUFFER 2048)) 0)
58   (write 1 BUFFER))
59
60 (exit 0)