/* * Mausezahn - A fast versatile traffic generator * Copyright (C) 2008-2010 Herbert Haas * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by the * Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html * */ #include "mz.h" #include "mops.h" #include #include // PURPOSE: Find usable network devices // // NOTE: // // 1. Ignores devices without IP address // 2. Ignores loopback (etc) // // RETURN VALUES: // // 0 if usable device found (device_list[] and tx.device set) // 1 if no usable device found // int lookupdev(void) { // char *tx.device is global, see as.h char ipaddress[IPADDRSIZE+1], errbuf[PCAP_ERRBUF_SIZE]; pcap_if_t *alldevs, *index = NULL; pcap_addr_t *pcap_addr; int i=0; // FIRST get a list of all available devices // if (pcap_findalldevs(&alldevs, errbuf) == -1) { fprintf(stderr," mz: %s\n",errbuf); return 1; } index = (pcap_if_t *) alldevs; while (index) { if (index->addresses) { pcap_addr = index->addresses; while(pcap_addr) { if (pcap_addr->addr && (pcap_addr->addr->sa_family==AF_INET)) { if (inet_ntop(pcap_addr->addr->sa_family, (void *)&pcap_addr->addr->sa_data[2], ipaddress, IPADDRSIZE)) { if (verbose) { fprintf(stderr," mz: device %s got assigned %s ", index->name, ipaddress); } if (strncmp(ipaddress, "127", 3)==0) { if (verbose) fprintf(stderr, "(loopback)\n"); strncpy(device_list[i].dev, index->name, 9); strncpy(device_list[i].ip_str, ipaddress, IPADDRSIZE); device_list[i].phy=0; get_if_addr(index->name, device_list[i].ip, device_list[i].mac); get_if_addr(index->name, device_list[i].ip_mops, device_list[i].mac_mops); i++; } else if (strncmp(ipaddress, "169.254", 7)==0) { if (verbose) fprintf(stderr, "but IGNORED (cause: host-scope address)\n"); } else // FOUND VALID INTERFACE { if (verbose) fprintf(stderr, "and is a possible candidate.\n"); strncpy(device_list[i].dev, index->name, 9); strncpy(device_list[i].ip_str, ipaddress, IPADDRSIZE); device_list[i].phy=1; get_if_addr(index->name, device_list[i].ip, device_list[i].mac); get_if_addr(index->name, device_list[i].ip_mops, device_list[i].mac_mops); i++; } // Select only interfaces with IP addresses // but avoid those that start with 127 or 169.254 // Put the remaining on a list. If this list has more than one entry // ask the user which interface to listen to. } else { return 1; } } pcap_addr = pcap_addr->next; } // closes while(pcap_addr) } index = index->next; } // closes while (index) device_list_entries = i; /* if (verbose) { for (i=0; i=0) { close(device_list[devind].ps); device_list[devind].ps=-1; } if (device_list[devind].ps<0) { ps = socket (PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); //ETH_P_ALL, ETH_P_802_3); if (ps<0) { fprintf(stderr, " Warning: [lookupdev.c get_dev_params()] Cannot open socket!\n"); return 1; } // Get device index strncpy(si.ifr_name, name, IFNAMSIZ); if (ioctl(ps, SIOCGIFINDEX, &si)==-1) { perror("ioctl"); close(ps); return 1; } index=si.ifr_ifindex; // Get MTU if (ioctl(ps, SIOCGIFMTU, &si)==-1) { perror("ioctl"); close(ps); return 1; } mtu = si.ifr_mtu; // ***** bind socket for later TX and RX **** psock.sll_family = AF_PACKET; // evident // psock.sll_protocol = 0; // unsigned short - Physical layer protocol psock.sll_ifindex = index; // int - Interface number psock.sll_hatype = 0; // unsigned short - Header type //ARPHRD_ETHER psock.sll_pkttype = 0; // unsigned char - Packet type psock.sll_halen = 6; // unsigned char - Length of address bind(ps, (const struct sockaddr *) &psock, sizeof(psock)); // <= !!! device_list[devind].ps = ps; // Note that close(ps) must be done upon termination } // Get MAC of default gateway service_arp(name, device_list[devind].ip_gw, device_list[devind].mac_gw); usleep(200); // this is a VERY short delay but it usually works in today's LANs cur=device_list[devind].arp_table; while(cur!=NULL) { if ((cur->sip[0]==dgw[0]) && (cur->sip[1]==dgw[1]) && (cur->sip[2]==dgw[2]) && (cur->sip[3]==dgw[3])) { // entry found! for (i=0; i<6; i++) { device_list[devind].mac_gw[i] = cur->smac[i]; } } cur=cur->next; } // FINALLY: Copy findings in device_list if (device_list[devind].phy) { for (i=0; i<4; i++) { device_list[devind].net[i] = net[i]; device_list[devind].mask[i] = mask[i]; device_list[devind].ip_gw[i] = dgw[i]; } } else { for (i=0; i<4; i++) { device_list[devind].net[i] = 0; device_list[devind].mask[i] = 0; device_list[devind].ip_gw[i] = 0; } } device_list[devind].index = index; device_list[devind].mtu = mtu; return 0; }