void lb_table_add_macs_from_vpd(struct lb_header *header) { /* * Mac addresses in the VPD can be stored in two groups, for ethernet * and WiFi, with keys 'ethernet_macX and wifi_macX. */ const char *mac_addr_key_bases[] = {"ethernet_mac0", "wifi_mac0"}; char mac_addr_key[20]; /* large enough for either key */ char mac_addr_str[13]; /* 12 symbols and the trailing zero. */ int i, count; struct lb_macs *macs = NULL; /* Make sure the copy is always zero terminated. */ mac_addr_key[sizeof(mac_addr_key) - 1] = '\0'; count = 0; for (i = 0; i < ARRAY_SIZE(mac_addr_key_bases); i++) { int index_of_index; strncpy(mac_addr_key, mac_addr_key_bases[i], sizeof(mac_addr_key) - 1); index_of_index = strlen(mac_addr_key) - 1; do { /* * If there are no more MAC addresses of this template * in the VPD - move on. */ if (!cros_vpd_gets(mac_addr_key, mac_addr_str, sizeof(mac_addr_str))) break; if (!macs) { macs = (struct lb_macs *)lb_new_record(header); macs->tag = LB_TAG_MAC_ADDRS; } decode_mac(macs->mac_addrs + count, mac_addr_str, mac_addr_key); count++; mac_addr_key[index_of_index]++; } while (count < 10); } if (!count) return; /* No MAC addresses in the VPD. */ macs->count = count; macs->size = sizeof(*macs) + count * sizeof(struct mac_address); }
int send_arp(struct myetheraddr *dst) { printf("Sending ARP resp to: "); decode_mac((uint8_t *)&dst->octet[0]); printf("\n"); fflush(stdout); bob.arp=libnet_build_arp( ARPHRD_ETHER, /* ethernet follows */ ETHERTYPE_IP, /* proto for addr res */ 6, /* hardware addr len */ 4, /* proto addr len */ ARPOP_REPLY, /* duh */ (uint8_t *)&bob.shwaddr.octet[0], /* source */ (uint8_t *)&bob.saddr, /* ip src */ (uint8_t *)&dst->octet[0], /* dst hw */ (uint8_t *)&bob.saddr, /* src ip */ NULL, /* no pl */ 0, /* zero len */ bob.l, /* libnet handle */ bob.arp); /* arp id? */ if (bob.arp < 0) { fprintf(stderr, "Can't build ARP header: %s\n", libnet_geterror(bob.l)); return -1; } bob.eth=libnet_build_ethernet( (uint8_t *)&dst->octet[0], /* dest host hw addr */ (uint8_t *)&bob.shwaddr.octet[0], /* dest host src addr */ ETHERTYPE_ARP, /* ethernet, arp */ NULL, /* no payload */ 0, /* obviously is 0 len */ bob.l, /* libnet handle */ bob.eth); /* eth id? */ if (bob.eth < 0) { fprintf(stderr, "Can't build ethernet header: %s\n", libnet_geterror(bob.l)); return -1; } if (libnet_write(bob.l) == -1) { fprintf(stderr, "%s", libnet_geterror(bob.l)); return -1; } return 1; }
static int cmd_syslog(const char *args[]) { char b1[32], b2[32]; if (args[0] && !strcmp(args[0], "off")) { syslog_addr.daddr = 0; return 0; } if (!args[1]) { pp_printf("use: syslog <ipaddr> <macaddr> (or just \"off\"\n"); return -1; } decode_ip(args[0], (void *)&syslog_addr.daddr); decode_mac(args[1], syslog_mac); pp_printf("Syslog parameters: %s, %s\n", format_ip(b1, (void *)&syslog_addr.daddr), format_mac(b2, syslog_mac)); tics = 0; /* send the first frame immediately to the new host */ return 0; }
void process_packet(uint8_t *user, const struct pcap_pkthdr *phdr, const uint8_t *packet) { const struct ether_header *ehdr_ptr=NULL; const struct arp_packet *ap=NULL; if (phdr->caplen != phdr->len || phdr->caplen < sizeof(struct ether_header)) { return; } ehdr_ptr=(const struct ether_header *)packet; if (ntohs(ehdr_ptr->ether_type) != ETHERTYPE_ARP) { return; } ap=(const struct arp_packet *)(packet + sizeof(struct ether_header)); if (phdr->caplen < (sizeof(struct ether_header) + sizeof(struct arp_packet))) { fprintf(stderr, "Short packet!!!!\n"); return; } /* ethernet -> ip -> hwsize = 6 and ip size = 4 */ if (ntohs(ap->hw_type) == 1 && ap->protocol == 8 && ap->hwsize == 6 && ap->protosize == 4) { #ifdef VERBOSE char src[17], dst[17]; #endif switch (ntohs(ap->opcode)) { case 1: /* arp request */ #ifdef VERBOSE printf("Arp Request: Source Mac: "); decode_mac(ap->smac); printf(" Dest Mac: "); decode_mac(ap->dmac); /* hide the children, they will cry if they see this */ snprintf(src, sizeof(src) -1, "%s", inet_ntoa(*((const struct in_addr *)&ap->sip))); snprintf(dst, sizeof(dst) -1, "%s", inet_ntoa(*((const struct in_addr *)&ap->dip))); printf(" [ %s -> %s ]\n", src, dst); #endif if (bob.addr_cleared) { if (ap->dip == bob.saddr) { struct myetheraddr sea; memset(&sea, 0, sizeof(sea)); memcpy(&(sea.octet[0]), &ap->smac[0], 6); send_arp((struct myetheraddr *)&sea); } else { } } break; case 2: /* reply */ #ifdef VERBOSE printf("Arp Reply: Source Mac: "); decode_mac(ap->smac); printf(" Dest Mac: "); decode_mac(ap->dmac); /* hide the children, they will cry if they see this */ snprintf(src, sizeof(src) -1, "%s", inet_ntoa(*((const struct in_addr *)&ap->sip))); snprintf(dst, sizeof(dst) -1, "%s", inet_ntoa(*((const struct in_addr *)&ap->dip))); printf(" [ %s -> %s ]\n", src, dst); #endif if (bob.addr_cleared == 0 && ap->sip == bob.saddr) { bob.addr_cleared=-1; } break; default: break; } } return; }
int main(int argc, char ** argv) { char errbuf[LIBNET_ERRBUF_SIZE]; char errors[PCAP_ERRBUF_SIZE], pfilter[2048]; struct ifreq ifr; bpf_u_int32 mask=0, net=0; int st=-1, tries=0; struct bpf_program filter; struct myetheraddr *e=NULL; pcap_t *pdev=NULL; memset(&ifr, 0, sizeof(ifr)); if (argc != 3) { printf("FantaIP by KIKI\nUsage: (example) %s eth0 192.168.13.211\n", argv[0]); exit(1); } bob.device=strdup(argv[1]); assert(bob.device != NULL); bob.saddr=(uint32_t)inet_addr(argv[2]); bob.addr_cleared=0; st=socket(AF_INET, SOCK_DGRAM, 0); if (st < 0) { fprintf(stderr, "create socket fails: %s", strerror(errno)); exit(1); } bob.l=libnet_init(LIBNET_LINK_ADV, bob.device, errbuf); if (bob.l == NULL) { fprintf(stderr, "libnet_init: %s\n", strerror(errno)); exit(1); } bob.arp=0; bob.eth=0; e=(struct myetheraddr *)libnet_get_hwaddr(bob.l); if (e == NULL) { perror("bad things batman"); exit(1); } memcpy(&bob.shwaddr, e, sizeof(bob.shwaddr)); snprintf(pfilter, sizeof(pfilter) -1, FILTER); memset(errors, 0, sizeof(errors)); pcap_lookupnet(bob.device, &net, &mask, errors); memset(errors, 0, sizeof(errors)); pdev=pcap_open_live(bob.device, 500, 1, 0, errors); if (util_getheadersize(pdev, errors) != 14) { fprintf(stderr, "You SURE this is an ethernet interface? doesnt look like one\n"); exit(1); } if (util_preparepcap(pdev, errors) < 0) { fprintf(stderr, "Can't prepare bpf socket: %s\n", strerror(errno)); exit(1); } pcap_compile(pdev, &filter, pfilter, 0, net); pcap_setfilter(pdev, &filter); /* look for dups */ if (pcap_setnonblock(pdev, 1, errors) < 0) { fprintf(stderr, "Can't set pcap dev nonblocking: %s\n", errors); exit(1); } bob.addr_cleared=0; while (bob.addr_cleared == 0 && tries < 3) { /* lets be sure about this ;] */ broadcast_arp(ARPOP_REQUEST, 0xFFFFFFFF); broadcast_arp(ARPOP_REQUEST, 0x00000000); broadcast_arp(ARPOP_REQUEST, bob.saddr); signal(SIGALRM, &alarm_hndlr); breakloop=0; alarm(1); while (1) { pcap_dispatch(pdev, -1, &process_packet, NULL); if (breakloop || bob.addr_cleared != 0) break; } alarm(0); signal(SIGALRM, SIG_DFL); tries++; } alarm(0); signal(SIGALRM, SIG_DFL); if (bob.addr_cleared == -1) { fprintf(stderr, "Error: Address already in use\n"); exit(1); } bob.addr_cleared=1; printf("arping for %s [", inet_ntoa(*((const struct in_addr *)&bob.saddr))); fflush(stdout); decode_mac(&bob.shwaddr.octet[0]); printf(" ]\n"); fflush(stdout); /* ok block now */ if (pcap_setnonblock(pdev, 0, errors) < 0) { fprintf(stderr, "Can't set pcap dev nonblocking: %s\n", errors); exit(1); } pcap_loop(pdev, 0, &process_packet, NULL); libnet_destroy(bob.l); exit(0); }