void inject_initialize() { struct sockaddr_ll sll; int ifindex = 0; fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (fd == -1) fatal(__func__, "inject module: raw socket not opened (%s)", strerror(errno)); /* Get iface index */ ifindex = get_iface_index(fd, gbls->iface); if (ifindex == -1) { close(fd); fd = -1; fatal(__func__, "inject module: invalid device index (%s)", strerror(errno)); } memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_ifindex = ifindex; sll.sll_protocol = htons(ETH_P_ALL); if (bind(fd, (struct sockaddr *)&sll, sizeof(sll)) == -1) { close(fd); fd = -1; fatal(__func__, "inject module: bind failed (%s)", strerror(errno)); } debug("inject module initialized"); }
int new_linrsk(const char *iface) { int sockfd = -1; struct timeval tm; if (promisc_mode_on(iface)) { sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); memset(&tm, 0, sizeof(tm)); tm.tv_sec = 1; setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tm, sizeof(tm)); struct sockaddr_ll sll; memset(&sll, 0, sizeof(sll)); sll.sll_family = AF_PACKET; sll.sll_protocol = htons(ETH_P_ALL); sll.sll_ifindex = get_iface_index(iface); if (bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) != 0) { del_linrsk(sockfd, iface); return -1; } } return sockfd; }
/** * Inner sendpacket_open() method for using Linux's PF_PACKET or TX_RING */ static sendpacket_t * sendpacket_open_pf(const char *device, char *errbuf) { int mysocket; sendpacket_t *sp; struct ifreq ifr; struct sockaddr_ll sa; int n = 1, err; socklen_t errlen = sizeof(err); unsigned int UNUSED(mtu) = 1500; assert(device); assert(errbuf); #if defined TX_RING dbg(1, "sendpacket: using TX_RING"); #else dbg(1, "sendpacket: using PF_PACKET"); #endif /* open our socket */ if ((mysocket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) < 0) { snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "socket: %s", strerror(errno)); return NULL; } /* get the interface id for the device */ if ((sa.sll_ifindex = get_iface_index(mysocket, device, errbuf)) < 0) { close(mysocket); return NULL; } /* bind socket to our interface id */ sa.sll_family = AF_PACKET; sa.sll_protocol = htons(ETH_P_ALL); if (bind(mysocket, (struct sockaddr *)&sa, sizeof(sa)) < 0) { snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "bind error: %s", strerror(errno)); close(mysocket); return NULL; } /* check for errors, network down, etc... */ if (getsockopt(mysocket, SOL_SOCKET, SO_ERROR, &err, &errlen) < 0) { snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "error opening %s: %s", device, strerror(errno)); close(mysocket); return NULL; } if (err > 0) { snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "error opening %s: %s", device, strerror(err)); close(mysocket); return NULL; } /* get hardware type for our interface */ memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); if (ioctl(mysocket, SIOCGIFHWADDR, &ifr) < 0) { close(mysocket); snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Error getting hardware type: %s", strerror(errno)); return NULL; } /* make sure it's not loopback (PF_PACKET doesn't support it) */ if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) warnx("Unsupported physical layer type 0x%04x on %s. Maybe it works, maybe it wont." " See tickets #123/318", ifr.ifr_hwaddr.sa_family, device); #ifdef SO_BROADCAST /* * man 7 socket * * Set or get the broadcast flag. When enabled, datagram sockets * receive packets sent to a broadcast address and they are allowed * to send packets to a broadcast address. This option has no * effect on stream-oriented sockets. */ if (setsockopt(mysocket, SOL_SOCKET, SO_BROADCAST, &n, sizeof(n)) == -1) { snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "SO_BROADCAST: %s", strerror(errno)); close(mysocket); return NULL; } #endif /* SO_BROADCAST */ /* prep & return our sp handle */ sp = (sendpacket_t *)safe_malloc(sizeof(sendpacket_t)); strlcpy(sp->device, device, sizeof(sp->device)); sp->handle.fd = mysocket; #ifdef HAVE_TX_RING /* Look up for MTU */ memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, sp->device, sizeof(ifr.ifr_name)); if (ioctl(mysocket, SIOCGIFMTU, &ifr) < 0) { close(mysocket); snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "Error getting MTU: %s", strerror(errno)); return NULL; } mtu = ifr.ifr_ifru.ifru_mtu; /* Init TX ring for sp->handle.fd socket */ if ((sp->tx_ring = txring_init(sp->handle.fd, mtu)) == 0) { snprintf(errbuf, SENDPACKET_ERRBUF_SIZE, "txring_init: %s", strerror(errno)); close(mysocket); return NULL; } sp->handle_type = SP_TYPE_TX_RING; #else sp->handle_type = SP_TYPE_PF_PACKET; #endif return sp; }
int recv_arp_reply(struct thread_context * tctx) { char device[10]; xmit buf; int s; int cc, j; char rcvd_src[6]; char rcvd_dest[6]; #ifndef __HTX_LINUX__ struct sockaddr_ndd_8022 sa; #else struct sockaddr_ll sa; #endif strcpy(device, &tctx->source.name); memset(&sa, 0, sizeof (sa)); #ifndef __HTX_LINUX__ sa.sndd_8022_family = AF_NDD; sa.sndd_8022_len = sizeof(sa); sa.sndd_8022_filtertype = NS_TAP; sa.sndd_8022_ethertype = (u_short)0x0806; sa.sndd_8022_filterlen = sizeof(struct ns_8022); bcopy(device, sa.sndd_8022_nddname, sizeof(sa.sndd_8022_nddname)); #else sa.sll_family = PF_PACKET; sa.sll_ifindex = get_iface_index(device); if (sa.sll_ifindex == -1) { printf("Unable to get device index, device = %s \n", device); return (-1); } sa.sll_protocol = htons(ETH_P_ALL); #endif #ifndef __HTX_LINUX__ s = socket(AF_NDD, SOCK_DGRAM, NDD_PROT_ETHER); #else s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); #endif if (s < 0) { printf("%s : error opening socket errno = %d \n", __FUNCTION__, errno); return(s); } if (bind(s, (struct sockaddr *)&sa, sizeof(sa))) { printf("%s error binding to socket errno = %d \n ",__FUNCTION__, errno); return(errno); } #ifndef __HTX_LINUX__ if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { printf("%s error connecting to socket errno = %d \n ",__FUNCTION__, errno); return(errno); } #else struct packet_mreq pkt_mreq; memset(&pkt_mreq, 0, sizeof(struct packet_mreq)); pkt_mreq.mr_ifindex = get_iface_index(device); pkt_mreq.mr_type = PACKET_MR_PROMISC; if (setsockopt(s, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &pkt_mreq, sizeof(struct packet_mreq))) { printf("Cannot set adapter %s in Promisc mode \n",device ); return(errno); } #endif do { if ((cc = read(s, &buf, sizeof(buf))) < 0) { printf("read failed with rc = %d, errno = %d \n", cc, errno); return(cc); } if(cc) { if(buf.arp_pkt.ea_hdr.ar_hrd != ARPHRD_ETHER) continue; /* * print_rcv_buffer(buf, tctx); */ memcpy(rcvd_src, buf.src, (sizeof(char)*6)); memcpy(rcvd_dest, buf.dst, (sizeof(char)*6)); /* Check whether my worker thread is the source for this packet */ if(!memcmp(rcvd_dest, &tctx->source.mac_addr, (sizeof(char)*6))) { /* Now copy the receivers details */ for(j = 0; j < tctx->num_devices; j++) { if(!memcmp(rcvd_src, &tctx->dev_list[j].mac_addr, (sizeof(char)*6))) { memcpy(&tctx->dest[tctx->num_reply], &tctx->dev_list[j], sizeof(struct dev_details)); tctx->rcvd_reply = 1; tctx->num_reply++; break; } } } } } while(cc > 0 && !tctx->exit_helper); close(s); return(0); }
int send_arp_packet(struct dev_details source, struct dev_details dest, u_int count) { char hwaddr[6], bcast_addr[6]; u_int size; xmit buf; int s; int last; int rc; #ifndef __HTX_LINUX__ struct sockaddr_ndd_8022 sa; #else struct sockaddr_ll sa; #endif memcpy(hwaddr, &source.mac_addr[0], 6); #ifdef __HTX_LINUX__ memcpy(bcast_addr, dest.mac_addr, 6); #else hwaddr_aton("FF:FF:FF:FF:FF:FF", bcast_addr); #endif count = NUM_RETRIES; /* Building Ethernet Header */ memcpy(buf.dst, bcast_addr, sizeof(buf.dst)); memcpy(buf.src, hwaddr, sizeof(buf.src)); bcopy(hwaddr, buf.src, sizeof(buf.src)); buf.ethertype = ETHERTYPE_ARP; /* ARP Header */ buf.arp_pkt.ea_hdr.ar_hrd = ARPHRD_ETHER; buf.arp_pkt.ea_hdr.ar_pro = SNAP_TYPE_IP; buf.arp_pkt.ea_hdr.ar_hln = 6; buf.arp_pkt.ea_hdr.ar_pln = 4; buf.arp_pkt.ea_hdr.ar_op = ARPOP_REQUEST; /* Grat ARP Packet */ bcopy(hwaddr, buf.arp_pkt.arp_sha, sizeof(buf.arp_pkt.arp_sha)); bcopy(bcast_addr, buf.arp_pkt.arp_tha, sizeof(buf.arp_pkt.arp_tha)); #ifdef __HTX_LINUX__ s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); #else s = socket(AF_NDD, SOCK_DGRAM, 0); #endif if (s < 0) { printf("Unable to open socket s = %d, errno = %d \n", s, errno); return(s); } /* Now Connect */ #ifndef __HTX_LINUX__ memset(&sa, 0, sizeof (sa)); sa.sndd_8022_family = AF_NDD; sa.sndd_8022_len = sizeof(sa); sa.sndd_8022_filtertype = NS_ETHERTYPE; sa.sndd_8022_ethertype = ETHERTYPE_ARP; sa.sndd_8022_filterlen = sizeof(struct ns_8022); memcpy(sa.sndd_8022_nddname, &source.name, sizeof(sa.sndd_8022_nddname)); if ((rc = connect(s, (struct sockaddr *)&sa, sizeof(sa))) < 0) { printf("failed to connect socket with source,rc = %d, errno = %s \n", rc, STRERROR(errno)); return(errno); } #else sa.sll_family = AF_PACKET; sa.sll_ifindex = get_iface_index(source.name); if (sa.sll_ifindex == -1) { printf("Unable to get device index, device = %s \n", source.name); return (-1); } sa.sll_protocol = htons(ETH_P_ALL); if((rc = bind(s, (struct sockaddr *)&sa, sizeof(sa))) < 0) { printf("failed to bind socket with source,rc = %d, errno = %s \n", rc, STRERROR(errno)); return(-1); } struct packet_mreq pkt_mreq; memset(&pkt_mreq, 0, sizeof(struct packet_mreq)); pkt_mreq.mr_ifindex = get_iface_index(source.name); pkt_mreq.mr_type = PACKET_MR_PROMISC; if (setsockopt(s, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &pkt_mreq, sizeof(struct packet_mreq))) { printf("Failed to set adapter %s in PROMISC mode \n", source.name ); return -1; } #endif #if 0 #ifndef __HTX_LINUX__ printf("%s:%s ", sa.sndd_8022_nddname, inet_ntoa(*(struct in_addr *)buf.arp_pkt.arp_spa)); #else printf("%s:%s ", source.name, inet_ntoa(*(struct in_addr *)buf.arp_pkt.arp_spa)); #endif printf("----------> "); printf("%s:",dest.name); printf("%s ", inet_ntoa(*(struct in_addr *)buf.arp_pkt.arp_tpa)); printf("\n"); #endif while (count-- > 0) { #ifndef __HTX_LINUX__ if (((rc = send(s, &buf, sizeof(buf), 0)) < 0) && (errno != ENOBUFS) ) { #else if(((rc = write(s, &buf, sizeof(buf))) != sizeof(buf)) && (errno != ENOBUFS) ) { #endif printf("Failed to send a packet, rc = %d, device = %s, err = %s \n", rc, source.name, STRERROR(errno)); return(-1); } usleep(5); } close(s); return(0); } int get_iface_index(const int8_t *device) { int sock; struct ifreq ifr; /* Open a generic IP socket for querying the stack */ sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if (sock < 0) { printf("Unable to open socket sock = %d, errno = %d \n", sock, errno); return(-1); } /* Get interface index */ memset(&ifr, 0, sizeof(ifr)); ifr.ifr_addr.sa_family = AF_PACKET; strncpy (ifr.ifr_name, device, sizeof(ifr.ifr_name) - 1); ifr.ifr_name[sizeof(ifr.ifr_name)-1] = '\0'; if (ioctl(sock, SIOCGIFINDEX, &ifr) == -1) { close(sock); return (-1); } close(sock); return ifr.ifr_ifindex; }