void caught_packet(u_char *user_args, const struct pcap_pkthdr *cap_header, const u_char *packet) { int tcp_header_length, total_header_size, pkt_data_len; u_char *pkt_data; int total_header_size2; //structs of the packet (different protocol headers) struct ether_header *ETHERheader; struct ip *IPheader; struct tcphdr *TCPheader; //copy of the packet char * packet_copy; packet_copy = malloc(cap_header->len); if (packet_copy <= 0 ) exit(-1); memcpy(packet_copy,packet,cap_header->len); printf("==== Got a %d byte packet ====\n", cap_header->len); decode_ethernet(packet,ETHERheader,packet_copy); decode_ip(packet+ETHER_HDR_LEN,IPheader,packet_copy+ETHER_HDR_LEN); tcp_header_length = decode_tcp(packet+ETHER_HDR_LEN+sizeof(struct ip_hdr),TCPheader, packet_copy+ETHER_HDR_LEN+sizeof(struct ip)); total_header_size = ETHER_HDR_LEN+sizeof(struct ip_hdr)+tcp_header_length; total_header_size2 = ETHER_HDR_LEN+sizeof(struct ip)+tcp_header_length; printf("total_header_size:%d \n total_header_size2:%d \n",total_header_size,total_header_size2); pkt_data = (u_char *)packet + total_header_size; // pkt_data points to the data portion pkt_data_len = cap_header->len - total_header_size; if(pkt_data_len > 0) { printf("\t\t\t%u bytes of packet data\n", pkt_data_len); //dump(pkt_data, pkt_data_len); dump(packet, cap_header->len); } else { printf("\t\t\tNo Packet Data\n"); dump(packet, cap_header->len); } printf("before ipspoof3\n"); //ipspoof3( inet_ntoa(IPheader->ip_src), inet_ntoa(IPheader->ip_dst), "0022433967e9",ETHERheader,IPheader,TCPheader,(u_char *)packet_copy + total_header_size, pkt_data_len); ipspoof4( "", "192.168.1.13", "701a04d83403", (char *)packet, cap_header->len); printf(" after ipspoof3 \n"); free(packet_copy); }
// IP解包函数 int decode_ip(char *ipbuf, int protocol) { switch(protocol) { case IPPROTO_TCP: // TCP类型数据包 decode_tcp(ipbuf); break; case IPPROTO_UDP: // UDP类型数据包 decode_udp(ipbuf); break; case IPPROTO_ICMP: // ICMP类型数据包 decode_icmp(ipbuf); break; default: break; } return true; }
void decode_ip6(const u_char * packet) { char str_sip[INET6_ADDRSTRLEN]; char str_dip[INET6_ADDRSTRLEN]; char buffer[128]; char * yellow_plen, *yellow_nxt, *b_sip, *b_dip; const struct ip6_hdr * ip_t; ip_t = (struct ip6_hdr *)(packet); inet_ntop(AF_INET6, &(ip_t->ip6_src), str_sip, INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &(ip_t->ip6_dst), str_dip, INET6_ADDRSTRLEN); b_sip = bold(str_sip); b_dip = bold(str_dip); sprintf(buffer, "%d", htons(ip_t->ip6_ctlun.ip6_un1.ip6_un1_plen)); yellow_plen = yellow(buffer); sprintf(buffer, "%x", ip_t->ip6_ctlun.ip6_un1.ip6_un1_plen); yellow_nxt = yellow(buffer); V(1, "IPv6 - %s --> %s\n", b_sip, b_dip); uint32_t flow = htonl(ip_t->ip6_ctlun.ip6_un1.ip6_un1_flow); VV(1, "Payload Length : %s - Next Header : %s\n", yellow_plen, yellow_nxt); /* htons(ip_t->ip6_ctlun.ip6_un1.ip6_un1_plen), ip_t->ip6_ctlun.ip6_un1.ip6_un1_nxt); */ VVV(1,"Version : %d - Traffic Class : %x - Flow Label : %x - Hop Limit : %d\n", flow >> 28, (flow & 0x0ff00000) >> 20, flow & 0x000fffff, ip_t->ip6_ctlun.ip6_un1.ip6_un1_hlim); int offset = sizeof(struct ip6_hdr); switch(ip_t->ip6_ctlun.ip6_un1.ip6_un1_nxt) { case 0x06: decode_tcp(packet + offset); break; case 0x11: decode_udp(packet + offset); break; } free(yellow_plen); free(yellow_nxt); free(b_sip); free(b_dip); }
void caught_packet(u_char *user_args, const struct pcap_pkthdr *cap_header, const u_char *packet) { int tcp_header_length, total_header_size, pkt_data_len; u_char *pkt_data; printf("==== %d バイトのパケットを取得しました ====\n", cap_header->len); decode_ethernet(packet); decode_ip(packet+ETHER_HDR_LEN); tcp_header_length = decode_tcp(packet+ETHER_HDR_LEN+sizeof(struct ip_hdr)); total_header_size = ETHER_HDR_LEN+sizeof(struct ip_hdr)+tcp_header_length; pkt_data = (u_char *)packet + total_header_size; // pkt_dataはデータ部分を指す pkt_data_len = cap_header->len - total_header_size; if(pkt_data_len > 0) { printf("\t\t\t%u バイトのパケットデータ\n", pkt_data_len); dump(pkt_data, pkt_data_len); } else printf("\t\t\tパケットデータがありません\n"); }
void decode_packet(void *packet_data) { struct ip *ip_hdr = (struct ip *)packet_data; // hd short int // hhd char printf("%d] " "IPv%hd HL:%hhd TOS:%s TL:%hu ID:%hu Off:%hu TTL:%hhu %s\n" "Sum:%hu ", get_stack_id(), (short)ip_hdr->ip_v, (short)ip_hdr->ip_hl, tos2str(ip_hdr->ip_tos), ntohs(ip_hdr->ip_len), ntohs(ip_hdr->ip_id), ntohs(ip_hdr->ip_off), ip_hdr->ip_ttl, protocol2str(ip_hdr->ip_p), ntohs(ip_hdr->ip_sum) ); printf("%s -> ", inet_ntoa(ip_hdr->ip_src)); printf("%s\n", inet_ntoa(ip_hdr->ip_dst)); if(ip_hdr->ip_p == 6) decode_tcp((unsigned char *)packet_data + (ip_hdr->ip_hl * 4), ntohs(ip_hdr->ip_len) - (ip_hdr->ip_hl * 4)); }
/* main processing function */ void proc_packet(const u_char *data, u_int size) { struct ip_stat istat; u_int data_offs; u_int tcp_hdr_sz; u_int udp_hdr_sz; /* print captured bytes */ printf("\n\nBytes Captured = [ %d ]\n", size); /* print L2 information */ decode_ethernet(data); /* obtain IP protocol number for further decoding */ decode_ip(data + ETHER_HDR_LEN, &istat); switch(istat.ip_prot) { case 1: decode_icmp(data + ETHER_HDR_LEN + istat.ip_len); data_offs = ETHER_HDR_LEN + istat.ip_len; break; case 6: tcp_hdr_sz = decode_tcp(data + ETHER_HDR_LEN + istat.ip_len); data_offs = ETHER_HDR_LEN + istat.ip_len + tcp_hdr_sz; break; case 17: udp_hdr_sz = decode_udp(data + ETHER_HDR_LEN + istat.ip_len); data_offs = ETHER_HDR_LEN + istat.ip_len + udp_hdr_sz; break; default: break; } /* print raw encapsulated data */ praw(data + data_offs, size); }
static void decode_ip (const uint8_t *packet, size_t pk_len, int pk_layer) { union { const struct myiphdr *i; const uint8_t *d; } i_u; uint16_t fragoff=0, totlen=0, ipid=0, chksum=0, c_chksum=0; uint32_t saddr=0, daddr=0; size_t opt_len=0; int bad_cksum=0; i_u.d=packet; r_u.i.flags=0; if (pk_len < sizeof(struct myiphdr)) { ERR("short ip packet"); return; } if (i_u.i->ihl < 5) { ERR("ihl is less than 5, this packet is likely confused/damaged"); return; } ipid=ntohs(i_u.i->id); fragoff=ntohs(i_u.i->frag_off); totlen=ntohs(i_u.i->tot_len); chksum=ntohs(i_u.i->check); /* XXX everything expects addresses in network order */ saddr=i_u.i->saddr; daddr=i_u.i->daddr; /* precalculated ip-pseudo header for transport layer checksumming */ ipph.saddr=saddr; ipph.daddr=daddr; ipph.zero=0; ipph.proto=i_u.i->protocol; ipph.len=0; opt_len=(i_u.i->ihl - (sizeof(struct myiphdr) / 4)) * 4; if (fragoff & IP_OFFMASK) { ERR("likely bad: (is DF set? perhaps we need it) ignoring fragmented packet"); return; } if (totlen > pk_len && pk_layer == 1) { /* this packet has an incorrect ip packet length, stop processing */ ERR("likely bad: packet has incorrect ip length, skipping it [ip total length claims %u and we have " STFMT, totlen, pk_len); return; } else if (pk_layer == 3 && totlen > pk_len) { totlen=pk_len; } if (pk_len > totlen) { /* * there is trailing junk past the end of the ip packet, save a pointer to it, * and its length, then update pk_len */ DBG(M_PKT, "packet has trailing junk, saving a pointer to it and its length " STFMT, pk_len - totlen); trailgarbage=packet + totlen; trailgarbage_len=pk_len - totlen; pk_len=totlen; } if ((opt_len + sizeof(struct myiphdr)) > pk_len) { DBG(M_PKT, "IP options seem to overlap the packet size, truncating and assuming no ip options"); opt_len=0; /* must be a trick, assume no options then, in case this is a damaged ip header is under a icmp reply */ } if ((c_chksum=do_ipchksum(packet, opt_len + sizeof(struct myiphdr))) != 0) { DBG(M_PKT, "bad cksum, ipchksum returned %u", c_chksum); bad_cksum=1; } if (ISDBG(M_PKT) || GET_SNIFF()) { char frag_flags[32]; char src_addr[32], dst_addr[32]; struct in_addr ia; ia.s_addr=saddr; sprintf(src_addr, "%s", inet_ntoa(ia)); ia.s_addr=daddr; sprintf(dst_addr, "%s", inet_ntoa(ia)); CLEAR(frag_flags); if (fragoff & IP_DF) { strcat(frag_flags, "DF "); } if (fragoff & IP_MF) { strcat(frag_flags, "MF "); } if (fragoff & IP_RF) { strcat(frag_flags, "RF "); } INF("IP : ihl %u (opt len " STFMT ") size " STFMT " version %u tos 0x%02x tot_len %u ipid %u frag_off %04x %s", i_u.i->ihl, opt_len, pk_len, i_u.i->version, i_u.i->tos, totlen, ipid, fragoff & IP_OFFMASK, frag_flags); INF("IP : ttl %u protocol `%s' chksum 0x%04x%s IP SRC %s IP DST %s", i_u.i->ttl, str_ipproto(i_u.i->protocol), chksum, (bad_cksum == 1 ? " [bad cksum]" : " [cksum ok]"), src_addr, dst_addr); } if (pk_layer == 1) { r_u.i.proto=i_u.i->protocol; r_u.i.host_addr=saddr; r_u.i.trace_addr=saddr; r_u.i.send_addr=daddr; r_u.i.ttl=i_u.i->ttl; if (bad_cksum) { r_u.i.flags |= REPORT_BADNETWORK_CKSUM; } } else if (pk_layer == 3) { /* this is a ip header within an icmp header normally */ /* * this was the _original host_ we sent to according * to the icmp error reflection */ r_u.i.host_addr=daddr; } else { ERR("decode IP at unknown layer %d", pk_layer); return; } if (opt_len > 0) { decode_ipopts(packet + sizeof(struct myiphdr), opt_len); } pk_len -= sizeof(struct myiphdr) + opt_len; packet += sizeof(struct myiphdr) + opt_len; if (pk_len) { switch (i_u.i->protocol) { case IPPROTO_TCP: decode_tcp(packet, pk_len, ++pk_layer); break; case IPPROTO_UDP: decode_udp(packet, pk_len, ++pk_layer); break; case IPPROTO_ICMP: decode_icmp(packet, pk_len, ++pk_layer); break; default: ERR("filter is broken?"); break; } } return; }
int main(int argc, char *argv[]) { IPHEADER *ip_header = NULL; int optval = 1; DWORD dwLen = 0; char packet[LS_MAX_PACKET_SIZE]; int iRet = 0; int ip_header_size = 0; char ipSrc[20], ipDest[20], thisIP[20]; BOOL bShowTCP = TRUE, bShowICMP = TRUE; // Check arguments if ( _argc > 1 ) { if ( !_stricmp(argv[1], "icmp") ) bShowTCP = FALSE; else if ( !_stricmp(argv[1], "tcp") ) bShowICMP = FALSE; else { printf( "\nUsage lsniff [ICMP|TCP]\n" ); exit(0); } } USocket us; us.init(); us.create(AF_INET, SOCK_RAW, IPPROTO_IP); memset( thisIP, 0x00, sizeof(thisIP) ); get_this_machine_ip(thisIP); struct sockaddr_in sock_sniff; sock_sniff.sin_family = AF_INET; sock_sniff.sin_port = htons(0); // If your machine has more than one IP you might put another one instead thisIP value sock_sniff.sin_addr.s_addr = inet_addr(thisIP); us.bind((struct sockaddr *)&sock_sniff); // Set socket to promiscuous mode // setsockopt wont work ... dont even try it if ( WSAIoctl( us, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwLen, NULL, NULL ) == SOCKET_ERROR ) { printf( "Error: WSAIoctl = %ld\n", WSAGetLastError() ); exit(-3); } while ( TRUE ) { memset( packet, 0x00, sizeof(packet) ); iRet = us.recv( packet, LS_MAX_PACKET_SIZE); if ( iRet < sizeof(IPHEADER) ) continue; ip_header = (IPHEADER *)packet; // I only want IPv4 not IPv6 if ( LS_HI_PART(ip_header->ver_ihl) != 4 ) continue; ip_header_size = LS_LO_PART(ip_header->ver_ihl); ip_header_size *= sizeof(DWORD); // size in 32 bits words // Checks the protocol IP is encapsulating memset( ipSrc, 0x00, sizeof(ipSrc) ); memset( ipDest, 0x00, sizeof(ipDest) ); translate_ip(ip_header->source_ip, ipSrc); translate_ip(ip_header->destination_ip, ipDest); // Read http://www.ietf.org/rfc/rfc1700.txt?number=1700 switch( ip_header->protocol ) { case 1: // ICMP if ( bShowICMP ) { printf("\n -------------------- // -------------------- "); printf("\n IP Header:"); printf("\n Source IP: %s", ipSrc); printf("\n Destination IP: %s", ipDest); printf("\n ICMP Header:"); decode_icmp(&packet[ip_header_size]); } break; case 6: // TCP if ( bShowTCP ) { printf("\n -------------------- // -------------------- "); printf("\n IP Header:"); printf("\n Source IP: %s", ipSrc); printf("\n Destination IP: %s", ipDest); printf("\n TCP Header:"); decode_tcp(&packet[ip_header_size]); } break; case 17: // UDP break; default: break; } } // end-while us.cleanup(); getchar(); return 0; }