packet.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "../../lib/includes.h"
  2. #include "../state.h"
  3. #ifndef PACKET_H
  4. #define PACKET_H
  5. #define MAX_PACKET_SIZE 4096
  6. typedef unsigned short __attribute__((__may_alias__)) alias_unsigned_short;
  7. void make_eth_header(struct ether_header *ethh, macaddr_t *src, macaddr_t *dst);
  8. void make_ip_header(struct ip *iph, uint8_t, uint16_t);
  9. void make_tcp_header(struct tcphdr*, port_h_t);
  10. void make_icmp_header(struct icmp *);
  11. void make_udp_header(struct udphdr *udp_header, port_h_t dest_port,
  12. uint16_t len);
  13. void fprintf_ip_header(FILE *fp, struct ip *iph);
  14. void fprintf_eth_header(FILE *fp, struct ether_header *ethh);
  15. static inline unsigned short in_checksum(unsigned short *ip_pkt, int len)
  16. {
  17. unsigned long sum = 0;
  18. for (int nwords = len/2; nwords > 0; nwords--) {
  19. sum += *ip_pkt++;
  20. }
  21. sum = (sum >> 16) + (sum & 0xffff);
  22. sum += (sum >> 16);
  23. return (unsigned short) (~sum);
  24. }
  25. static inline uint32_t fletcher32( uint16_t const *data, size_t words )
  26. {
  27. // 1 word = 2 Bytes
  28. uint32_t sum1 = 0xffff, sum2 = 0xffff;
  29. while (words) {
  30. unsigned tlen = words > 359 ? 359 : words;
  31. words -= tlen;
  32. do {
  33. //sum2 += sum1 += *data++;
  34. sum2 += sum1 += htons(*data++);
  35. } while (--tlen);
  36. sum1 = (sum1 & 0xffff) + (sum1 >> 16);
  37. sum2 = (sum2 & 0xffff) + (sum2 >> 16);
  38. }
  39. /* Second reduction step to reduce sums to 16 bits */
  40. sum1 = (sum1 & 0xffff) + (sum1 >> 16);
  41. sum2 = (sum2 & 0xffff) + (sum2 >> 16);
  42. return sum2 << 16 | sum1;
  43. }
  44. __attribute__((unused)) static inline unsigned short zmap_ip_checksum(
  45. unsigned short *buf)
  46. {
  47. return in_checksum(buf, (int) sizeof(struct ip));
  48. }
  49. __attribute__((unused)) static inline unsigned short icmp_checksum(
  50. unsigned short *buf)
  51. {
  52. return in_checksum(buf, (int) sizeof(struct icmp));
  53. }
  54. static __attribute__((unused)) uint16_t tcp_checksum(unsigned short len_tcp,
  55. uint32_t saddr, uint32_t daddr, struct tcphdr *tcp_pkt)
  56. {
  57. alias_unsigned_short *src_addr = (alias_unsigned_short *) &saddr;
  58. alias_unsigned_short *dest_addr = (alias_unsigned_short *) &daddr;
  59. unsigned char prot_tcp = 6;
  60. unsigned long sum = 0;
  61. int nleft = len_tcp;
  62. unsigned short *w;
  63. w = (unsigned short *) tcp_pkt;
  64. // calculate the checksum for the tcp header and tcp data
  65. while(nleft > 1) {
  66. sum += *w++;
  67. nleft -= 2;
  68. }
  69. // if nleft is 1 there ist still on byte left.
  70. // We add a padding byte (0xFF) to build a 16bit word
  71. if (nleft > 0) {
  72. sum += *w & ntohs(0xFF00);
  73. }
  74. // add the pseudo header
  75. sum += src_addr[0];
  76. sum += src_addr[1];
  77. sum += dest_addr[0];
  78. sum += dest_addr[1];
  79. sum += htons(len_tcp);
  80. sum += htons(prot_tcp);
  81. sum = (sum >> 16) + (sum & 0xFFFF);
  82. sum += (sum >> 16);
  83. // Take the one's complement of sum
  84. return (unsigned short) (~sum);
  85. }
  86. // Returns 0 if dst_port is outside the expected valid range, non-zero otherwise
  87. static __attribute__((unused)) inline int check_dst_port(uint16_t port,
  88. int num_ports, uint32_t *validation)
  89. {
  90. if (port > zconf.source_port_last
  91. || port < zconf.source_port_first) {
  92. return -1;
  93. }
  94. int32_t to_validate = port - zconf.source_port_first;
  95. int32_t min = validation[1] % num_ports;
  96. int32_t max = (validation[1] + zconf.packet_streams - 1) % num_ports;
  97. return (((max - min) % num_ports) >= ((to_validate - min) % num_ports));
  98. }
  99. static __attribute__((unused)) inline uint16_t get_src_port(int num_ports,
  100. int probe_num, uint32_t *validation)
  101. {
  102. return zconf.source_port_first + ((validation[1] + probe_num) % num_ports);
  103. }
  104. // Note: caller must free return value
  105. char *make_ip_str(uint32_t ip);
  106. #endif