Making magic with the network stack
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

372 lines
10 KiB

  1. //
  2. // Created by conntrack on 4/30/23.
  3. //
  4. #include "netguard.h"
  5. struct ng_session *debug_socket;
  6. const char* debug_src_ip=""; // Android wlan IP
  7. const char* debug_dest_ip=""; // Debug server pub IP
  8. const uint16_t sport = 40408; // local port
  9. const uint16_t dport = 50508; // server port
  10. // pseudo header needed for tcp header checksum calculation
  11. struct pseudo_header
  12. {
  13. u_int32_t source_address;
  14. u_int32_t dest_address;
  15. u_int8_t placeholder;
  16. u_int8_t protocol;
  17. u_int16_t tcp_length;
  18. };
  19. #define DATAGRAM_LEN 4096
  20. #define OPT_SIZE 20
  21. unsigned short checksum(const char *buf, unsigned size)
  22. {
  23. unsigned sum = 0, i;
  24. /* Accumulate checksum */
  25. for (i = 0; i < size - 1; i += 2)
  26. {
  27. unsigned short word16 = *(unsigned short *) &buf[i];
  28. sum += word16;
  29. }
  30. /* Handle odd-sized case */
  31. if (size & 1)
  32. {
  33. unsigned short word16 = (unsigned char) buf[i];
  34. sum += word16;
  35. }
  36. /* Fold to get the ones-complement result */
  37. while (sum >> 16) sum = (sum & 0xFFFF)+(sum >> 16);
  38. /* Invert to get the negative in ones-complement arithmetic */
  39. return ~sum;
  40. }
  41. void create_data_packet(char** out_packet, int* out_packet_len, struct tcp_session tcps)
  42. {
  43. // datagram to represent the packet
  44. char *datagram = calloc(DATAGRAM_LEN, sizeof(char));
  45. // required structs for IP and TCP header
  46. struct iphdr *iph = (struct iphdr*)datagram;
  47. struct tcphdr *tcph = (struct tcphdr*)(datagram + sizeof(struct iphdr));
  48. struct pseudo_header psh;
  49. char source_ip[32];
  50. struct sockaddr_in sin;
  51. //some address resolution
  52. strcpy(source_ip , debug_src_ip); // cli ip
  53. sin.sin_family = AF_INET;
  54. sin.sin_port = htons(dport); // server port
  55. sin.sin_addr.s_addr = inet_addr (debug_dest_ip); // server ip
  56. // IP header configuration
  57. iph->ihl = 5;
  58. iph->version = 4;
  59. iph->tos = 0;
  60. iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE);
  61. iph->id = htons(54321);
  62. iph->frag_off = 0;
  63. iph->ttl = 64;
  64. iph->protocol = IPPROTO_TCP;
  65. iph->check = 0; // do calc later
  66. iph->saddr = inet_addr ( source_ip );
  67. iph->daddr = sin.sin_addr.s_addr;
  68. // TCP header configuration
  69. tcph->source = htons (sport);
  70. tcph->dest = htons (dport);
  71. tcph->seq = htonl(rand() % 4294967295);
  72. tcph->ack_seq = htonl(0);
  73. tcph->doff = 10; // tcp header size
  74. tcph->fin = 0;
  75. tcph->syn = 1;
  76. tcph->rst = 0;
  77. tcph->psh = 0;
  78. tcph->ack = 0;
  79. tcph->urg = 0;
  80. tcph->check = 0;
  81. tcph->window = htons(16000); // window size
  82. tcph->urg_ptr = 0;
  83. // TCP pseudo header for checksum calculation
  84. psh.source_address = inet_addr ( source_ip );
  85. psh.dest_address = sin.sin_addr.s_addr;
  86. psh.placeholder = 0;
  87. psh.protocol = IPPROTO_TCP;
  88. psh.tcp_length = htons(sizeof(struct tcphdr) + OPT_SIZE);
  89. int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + OPT_SIZE;
  90. // fill pseudo packet
  91. char* pseudogram = malloc(psize);
  92. memcpy(pseudogram, (char*)&psh, sizeof(struct pseudo_header));
  93. memcpy(pseudogram + sizeof(struct pseudo_header), tcph, sizeof(struct tcphdr) + OPT_SIZE);
  94. // TODO: change options to PA
  95. // TCP options are only set in the SYN packet
  96. // ---- set mss ----
  97. datagram[40] = 0x02;
  98. datagram[41] = 0x04;
  99. int16_t mss = htons(48); // mss value
  100. memcpy(datagram + 42, &mss, sizeof(int16_t));
  101. // ---- enable SACK ----
  102. datagram[44] = 0x04;
  103. datagram[45] = 0x02;
  104. // do the same for the pseudo header
  105. pseudogram[32] = 0x02;
  106. pseudogram[33] = 0x04;
  107. memcpy(pseudogram + 34, &mss, sizeof(int16_t));
  108. pseudogram[36] = 0x04;
  109. pseudogram[37] = 0x02;
  110. tcph->check = checksum((const char*)pseudogram, psize);
  111. iph->check = checksum((const char*)datagram, iph->tot_len);
  112. *out_packet = datagram;
  113. *out_packet_len = sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE;
  114. free(pseudogram);
  115. }
  116. void create_syn_packet(char** out_packet, int* out_packet_len)
  117. {
  118. // datagram to represent the packet
  119. char *datagram = calloc(DATAGRAM_LEN, sizeof(char));
  120. // required structs for IP and TCP header
  121. struct iphdr *iph = (struct iphdr*)datagram;
  122. struct tcphdr *tcph = (struct tcphdr*)(datagram + sizeof(struct iphdr));
  123. struct pseudo_header psh;
  124. char source_ip[32];
  125. struct sockaddr_in sin;
  126. //some address resolution
  127. strcpy(source_ip , debug_src_ip); // cli ip
  128. sin.sin_family = AF_INET;
  129. sin.sin_port = htons(dport); // server port
  130. sin.sin_addr.s_addr = inet_addr (debug_dest_ip); // server ip
  131. // IP header configuration
  132. iph->ihl = 5;
  133. iph->version = 4;
  134. iph->tos = 0;
  135. iph->tot_len = htons(sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE);
  136. iph->id = htons(54321);
  137. iph->frag_off = 0;
  138. iph->ttl = 64;
  139. iph->protocol = IPPROTO_TCP;
  140. iph->check = 0; // do calc later
  141. iph->saddr = inet_addr ( source_ip );
  142. iph->daddr = sin.sin_addr.s_addr;
  143. // TCP header configuration
  144. tcph->source = htons (sport);
  145. tcph->dest = htons (dport);
  146. tcph->seq = htonl(rand() % 4294967295);
  147. tcph->ack_seq = htonl(0);
  148. tcph->doff = 10; // tcp header size
  149. tcph->fin = 0;
  150. tcph->syn = 1;
  151. tcph->rst = 0;
  152. tcph->psh = 0;
  153. tcph->ack = 0;
  154. tcph->urg = 0;
  155. tcph->check = 0;
  156. tcph->window = htons(16000); // window size
  157. tcph->urg_ptr = 0;
  158. // TCP pseudo header for checksum calculation
  159. psh.source_address = inet_addr ( source_ip );
  160. psh.dest_address = sin.sin_addr.s_addr;
  161. psh.placeholder = 0;
  162. psh.protocol = IPPROTO_TCP;
  163. psh.tcp_length = htons(sizeof(struct tcphdr) + OPT_SIZE);
  164. int psize = sizeof(struct pseudo_header) + sizeof(struct tcphdr) + OPT_SIZE;
  165. // fill pseudo packet
  166. char* pseudogram = malloc(psize);
  167. memcpy(pseudogram, (char*)&psh, sizeof(struct pseudo_header));
  168. memcpy(pseudogram + sizeof(struct pseudo_header), tcph, sizeof(struct tcphdr) + OPT_SIZE);
  169. // TCP options are only set in the SYN packet
  170. // ---- set mss ----
  171. datagram[40] = 0x02;
  172. datagram[41] = 0x04;
  173. int16_t mss = htons(48); // mss value
  174. memcpy(datagram + 42, &mss, sizeof(int16_t));
  175. // ---- enable SACK ----
  176. datagram[44] = 0x04;
  177. datagram[45] = 0x02;
  178. // do the same for the pseudo header
  179. pseudogram[32] = 0x02;
  180. pseudogram[33] = 0x04;
  181. memcpy(pseudogram + 34, &mss, sizeof(int16_t));
  182. pseudogram[36] = 0x04;
  183. pseudogram[37] = 0x02;
  184. tcph->check = checksum((const char*)pseudogram, psize);
  185. iph->check = checksum((const char*)datagram, iph->tot_len);
  186. *out_packet = datagram;
  187. *out_packet_len = sizeof(struct iphdr) + sizeof(struct tcphdr) + OPT_SIZE;
  188. free(pseudogram);
  189. }
  190. int write_data_packet(const struct arguments *args, int epoll_fd, const uint8_t *buffer, size_t length) {
  191. // send PSH data
  192. char* psh_packet;
  193. int psh_packet_len;
  194. psh_packet = "testoooo";
  195. psh_packet_len = 8;
  196. //create_data_packet(&psh_packet, &psh_packet_len, tcps);
  197. //handle_ip(args, psh_packet, (size_t) psh_packet_len, epoll_fd, 10, 200);
  198. //write(debug_socket->socket, psh_packet, (size_t) psh_packet_len);
  199. write(debug_socket->socket, buffer, length);
  200. //write_ack(args, &debug_socket->tcp); this will send acks from dst to source (wrong direction) if uncommented
  201. log_android(ANDROID_LOG_ERROR, "Handling push data IP create with length: %d", psh_packet_len);
  202. }
  203. int open_debug_packet(const struct arguments *args, int epoll_fd) {
  204. // send SYN
  205. char* packet;
  206. int packet_len;
  207. create_syn_packet(&packet, &packet_len);
  208. handle_ip(args, packet, (size_t) packet_len, epoll_fd, 10, 200);
  209. /*
  210. ssize_t res = write(args->tun, packet, (size_t) packet_len);
  211. if (res >= 0) {
  212. log_android(ANDROID_LOG_ERROR, "successfuly wrote new syn packet to tun");
  213. //handle_ip(args, packet, (size_t) packet_len, epoll_fd, 10, 200);
  214. } else {
  215. log_android(ANDROID_LOG_ERROR, "tcp write error..");
  216. }
  217. */
  218. return 1;
  219. }
  220. int debug_socket_init(const struct arguments *args, int epoll_fd) {
  221. log_android(ANDROID_LOG_ERROR, "init debug socket");
  222. open_debug_packet(args, epoll_fd);
  223. return 1;
  224. }
  225. struct ng_session *get_debug_session(const struct arguments *args) {
  226. // Search session
  227. struct ng_session *cur = args->ctx->ng_session;
  228. while (cur != NULL &&
  229. !(cur->protocol == IPPROTO_TCP &&
  230. cur->tcp.version == 4 &&
  231. cur->tcp.source == ntohs(40408) && cur->tcp.dest == ntohs(50508)))
  232. cur = cur->next;
  233. if (cur == NULL) {
  234. log_android(ANDROID_LOG_ERROR, "Found null debug session...");
  235. } else {
  236. log_android(ANDROID_LOG_ERROR, "Found the debug session..");
  237. debug_socket = cur;
  238. }
  239. return debug_socket;
  240. }
  241. void read_debug_socket() {
  242. // TODO: Figure out what needs to be passed as parameters to this function
  243. return ;
  244. }
  245. void write_debug_socket(const struct arguments *args, int epoll_fd, const uint8_t *buffer, size_t length) {
  246. // TODO: This function is modelled after write_pcap_ret so I made
  247. // parameters for this function the same since we basically want to do the same thing.
  248. if (debug_socket != NULL) {
  249. log_android(ANDROID_LOG_ERROR,"Trying to write to the debug socket now..");
  250. write_data_packet(args, epoll_fd, buffer, length);
  251. }
  252. /*
  253. struct tcp_session *cur = &debug_socket->tcp;
  254. // test write to the debug socket
  255. //write_data(args, cur, buffer, length);
  256. log_android(ANDROID_LOG_ERROR, "debug tcp port: %d", cur->source);
  257. int is_debug_server = strcmp(dest_ip, "");
  258. if (is_debug_server != 0) {
  259. int res = write_ack(args, &debug_socket->tcp);
  260. log_android(ANDROID_LOG_ERROR, "write ack result %d", res);
  261. log_android(ANDROID_LOG_ERROR, "writing debug packet to %s with length: %d", dest_ip, length);
  262. // Forward to tun
  263. if (write_data(args, &debug_socket->tcp, buffer, length) >= 0) {
  264. log_android(ANDROID_LOG_ERROR, "Successfully wrote to debug socket with length: %d", length);
  265. debug_socket->tcp.local_seq += length;
  266. debug_socket->tcp.unconfirmed++;
  267. }
  268. } else {
  269. log_android(ANDROID_LOG_ERROR, "skipping writing debug packet to %s with length: %d", dest_ip, length);
  270. }
  271. */
  272. }