u_int sl_if_print(const struct pcap_pkthdr *h, const u_char *p) { register u_int caplen = h->caplen; register u_int length = h->len; register const struct ip *ip; if (caplen < SLIP_HDRLEN) { printf("[|slip]"); return (caplen); } length -= SLIP_HDRLEN; ip = (struct ip *)(p + SLIP_HDRLEN); if (eflag) sliplink_print(p, ip, length); switch (IP_V(ip)) { case 4: ip_print(gndo, (u_char *)ip, length); break; #ifdef INET6 case 6: ip6_print((u_char *)ip, length); break; #endif default: printf ("ip v%d", IP_V(ip)); } return (SLIP_HDRLEN); }
u_int sl_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p) { register u_int caplen = h->caplen; register u_int length = h->len; register const struct ip *ip; if (caplen < SLIP_HDRLEN || length < SLIP_HDRLEN) { ND_PRINT((ndo, "%s", tstr)); return (caplen); } length -= SLIP_HDRLEN; ip = (struct ip *)(p + SLIP_HDRLEN); if (ndo->ndo_eflag) sliplink_print(ndo, p, ip, length); switch (IP_V(ip)) { case 4: ip_print(ndo, (u_char *)ip, length); break; case 6: ip6_print(ndo, (u_char *)ip, length); break; default: ND_PRINT((ndo, "ip v%d", IP_V(ip))); } return (SLIP_HDRLEN); }
/** * Creates an addr_pair from an ip (and tcp/udp) header, swapping src and dst * if required */ void assign_addr_pair(addr_pair* ap, struct ip* iptr, int flip) { unsigned short int src_port = 0; unsigned short int dst_port = 0; /* Arrange for predictable values. */ memset(ap, '\0', sizeof(*ap)); if(IP_V(iptr) == 4) { ap->af = AF_INET; /* Does this protocol use ports? */ if(iptr->ip_p == IPPROTO_TCP || iptr->ip_p == IPPROTO_UDP) { /* We take a slight liberty here by treating UDP the same as TCP */ /* Find the TCP/UDP header */ struct tcphdr* thdr = ((void*)iptr) + IP_HL(iptr) * 4; src_port = ntohs(thdr->th_sport); dst_port = ntohs(thdr->th_dport); } if(flip == 0) { ap->src = iptr->ip_src; ap->src_port = src_port; ap->dst = iptr->ip_dst; ap->dst_port = dst_port; } else { ap->src = iptr->ip_dst; ap->src_port = dst_port; ap->dst = iptr->ip_src; ap->dst_port = src_port; } } /* IPv4 */ else if (IP_V(iptr) == 6) { /* IPv6 packet seen. */ struct ip6_hdr *ip6tr = (struct ip6_hdr *) iptr; ap->af = AF_INET6; if( (ip6tr->ip6_nxt == IPPROTO_TCP) || (ip6tr->ip6_nxt == IPPROTO_UDP) ) { struct tcphdr *thdr = ((void *) ip6tr) + 40; src_port = ntohs(thdr->th_sport); dst_port = ntohs(thdr->th_dport); } if(flip == 0) { memcpy(&ap->src6, &ip6tr->ip6_src, sizeof(ap->src6)); ap->src_port = src_port; memcpy(&ap->dst6, &ip6tr->ip6_dst, sizeof(ap->dst6)); ap->dst_port = dst_port; } else { memcpy(&ap->src6, &ip6tr->ip6_dst, sizeof(ap->src6)); ap->src_port = dst_port; memcpy(&ap->dst6, &ip6tr->ip6_src, sizeof(ap->dst6)); ap->dst_port = src_port; } } }
static void print_nfsaddr(netdissect_options *ndo, const u_char *bp, const char *s, const char *d) { const struct ip *ip; const struct ip6_hdr *ip6; char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN]; srcaddr[0] = dstaddr[0] = '\0'; switch (IP_V((const struct ip *)bp)) { case 4: ip = (const struct ip *)bp; strlcpy(srcaddr, ipaddr_string(ndo, &ip->ip_src), sizeof(srcaddr)); strlcpy(dstaddr, ipaddr_string(ndo, &ip->ip_dst), sizeof(dstaddr)); break; case 6: ip6 = (const struct ip6_hdr *)bp; strlcpy(srcaddr, ip6addr_string(ndo, &ip6->ip6_src), sizeof(srcaddr)); strlcpy(dstaddr, ip6addr_string(ndo, &ip6->ip6_dst), sizeof(dstaddr)); break; default: strlcpy(srcaddr, "?", sizeof(srcaddr)); strlcpy(dstaddr, "?", sizeof(dstaddr)); break; } ND_PRINT("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d); }
int getIpHeader (struct ip *ip_b, u_int32_t *proto, u_int16_t *id, u_int32_t *len, u_int32_t *src, u_int32_t *dst) { u_int32_t *ip = (u_int32_t *) ip_b; u_int32_t off; /* * If it's not IPv4, then we're completely lost. */ if (IP_V (ip_b) != 4) { return (-1); } /* * If this isn't fragment zero of an higher-level "packet", * then it's not something that we're interested in, so dump * it. */ off = ntohs(ip_b->ip_off); if ((off & 0x1fff) != 0) { printf("# it's a fragment (offset=%d) of %d\n", (off & 0x1fff), ntohs(ip_b->ip_len)); return (0); } *proto = ip_b->ip_p; *len = ntohs (ip_b->ip_len); *src = ntohl (ip [3]); *dst = ntohl (ip [4]); *id = ntohs (ip_b->ip_id); return (IP_HL (ip_b) * 4); }
/* * Returns 0 and puts NFSPROC_xxx in proc return and * version in vers return, or returns -1 on failure */ static int xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, u_int32_t *proc, u_int32_t *vers) { int i; struct xid_map_entry *xmep; u_int32_t xid = rp->rm_xid; struct ip *ip = (struct ip *)bp; #ifdef INET6 struct ip6_hdr *ip6 = (struct ip6_hdr *)bp; #endif int cmp; /* Start searching from where we last left off */ i = xid_map_hint; do { xmep = &xid_map[i]; cmp = 1; if (xmep->ipver != IP_V(ip) || xmep->xid != xid) goto nextitem; switch (xmep->ipver) { case 4: if (memcmp(&ip->ip_src, &xmep->server, sizeof(ip->ip_src)) != 0 || memcmp(&ip->ip_dst, &xmep->client, sizeof(ip->ip_dst)) != 0) { cmp = 0; } break; #ifdef INET6 case 6: if (memcmp(&ip6->ip6_src, &xmep->server, sizeof(ip6->ip6_src)) != 0 || memcmp(&ip6->ip6_dst, &xmep->client, sizeof(ip6->ip6_dst)) != 0) { cmp = 0; } break; #endif default: cmp = 0; break; } if (cmp) { /* match */ xid_map_hint = i; *proc = xmep->proc; *vers = xmep->vers; return 0; } nextitem: if (++i >= XIDMAPSIZE) i = 0; } while (i != xid_map_hint); /* search failed */ return (-1); }
u_char* handle_IP (u_char *args,const struct pcap_pkthdr* pkthdr,const u_char* packet) { const struct my_ip* ip; u_int length = pkthdr->len; u_int hlen,off,version; int i; int len; /* jump pass the ethernet header */ ip = (struct my_ip*)(packet + sizeof(struct ether_header)); length -= sizeof(struct ether_header); /* check to see we have a packet of valid length */ if (length < sizeof(struct my_ip)) { printf("truncated ip %d",length); return NULL; } len = ntohs(ip->ip_len); hlen = IP_HL(ip); /* header length */ version = IP_V(ip);/* ip version */ /* check version */ if(version != 4) { fprintf(stdout,"Unknown version %d\n",version); return NULL; } /* check header length */ if(hlen < 5 ) { fprintf(stdout,"bad-hlen %d \n",hlen); } /* see if we have as much packet as we should */ if(length < len) printf("\ntruncated IP - %d bytes missing\n",len - length); /* Check to see if we have the first fragment */ off = ntohs(ip->ip_off); if((off & 0x1fff) == 0 )/* aka no 1's in first 13 bits */ {/* print SOURCE DESTINATION hlen version len offset */ fprintf(stdout,"IP: "); fprintf(stdout,"%s ", inet_ntoa(ip->ip_src)); fprintf(stdout,"%s %d %d %d %d\n", inet_ntoa(ip->ip_dst), hlen,version,len,off); } return NULL; }
void prepare_raw(packetinfo *pi) { pi->eth_hlen = 0; if (IP_V((ip4_header *)pi->packet) == 4) { pi->eth_type = ETHERNET_TYPE_IP; } else { pi->eth_type = ETHERNET_TYPE_IPV6; } }
void prepare_sll(packetinfo *pi) { pi->eth_hlen = SLL_HDR_LEN; if (IP_V((ip4_header *)(pi->packet + SLL_HDR_LEN)) == 4) { pi->eth_type = ETHERNET_TYPE_IP; } else { pi->eth_type = ETHERNET_TYPE_IPV6; } }
void parse_http_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pkt) { char *header_line, *req_value; int is_request = 0, is_response = 0; const struct ip_header *ip; const struct tcp_header *tcp; const char *data; int ip_headlen, tcp_headlen, data_len, family; ip = (struct ip_header *) (pkt + link_header_offset); switch (IP_V(ip)) { case 4: family = AF_INET; break; default: return; } ip_headlen = IP_HL(ip) * 4; if (ip_headlen < 20) return; if (ip->ip_p != IPPROTO_TCP) return; tcp = (struct tcp_header *) ((char *)ip + ip_headlen); tcp_headlen = TH_OFF(tcp) * 4; if (tcp_headlen< 20) return; data = (char *)tcp + tcp_headlen; data_len = (header->caplen - (link_header_offset + ip_headlen + tcp_headlen)); if (data_len <= 0) return; if (have_request_method(data)) { is_request = 1; } else if (strncmp(data, "HTTP/", strlen("HTTP/")) == 0) { is_response = 1; } else { return; } if (data_len > BUFSIZ) data_len = BUFSIZ; memcpy(buf, data, data_len); buf[data_len-1] = '\0'; if (is_request) { char *p = strchr(buf, '?'); if(p) *p = '\0'; debug_ascii(buf, data_len, "TEST" ); } else if (is_response) { } return; }
static int xid_map_enter(netdissect_options *ndo, const struct sunrpc_msg *rp, const u_char *bp) { struct ip *ip = NULL; #ifdef INET6 struct ip6_hdr *ip6 = NULL; #endif struct xid_map_entry *xmep; if (!ND_TTEST(rp->rm_call.cb_vers)) return (0); switch (IP_V((struct ip *)bp)) { case 4: ip = (struct ip *)bp; break; #ifdef INET6 case 6: ip6 = (struct ip6_hdr *)bp; break; #endif default: return (1); } xmep = &xid_map[xid_map_next]; if (++xid_map_next >= XIDMAPSIZE) xid_map_next = 0; UNALIGNED_MEMCPY(&xmep->xid, &rp->rm_xid, sizeof(xmep->xid)); if (ip) { xmep->ipver = 4; UNALIGNED_MEMCPY(&xmep->client, &ip->ip_src, sizeof(ip->ip_src)); UNALIGNED_MEMCPY(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst)); } #ifdef INET6 else if (ip6) { xmep->ipver = 6; UNALIGNED_MEMCPY(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src)); UNALIGNED_MEMCPY(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); } #endif xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers); return (1); }
static void xid_map_enter(const struct sunrpc_msg *rp, const u_char *bp) { struct ip *ip = NULL; #ifdef INET6 struct ip6_hdr *ip6 = NULL; #endif struct xid_map_entry *xmep; switch (IP_V((struct ip *)bp)) { case 4: ip = (struct ip *)bp; break; #ifdef INET6 case 6: ip6 = (struct ip6_hdr *)bp; break; #endif default: return; } xmep = &xid_map[xid_map_next]; if (++xid_map_next >= XIDMAPSIZE) xid_map_next = 0; xmep->xid = rp->rm_xid; if (ip) { xmep->ipver = 4; memcpy(&xmep->client, &ip->ip_src, sizeof(ip->ip_src)); memcpy(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst)); } #ifdef INET6 else if (ip6) { xmep->ipver = 6; memcpy(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src)); memcpy(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); } #endif xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc); xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers); }
static int reaper_rtcp_format(const struct ip *ip, int sport, int dport, const char* data, int len) { char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char *buffer = reaper_packet_buffer_rtcp; #ifdef INET6 if (IP_V(ip) == 6) { const struct ip6_hdr *ip6; ip6 = (const struct ip6_hdr *)ip; buffer += sprintf(reaper_packet_buffer_rtcp, FORMAT, reaper_source_mac, ip6addr_string(&ip6->ip6_src), udpport_string(sport), reaper_destination_mac, ip6addr_string(&ip6->ip6_dst), udpport_string(dport)); } else { #endif /*INET6*/ buffer += sprintf(reaper_packet_buffer_rtcp, FORMAT, reaper_source_mac, ipaddr_string(&ip->ip_src), udpport_string(sport), reaper_destination_mac, ipaddr_string(&ip->ip_dst), udpport_string(dport)); #ifdef INET6 } #endif /*INET6*/ fprintf(stderr, "Sending RTCP packet <%s>\n", reaper_packet_buffer_rtcp); char *end_buffer = reaper_packet_buffer_rtcp + sizeof(reaper_packet_buffer_rtcp) - 3; const char *end_data = data + len; while (data < end_data) { *(buffer++) = hex[((*data >> 4) & 0xF)]; *(buffer++) = hex[(*data & 0xF)]; if (buffer >= end_buffer) break; ++data; } *(buffer++) = '\n'; *(buffer) = '\0'; return (buffer - reaper_packet_buffer_rtcp); }
uint16_t handle_IP (u_char *args,const struct pcap_pkthdr* hdr, const u_char *packet){ const struct my_ip *ip; u_int length =hdr->len; u_int hlen, off, version; int len; ip =(struct my_ip*)(packet+sizeof(struct ether_header)); length-=sizeof(struct ether_header); // if IP hdr is smaller than the normal if(length < sizeof(struct my_ip)){ printf("truncated ip %d",length); return -1; } len =ntohs(ip->ip_len); hlen =IP_HL(ip); version =IP_V(ip); if(version != 4){ printf("Unknown version\n"); return -1; } if(hlen < 5){ printf("error in IHL\n"); return -1; } if(length < len) printf("\ntruncated IP - %d bytes missing\n", len-length); off =ntohs(ip->ip_off); printf("IP: "); printf("%s ",inet_ntoa(ip->ip_src)); printf("%s %d %d %d %d\n",inet_ntoa(ip->ip_dst),hlen,version, len,off); return (uint16_t)ip->ip_p; }
static void print_nfsaddr(netdissect_options *ndo, const u_char *bp, const char *s, const char *d) { struct ip *ip; #ifdef INET6 struct ip6_hdr *ip6; char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN]; #else #ifndef INET_ADDRSTRLEN #define INET_ADDRSTRLEN 16 #endif char srcaddr[INET_ADDRSTRLEN], dstaddr[INET_ADDRSTRLEN]; #endif srcaddr[0] = dstaddr[0] = '\0'; switch (IP_V((struct ip *)bp)) { case 4: ip = (struct ip *)bp; strlcpy(srcaddr, ipaddr_string(ndo, &ip->ip_src), sizeof(srcaddr)); strlcpy(dstaddr, ipaddr_string(ndo, &ip->ip_dst), sizeof(dstaddr)); break; #ifdef INET6 case 6: ip6 = (struct ip6_hdr *)bp; strlcpy(srcaddr, ip6addr_string(ndo, &ip6->ip6_src), sizeof(srcaddr)); strlcpy(dstaddr, ip6addr_string(ndo, &ip6->ip6_dst), sizeof(dstaddr)); break; #endif default: strlcpy(srcaddr, "?", sizeof(srcaddr)); strlcpy(dstaddr, "?", sizeof(dstaddr)); break; } ND_PRINT((ndo, "%s.%s > %s.%s: ", srcaddr, s, dstaddr, d)); }
static int reaper_rtp_format(const struct ip *ip, int sport, int dport, const char* data, int len) { if (reaper_packet_pointer == NULL) reaper_packet_pointer = reaper_packet_buffer; char *buffer = reaper_packet_pointer; #ifdef INET6 if (IP_V(ip) == 6) { const struct ip6_hdr *ip6; ip6 = (const struct ip6_hdr *)ip; buffer += sprintf(buffer, FORMAT, reaper_source_mac, ip6addr_string(&ip6->ip6_src), udpport_string(sport), reaper_destination_mac, ip6addr_string(&ip6->ip6_dst), udpport_string(dport)); } else { #endif /*INET6*/ buffer += sprintf(buffer, FORMAT, reaper_source_mac, ipaddr_string(&ip->ip_src), udpport_string(sport), reaper_destination_mac, ipaddr_string(&ip->ip_dst), udpport_string(dport)); #ifdef INET6 } #endif /*INET6*/ short sequenceNumber = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF); int timeStamp = ((data[4] & 0xFF) << 24) | ((data[5] & 0xFF) << 16) | ((data[6] & 0xFF) << 8) | (data[7] & 0xFF); buffer += sprintf(buffer, "%d;%d;%d", sequenceNumber, timeStamp, reaper_time_stamp()); *(buffer++) = '\n'; *(buffer) = '\0'; reaper_packet_pointer = buffer; return (buffer - reaper_packet_buffer); }
int mpac_print_ipheader(sniff_cntx* context){ printf("\n\n---------IP Header Starts----\n\n"); printf("Version : %d \n", IP_V(context->ipHeader)); printf("Header length : %d \n", context->ipHeaderSize); printf("Type of service : %d \n", context->ipHeader->ip_tos); printf("Datagram length : %d \n", context->ipHeader->ip_len); printf("Identication no. : %d \n", context->ipHeader->ip_id); printf("Offset : %d \n", IP_OFF(context->ipHeader)); printf("Reserved fragment bit : %d \n", RF(context->ipHeader)); printf("Dont fragment bit : %d \n", DF(context->ipHeader)); printf("More fragment bit : %d \n", MF(context->ipHeader)); printf("Time to live : %d \n", context->ipHeader->ip_ttl); printf("Protocol : %d \n", context->ipHeader->ip_p); printf("Checksum : %d \n", context->ipHeader->ip_sum); printf("Source IP : %s\n",inet_ntoa(context->ipHeader->ip_src)); printf("Destination IP : %s\n",inet_ntoa(context->ipHeader->ip_dst)); printf("\n\n---------IP Header Ends----\n\n"); return 0; }
void printIP(const struct ip* ip, int verbosite) { char *aux = inet_ntoa(ip->ip_src); char *ab = strcpy(malloc(strlen(aux)+1), aux); char *bux = inet_ntoa(ip->ip_dst); char *cd = strcpy(malloc(strlen(aux)+1), bux); printf("**********IP**********\n"); printf("From IP: %s\nTo: %s\n",ab,cd); if(verbosite>1) { printf("Version: %d\n", IP_V(ip)); printf("Length: %d\n", ip->ip_len); printf("Type de service : %d\n", ip->ip_tos); printf("Identification : %d\n", ip->ip_id); if(verbosite>2) { printf("Fragment offset: %d\n", ip->ip_off); printf("Time to live: %d\n", ip->ip_ttl); printf("Checksum: %d\n", ip->ip_sum); printPacket((u_char *) ip, sizeof(struct ip)); } } printf("\n"); }
void tcp_print(netdissect_options *ndo, register const u_char *bp, register u_int length, register const u_char *bp2, int fragmented) { register const struct tcphdr *tp; register const struct ip *ip; register u_char flags; register u_int hlen; register char ch; uint16_t sport, dport, win, urp; uint32_t seq, ack, thseq, thack; u_int utoval; uint16_t magic; register int rev; #ifdef INET6 register const struct ip6_hdr *ip6; #endif tp = (const struct tcphdr *)bp; ip = (const struct ip *)bp2; #ifdef INET6 if (IP_V(ip) == 6) ip6 = (const struct ip6_hdr *)bp2; else ip6 = NULL; #endif /*INET6*/ ch = '\0'; if (!ND_TTEST(tp->th_dport)) { ND_PRINT((ndo, "%s > %s: [|tcp]", ipaddr_string(ndo, &ip->ip_src), ipaddr_string(ndo, &ip->ip_dst))); return; } sport = EXTRACT_16BITS(&tp->th_sport); dport = EXTRACT_16BITS(&tp->th_dport); hlen = TH_OFF(tp) * 4; #ifdef INET6 if (ip6) { if (ip6->ip6_nxt == IPPROTO_TCP) { ND_PRINT((ndo, "%s.%s > %s.%s: ", ip6addr_string(ndo, &ip6->ip6_src), tcpport_string(ndo, sport), ip6addr_string(ndo, &ip6->ip6_dst), tcpport_string(ndo, dport))); } else { ND_PRINT((ndo, "%s > %s: ", tcpport_string(ndo, sport), tcpport_string(ndo, dport))); } } else #endif /*INET6*/ { if (ip->ip_p == IPPROTO_TCP) { ND_PRINT((ndo, "%s.%s > %s.%s: ", ipaddr_string(ndo, &ip->ip_src), tcpport_string(ndo, sport), ipaddr_string(ndo, &ip->ip_dst), tcpport_string(ndo, dport))); } else { ND_PRINT((ndo, "%s > %s: ", tcpport_string(ndo, sport), tcpport_string(ndo, dport))); } } if (hlen < sizeof(*tp)) { ND_PRINT((ndo, " tcp %d [bad hdr length %u - too short, < %lu]", length - hlen, hlen, (unsigned long)sizeof(*tp))); return; } ND_TCHECK(*tp); seq = EXTRACT_32BITS(&tp->th_seq); ack = EXTRACT_32BITS(&tp->th_ack); win = EXTRACT_16BITS(&tp->th_win); urp = EXTRACT_16BITS(&tp->th_urp); if (ndo->ndo_qflag) { ND_PRINT((ndo, "tcp %d", length - hlen)); if (hlen > length) { ND_PRINT((ndo, " [bad hdr length %u - too long, > %u]", hlen, length)); } return; } flags = tp->th_flags; ND_PRINT((ndo, "Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags))); if (!ndo->ndo_Sflag && (flags & TH_ACK)) { /* * Find (or record) the initial sequence numbers for * this conversation. (we pick an arbitrary * collating order so there's only one entry for * both directions). */ rev = 0; #ifdef INET6 if (ip6) { register struct tcp_seq_hash6 *th; struct tcp_seq_hash6 *tcp_seq_hash; const struct in6_addr *src, *dst; struct tha6 tha; tcp_seq_hash = tcp_seq_hash6; src = &ip6->ip6_src; dst = &ip6->ip6_dst; if (sport > dport) rev = 1; else if (sport == dport) { if (UNALIGNED_MEMCMP(src, dst, sizeof ip6->ip6_dst) > 0) rev = 1; } if (rev) { UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip6->ip6_dst); UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip6->ip6_src); tha.port = dport << 16 | sport; } else { UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip6->ip6_dst); UNALIGNED_MEMCPY(&tha.src, src, sizeof ip6->ip6_src); tha.port = sport << 16 | dport; } for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; th->nxt; th = th->nxt) if (memcmp((char *)&tha, (char *)&th->addr, sizeof(th->addr)) == 0) break; if (!th->nxt || (flags & TH_SYN)) { /* didn't find it or new conversation */ if (th->nxt == NULL) { th->nxt = (struct tcp_seq_hash6 *) calloc(1, sizeof(*th)); if (th->nxt == NULL) (*ndo->ndo_error)(ndo, "tcp_print: calloc"); } th->addr = tha; if (rev) th->ack = seq, th->seq = ack - 1; else th->seq = seq, th->ack = ack - 1; } else { if (rev) seq -= th->ack, ack -= th->seq; else seq -= th->seq, ack -= th->ack; } thseq = th->seq; thack = th->ack; } else { #else /*INET6*/ { #endif /*INET6*/ register struct tcp_seq_hash *th; struct tcp_seq_hash *tcp_seq_hash; const struct in_addr *src, *dst; struct tha tha; tcp_seq_hash = tcp_seq_hash4; src = &ip->ip_src; dst = &ip->ip_dst; if (sport > dport) rev = 1; else if (sport == dport) { if (UNALIGNED_MEMCMP(src, dst, sizeof ip->ip_dst) > 0) rev = 1; } if (rev) { UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip->ip_dst); UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip->ip_src); tha.port = dport << 16 | sport; } else { UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip->ip_dst); UNALIGNED_MEMCPY(&tha.src, src, sizeof ip->ip_src); tha.port = sport << 16 | dport; } for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE]; th->nxt; th = th->nxt) if (memcmp((char *)&tha, (char *)&th->addr, sizeof(th->addr)) == 0) break; if (!th->nxt || (flags & TH_SYN)) { /* didn't find it or new conversation */ if (th->nxt == NULL) { th->nxt = (struct tcp_seq_hash *) calloc(1, sizeof(*th)); if (th->nxt == NULL) (*ndo->ndo_error)(ndo, "tcp_print: calloc"); } th->addr = tha; if (rev) th->ack = seq, th->seq = ack - 1; else th->seq = seq, th->ack = ack - 1; } else { if (rev) seq -= th->ack, ack -= th->seq; else seq -= th->seq, ack -= th->ack; } thseq = th->seq; thack = th->ack; } } else {
void sunrpcrequest_print(netdissect_options *ndo, register const u_char *bp, register u_int length, register const u_char *bp2) { register const struct sunrpc_msg *rp; register const struct ip *ip; #ifdef INET6 register const struct ip6_hdr *ip6; #endif u_int32_t x; char srcid[20], dstid[20]; /*fits 32bit*/ rp = (struct sunrpc_msg *)bp; if (!ndo->ndo_nflag) { snprintf(srcid, sizeof(srcid), "0x%x", EXTRACT_32BITS(&rp->rm_xid)); strlcpy(dstid, "sunrpc", sizeof(dstid)); } else { snprintf(srcid, sizeof(srcid), "0x%x", EXTRACT_32BITS(&rp->rm_xid)); snprintf(dstid, sizeof(dstid), "0x%x", SUNRPC_PMAPPORT); } switch (IP_V((struct ip *)bp2)) { case 4: ip = (struct ip *)bp2; ND_PRINT((ndo, "%s.%s > %s.%s: %d", ipaddr_string(&ip->ip_src), srcid, ipaddr_string(&ip->ip_dst), dstid, length)); break; #ifdef INET6 case 6: ip6 = (struct ip6_hdr *)bp2; ND_PRINT((ndo, "%s.%s > %s.%s: %d", ip6addr_string(&ip6->ip6_src), srcid, ip6addr_string(&ip6->ip6_dst), dstid, length)); break; #endif default: ND_PRINT((ndo, "%s.%s > %s.%s: %d", "?", srcid, "?", dstid, length)); break; } ND_PRINT((ndo, " %s", tok2str(proc2str, " proc #%u", EXTRACT_32BITS(&rp->rm_call.cb_proc)))); x = EXTRACT_32BITS(&rp->rm_call.cb_rpcvers); if (x != 2) ND_PRINT((ndo, " [rpcver %u]", x)); switch (EXTRACT_32BITS(&rp->rm_call.cb_proc)) { case SUNRPC_PMAPPROC_SET: case SUNRPC_PMAPPROC_UNSET: case SUNRPC_PMAPPROC_GETPORT: case SUNRPC_PMAPPROC_CALLIT: x = EXTRACT_32BITS(&rp->rm_call.cb_prog); if (!ndo->ndo_nflag) ND_PRINT((ndo, " %s", progstr(x))); else ND_PRINT((ndo, " %u", x)); ND_PRINT((ndo, ".%u", EXTRACT_32BITS(&rp->rm_call.cb_vers))); break; } }
void my_pcap_handler (uint8_t *user, const struct pcap_pkthdr *header, const uint8_t *packet) { #if !__NO_ETHERNET__ struct ether_header *ether; #endif struct my_iphdr *ip; struct my_tcphdr *tcp; struct udphdr *udp; #if __DEBUG__ uint16_t src_port; #endif uint16_t dst_port; #if !__NO_ETHERNET__ /* Process ethernet header */ assert(header->caplen >= SIZE_ETHERNET); ether = (struct ether_header *) packet; if (unlikely(ether->ether_type != h16ton16(ETHERTYPE_IP))) { #if __DEBUG__ fprintf(stderr, "WARNING: ether->ether_type != ETHERTYPE_IP. Ignoring.\n"); #endif return; } #endif /* Process IP header */ assert(header->caplen >= SIZE_ETHERNET + MIN_SIZE_IP); ip = (struct my_iphdr *) (packet + SIZE_ETHERNET); if (unlikely(IP_V(ip) != IPVERSION)) { #if __DEBUG__ fprintf(stderr, "WARNING: IP_V(ip) != 4. Ignoring.\n"); #endif return; } switch(ip->protocol) { case IPPROTO_TCP: { /* Process TCP header */ assert(header->caplen >= SIZE_ETHERNET + (IP_HL(ip) * sizeof(uint32_t)) + MIN_SIZE_TCP); tcp = (struct my_tcphdr *) (packet + SIZE_ETHERNET + (IP_HL(ip) * sizeof(uint32_t))); #if __DEBUG__ src_port = tcp->source; #endif dst_port = tcp->dest; } break; case IPPROTO_UDP: { /* Process UDP header */ assert(header->caplen >= SIZE_ETHERNET + (IP_HL(ip) * sizeof(uint32_t)) + MIN_SIZE_UDP); udp = (struct udphdr *) (packet + SIZE_ETHERNET + (IP_HL(ip) * sizeof(uint32_t))); #if __DEBUG__ src_port = udp->source; #endif dst_port = udp->dest; } break; default: #if __DEBUG__ src_port = 0; #endif dst_port = 0; break; } #if __DEBUG__ /* Save to dump file. We do this after we transmit to the dispatcher so * that the dump reflects only packets that were sucessfuly transmitted. */ pcap_dump((u_char *)pcap_dumper_handle, header, packet); #endif #if __DEBUG__ fprintf(stdout, "%u.%u.%u.%u:%u -> %u.%u.%u.%u:[%u]\n", *(((uint8_t *)&(ip->saddr)) + 0), *(((uint8_t *)&(ip->saddr)) + 1), *(((uint8_t *)&(ip->saddr)) + 2), *(((uint8_t *)&(ip->saddr)) + 3), n16toh16(src_port), *(((uint8_t *)&(ip->daddr)) + 0), *(((uint8_t *)&(ip->daddr)) + 1), *(((uint8_t *)&(ip->daddr)) + 2), *(((uint8_t *)&(ip->daddr)) + 3), n16toh16(dst_port)); #endif /* If one counter is about to overflow, reset them all */ if (unlikely(flow_counts[dst_port] == UINT_MAX)) { memset(flow_counts, 0, sizeof(flow_counts)); } /* Increase flow count for this destination port */ flow_counts[dst_port] += 1; }
/** * dccp_print - show dccp packet * @bp - beginning of dccp packet * @data2 - beginning of enclosing * @len - lenght of ip packet */ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, u_int len) { const struct dccp_hdr *dh; const struct ip *ip; #ifdef INET6 const struct ip6_hdr *ip6; #endif const u_char *cp; u_short sport, dport; u_int hlen; u_int fixed_hdrlen; dh = (const struct dccp_hdr *)bp; ip = (struct ip *)data2; #ifdef INET6 if (IP_V(ip) == 6) ip6 = (const struct ip6_hdr *)data2; else ip6 = NULL; #endif /*INET6*/ /* make sure we have enough data to look at the X bit */ cp = (const u_char *)(dh + 1); if (cp > ndo->ndo_snapend) { ND_PRINT((ndo, "[Invalid packet|dccp]")); return; } if (len < sizeof(struct dccp_hdr)) { ND_PRINT((ndo, "truncated-dccp - %u bytes missing!", len - (u_int)sizeof(struct dccp_hdr))); return; } /* get the length of the generic header */ fixed_hdrlen = dccp_basic_hdr_len(dh); if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp - %u bytes missing!", len - fixed_hdrlen)); return; } ND_TCHECK2(*dh, fixed_hdrlen); sport = EXTRACT_16BITS(&dh->dccph_sport); dport = EXTRACT_16BITS(&dh->dccph_dport); hlen = dh->dccph_doff * 4; #ifdef INET6 if (ip6) { ND_PRINT((ndo, "%s.%d > %s.%d: ", ip6addr_string(ndo, &ip6->ip6_src), sport, ip6addr_string(ndo, &ip6->ip6_dst), dport)); } else #endif /*INET6*/ { ND_PRINT((ndo, "%s.%d > %s.%d: ", ipaddr_string(ndo, &ip->ip_src), sport, ipaddr_string(ndo, &ip->ip_dst), dport)); } if (ndo->ndo_qflag) { ND_PRINT((ndo, " %d", len - hlen)); if (hlen > len) { ND_PRINT((ndo, "dccp [bad hdr length %u - too long, > %u]", hlen, len)); } return; } /* other variables in generic header */ if (ndo->ndo_vflag) { ND_PRINT((ndo, "CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh))); } /* checksum calculation */ if (ndo->ndo_vflag && ND_TTEST2(bp[0], len)) { u_int16_t sum = 0, dccp_sum; dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum); ND_PRINT((ndo, "cksum 0x%04x ", dccp_sum)); if (IP_V(ip) == 4) sum = dccp_cksum(ndo, ip, dh, len); #ifdef INET6 else if (IP_V(ip) == 6) sum = dccp6_cksum(ip6, dh, len); #endif if (sum != 0) ND_PRINT((ndo, "(incorrect -> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum))); else ND_PRINT((ndo, "(correct), ")); } switch (DCCPH_TYPE(dh)) { case DCCP_PKT_REQUEST: { struct dccp_hdr_request *dhr = (struct dccp_hdr_request *)(bp + fixed_hdrlen); fixed_hdrlen += 4; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp request - %u bytes missing!", len - fixed_hdrlen)); return; } ND_TCHECK(*dhr); ND_PRINT((ndo, "request (service=%d) ", EXTRACT_32BITS(&dhr->dccph_req_service))); break; } case DCCP_PKT_RESPONSE: { struct dccp_hdr_response *dhr = (struct dccp_hdr_response *)(bp + fixed_hdrlen); fixed_hdrlen += 12; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp response - %u bytes missing!", len - fixed_hdrlen)); return; } ND_TCHECK(*dhr); ND_PRINT((ndo, "response (service=%d) ", EXTRACT_32BITS(&dhr->dccph_resp_service))); break; } case DCCP_PKT_DATA: ND_PRINT((ndo, "data ")); break; case DCCP_PKT_ACK: { fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp ack - %u bytes missing!", len - fixed_hdrlen)); return; } ND_PRINT((ndo, "ack ")); break; } case DCCP_PKT_DATAACK: { fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp dataack - %u bytes missing!", len - fixed_hdrlen)); return; } ND_PRINT((ndo, "dataack ")); break; } case DCCP_PKT_CLOSEREQ: fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp closereq - %u bytes missing!", len - fixed_hdrlen)); return; } ND_PRINT((ndo, "closereq ")); break; case DCCP_PKT_CLOSE: fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp close - %u bytes missing!", len - fixed_hdrlen)); return; } ND_PRINT((ndo, "close ")); break; case DCCP_PKT_RESET: { struct dccp_hdr_reset *dhr = (struct dccp_hdr_reset *)(bp + fixed_hdrlen); fixed_hdrlen += 12; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp reset - %u bytes missing!", len - fixed_hdrlen)); return; } ND_TCHECK(*dhr); ND_PRINT((ndo, "reset (code=%s) ", dccp_reset_code(dhr->dccph_reset_code))); break; } case DCCP_PKT_SYNC: fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp sync - %u bytes missing!", len - fixed_hdrlen)); return; } ND_PRINT((ndo, "sync ")); break; case DCCP_PKT_SYNCACK: fixed_hdrlen += 8; if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp syncack - %u bytes missing!", len - fixed_hdrlen)); return; } ND_PRINT((ndo, "syncack ")); break; default: ND_PRINT((ndo, "invalid ")); break; } if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) && (DCCPH_TYPE(dh) != DCCP_PKT_REQUEST)) dccp_print_ack_no(ndo, bp); if (ndo->ndo_vflag < 2) return; ND_PRINT((ndo, "seq %" PRIu64, dccp_seqno(bp))); /* process options */ if (hlen > fixed_hdrlen){ const u_char *cp; u_int optlen; cp = bp + fixed_hdrlen; ND_PRINT((ndo, " <")); hlen -= fixed_hdrlen; while(1){ optlen = dccp_print_option(ndo, cp, hlen); if (!optlen) break; if (hlen <= optlen) break; hlen -= optlen; cp += optlen; ND_PRINT((ndo, ", ")); } ND_PRINT((ndo, ">")); } return; trunc: ND_PRINT((ndo, "%s", tstr)); return; }
static int cookie_sidecheck(int i, const u_char *bp2, int initiator) { struct sockaddr_storage ss; struct sockaddr *sa; struct ip *ip; struct sockaddr_in *sin; #ifdef INET6 struct ip6_hdr *ip6; struct sockaddr_in6 *sin6; #endif int salen; memset(&ss, 0, sizeof(ss)); ip = (struct ip *)bp2; switch (IP_V(ip)) { case 4: sin = (struct sockaddr_in *)&ss; #ifdef HAVE_SOCKADDR_SA_LEN sin->sin_len = sizeof(struct sockaddr_in); #endif sin->sin_family = AF_INET; memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); break; #ifdef INET6 case 6: ip6 = (struct ip6_hdr *)bp2; sin6 = (struct sockaddr_in6 *)&ss; #ifdef HAVE_SOCKADDR_SA_LEN sin6->sin6_len = sizeof(struct sockaddr_in6); #endif sin6->sin6_family = AF_INET6; memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); break; #endif default: return 0; } sa = (struct sockaddr *)&ss; if (initiator) { if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family) return 0; #ifdef HAVE_SOCKADDR_SA_LEN salen = sa->sa_len; #else #ifdef INET6 if (sa->sa_family == AF_INET6) salen = sizeof(struct sockaddr_in6); else salen = sizeof(struct sockaddr); #else salen = sizeof(struct sockaddr); #endif #endif if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0) return 1; } else { if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family) return 0; #ifdef HAVE_SOCKADDR_SA_LEN salen = sa->sa_len; #else #ifdef INET6 if (sa->sa_family == AF_INET6) salen = sizeof(struct sockaddr_in6); else salen = sizeof(struct sockaddr); #else salen = sizeof(struct sockaddr); #endif #endif if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0) return 1; } return 0; }
void pgm_print(register const u_char *bp, register u_int length, register const u_char *bp2) { register const struct pgm_header *pgm; register const struct ip *ip; register char ch; u_int16_t sport, dport; int addr_size; const void *nla; int nla_af; #ifdef INET6 char nla_buf[INET6_ADDRSTRLEN]; register const struct ip6_hdr *ip6; #else char nla_buf[INET_ADDRSTRLEN]; #endif u_int8_t opt_type, opt_len, flags1, flags2; u_int32_t seq, opts_len, len, offset; pgm = (struct pgm_header *)bp; ip = (struct ip *)bp2; #ifdef INET6 if (IP_V(ip) == 6) ip6 = (struct ip6_hdr *)bp2; else ip6 = NULL; #else /* INET6 */ if (IP_V(ip) == 6) { (void)printf("Can't handle IPv6"); return; } #endif /* INET6 */ ch = '\0'; if (!TTEST(pgm->pgm_dport)) { #ifdef INET6 if (ip6) { (void)printf("%s > %s: [|pgm]", ip6addr_string(&ip6->ip6_src), ip6addr_string(&ip6->ip6_dst)); return; } else #endif /* INET6 */ { (void)printf("%s > %s: [|pgm]", ipaddr_string(&ip->ip_src), ipaddr_string(&ip->ip_dst)); return; } } sport = EXTRACT_16BITS(&pgm->pgm_sport); dport = EXTRACT_16BITS(&pgm->pgm_dport); #ifdef INET6 if (ip6) { if (ip6->ip6_nxt == IPPROTO_PGM) { (void)printf("%s.%s > %s.%s: ", ip6addr_string(&ip6->ip6_src), tcpport_string(sport), ip6addr_string(&ip6->ip6_dst), tcpport_string(dport)); } else { (void)printf("%s > %s: ", tcpport_string(sport), tcpport_string(dport)); } } else #endif /*INET6*/ { if (ip->ip_p == IPPROTO_PGM) { (void)printf("%s.%s > %s.%s: ", ipaddr_string(&ip->ip_src), tcpport_string(sport), ipaddr_string(&ip->ip_dst), tcpport_string(dport)); } else { (void)printf("%s > %s: ", tcpport_string(sport), tcpport_string(dport)); } } TCHECK(*pgm); (void)printf("PGM, length %u", pgm->pgm_length); if (!vflag) return; if (length > pgm->pgm_length) length = pgm->pgm_length; (void)printf(" 0x%02x%02x%02x%02x%02x%02x ", pgm->pgm_gsid[0], pgm->pgm_gsid[1], pgm->pgm_gsid[2], pgm->pgm_gsid[3], pgm->pgm_gsid[4], pgm->pgm_gsid[5]); switch (pgm->pgm_type) { case PGM_SPM: { struct pgm_spm *spm; spm = (struct pgm_spm *)(pgm + 1); TCHECK(*spm); switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) { case AFI_IP: addr_size = sizeof(struct in_addr); nla_af = AF_INET; break; #ifdef INET6 case AFI_IP6: addr_size = sizeof(struct in6_addr); nla_af = AF_INET6; break; #endif default: goto trunc; break; } bp = (u_char *) (spm + 1); TCHECK2(*bp, addr_size); nla = bp; bp += addr_size; inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); (void)printf("SPM seq %u trail %u lead %u nla %s", EXTRACT_32BITS(&spm->pgms_seq), EXTRACT_32BITS(&spm->pgms_trailseq), EXTRACT_32BITS(&spm->pgms_leadseq), nla_buf); break; } case PGM_POLL: { struct pgm_poll *poll; poll = (struct pgm_poll *)(pgm + 1); TCHECK(*poll); (void)printf("POLL seq %u round %u", EXTRACT_32BITS(&poll->pgmp_seq), EXTRACT_16BITS(&poll->pgmp_round)); bp = (u_char *) (poll + 1); break; } case PGM_POLR: { struct pgm_polr *polr; u_int32_t ivl, rnd, mask; polr = (struct pgm_polr *)(pgm + 1); TCHECK(*polr); switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) { case AFI_IP: addr_size = sizeof(struct in_addr); nla_af = AF_INET; break; #ifdef INET6 case AFI_IP6: addr_size = sizeof(struct in6_addr); nla_af = AF_INET6; break; #endif default: goto trunc; break; } bp = (u_char *) (polr + 1); TCHECK2(*bp, addr_size); nla = bp; bp += addr_size; inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); TCHECK2(*bp, sizeof(u_int32_t)); ivl = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); TCHECK2(*bp, sizeof(u_int32_t)); rnd = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); TCHECK2(*bp, sizeof(u_int32_t)); mask = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); (void)printf("POLR seq %u round %u nla %s ivl %u rnd 0x%08x " "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq), EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask); break; } case PGM_ODATA: { struct pgm_data *odata; odata = (struct pgm_data *)(pgm + 1); TCHECK(*odata); (void)printf("ODATA trail %u seq %u", EXTRACT_32BITS(&odata->pgmd_trailseq), EXTRACT_32BITS(&odata->pgmd_seq)); bp = (u_char *) (odata + 1); break; } case PGM_RDATA: { struct pgm_data *rdata; rdata = (struct pgm_data *)(pgm + 1); TCHECK(*rdata); (void)printf("RDATA trail %u seq %u", EXTRACT_32BITS(&rdata->pgmd_trailseq), EXTRACT_32BITS(&rdata->pgmd_seq)); bp = (u_char *) (rdata + 1); break; } case PGM_NAK: case PGM_NULLNAK: case PGM_NCF: { struct pgm_nak *nak; const void *source, *group; int source_af, group_af; #ifdef INET6 char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN]; #else char source_buf[INET_ADDRSTRLEN], group_buf[INET_ADDRSTRLEN]; #endif nak = (struct pgm_nak *)(pgm + 1); TCHECK(*nak); /* * Skip past the source, saving info along the way * and stopping if we don't have enough. */ switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) { case AFI_IP: addr_size = sizeof(struct in_addr); source_af = AF_INET; break; #ifdef INET6 case AFI_IP6: addr_size = sizeof(struct in6_addr); source_af = AF_INET6; break; #endif default: goto trunc; break; } bp = (u_char *) (nak + 1); TCHECK2(*bp, addr_size); source = bp; bp += addr_size; /* * Skip past the group, saving info along the way * and stopping if we don't have enough. */ switch (EXTRACT_16BITS(bp)) { case AFI_IP: addr_size = sizeof(struct in_addr); group_af = AF_INET; break; #ifdef INET6 case AFI_IP6: addr_size = sizeof(struct in6_addr); group_af = AF_INET6; break; #endif default: goto trunc; break; } bp += (2 * sizeof(u_int16_t)); TCHECK2(*bp, addr_size); group = bp; bp += addr_size; /* * Options decoding can go here. */ inet_ntop(source_af, source, source_buf, sizeof(source_buf)); inet_ntop(group_af, group, group_buf, sizeof(group_buf)); switch (pgm->pgm_type) { case PGM_NAK: (void)printf("NAK "); break; case PGM_NULLNAK: (void)printf("NNAK "); break; case PGM_NCF: (void)printf("NCF "); break; default: break; } (void)printf("(%s -> %s), seq %u", source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq)); break; } case PGM_ACK: { struct pgm_ack *ack; ack = (struct pgm_ack *)(pgm + 1); TCHECK(*ack); (void)printf("ACK seq %u", EXTRACT_32BITS(&ack->pgma_rx_max_seq)); bp = (u_char *) (ack + 1); break; } case PGM_SPMR: (void)printf("SPMR"); break; default: (void)printf("UNKNOWN type %0x02x", pgm->pgm_type); break; } if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) { /* * make sure there's enough for the first option header */ if (!TTEST2(*bp, PGM_MIN_OPT_LEN)) { (void)printf("[|OPT]"); return; } /* * That option header MUST be an OPT_LENGTH option * (see the first paragraph of section 9.1 in RFC 3208). */ opt_type = *bp++; if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) { (void)printf("[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK); return; } opt_len = *bp++; if (opt_len != 4) { (void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len); return; } opts_len = EXTRACT_16BITS(bp); if (opts_len < 4) { (void)printf("[Bad total option length %u < 4]", opts_len); return; } bp += sizeof(u_int16_t); (void)printf(" OPTS LEN %d", opts_len); opts_len -= 4; while (opts_len) { if (opts_len < PGM_MIN_OPT_LEN) { (void)printf("[Total option length leaves no room for final option]"); return; } opt_type = *bp++; opt_len = *bp++; if (opt_len < PGM_MIN_OPT_LEN) { (void)printf("[Bad option, length %u < %u]", opt_len, PGM_MIN_OPT_LEN); break; } if (opts_len < opt_len) { (void)printf("[Total option length leaves no room for final option]"); return; } if (!TTEST2(*bp, opt_len - 2)) { (void)printf(" [|OPT]"); return; } switch (opt_type & PGM_OPT_MASK) { case PGM_OPT_LENGTH: if (opt_len != 4) { (void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len); return; } (void)printf(" OPTS LEN (extra?) %d", EXTRACT_16BITS(bp)); bp += sizeof(u_int16_t); opts_len -= 4; break; case PGM_OPT_FRAGMENT: if (opt_len != 16) { (void)printf("[Bad OPT_FRAGMENT option, length %u != 16]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; seq = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); offset = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); len = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); (void)printf(" FRAG seq %u off %u len %u", seq, offset, len); opts_len -= 16; break; case PGM_OPT_NAK_LIST: flags1 = *bp++; flags2 = *bp++; opt_len -= sizeof(u_int32_t); /* option header */ (void)printf(" NAK LIST"); while (opt_len) { if (opt_len < sizeof(u_int32_t)) { (void)printf("[Option length not a multiple of 4]"); return; } TCHECK2(*bp, sizeof(u_int32_t)); (void)printf(" %u", EXTRACT_32BITS(bp)); bp += sizeof(u_int32_t); opt_len -= sizeof(u_int32_t); opts_len -= sizeof(u_int32_t); } break; case PGM_OPT_JOIN: if (opt_len != 8) { (void)printf("[Bad OPT_JOIN option, length %u != 8]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; seq = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); (void)printf(" JOIN %u", seq); opts_len -= 8; break; case PGM_OPT_NAK_BO_IVL: if (opt_len != 12) { (void)printf("[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; offset = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); seq = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); (void)printf(" BACKOFF ivl %u ivlseq %u", offset, seq); opts_len -= 12; break; case PGM_OPT_NAK_BO_RNG: if (opt_len != 12) { (void)printf("[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; offset = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); seq = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); (void)printf(" BACKOFF max %u min %u", offset, seq); opts_len -= 12; break; case PGM_OPT_REDIRECT: flags1 = *bp++; flags2 = *bp++; switch (EXTRACT_16BITS(bp)) { case AFI_IP: addr_size = sizeof(struct in_addr); nla_af = AF_INET; break; #ifdef INET6 case AFI_IP6: addr_size = sizeof(struct in6_addr); nla_af = AF_INET6; break; #endif default: goto trunc; break; } bp += (2 * sizeof(u_int16_t)); if (opt_len != 4 + addr_size) { (void)printf("[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len); return; } TCHECK2(*bp, addr_size); nla = bp; bp += addr_size; inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); (void)printf(" REDIRECT %s", (char *)nla); opts_len -= 4 + addr_size; break; case PGM_OPT_PARITY_PRM: if (opt_len != 8) { (void)printf("[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; len = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); (void)printf(" PARITY MAXTGS %u", len); opts_len -= 8; break; case PGM_OPT_PARITY_GRP: if (opt_len != 8) { (void)printf("[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; seq = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); (void)printf(" PARITY GROUP %u", seq); opts_len -= 8; break; case PGM_OPT_CURR_TGSIZE: if (opt_len != 8) { (void)printf("[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; len = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); (void)printf(" PARITY ATGS %u", len); opts_len -= 8; break; case PGM_OPT_NBR_UNREACH: if (opt_len != 4) { (void)printf("[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; (void)printf(" NBR_UNREACH"); opts_len -= 4; break; case PGM_OPT_PATH_NLA: (void)printf(" PATH_NLA [%d]", opt_len); bp += opt_len; opts_len -= opt_len; break; case PGM_OPT_SYN: if (opt_len != 4) { (void)printf("[Bad OPT_SYN option, length %u != 4]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; (void)printf(" SYN"); opts_len -= 4; break; case PGM_OPT_FIN: if (opt_len != 4) { (void)printf("[Bad OPT_FIN option, length %u != 4]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; (void)printf(" FIN"); opts_len -= 4; break; case PGM_OPT_RST: if (opt_len != 4) { (void)printf("[Bad OPT_RST option, length %u != 4]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; (void)printf(" RST"); opts_len -= 4; break; case PGM_OPT_CR: (void)printf(" CR"); bp += opt_len; opts_len -= opt_len; break; case PGM_OPT_CRQST: if (opt_len != 4) { (void)printf("[Bad OPT_CRQST option, length %u != 4]", opt_len); return; } flags1 = *bp++; flags2 = *bp++; (void)printf(" CRQST"); opts_len -= 4; break; case PGM_OPT_PGMCC_DATA: flags1 = *bp++; flags2 = *bp++; offset = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); switch (EXTRACT_16BITS(bp)) { case AFI_IP: addr_size = sizeof(struct in_addr); nla_af = AF_INET; break; #ifdef INET6 case AFI_IP6: addr_size = sizeof(struct in6_addr); nla_af = AF_INET6; break; #endif default: goto trunc; break; } bp += (2 * sizeof(u_int16_t)); if (opt_len != 12 + addr_size) { (void)printf("[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len); return; } TCHECK2(*bp, addr_size); nla = bp; bp += addr_size; inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); (void)printf(" PGMCC DATA %u %s", offset, (char*)nla); opts_len -= 16; break; case PGM_OPT_PGMCC_FEEDBACK: flags1 = *bp++; flags2 = *bp++; offset = EXTRACT_32BITS(bp); bp += sizeof(u_int32_t); switch (EXTRACT_16BITS(bp)) { case AFI_IP: addr_size = sizeof(struct in_addr); nla_af = AF_INET; break; #ifdef INET6 case AFI_IP6: addr_size = sizeof(struct in6_addr); nla_af = AF_INET6; break; #endif default: goto trunc; break; } bp += (2 * sizeof(u_int16_t)); if (opt_len != 12 + addr_size) { (void)printf("[Bad OPT_PGMCC_FEEDBACK option, length %u != 12 + address size]", opt_len); return; } TCHECK2(*bp, addr_size); nla = bp; bp += addr_size; inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf)); (void)printf(" PGMCC FEEDBACK %u %s", offset, (char*)nla); opts_len -= 16; break; default: (void)printf(" OPT_%02X [%d] ", opt_type, opt_len); bp += opt_len; opts_len -= opt_len; break; } if (opt_type & PGM_OPT_END) break; } } (void)printf(" [%u]", EXTRACT_16BITS(&pgm->pgm_length)); return; trunc: fputs("[|pgm]", stdout); if (ch != '\0') putchar('>'); }
/* Process each packet that passes the capture filter */ void parse_http_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pkt) { struct tm *pkt_time; char *header_line, *req_value; char saddr[INET6_ADDRSTRLEN], daddr[INET6_ADDRSTRLEN]; char sport[PORTSTRLEN], dport[PORTSTRLEN]; char ts[MAX_TIME_LEN]; int is_request = 0, is_response = 0; unsigned int eth_type = 0, offset; const struct eth_header *eth; const struct ip_header *ip; const struct ip6_header *ip6; const struct tcp_header *tcp; const char *data; int size_ip, size_tcp, size_data, family; /* Check the ethernet type and insert a VLAN offset if necessary */ eth = (struct eth_header *) pkt; eth_type = ntohs(eth->ether_type); if (eth_type == ETHER_TYPE_VLAN) { offset = link_offset + 4; } else { offset = link_offset; } offset += eth_skip_bits; /* Position pointers within packet stream and do sanity checks */ ip = (struct ip_header *) (pkt + offset); ip6 = (struct ip6_header *) (pkt + offset); switch (IP_V(ip)) { case 4: family = AF_INET; break; case 6: family = AF_INET6; break; default: return; } if (family == AF_INET) { size_ip = IP_HL(ip) * 4; if (size_ip < 20) return; if (ip->ip_p != IPPROTO_TCP) return; } else { /* AF_INET6 */ size_ip = sizeof(struct ip6_header); if (ip6->ip6_nh != IPPROTO_TCP) size_ip = process_ip6_nh(pkt, size_ip, header->caplen, offset); if (size_ip < 40) return; } tcp = (struct tcp_header *) (pkt + offset + size_ip); size_tcp = TH_OFF(tcp) * 4; if (size_tcp < 20) return; data = (char *) (pkt + offset + size_ip + size_tcp); size_data = (header->caplen - (offset + size_ip + size_tcp)); if (size_data <= 0) return; /* Check if we appear to have a valid request or response */ if (is_request_method(data)) { is_request = 1; } else if (strncmp(data, HTTP_STRING, strlen(HTTP_STRING)) == 0) { is_response = 1; } else { return; } /* Copy packet data to editable buffer that was created in main() */ if (size_data > BUFSIZ) size_data = BUFSIZ; memcpy(buf, data, size_data); buf[size_data] = '\0'; /* Parse header line, bail if malformed */ if ((header_line = parse_header_line(buf)) == NULL) return; if (is_request) { if (parse_client_request(header_line)) return; } else if (is_response) { if (parse_server_response(header_line)) return; } /* Iterate through request/entity header fields */ while ((header_line = parse_header_line(NULL)) != NULL) { if ((req_value = strchr(header_line, ':')) == NULL) continue; *req_value++ = '\0'; while (isspace(*req_value)) req_value++; insert_value(header_line, req_value); } /* Grab source/destination IP addresses */ if (family == AF_INET) { inet_ntop(family, &ip->ip_src, saddr, sizeof(saddr)); inet_ntop(family, &ip->ip_dst, daddr, sizeof(daddr)); } else { /* AF_INET6 */ inet_ntop(family, &ip6->ip_src, saddr, sizeof(saddr)); inet_ntop(family, &ip6->ip_dst, daddr, sizeof(daddr)); } insert_value("source-ip", saddr); insert_value("dest-ip", daddr); /* Grab source/destination ports */ snprintf(sport, PORTSTRLEN, "%d", ntohs(tcp->th_sport)); snprintf(dport, PORTSTRLEN, "%d", ntohs(tcp->th_dport)); insert_value("source-port", sport); insert_value("dest-port", dport); /* Extract packet capture time */ pkt_time = localtime((time_t *) &header->ts.tv_sec); strftime(ts, MAX_TIME_LEN, "%Y-%m-%d %H:%M:%S", pkt_time); insert_value("timestamp", ts); if (rate_stats) { update_host_stats(get_value("host"), header->ts.tv_sec); clear_values(); } else { print_format_values(); } if (dumpfile) pcap_dump((unsigned char *) dumpfile, header, pkt); num_parsed++; if (parse_count && (num_parsed >= parse_count)) pcap_breakloop(pcap_hnd); return; }
void sunrpc_print(netdissect_options *ndo, const u_char *bp, u_int length, const u_char *bp2) { const struct sunrpc_msg *rp; const struct ip *ip; const struct ip6_hdr *ip6; uint32_t x; char srcid[20], dstid[20]; /*fits 32bit*/ rp = (const struct sunrpc_msg *)bp; if (!ndo->ndo_nflag) { nd_snprintf(srcid, sizeof(srcid), "0x%x", EXTRACT_BE_U_4(rp->rm_xid)); strlcpy(dstid, "sunrpc", sizeof(dstid)); } else { nd_snprintf(srcid, sizeof(srcid), "0x%x", EXTRACT_BE_U_4(rp->rm_xid)); nd_snprintf(dstid, sizeof(dstid), "0x%x", SUNRPC_PMAPPORT); } switch (IP_V((const struct ip *)bp2)) { case 4: ip = (const struct ip *)bp2; ND_PRINT("%s.%s > %s.%s: %u", ipaddr_string(ndo, ip->ip_src), srcid, ipaddr_string(ndo, ip->ip_dst), dstid, length); break; case 6: ip6 = (const struct ip6_hdr *)bp2; ND_PRINT("%s.%s > %s.%s: %u", ip6addr_string(ndo, ip6->ip6_src), srcid, ip6addr_string(ndo, ip6->ip6_dst), dstid, length); break; default: ND_PRINT("%s.%s > %s.%s: %u", "?", srcid, "?", dstid, length); break; } ND_PRINT(" %s", tok2str(proc2str, " proc #%u", EXTRACT_BE_U_4(rp->rm_call.cb_proc))); x = EXTRACT_BE_U_4(rp->rm_call.cb_rpcvers); if (x != 2) ND_PRINT(" [rpcver %u]", x); switch (EXTRACT_BE_U_4(rp->rm_call.cb_proc)) { case SUNRPC_PMAPPROC_SET: case SUNRPC_PMAPPROC_UNSET: case SUNRPC_PMAPPROC_GETPORT: case SUNRPC_PMAPPROC_CALLIT: x = EXTRACT_BE_U_4(rp->rm_call.cb_prog); if (!ndo->ndo_nflag) ND_PRINT(" %s", progstr(x)); else ND_PRINT(" %u", x); ND_PRINT(".%u", EXTRACT_BE_U_4(rp->rm_call.cb_vers)); break; } }
void sctp_print(const u_char *bp, const u_char *bp2, u_int sctpPacketLength) { const struct sctpHeader *sctpPktHdr; const struct ip *ip; #ifdef INET6 const struct ip6_hdr *ip6; #endif const void *endPacketPtr; u_short sourcePort, destPort; int chunkCount; const struct sctpChunkDesc *chunkDescPtr; const void *nextChunk; const char *sep; sctpPktHdr = (const struct sctpHeader*) bp; endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength; if( (u_long) endPacketPtr > (u_long) snapend) endPacketPtr = (const void *) snapend; ip = (struct ip *)bp2; #ifdef INET6 if (IP_V(ip) == 6) ip6 = (const struct ip6_hdr *)bp2; else ip6 = NULL; #endif TCHECK(*sctpPktHdr); if (sctpPacketLength < sizeof(struct sctpHeader)) { (void)printf("truncated-sctp - %ld bytes missing!", (long)sctpPacketLength-sizeof(struct sctpHeader)); return; } sourcePort = EXTRACT_16BITS(&sctpPktHdr->source); destPort = EXTRACT_16BITS(&sctpPktHdr->destination); #ifdef INET6 if (ip6) { (void)printf("%s.%d > %s.%d: sctp", ip6addr_string(&ip6->ip6_src), sourcePort, ip6addr_string(&ip6->ip6_dst), destPort); } else #endif { (void)printf("%s.%d > %s.%d: sctp", ipaddr_string(&ip->ip_src), sourcePort, ipaddr_string(&ip->ip_dst), destPort); } fflush(stdout); if (vflag >= 2) sep = "\n\t"; else sep = " ("; for (chunkCount = 0, chunkDescPtr = (const struct sctpChunkDesc *) ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader)); chunkDescPtr != NULL && ( (const void *) ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc)) <= endPacketPtr); chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++) { u_int16_t chunkLength; const u_char *chunkEnd; u_int16_t align; TCHECK(*chunkDescPtr); chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength); if (chunkLength < sizeof(*chunkDescPtr)) { printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength); break; } TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength); chunkEnd = ((const u_char*)chunkDescPtr + chunkLength); align=chunkLength % 4; if (align != 0) align = 4 - align; nextChunk = (const void *) (chunkEnd + align); printf("%s%d) ", sep, chunkCount+1); switch (chunkDescPtr->chunkID) { case SCTP_DATA : { const struct sctpDataPart *dataHdrPtr; printf("[DATA] "); if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED) printf("(U)"); if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) printf("(B)"); if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) == SCTP_DATA_LAST_FRAG) printf("(E)"); if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED) == SCTP_DATA_UNORDERED) || ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) || ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG) == SCTP_DATA_LAST_FRAG) ) printf(" "); dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1); printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN)); printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId)); printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence)); printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype)); fflush(stdout); if (vflag >= 2) { const u_char *payloadPtr; printf("[Payload"); if (!suppress_default_print) { payloadPtr = (const u_char *) (++dataHdrPtr); printf(":"); if (htons(chunkDescPtr->chunkLength) < sizeof(struct sctpDataPart)+ sizeof(struct sctpChunkDesc)+1) { printf("bogus chunk length %u]", htons(chunkDescPtr->chunkLength)); return; } default_print(payloadPtr, htons(chunkDescPtr->chunkLength) - (sizeof(struct sctpDataPart)+ sizeof(struct sctpChunkDesc))); } else printf("]"); } break; } case SCTP_INITIATION : { const struct sctpInitiation *init; printf("[INIT] "); init=(const struct sctpInitiation*)(chunkDescPtr+1); printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag)); printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit)); printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams)); printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams)); printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN)); #if(0) if( (init+1) < chunkEnd ) printf(" @@@@@ UNFINISHED @@@@@@%s\n", "Optional params present, but not printed."); #endif break; } case SCTP_INITIATION_ACK : { const struct sctpInitiation *init; printf("[INIT ACK] "); init=(const struct sctpInitiation*)(chunkDescPtr+1); printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag)); printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit)); printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams)); printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams)); printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN)); #if(0) if( (init+1) < chunkEnd ) printf(" @@@@@ UNFINISHED @@@@@@%s\n", "Optional params present, but not printed."); #endif break; } case SCTP_SELECTIVE_ACK: { const struct sctpSelectiveAck *sack; const struct sctpSelectiveFrag *frag; int fragNo, tsnNo; const u_char *dupTSN; printf("[SACK] "); sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1); printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN)); printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd)); printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc)); printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns)); for (frag = ( (const struct sctpSelectiveFrag *) ((const struct sctpSelectiveAck *) sack+1)), fragNo=0; (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc); frag++, fragNo++) printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ", fragNo+1, EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart), EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd)); for (dupTSN = (const u_char *)frag, tsnNo=0; (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns); dupTSN += 4, tsnNo++) printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1, EXTRACT_32BITS(dupTSN)); break; } case SCTP_HEARTBEAT_REQUEST : { const struct sctpHBsender *hb; hb=(const struct sctpHBsender*)chunkDescPtr; printf("[HB REQ] "); break; } case SCTP_HEARTBEAT_ACK : printf("[HB ACK] "); break; case SCTP_ABORT_ASSOCIATION : printf("[ABORT] "); break; case SCTP_SHUTDOWN : printf("[SHUTDOWN] "); break; case SCTP_SHUTDOWN_ACK : printf("[SHUTDOWN ACK] "); break; case SCTP_OPERATION_ERR : printf("[OP ERR] "); break; case SCTP_COOKIE_ECHO : printf("[COOKIE ECHO] "); break; case SCTP_COOKIE_ACK : printf("[COOKIE ACK] "); break; case SCTP_ECN_ECHO : printf("[ECN ECHO] "); break; case SCTP_ECN_CWR : printf("[ECN CWR] "); break; case SCTP_SHUTDOWN_COMPLETE : printf("[SHUTDOWN COMPLETE] "); break; case SCTP_FORWARD_CUM_TSN : printf("[FOR CUM TSN] "); break; case SCTP_RELIABLE_CNTL : printf("[REL CTRL] "); break; case SCTP_RELIABLE_CNTL_ACK : printf("[REL CTRL ACK] "); break; default : printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID); return; } if (vflag < 2) sep = ", ("; } return; trunc: printf("[|sctp]"); return; }
/* * dissect/print packet */ void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { static int count = 1; /* packet counter */ /* declare pointers to packet headers */ const struct sniff_ethernet *ethernet; /* The ethernet header [1] */ const struct sniff_ip *ip; /* The IP header */ const struct sniff_tcp *tcp; /* The TCP header */ const char *payload; /* Packet payload */ int size_ip; int size_tcp; int size_payload; memcpy(&buffer,packet,sizeof(buffer)); printf("\nPacket number %d:\n", count); count++; /* define ethernet header */ ethernet = (struct sniff_ethernet*)(packet); const u_char *ptr; int i; ptr = ethernet->ether_dhost; i = ETHER_ADDR_LEN; printf(" Ethernet Header\n"); printf(" Destination Address: "); do{ printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++); }while(--i>0); printf("\n"); ptr = ethernet->ether_shost; i = ETHER_ADDR_LEN; printf(" Source Address: "); do{ printf("%s%x",(i == ETHER_ADDR_LEN) ? " " : ":",*ptr++); }while(--i>0); printf("\n"); /* define/compute ip header offset */ ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); size_ip = IP_HL(ip)*4; if (size_ip < 20) { printf(" * Invalid IP header length: %u bytes\n", size_ip); return; } #if PRINTHEADER /* print source and destination IP addresses */ printf("IP Header\n"); printf(" From: %s\n", inet_ntoa(ip->ip_src)); printf(" To: %s\n", inet_ntoa(ip->ip_dst)); printf(" Type: %d\n", IP_V(ip)); printf(" TTL : %d\n", ip->ip_ttl); printf(" CheckSum: 0x%x\n", ntohs(ip->ip_sum)); /* determine protocol */ switch(ip->ip_p) { case IPPROTO_TCP: printf(" Protocol: TCP\n"); break; case IPPROTO_UDP: printf(" Protocol: UDP\n"); return; case IPPROTO_ICMP: printf(" Protocol: ICMP\n"); return; case IPPROTO_IP: printf(" Protocol: IP\n"); return; default: printf(" Protocol: unknown\n"); return; } /*OK, this packet is TCP.*/ /* define/compute tcp header offset */ tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip); size_tcp = TH_OFF(tcp)*4; if (size_tcp < 20) { printf(" * Invalid TCP header length: %u bytes\n", size_tcp); return; } printf("TCP Header\n"); printf(" Src port: %d\n", ntohs(tcp->th_sport)); printf(" Dst port: %d\n", ntohs(tcp->th_dport)); printf(" Sequence: %u\n", tcp->th_seq); printf(" Ack : %u\n",tcp->th_ack); printf(" DataOff : 0x%x\n", tcp->th_offx2); printf(" Urgt Ptr: 0x%x\n", ntohs(tcp->th_urp)); printf(" Window : 0x%x\n", ntohs(tcp->th_win)); printf(" ChkSm : 0x%x\n", ntohs(tcp->th_sum)); /* define/compute tcp payload (segment) offset */ payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp); /* compute tcp payload (segment) size */ size_payload = ntohs(ip->ip_len) - (size_ip + size_tcp); /* * Print payload data; it might be binary, so don't just * treat it as a string. */ if (size_payload > 0) { printf(" Payload (%d bytes):\n", size_payload); print_payload(payload, size_payload); } else { printf(" Payload not printed\n"); } #endif return; }
static void handle_ip_packet(struct ip* iptr, int hw_dir) { int direction = 0; /* incoming */ history_type* ht; union { history_type **ht_pp; void **void_pp; } u_ht = { &ht }; addr_pair ap; unsigned int len = 0; struct in6_addr scribdst; /* Scratch pad. */ struct in6_addr scribsrc; /* Scratch pad. */ /* Reinterpret packet type. */ struct ip6_hdr* ip6tr = (struct ip6_hdr *) iptr; memset(&ap, '\0', sizeof(ap)); if( (IP_V(iptr) ==4 && options.netfilter == 0) || (IP_V(iptr) == 6 && options.netfilter6 == 0) ) { /* * Net filter is off, so assign direction based on MAC address */ if(hw_dir == 1) { /* Packet leaving this interface. */ assign_addr_pair(&ap, iptr, 0); direction = 1; } else if(hw_dir == 0) { /* Packet incoming */ assign_addr_pair(&ap, iptr, 1); direction = 0; } /* Packet direction is not given away by h/ware layer. Try IP * layer */ else if((IP_V(iptr) == 4) && have_ip_addr && ip_addr_match(iptr->ip_src)) { /* outgoing */ assign_addr_pair(&ap, iptr, 0); direction = 1; } else if((IP_V(iptr) == 4) && have_ip_addr && ip_addr_match(iptr->ip_dst)) { /* incoming */ assign_addr_pair(&ap, iptr, 1); direction = 0; } else if((IP_V(iptr) == 6) && have_ip6_addr && ip6_addr_match(&ip6tr->ip6_src)) { /* outgoing */ assign_addr_pair(&ap, iptr, 0); direction = 1; } else if((IP_V(iptr) == 6) && have_ip6_addr && ip6_addr_match(&ip6tr->ip6_dst)) { /* incoming */ assign_addr_pair(&ap, iptr, 1); direction = 0; } /* * Cannot determine direction from hardware or IP levels. Therefore * assume that it was a packet between two other machines, assign * source and dest arbitrarily (by numerical value) and account as * incoming. */ else if (options.promiscuous_but_choosy) { return; /* junk it */ } else if((IP_V(iptr) == 4) && (iptr->ip_src.s_addr < iptr->ip_dst.s_addr)) { assign_addr_pair(&ap, iptr, 1); direction = 0; } else if(IP_V(iptr) == 4) { assign_addr_pair(&ap, iptr, 0); direction = 0; } /* Drop other uncertain packages. */ } if(IP_V(iptr) == 4 && options.netfilter != 0) { /* * Net filter on, assign direction according to netmask */ if(in_filter_net(iptr->ip_src) && !in_filter_net(iptr->ip_dst)) { /* out of network */ assign_addr_pair(&ap, iptr, 0); direction = 1; } else if(in_filter_net(iptr->ip_dst) && !in_filter_net(iptr->ip_src)) { /* into network */ assign_addr_pair(&ap, iptr, 1); direction = 0; } else { /* drop packet */ return ; } } if(IP_V(iptr) == 6 && options.netfilter6 != 0) { /* * Net filter IPv6 active. */ int j; //else if((IP_V(iptr) == 6) && have_ip6_addr && ip6_addr_match(&ip6tr->ip6_dst)) { /* First reduce the participating addresses using the netfilter prefix. * We need scratch pads to do this. */ for (j=0; j < 16; ++j) { scribdst.s6_addr[j] = ip6tr->ip6_dst.s6_addr[j] & options.netfilter6mask.s6_addr[j]; scribsrc.s6_addr[j] = ip6tr->ip6_src.s6_addr[j] & options.netfilter6mask.s6_addr[j]; } /* Now look for any hits. */ //if(in_filter_net(iptr->ip_src) && !in_filter_net(iptr->ip_dst)) { if (IN6_ARE_ADDR_EQUAL(&scribsrc, &options.netfilter6net) && ! IN6_ARE_ADDR_EQUAL(&scribdst, &options.netfilter6net)) { /* out of network */ assign_addr_pair(&ap, iptr, 0); direction = 1; } //else if(in_filter_net(iptr->ip_dst) && !in_filter_net(iptr->ip_src)) { else if (! IN6_ARE_ADDR_EQUAL(&scribsrc, &options.netfilter6net) && IN6_ARE_ADDR_EQUAL(&scribdst, &options.netfilter6net)) { /* into network */ assign_addr_pair(&ap, iptr, 1); direction = 0; } else { /* drop packet */ return ; } } #if 1 /* Test if link-local IPv6 packets should be dropped. */ if( IP_V(iptr) == 6 && !options.link_local && (IN6_IS_ADDR_LINKLOCAL(&ip6tr->ip6_dst) || IN6_IS_ADDR_LINKLOCAL(&ip6tr->ip6_src)) ) return; #endif /* Do address resolving. */ switch (IP_V(iptr)) { case 4: ap.protocol = iptr->ip_p; /* Add the addresses to be resolved */ /* The IPv4 address is embedded in a in6_addr structure, * so it need be copied, and delivered to resolve(). */ memset(&scribdst, '\0', sizeof(scribdst)); memcpy(&scribdst, &iptr->ip_dst, sizeof(struct in_addr)); resolve(ap.af, &scribdst, NULL, 0); memset(&scribsrc, '\0', sizeof(scribsrc)); memcpy(&scribsrc, &iptr->ip_src, sizeof(struct in_addr)); resolve(ap.af, &scribsrc, NULL, 0); break; case 6: ap.protocol = ip6tr->ip6_nxt; /* Add the addresses to be resolved */ resolve(ap.af, &ip6tr->ip6_dst, NULL, 0); resolve(ap.af, &ip6tr->ip6_src, NULL, 0); default: break; } if(hash_find(history, &ap, u_ht.void_pp) == HASH_STATUS_KEY_NOT_FOUND) { ht = history_create(); hash_insert(history, &ap, ht); } /* Do accounting. */ switch (IP_V(iptr)) { case 4: len = ntohs(iptr->ip_len); break; case 6: len = ntohs(ip6tr->ip6_plen) + 40; default: break; } /* Update record */ ht->last_write = history_pos; if( ((IP_V(iptr) == 4) && (iptr->ip_src.s_addr == ap.src.s_addr)) || ((IP_V(iptr) == 6) && !memcmp(&ip6tr->ip6_src, &ap.src6, sizeof(ap.src6))) ) { ht->sent[history_pos] += len; ht->total_sent += len; } else { ht->recv[history_pos] += len; ht->total_recv += len; } if(direction == 0) { /* incoming */ history_totals.recv[history_pos] += len; history_totals.total_recv += len; } else { history_totals.sent[history_pos] += len; history_totals.total_sent += len; } }
/* record initiator */ static void cookie_record(cookie_t *in, const u_char *bp2) { int i; struct ip *ip; struct sockaddr_in *sin; #ifdef INET6 struct ip6_hdr *ip6; struct sockaddr_in6 *sin6; #endif i = cookie_find(in); if (0 <= i) { ninitiator = (i + 1) % MAXINITIATORS; return; } ip = (struct ip *)bp2; switch (IP_V(ip)) { case 4: memset(&cookiecache[ninitiator].iaddr, 0, sizeof(cookiecache[ninitiator].iaddr)); memset(&cookiecache[ninitiator].raddr, 0, sizeof(cookiecache[ninitiator].raddr)); sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr; #ifdef HAVE_SOCKADDR_SA_LEN sin->sin_len = sizeof(struct sockaddr_in); #endif sin->sin_family = AF_INET; memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr; #ifdef HAVE_SOCKADDR_SA_LEN sin->sin_len = sizeof(struct sockaddr_in); #endif sin->sin_family = AF_INET; memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)); break; #ifdef INET6 case 6: memset(&cookiecache[ninitiator].iaddr, 0, sizeof(cookiecache[ninitiator].iaddr)); memset(&cookiecache[ninitiator].raddr, 0, sizeof(cookiecache[ninitiator].raddr)); ip6 = (struct ip6_hdr *)bp2; sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr; #ifdef HAVE_SOCKADDR_SA_LEN sin6->sin6_len = sizeof(struct sockaddr_in6); #endif sin6->sin6_family = AF_INET6; memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr; #ifdef HAVE_SOCKADDR_SA_LEN sin6->sin6_len = sizeof(struct sockaddr_in6); #endif sin6->sin6_family = AF_INET6; memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); break; #endif default: return; } memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in)); ninitiator = (ninitiator + 1) % MAXINITIATORS; }