packet.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * ZMap Copyright 2013 Regents of the University of Michigan
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. */
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <assert.h>
  12. #include "../../lib/includes.h"
  13. #include "../../lib/xalloc.h"
  14. #include "packet.h"
  15. #include "../state.h"
  16. #ifndef NDEBUG
  17. void print_macaddr(struct ifreq* i)
  18. {
  19. printf("Device %s -> Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n",
  20. i->ifr_name,
  21. (int) ((unsigned char *) &i->ifr_addr.sa_data)[0],
  22. (int) ((unsigned char *) &i->ifr_addr.sa_data)[1],
  23. (int) ((unsigned char *) &i->ifr_addr.sa_data)[2],
  24. (int) ((unsigned char *) &i->ifr_addr.sa_data)[3],
  25. (int) ((unsigned char *) &i->ifr_addr.sa_data)[4],
  26. (int) ((unsigned char *) &i->ifr_addr.sa_data)[5]);
  27. }
  28. #endif /* NDEBUG */
  29. #define IP_ADDR_LEN_STR 20
  30. void fprintf_ip_header(FILE *fp, struct ip *iph)
  31. {
  32. struct in_addr *s = (struct in_addr *) &(iph->ip_src);
  33. struct in_addr *d = (struct in_addr *) &(iph->ip_dst);
  34. char srcip[IP_ADDR_LEN_STR+1];
  35. char dstip[IP_ADDR_LEN_STR+1];
  36. // inet_ntoa is a const char * so we if just call it in
  37. // fprintf, you'll get back wrong results since we're
  38. // calling it twice.
  39. strncpy(srcip, inet_ntoa(*s), IP_ADDR_LEN_STR - 1);
  40. strncpy(dstip, inet_ntoa(*d), IP_ADDR_LEN_STR - 1);
  41. srcip[IP_ADDR_LEN_STR] = '\0';
  42. dstip[IP_ADDR_LEN_STR] = '\0';
  43. fprintf(fp, "ip { saddr: %s | daddr: %s | checksum: %#04X }\n",
  44. srcip,
  45. dstip,
  46. ntohs(iph->ip_sum));
  47. }
  48. void fprintf_eth_header(FILE *fp, struct ether_header *ethh)
  49. {
  50. fprintf(fp, "eth { shost: %02x:%02x:%02x:%02x:%02x:%02x | "
  51. "dhost: %02x:%02x:%02x:%02x:%02x:%02x }\n",
  52. (int) ((unsigned char *) ethh->ether_shost)[0],
  53. (int) ((unsigned char *) ethh->ether_shost)[1],
  54. (int) ((unsigned char *) ethh->ether_shost)[2],
  55. (int) ((unsigned char *) ethh->ether_shost)[3],
  56. (int) ((unsigned char *) ethh->ether_shost)[4],
  57. (int) ((unsigned char *) ethh->ether_shost)[5],
  58. (int) ((unsigned char *) ethh->ether_dhost)[0],
  59. (int) ((unsigned char *) ethh->ether_dhost)[1],
  60. (int) ((unsigned char *) ethh->ether_dhost)[2],
  61. (int) ((unsigned char *) ethh->ether_dhost)[3],
  62. (int) ((unsigned char *) ethh->ether_dhost)[4],
  63. (int) ((unsigned char *) ethh->ether_dhost)[5]);
  64. }
  65. void make_eth_header(struct ether_header *ethh, macaddr_t *src, macaddr_t *dst)
  66. {
  67. memcpy(ethh->ether_shost, src, ETHER_ADDR_LEN);
  68. memcpy(ethh->ether_dhost, dst, ETHER_ADDR_LEN);
  69. ethh->ether_type = htons(ETHERTYPE_IP);
  70. }
  71. void make_ip_header(struct ip *iph, uint8_t protocol, uint16_t len)
  72. {
  73. iph->ip_hl = 5; // Internet Header Length
  74. iph->ip_v = 4; // IPv4
  75. iph->ip_tos = 0; // Type of Service
  76. iph->ip_len = len;
  77. iph->ip_id = htons(54321); // identification number
  78. iph->ip_off = 0; //fragmentation flag
  79. iph->ip_ttl = MAXTTL; // time to live (TTL)
  80. iph->ip_p = protocol; // upper layer protocol => TCP
  81. // we set the checksum = 0 for now because that's
  82. // what it needs to be when we run the IP checksum
  83. iph->ip_sum = 0;
  84. }
  85. void make_icmp_header(struct icmp *buf)
  86. {
  87. buf->icmp_type = ICMP_ECHO;
  88. buf->icmp_code = 0;
  89. buf->icmp_seq = 0;
  90. }
  91. void make_tcp_header(struct tcphdr *tcp_header, port_h_t dest_port)
  92. {
  93. tcp_header->th_seq = random();
  94. tcp_header->th_ack = 0;
  95. tcp_header->th_x2 = 0;
  96. tcp_header->th_off = 5; // data offset
  97. tcp_header->th_flags = 0;
  98. tcp_header->th_flags |= TH_SYN;
  99. tcp_header->th_win = htons(65535); // largest possible window
  100. tcp_header->th_sum = 0;
  101. tcp_header->th_urp = 0;
  102. tcp_header->th_dport = htons(dest_port);
  103. }
  104. void make_udp_header(struct udphdr *udp_header, port_h_t dest_port,
  105. uint16_t len)
  106. {
  107. udp_header->uh_dport = htons(dest_port);
  108. udp_header->uh_ulen = htons(len);
  109. // checksum ignored in IPv4 if 0
  110. udp_header->uh_sum = 0;
  111. }
  112. // Note: caller must free return value
  113. char *make_ip_str(uint32_t ip)
  114. {
  115. struct in_addr t;
  116. t.s_addr = ip;
  117. const char *temp = inet_ntoa(t);
  118. char *retv = xmalloc(strlen(temp)+1);
  119. strcpy(retv, temp);
  120. return retv;
  121. }