/* * headers.c, a header analysis tool written by Javaman * This software is for educational use only. * You have been warned. */ #include #include #include #include #include #include #include #include #include #include #include char ethdump, ipdump, tcpdump, udpdump, icmpdump, arpdump; char ethlen, iplen, tcplen, udplen, icmplen, arplen; void handler(char *, const struct pcap_pkthdr *, const u_char *); void help(void); int main(int argc, char **argv) { int buffsize = 65535; int promisc = 1; int timeout = 1000; char pcap_err[PCAP_ERRBUF_SIZE]; u_char buffer[255]; char i; char *dev; struct in_addr net, mask; pcap_t *pcap_nic; ethdump = 0; ipdump = 0; icmpdump = 0; tcpdump = 0; udpdump = 0; arpdump = 0; ethlen = sizeof(struct ether_header); iplen = sizeof(struct iphdr); tcplen = sizeof(struct tcphdr); udplen = sizeof(struct udphdr); icmplen = sizeof(struct icmphdr); arplen = sizeof(struct ether_arp); if (argc == 1) { help(); exit(0); } while ((i = getopt(argc, argv, "eutica")) != EOF) { switch (i) { case 'i': ipdump = 1; break; case 'e': ethdump = 1; break; case 't': tcpdump = 1; break; case 'u': udpdump = 1; break; case 'c': icmpdump = 1; break; case 'a': arpdump = 1; break; } } if (!(dev = pcap_lookupdev(pcap_err))) { perror(pcap_err); exit(-1); } if ((pcap_nic = pcap_open_live(dev, buffsize, promisc, timeout, pcap_err)) == NULL) { perror(pcap_err); exit(-1); } if (pcap_lookupnet(dev, &net.s_addr, &mask.s_addr, pcap_err) == -1) { perror(pcap_err); exit(-1); } while (pcap_loop(pcap_nic, -1, (pcap_handler) handler, buffer)); } void handler(char *usr, const struct pcap_pkthdr *header, const u_char * pkt) { struct ether_header *ethheader; struct iphdr *ipheader; struct udphdr *udpheader; struct tcphdr *tcpheader; struct icmphdr *icmpheader; struct ether_arp *arppkt; struct in_addr source, dest; int y; ethheader = (struct ether_header *) pkt; if (ethdump) { printf("\nEthernet:\n"); for (y = 0; y < 6; y++) { printf("%02x", ethheader->ether_dhost[y]); if (y != 5) { printf(":"); } else { printf("\n"); } } for (y = 0; y < 6; y++) { printf("%02x", ethheader->ether_shost[y]); if (y != 5) { printf(":"); } else { printf("\n"); } } printf("Proto: %04x\n", ntohs(ethheader->ether_type)); } if (arpdump && ((ethheader->ether_type == 0x0608) || (ethheader->ether_type == 0x3508))) { arppkt = (struct ether_arp *) (pkt + ethlen); memcpy(&source, &arppkt->arp_spa, 4); memcpy(&dest, &arppkt->arp_tpa, 4); printf("\nARP:\n"); printf("%04x %04x\n", ntohs(arppkt->ea_hdr.ar_hrd), ntohs(arppkt->ea_hdr.ar_pro)); printf("%02x %02x %04x\n", arppkt->ea_hdr.ar_hln, arppkt->ea_hdr.ar_pln, ntohs(arppkt->ea_hdr.ar_op)); for (y = 0; y < 6; y++) { printf("%02x", arppkt->arp_sha[y]); if (y != 5) { printf(":"); } else { printf("\n"); } } for (y = 0; y < 4; y++) { printf("%02x", arppkt->arp_spa[y]); if (y != 3) { printf("."); } else { printf("\t(%s)\n", inet_ntoa(source)); } } for (y = 0; y < 6; y++) { printf("%02x", arppkt->arp_tha[y]); if (y != 5) { printf(":"); } else { printf("\n"); } } for (y = 0; y < 4; y++) { printf("%02x", arppkt->arp_tpa[y]); if (y != 3) { printf("."); } else { printf("\t(%s)\n", inet_ntoa(dest)); } } } if (ethheader->ether_type == 0x0008) { ipheader = (struct iphdr *) (pkt + ethlen); if (ipdump && (ipheader->version == 0x04)) { memcpy(&source, &ipheader->saddr, 4); memcpy(&dest, &ipheader->daddr, 4); printf("\nIP:\n"); printf("%1x %1x %02x %04x\n", ipheader->version, ipheader->ihl, ipheader->tos, ntohs(ipheader->tot_len)); printf("%04x %04x\n", ntohs(ipheader->id), ntohs(ipheader->frag_off)); printf("%02x %02x %04x\n", ipheader->ttl, ipheader->protocol, ntohs(ipheader->check)); printf("%08x (%s)\n", ntohl(ipheader->saddr), inet_ntoa(source)); printf("%08x (%s)\n", ntohl(ipheader->daddr), inet_ntoa(dest)); } if (udpdump && (ipheader->protocol == 0x11)) { udpheader = (struct udphdr *) (pkt + ethlen + iplen); printf("\nUDP:\n"); printf("%04x %04x\n", ntohs(udpheader->source), ntohs(udpheader->dest)); printf("%04x %04x\n", ntohs(udpheader->len), ntohs(udpheader->check)); } if (tcpdump && (ipheader->protocol == 0x06)) { tcpheader = (struct tcphdr *) (pkt + ethlen + iplen); printf("\nTCP:\n"); printf("%04x %04x\n", ntohs(tcpheader->source), ntohs(tcpheader->dest)); printf("%08x\n", ntohl(tcpheader->seq)); printf("%08x\n", ntohl(tcpheader->ack_seq)); printf("%1x %02x %1x:%1x:%1x:%1x:%1x:%1x %04x\n", tcpheader->doff, tcpheader->res1 + tcpheader->res2, tcpheader->urg, tcpheader->ack, tcpheader->psh, tcpheader->rst, tcpheader->syn, tcpheader->fin, ntohs(tcpheader->window)); printf("%04x %04x\n", ntohs(tcpheader->check), ntohs(tcpheader->urg_ptr)); } if (icmpdump && (ipheader->protocol == 0x01)) { icmpheader = (struct icmphdr *) (pkt + ethlen + iplen); printf("\nICMP:\n"); printf("%02x %02x %04x\n", icmpheader->type, icmpheader->code, ntohs(icmpheader->checksum)); if ((icmpheader->type == 0x08) || (icmpheader->type == 0x00) || (icmpheader->type == 0x0d) || (icmpheader->type == 0x0e) || (icmpheader->type == 0x0f) || (icmpheader->type == 0x10)) { printf("%04x %04x\n", ntohs(icmpheader->un.echo.id), ntohs(icmpheader->un.echo.sequence)); } else if (icmpheader->type == 0x05) { printf("%08x Gw: %s\n", ntohl(icmpheader->un.gateway), inet_ntoa(dest)); } } } return; } void help(void) { printf("Headers by Javaman v1\n"); printf("For information purposes only.\n"); printf("Options:\n"); printf("\t-e\tDump Ethernet header\n"); printf("\t-a\tDump ARP/RARP info\n"); printf("\t-i\tDump IP header\n"); printf("\t-c\tDump ICMP header\n"); printf("\t-t\tDump TCP header\n"); printf("\t-u\tDump UDP header\n"); }