#include #include #include #include #include #include #define BUFFSIZE 10000 char buffer[BUFFSIZE]; void ppp(const u_char *packet, int size); void arp(const u_char *packet, int size); void print_rest(int from, int to, const u_char *packet); void ip(const u_char *packet, int size); void dispatch_by_ethernet_type(u_short eType, const u_char *packet, int size); void print_ethernet_addr(const u_char *addr); void ethernet(const u_char *packet, int size); void print_time(); void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet); void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){ int size = header->caplen; print_time(); ethernet(packet, size); write(STDOUT_FILENO, "\n\n", 2); } void ppp(const u_char *packet, int size) { u_char protocol; memcpy(&protocol, packet+7, 1); if(protocol == 33) { ip(packet+8, size-8); } } void arp(const u_char *packet, int size) { u_short hardware_type; u_short protocol_type; u_int sender_ip; u_int target_ip; u_short operation; int temp; memcpy(&hardware_type, packet, 2); memcpy(&protocol_type, packet+2, 2); if(ntohs(hardware_type) == 1 && ntohs(protocol_type) == 2048) { memcpy(&sender_ip, packet + 14, 4); memcpy(&target_ip, packet + 20, 4); memcpy(&operation, packet + 6, 2); memset(buffer, 0, BUFFSIZE); sprintf(buffer, "%s > %s ", inet_ntoa(sender_ip), inet_ntoa(target_ip)); temp = strlen(buffer); switch(ntohs(operation)) { case 1: sprintf(buffer+temp, "ARP request\n"); break; case 2: sprintf(buffer+temp, "ARP response\n"); break; case 3: sprintf(buffer+temp, "RARP request\n"); break; case 4: sprintf(buffer+temp, "RARP response\n"); break; default: sprintf(buffer+temp, "%x\n", ntohs(operation)); break; } } write(STDOUT_FILENO, buffer, strlen(buffer)); } void ip(const u_char *packet, int size) { int data_start; struct servent *serv; struct protoent *p_ent; memset(buffer, 0, BUFFSIZE); char hlen = 0; memcpy(&hlen, packet, 1); hlen = hlen & 15; hlen = hlen * 4; char char_protocol = 0; int int_protocol; memcpy(&char_protocol, packet+9, 1); int_protocol = char_protocol; /* source addr.port */ int source_ip = 0; memcpy(&source_ip, packet+12, 4); u_short source_port = 0; memcpy(&source_port, packet+hlen, 2); p_ent = getprotobynumber(int_protocol); serv = getservbyport(source_port, p_ent->p_name); memset(buffer, 0, BUFFSIZE); if(serv == 0) { sprintf(buffer, "%s:%d > ", inet_ntoa(source_ip), ntohs(source_port)); } else { sprintf(buffer, "%s:%s > ", inet_ntoa(source_ip), serv->s_name); } write(STDOUT_FILENO, buffer, strlen(buffer)); /* destination addr.port */ int dest_ip = 0; memcpy(&dest_ip, packet+16, 4); u_short dest_port = 0; memcpy(&dest_port, packet+2+hlen, 2); serv = getservbyport(dest_port, p_ent->p_name); memset(buffer, 0, BUFFSIZE); if(serv == 0) { sprintf(buffer, "%s:%d", inet_ntoa(dest_ip), ntohs(dest_port)); } else { sprintf(buffer, "%s:%s", inet_ntoa(dest_ip), serv->s_name); } write(STDOUT_FILENO, buffer, strlen(buffer)); memset(buffer, 0, BUFFSIZE); sprintf(buffer, " using %s\n", p_ent->p_name); write(STDOUT_FILENO, buffer, strlen(buffer)); if(int_protocol == 17) {//udp data_start = hlen + 8; //(orig +) ip_header + udp_header } else if(int_protocol == 6) {//tcp //get tcp header length char tcp_hlen = 0; memcpy(&tcp_hlen, packet + hlen + 12, 1); tcp_hlen = tcp_hlen >> 4; tcp_hlen = tcp_hlen & 15; data_start = hlen + tcp_hlen; } else if(int_protocol == 1) {//icmp u_short type; u_short code; memcpy(&type, packet + hlen, 2); memcpy(&code, packet + hlen + 2, 2); memset(buffer, 0, BUFFSIZE); sprintf(buffer, "type:%d code:%d", type, ntohs(code)); write(STDOUT_FILENO, buffer, strlen(buffer)); data_start = hlen + 4; } else { memset(buffer, 0, BUFFSIZE); sprintf(buffer, "protocol number:%d\n", int_protocol); write(STDOUT_FILENO, buffer, strlen(buffer)); data_start = hlen; } print_rest(data_start, size, packet); } void print_rest(int from, int to, const u_char *packet) { int i=from; int j=0; char cur_char; char *buf2 = (char *) malloc(100); short was_char = 1; memset(buffer, 0, BUFFSIZE); for(i=from; i=32 && cur_char<='~') || cur_char=='\n' || cur_char=='\t'){ if(!was_char){ *(buffer + j) = '\n'; j++; } *(buffer + j) = cur_char; was_char = 1; j++; } else{ memset(buf2, 0, 100); int cur_int = cur_char; if(was_char) { sprintf(buf2, "\n0x%x", cur_int); } else { sprintf(buf2, "%x", cur_int); } memcpy(buffer+j, buf2, strlen(buf2)); j += strlen(buf2); was_char = 0; } } write(STDOUT_FILENO, buffer, strlen(buffer)); free(buf2); } void ethernet(const u_char *packet, int size) { char *destAddr = (char *) malloc(6); char *srcAddr = (char *) malloc(6); u_short eType = 0; memcpy(destAddr, packet, 6); memcpy(srcAddr, packet+6, 6); memcpy(&eType, packet+12, 2); eType = ntohs(eType); print_ethernet_addr(srcAddr); memset(buffer, 0, BUFFSIZE); sprintf(buffer, " > "); write(STDOUT_FILENO, buffer, strlen(buffer)); print_ethernet_addr(destAddr); memset(buffer, 0, BUFFSIZE); sprintf(buffer, " using "); write(STDOUT_FILENO, buffer, strlen(buffer)); dispatch_by_ethernet_type(eType, packet+14, size-14); free(destAddr); free(srcAddr); } void print_ethernet_addr(const u_char *addr) { int i; u_char cur_val; u_char tot_val; char cur_char; memset(buffer, 0, BUFFSIZE); for(i=0; i<6; i++) { tot_val = *(addr+i); cur_val = tot_val >> 4; cur_val = cur_val & 15; if(cur_val < 10) { cur_char = cur_val + '0'; } else { cur_char = cur_val - 10 + 'A'; } *(buffer + (i*3)) = cur_char; cur_val = tot_val & 15; if(cur_val < 10) { cur_char = cur_val + '0'; } else { cur_char = cur_val - 10 + 'A'; } *(buffer + (i*3+1)) = cur_char; *(buffer + (i*3+2)) = ':'; } *(buffer + 17) = 0; write(STDOUT_FILENO, buffer, strlen(buffer)); } void dispatch_by_ethernet_type(u_short eType, const u_char *packet, int size) { memset(buffer, 0, BUFFSIZE); switch(eType) { case 512: sprintf(buffer, "PUP\n"); write(STDOUT_FILENO, buffer, strlen(buffer)); break; case 2048: sprintf(buffer, "IP\n"); write(STDOUT_FILENO, buffer, strlen(buffer)); ip(packet, size); break; case 2054: sprintf(buffer, "ARP\n"); write(STDOUT_FILENO, buffer, strlen(buffer)); arp(packet, size); break; case 32821: sprintf(buffer, "RARP\n"); write(STDOUT_FILENO, buffer, strlen(buffer)); arp(packet, size); break; case 33024: sprintf(buffer, "802.1q\n"); write(STDOUT_FILENO, buffer, strlen(buffer)); break; case 34525: sprintf(buffer, "IPv6\n"); write(STDOUT_FILENO, buffer, strlen(buffer)); break; case 34915: sprintf(buffer, "PPPOE discovery\n"); write(STDOUT_FILENO, buffer, strlen(buffer)); break; case 34916: sprintf(buffer, "PPPOE session\n"); write(STDOUT_FILENO, buffer, strlen(buffer)); ppp(packet, size); break; default: sprintf(buffer, "unknown code:%d\n", eType); write(STDOUT_FILENO, buffer, strlen(buffer)); break; } } void print_time() { static struct timeval tv; static struct timezone tz; static char *asctime(); struct tm *localtime(); gettimeofday(&tv, &tz); memset(buffer, 0, BUFFSIZE); sprintf(buffer, "%s\n", asctime(localtime(&tv.tv_sec))); write(STDOUT_FILENO, buffer, strlen(buffer)-1); } int main(int argc, char *argv[]) { pcap_t *pcapPtr; char *device = "eth0"; int snaplen = 1500;// max length of packet int promisc = 1;// change device mode to promiscuous int to_ms = 0;// read timeout in ms char *_errbuf = (char *) malloc(PCAP_ERRBUF_SIZE); char *errbuf = _errbuf; int num_packets_read; int cnt = -1;// number of packets to process before returning pcap_handler callback; u_char *_user = (u_char *) malloc(sizeof(u_char)); // for callback u_char *user = _user; memset(errbuf, 0, PCAP_ERRBUF_SIZE); memset(user, 0, sizeof(u_char)); pcapPtr = pcap_open_live(device, snaplen, promisc, to_ms, errbuf); num_packets_read = pcap_loop(pcapPtr, cnt, got_packet, user); free(_errbuf); free(_user); return 0; }