uint16_t TcpLayer::calculateChecksum(bool writeResultToPacket) { tcphdr* tcpHdr = getTcpHeader(); uint16_t checksumRes = 0; uint16_t currChecksumValue = tcpHdr->headerChecksum; if (m_PrevLayer != NULL) { tcpHdr->headerChecksum = 0; ScalarBuffer<uint16_t> vec[2]; LOG_DEBUG("data len = %d", (int)m_DataLen); vec[0].buffer = (uint16_t*)m_Data; vec[0].len = m_DataLen; if (m_PrevLayer->getProtocol() == IPv4) { uint32_t srcIP = ((IPv4Layer*)m_PrevLayer)->getSrcIpAddress().toInt(); uint32_t dstIP = ((IPv4Layer*)m_PrevLayer)->getDstIpAddress().toInt(); uint16_t pseudoHeader[6]; pseudoHeader[0] = srcIP >> 16; pseudoHeader[1] = srcIP & 0xFFFF; pseudoHeader[2] = dstIP >> 16; pseudoHeader[3] = dstIP & 0xFFFF; pseudoHeader[4] = 0xffff & htons(m_DataLen); pseudoHeader[5] = htons(0x00ff & PACKETPP_IPPROTO_TCP); vec[1].buffer = pseudoHeader; vec[1].len = 12; checksumRes = compute_checksum(vec, 2); LOG_DEBUG("calculated checksum = 0x%4X", checksumRes); }
bool TcpLayer::removeAllTcpOptions() { int offset = sizeof(tcphdr); if (!shortenLayer(offset, getHeaderLen()-offset)) return false; getTcpHeader()->dataOffset = sizeof(tcphdr)/4; m_NumOfTrailingBytes = 0; m_TcpOptionsCount = 0; return true; }
bool TcpLayer::removeAllTcpOptions() { int offset = sizeof(tcphdr); if (!shortenLayer(offset, getHeaderLen()-offset)) return false; getTcpHeader()->dataOffset = sizeof(tcphdr)/4; m_NumOfTrailingBytes = 0; m_OptionReader.changeTLVRecordCount(0-getTcpOptionCount()); return true; }
void TcpLayer::adjustTcpOptionTrailer(size_t totalOptSize) { int newNumberOfTrailingBytes = 0; while ((totalOptSize + newNumberOfTrailingBytes) % 4 != 0) newNumberOfTrailingBytes++; if (newNumberOfTrailingBytes < m_NumOfTrailingBytes) shortenLayer(sizeof(tcphdr)+totalOptSize, m_NumOfTrailingBytes - newNumberOfTrailingBytes); else if (newNumberOfTrailingBytes > m_NumOfTrailingBytes) extendLayer(sizeof(tcphdr)+totalOptSize, newNumberOfTrailingBytes - m_NumOfTrailingBytes); m_NumOfTrailingBytes = newNumberOfTrailingBytes; for (int i = 0; i < m_NumOfTrailingBytes; i++) m_Data[sizeof(tcphdr) + totalOptSize + i] = TCPOPT_DUMMY; getTcpHeader()->dataOffset = (sizeof(tcphdr) + totalOptSize + m_NumOfTrailingBytes)/4; }
int processPacket (struct pcap_pkthdr *h, /* Captured stuff */ u_char *pp, /* packet pointer */ nfs_pkt_t *record ) { struct ip *ip_b = NULL; struct tcphdr *tcp_b = NULL; struct udphdr *udp_b = NULL; u_int32_t tot_len = h->caplen; u_int32_t consumed = 0; u_int32_t src_port = 0; u_int32_t dst_port = 0; u_int16_t id; int e_len, i_len, h_len; u_int32_t rpc_len; unsigned int length; u_int32_t srcHost, dstHost; unsigned int proto; if (OutFile == NULL) { OutFile = stdout; } /* * It doesn't make any sense to run this program with a small * caplen (aka snap length) because the important stuff will * get lost. * * Too-short packets *should* never happen, since the min * packet length is longer than this, but it's always better * to be safe than to be sucker-punched by a bug elsewhere... */ if (tot_len <= (MIN_ETHER_HDR_LEN + MIN_IP_HDR_LEN + MIN_UDP_HDR_LEN)) { return (0); } e_len = getEtherHeader (tot_len, pp, &proto, &length); if (e_len <= 0) { return (-1); } consumed += e_len; /* * If the type of the packet isn't IP, then we're not * interested in it-- chuck it now. * * Note-- ordinarily by the time we get here, we've already * filtered out the packets using a pattern in the pcap * library, so this shouldn't happen (unless we are running * off a capture of the entire traffic on the wire). */ if (proto != 0x0800) { return (0); } ip_b = (struct ip *) (pp + e_len); i_len = getIpHeader (ip_b, &proto, &id, &length, &srcHost, &dstHost); if (i_len <= 0) { return (-2); } record->ipLen = length; record->ipIdentifier = id; consumed += i_len; /* * Truncated packet-- what's up with that? At this point, * this can only happen if the packet is very short and the IP * options are very long. Still, must be cautious... */ if (consumed >= tot_len) { return (0); } if (proto == IPPROTO_TCP) { if (consumed + MIN_TCP_HDR_LEN >= tot_len) { /* fprintf (OutFile, "XX 1: TCP pkt too short.\n"); */ return (0); } tcp_b = (struct tcphdr *) (pp + consumed); h_len = getTcpHeader (tcp_b); if (h_len <= 0) { /* fprintf (OutFile, "XX 2: TCP header error\n"); */ return (-3); } consumed += h_len; if (consumed >= tot_len) { /* fprintf (OutFile, */ /* "XX 3: Dropped (consumed = %d, tot_len = %d)\n", */ /* consumed, tot_len); */ return (0); } h_len += sizeof (u_int32_t); src_port = ntohs (tcp_b->th_sport); dst_port = ntohs (tcp_b->th_dport); record->ipProto = 'T'; } else if (proto == IPPROTO_UDP) { if (consumed + MIN_UDP_HDR_LEN >= tot_len) { return (0); } udp_b = (struct udphdr *) (pp + consumed); h_len = getUdpHeader (udp_b); if (h_len <= 0) { return (-4); } consumed += h_len; if (consumed >= tot_len) { return (0); } src_port = ntohs (udp_b->uh_sport); dst_port = ntohs (udp_b->uh_dport); rpc_len = tot_len - consumed; record->ipProto = 'U'; } else if (proto == IPPROTO_ICMP) { struct icmp *icmp_b; if (consumed + sizeof(struct icmp) >= tot_len) { return (0); } icmp_b = (struct icmp *) (pp + consumed); h_len = getIcmpHeader (icmp_b); record->ipProto = 'C'; record->icmpType = icmp_b->icmp_type; if (icmp_b->icmp_type == ICMP_ECHO) { memmove(record->icmpPayload, (pp + consumed + sizeof(struct icmp)), 16); } } else { /* * If it's not TCP, UPD, or ICMP, then no matter what * it is, we don't care about it, so just ignore it. */ /* fprintf (OutFile, "XX 5: Not TCP or UDP.\n"); */ return (0); } /* * If we get to this point, there's a good chance this packet * contains something interesting, so we start filling in the * fields of the record immediately. */ record->secs = h->ts.tv_sec; record->usecs = h->ts.tv_usec; record->srcHost = srcHost; record->dstHost = dstHost; record->srcPort = src_port; record->dstPort = dst_port; record->ipLen = length; printPacketHeader(record, stdout); return 0; }