dev: mark paths likely/unlikely
[netsniff-ng.git] / staging / mops_ext_arp.c
blob79c33a40afcd2d243149855cd7b74560fa0ca8df
1 /*
2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * details.
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
21 #include "mz.h"
22 #include "mops.h"
25 // Initialization function - specify defaults here!
26 //
27 int mops_init_pdesc_arp(struct mops *mp)
30 struct mops_ext_arp * pd;
32 char tmac[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
34 if (mp->p_desc == NULL) return 1; // p_desc not properly assigned
36 pd = mp->p_desc;
38 pd->hw_type = 0x0001;
39 pd->pr_type = 0x800;
40 pd->hw_size = 6;
41 pd->pr_size = 4;
42 pd->opcode = 0x0001; // request
43 memcpy ((void*) pd->sender_mac, (void*) tx.eth_src, 6);
44 memcpy ((void*) pd->target_mac, (void*) tmac, 6);
45 memcpy ((void*) pd->sender_ip, (void*) &tx.ip_src, 4);
46 memcpy ((void*) pd->target_ip, (void*) &tx.ip_src, 4);
48 pd->trailer = 18; // default is 18 byte trailer to get a 60 byte packet (instead of only 42)
50 return 0;
60 /////////////////////////////////////////////////////////////////////////////////
61 /////////////////////////////// Update functions ////////////////////////////////
63 // **** Here is a summary of mops tool functions: ****
65 // Adds single byte to msg
66 // int mops_msg_add_byte (struct mops *mp, u_int8_t data);
67 //
68 // Adds bit field in *previous* msg-byte using optional left-shift
69 // int mops_msg_add_field (struct mops *mp, u_int8_t data, int shift);
70 //
71 // Adds two bytes in network byte order to msg
72 // int mops_msg_add_2bytes (struct mops *mp, u_int16_t data);
73 //
74 // Adds four bytes in network byte order to msg
75 // int mops_msg_add_4bytes (struct mops *mp, u_int32_t data);
76 //
77 // Adds string of bytes with lenght len
78 // int mops_msg_add_string (struct mops *mp, u_int8_t *str, int len);
79 //
80 // Add counter to message
81 // int mops_msg_add_counter (struct mops *mp,
82 // int random, // 1=random, 0=use start/stop/step
83 // u_int32_t start, // HOST BYTE ORDER
84 // u_int32_t stop, // HOST BYTE ORDER
85 // u_int32_t step, // HOST BYTE ORDER
86 // int bytes // number of bytes used (1|2|4) - selects hton2 or hton4
87 // );
88 //
89 //
92 int mops_update_arp(struct mops * mp)
95 struct mops_ext_arp * pd;
96 int i;
98 pd = mp->p_desc;
99 if (pd==NULL) return 1; // no valid pointer to a p_desc
101 mp->msg_s = 0; // important! Otherwise the msg would get longer and longer after each call!
103 mops_msg_add_2bytes (mp, pd->hw_type);
104 mops_msg_add_2bytes (mp, pd->pr_type);
105 mops_msg_add_byte (mp, pd->hw_size);
106 mops_msg_add_byte (mp, pd->pr_size);
107 mops_msg_add_2bytes (mp, pd->opcode);
108 mops_msg_add_string (mp, pd->sender_mac, 6);
109 mops_msg_add_string (mp, pd->sender_ip, 4);
110 mops_msg_add_string (mp, pd->target_mac, 6);
111 mops_msg_add_string (mp, pd->target_ip, 4);
113 // Avoid buffer problems:
114 if (pd->trailer>2000)
116 pd->trailer=2000;
119 for (i=0; i<pd->trailer; i++)
121 mops_msg_add_byte (mp, 0x00);
124 return 0;
129 // ARP Service: Resolves MAC address of given IP address and interface
130 // The result is stored in the last argument 'mac'.
132 // EXAMPLE:
134 // u_int8_t mymac[6];
135 // int ip[4]={192,186,0,1};
137 // service_arp("eth0", ip, mymac);
138 // /* now mymac should contain the MAC address */
140 // RETURN VALUE: 0 upon success
141 // 1 upon error
143 int service_arp(char *dev, u_int8_t *ip, u_int8_t *mac)
145 int i, devind=0, dev_found=0;
146 struct mops * mp;
147 struct mops_ext_arp * pd;
148 char tmac[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
149 struct arp_table_struct *cur;
151 // MOPS framework already available?
152 if (mp_head==NULL) return 1;
154 // Get list index for that device:
155 for (i=0; i<device_list_entries; i++) {
156 if (strncmp(device_list[i].dev, dev, 16)==0) {
157 devind=i;
158 dev_found=1;
159 break;
162 if (dev_found==0) {
163 fprintf(stderr, " Warning: Unknown device (sysARP_service)\n");
164 return 1; // ERROR: device name not found !!!!
165 } else {
166 if (verbose) {
167 fprintf(stderr, " sysARP_service triggered through interface %s\n", dev);
171 // Look up mops table if already a sysARP packet is available
172 mp = mops_search_name (mp_head, "sysARP_service");
173 if (mp!=NULL) { // entry exists...stop if active!
174 if (mops_state(mp)==MOPS_STATE_ACTIVE) {
175 if (verbose==2) fprintf(stderr, " Warning: Stop active MOPS (sysARP_service)\n");
176 mops_destroy_thread(mp);
178 } else {
179 // Allocate a new packet
180 if ((mp = mops_alloc_packet(mp_head)) == NULL) {
181 fprintf(stderr, " sysARP_service: ERROR -- cannot allocate MOPS\n");
182 return 1; // Problem, memory full?
183 } else {
184 strncpy (mp->packet_name, "sysARP_service", 15);
185 mp->mz_system=1; // indicates MZ private packet
186 if (mops_ext_add_pdesc (mp, MOPS_ARP)) {
187 return 1; // error
192 // Configure ARP request:
193 mops_clear_layers(mp, MOPS_ALL);
194 mops_init_pdesc_arp(mp);
196 mp->verbose = 0;
197 mp->use_ETHER = 1;
198 mp->count = 1;
199 mp->eth_type = 0x806;
200 mz_strncpy(mp->device, dev, 16);
202 pd = mp->p_desc;
203 memcpy ((void*) pd->sender_mac, (void*) device_list[devind].mac_mops, 6);
204 memcpy ((void*) pd->target_mac, (void*) tmac, 6);
205 memcpy ((void*) pd->sender_ip, (void*) device_list[devind].ip_mops, 4);
206 pd->target_ip[0]=ip[0];
207 pd->target_ip[1]=ip[1];
208 pd->target_ip[2]=ip[2];
209 pd->target_ip[3]=ip[3];
211 mops_update_arp(mp);
212 mops_set_conf(mp);
214 // Send ARP request
216 if (mops_tx_simple (mp)) {
217 fprintf(stderr, " Warning: sysARP_service failed!\n");
218 return 1;
221 usleep(100000); // wait 100 ms
222 // Now hopefully we got an ARP response;
223 // look up in ARP cache
225 cur=device_list[devind].arp_table;
226 while(cur!=NULL) {
227 if ((cur->sip[0]==ip[0]) &&
228 (cur->sip[1]==ip[1]) &&
229 (cur->sip[2]==ip[2]) &&
230 (cur->sip[3]==ip[3])) { // entry found!
231 for (i=0; i<6; i++) {
232 mac[i] = cur->smac[i];
235 cur=cur->next;
238 return 0;