edit_packet.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204
  1. /* $Id$ */
  2. /*
  3. * Copyright (c) 2001-2010 Aaron Turner <aturner at synfin dot net>
  4. * Copyright (c) 2013-2018 Fred Klassen <tcpreplay at appneta dot com> - AppNeta
  5. *
  6. * The Tcpreplay Suite of tools is free software: you can redistribute it
  7. * and/or modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation, either version 3 of the
  9. * License, or with the authors permission any later version.
  10. *
  11. * The Tcpreplay Suite is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the Tcpreplay Suite. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "config.h"
  20. #include "defines.h"
  21. #include "common.h"
  22. #include "tcpedit.h"
  23. #include "edit_packet.h"
  24. #include "checksum.h"
  25. #include "incremental_checksum.h"
  26. #include "lib/sll.h"
  27. #include "dlt.h"
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <sys/types.h>
  31. #include <sys/socket.h>
  32. #include <netinet/in.h>
  33. #include <arpa/inet.h>
  34. static uint32_t randomize_ipv4_addr(tcpedit_t *tcpedit, uint32_t ip);
  35. static uint32_t remap_ipv4(tcpedit_t *tcpedit, tcpr_cidr_t *cidr, const uint32_t original);
  36. static int is_unicast_ipv4(tcpedit_t *tcpedit, uint32_t ip);
  37. static void randomize_ipv6_addr(tcpedit_t *tcpedit, struct tcpr_in6_addr *addr);
  38. static int remap_ipv6(tcpedit_t *tcpedit, tcpr_cidr_t *cidr, struct tcpr_in6_addr *addr);
  39. static int is_multicast_ipv6(tcpedit_t *tcpedit, struct tcpr_in6_addr *addr);
  40. static int ipv6_header_length(ipv6_hdr_t const * ip6_hdr, int pkt_len);
  41. /**
  42. * this code re-calcs the IP and Layer 4 checksums
  43. * the IMPORTANT THING is that the Layer 4 header
  44. * is contiguous in memory after *ip_hdr we're actually
  45. * writing to the layer 4 header via the ip_hdr ptr.
  46. * (Yes, this sucks, but that's the way libnet works, and
  47. * I was too lazy to re-invent the wheel.
  48. * Returns 0 on success, -1 on error
  49. */
  50. int
  51. fix_ipv4_checksums(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr, ipv4_hdr_t *ip_hdr)
  52. {
  53. int ret1 = 0, ret2 = 0, ip_len;
  54. assert(tcpedit);
  55. assert(pkthdr);
  56. assert(ip_hdr);
  57. /* calc the L4 checksum if we have the whole packet && not a frag or first frag */
  58. if (pkthdr->caplen == pkthdr->len &&
  59. (htons(ip_hdr->ip_off) & (IP_MF | IP_OFFMASK)) == 0) {
  60. if (ntohs(ip_hdr->ip_len) < (ip_hdr->ip_hl << 2))
  61. return TCPEDIT_WARN;
  62. ip_len = (int)ntohs(ip_hdr->ip_len);
  63. ret1 = do_checksum(tcpedit, (u_char *) ip_hdr, ip_hdr->ip_p,
  64. ip_len - (ip_hdr->ip_hl << 2));
  65. if (ret1 < 0)
  66. return TCPEDIT_ERROR;
  67. }
  68. /* calc IP checksum */
  69. ip_len = (int)ntohs(ip_hdr->ip_len);
  70. ret2 = do_checksum(tcpedit, (u_char *) ip_hdr, IPPROTO_IP, ip_len);
  71. if (ret2 < 0)
  72. return TCPEDIT_ERROR;
  73. /* what do we return? */
  74. if (ret1 == TCPEDIT_WARN || ret2 == TCPEDIT_WARN)
  75. return TCPEDIT_WARN;
  76. return TCPEDIT_OK;
  77. }
  78. /**
  79. * Returns ipv6 header length with all ipv6 options on success
  80. * -1 on error
  81. */
  82. static int
  83. ipv6_header_length(ipv6_hdr_t const * ip6_hdr, int pkt_len)
  84. {
  85. struct tcpr_ipv6_ext_hdr_base const * nhdr;
  86. uint8_t next_header;
  87. int offset;
  88. offset = sizeof(*ip6_hdr);
  89. next_header = ip6_hdr->ip_nh;
  90. while (sizeof(*nhdr) + offset < (size_t)pkt_len)
  91. {
  92. if (next_header != TCPR_IPV6_NH_HBH
  93. && next_header != TCPR_IPV6_NH_ROUTING
  94. && next_header != TCPR_IPV6_NH_FRAGMENT) {
  95. return offset;
  96. }
  97. nhdr = (struct tcpr_ipv6_ext_hdr_base const *) (((uint8_t const *)ip6_hdr) + offset);
  98. next_header = nhdr->ip_nh;
  99. offset += ((nhdr->ip_len + 1) << 3);
  100. }
  101. return -1;
  102. }
  103. int
  104. fix_ipv6_checksums(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr, ipv6_hdr_t *ip6_hdr)
  105. {
  106. int ret = 0;
  107. assert(tcpedit);
  108. assert(pkthdr);
  109. assert(ip6_hdr);
  110. /* calc the L4 checksum if we have the whole packet && not a frag or first frag */
  111. if (pkthdr->caplen == pkthdr->len) {
  112. if (ip6_hdr->ip_len < ipv6_header_length(ip6_hdr, pkthdr->len))
  113. return TCPEDIT_WARN;
  114. ret = do_checksum(tcpedit, (u_char *) ip6_hdr, ip6_hdr->ip_nh,
  115. htons(ip6_hdr->ip_len));
  116. if (ret < 0)
  117. return TCPEDIT_ERROR;
  118. }
  119. /* what do we return? */
  120. if (ret == TCPEDIT_WARN)
  121. return TCPEDIT_WARN;
  122. return TCPEDIT_OK;
  123. }
  124. /*
  125. * #406 fix IP headers which may be not be set properly due to TCP segmentation
  126. */
  127. void fix_ipv4_length(struct pcap_pkthdr *pkthdr, ipv4_hdr_t *ip_hdr)
  128. {
  129. if (!ip_hdr->ip_len)
  130. ip_hdr->ip_len = htons((uint16_t)pkthdr->len);
  131. }
  132. void fix_ipv6_length(struct pcap_pkthdr *pkthdr, ipv6_hdr_t *ip6_hdr)
  133. {
  134. if (!ip6_hdr->ip_len)
  135. ip6_hdr->ip_len = htons((uint16_t)pkthdr->len);
  136. }
  137. static void ipv4_l34_csum_replace(uint8_t *data, uint8_t protocol,
  138. uint32_t old, uint32_t new)
  139. {
  140. ipv4_hdr_t *ipv4;
  141. tcp_hdr_t *tcp_hdr;
  142. udp_hdr_t *udp_hdr;
  143. assert(data);
  144. switch (protocol) {
  145. case IPPROTO_IP:
  146. ipv4 = (ipv4_hdr_t *)data;
  147. csum_replace4(&ipv4->ip_sum, old, new);
  148. break;
  149. case IPPROTO_TCP:
  150. tcp_hdr = (tcp_hdr_t *)data;
  151. csum_replace4(&tcp_hdr->th_sum, old, new);
  152. break;
  153. case IPPROTO_UDP:
  154. udp_hdr = (udp_hdr_t *)data;
  155. if (udp_hdr->uh_sum)
  156. csum_replace4(&udp_hdr->uh_sum, old, new);
  157. break;
  158. default:
  159. assert(false);
  160. }
  161. }
  162. static void ipv6_l34_csum_replace(uint8_t *data, uint8_t protocol,
  163. uint32_t *old, uint32_t *new)
  164. {
  165. tcp_hdr_t *tcp_hdr;
  166. udp_hdr_t *udp_hdr;
  167. icmpv4_hdr_t *icmp;
  168. icmpv6_hdr_t *icmp6;
  169. assert(data);
  170. switch (protocol) {
  171. case IPPROTO_TCP:
  172. tcp_hdr = (tcp_hdr_t *)data;
  173. csum_replace16(&tcp_hdr->th_sum, old, new);
  174. break;
  175. case IPPROTO_UDP:
  176. udp_hdr = (udp_hdr_t *)data;
  177. if (udp_hdr->uh_sum)
  178. csum_replace16(&udp_hdr->uh_sum, old, new);
  179. break;
  180. case IPPROTO_ICMP:
  181. icmp = (icmpv4_hdr_t *)data;
  182. csum_replace16(&icmp->icmp_sum, old, new);
  183. break;
  184. case IPPROTO_ICMP6:
  185. icmp6 = (icmpv6_hdr_t *)data;
  186. csum_replace16(&icmp6->icmp_sum, old, new);
  187. break;
  188. default:
  189. assert(false);
  190. }
  191. }
  192. static void ipv4_addr_csum_replace(ipv4_hdr_t *ip_hdr, uint32_t old_ip,
  193. uint32_t new_ip, int len)
  194. {
  195. uint8_t *l4, protocol;
  196. assert(ip_hdr);
  197. if ((size_t)len < sizeof(*ip_hdr))
  198. return;
  199. ipv4_l34_csum_replace((uint8_t*)ip_hdr, IPPROTO_IP, old_ip, new_ip);
  200. protocol = ip_hdr->ip_p;
  201. switch (protocol) {
  202. case IPPROTO_UDP:
  203. l4 = get_layer4_v4(ip_hdr, len);
  204. len -= ip_hdr->ip_hl << 2;
  205. len -= TCPR_UDP_H;
  206. break;
  207. case IPPROTO_TCP:
  208. l4 = get_layer4_v4(ip_hdr, len);
  209. len -= ip_hdr->ip_hl << 2;
  210. len -= TCPR_TCP_H;
  211. break;
  212. default:
  213. l4 = NULL;
  214. }
  215. if (!l4 || len < 0)
  216. return;
  217. /* if this is a fragment, don't attempt to checksum the Layer4 header */
  218. if ((htons(ip_hdr->ip_off) & IP_OFFMASK) == 0)
  219. ipv4_l34_csum_replace(l4, protocol, old_ip, new_ip);
  220. }
  221. static void ipv6_addr_csum_replace(ipv6_hdr_t *ip6_hdr,
  222. struct tcpr_in6_addr *old_ip, struct tcpr_in6_addr *new_ip, int len)
  223. {
  224. uint8_t *l4, protocol;
  225. assert(ip6_hdr);
  226. if ((size_t)len < sizeof(*ip6_hdr))
  227. return;
  228. protocol = get_ipv6_l4proto(ip6_hdr, len);
  229. switch (protocol) {
  230. case IPPROTO_UDP:
  231. l4 = get_layer4_v6(ip6_hdr, len);
  232. len -= sizeof(*ip6_hdr);
  233. len -= TCPR_UDP_H;
  234. break;
  235. case IPPROTO_TCP:
  236. l4 = get_layer4_v6(ip6_hdr, len);
  237. len -= sizeof(*ip6_hdr);
  238. len -= TCPR_TCP_H;
  239. break;
  240. default:
  241. l4 = NULL;
  242. }
  243. if (!l4 || len < 0)
  244. return;
  245. ipv6_l34_csum_replace(l4, protocol, (uint32_t*)old_ip, (uint32_t*)new_ip);
  246. }
  247. /**
  248. * returns a new 32bit integer which is the randomized IP
  249. * based upon the user specified seed
  250. */
  251. static uint32_t
  252. randomize_ipv4_addr(tcpedit_t *tcpedit, uint32_t ip)
  253. {
  254. assert(tcpedit);
  255. /* don't rewrite broadcast addresses */
  256. if (tcpedit->skip_broadcast && !is_unicast_ipv4(tcpedit, ip))
  257. return ip;
  258. return ((ip ^ htonl(tcpedit->seed)) - (ip & htonl(tcpedit->seed)));
  259. }
  260. static void
  261. randomize_ipv6_addr(tcpedit_t *tcpedit, struct tcpr_in6_addr *addr)
  262. {
  263. uint32_t *p;
  264. int i;
  265. u_char was_multicast;
  266. assert(tcpedit);
  267. p = &addr->__u6_addr.__u6_addr32[0];
  268. was_multicast = is_multicast_ipv6(tcpedit, addr);
  269. for (i = 0; i < 4; ++i) {
  270. p[i] = ((p[i] ^ htonl(tcpedit->seed)) - (p[i] & htonl(tcpedit->seed)));
  271. }
  272. if (was_multicast) {
  273. addr->tcpr_s6_addr[0] = 0xff;
  274. } else if (is_multicast_ipv6(tcpedit, addr)) {
  275. addr->tcpr_s6_addr[0] = 0xaa;
  276. }
  277. }
  278. /**
  279. * randomizes the source and destination IP addresses based on a
  280. * pseudo-random number which is generated via the seed.
  281. * return 1 since we changed one or more IP addresses
  282. */
  283. int
  284. randomize_ipv4(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
  285. u_char *pktdata, ipv4_hdr_t *ip_hdr, int len)
  286. {
  287. #ifdef DEBUG
  288. char srcip[16], dstip[16];
  289. #endif
  290. assert(tcpedit);
  291. assert(pkthdr);
  292. assert(pktdata);
  293. assert(ip_hdr);
  294. #ifdef DEBUG
  295. strlcpy(srcip, get_addr2name4(ip_hdr->ip_src.s_addr, RESOLVE), 16);
  296. strlcpy(dstip, get_addr2name4(ip_hdr->ip_dst.s_addr, RESOLVE), 16);
  297. #endif
  298. /* randomize IP addresses based on the value of random */
  299. dbgx(1, "Old Src IP: %s\tOld Dst IP: %s", srcip, dstip);
  300. /* don't rewrite broadcast addresses */
  301. if ((tcpedit->skip_broadcast && is_unicast_ipv4(tcpedit, (u_int32_t)ip_hdr->ip_dst.s_addr))
  302. || !tcpedit->skip_broadcast) {
  303. uint32_t old_ip = ip_hdr->ip_dst.s_addr;
  304. ip_hdr->ip_dst.s_addr = randomize_ipv4_addr(tcpedit, ip_hdr->ip_dst.s_addr);
  305. ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_dst.s_addr, len);
  306. }
  307. if ((tcpedit->skip_broadcast && is_unicast_ipv4(tcpedit, (u_int32_t)ip_hdr->ip_src.s_addr))
  308. || !tcpedit->skip_broadcast) {
  309. uint32_t old_ip = ip_hdr->ip_src.s_addr;
  310. ip_hdr->ip_src.s_addr = randomize_ipv4_addr(tcpedit, ip_hdr->ip_src.s_addr);
  311. ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_src.s_addr, len);
  312. }
  313. #ifdef DEBUG
  314. strlcpy(srcip, get_addr2name4(ip_hdr->ip_src.s_addr, RESOLVE), 16);
  315. strlcpy(dstip, get_addr2name4(ip_hdr->ip_dst.s_addr, RESOLVE), 16);
  316. #endif
  317. dbgx(1, "New Src IP: %s\tNew Dst IP: %s\n", srcip, dstip);
  318. return 0;
  319. }
  320. int
  321. randomize_ipv6(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
  322. u_char *pktdata, ipv6_hdr_t *ip6_hdr, int len)
  323. {
  324. #ifdef DEBUG
  325. char srcip[INET6_ADDRSTRLEN], dstip[INET6_ADDRSTRLEN];
  326. #endif
  327. assert(tcpedit);
  328. assert(pkthdr);
  329. assert(pktdata);
  330. assert(ip6_hdr);
  331. #ifdef DEBUG
  332. strlcpy(srcip, get_addr2name6(&ip6_hdr->ip_src, RESOLVE), INET6_ADDRSTRLEN);
  333. strlcpy(dstip, get_addr2name6(&ip6_hdr->ip_dst, RESOLVE), INET6_ADDRSTRLEN);
  334. #endif
  335. /* randomize IP addresses based on the value of random */
  336. dbgx(1, "Old Src IP: %s\tOld Dst IP: %s", srcip, dstip);
  337. /* don't rewrite broadcast addresses */
  338. if ((tcpedit->skip_broadcast && !is_multicast_ipv6(tcpedit, &ip6_hdr->ip_dst))
  339. || !tcpedit->skip_broadcast) {
  340. struct tcpr_in6_addr old_ip6;
  341. memcpy(&old_ip6, &ip6_hdr->ip_dst, sizeof(old_ip6));
  342. randomize_ipv6_addr(tcpedit, &ip6_hdr->ip_dst);
  343. ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_dst, len);
  344. }
  345. if ((tcpedit->skip_broadcast && !is_multicast_ipv6(tcpedit, &ip6_hdr->ip_src))
  346. || !tcpedit->skip_broadcast) {
  347. struct tcpr_in6_addr old_ip6;
  348. memcpy(&old_ip6, &ip6_hdr->ip_src, sizeof(old_ip6));
  349. randomize_ipv6_addr(tcpedit, &ip6_hdr->ip_src);
  350. ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_src, len);
  351. }
  352. #ifdef DEBUG
  353. strlcpy(srcip, get_addr2name6(&ip6_hdr->ip_src, RESOLVE), INET6_ADDRSTRLEN);
  354. strlcpy(dstip, get_addr2name6(&ip6_hdr->ip_dst, RESOLVE), INET6_ADDRSTRLEN);
  355. #endif
  356. dbgx(1, "New Src IP: %s\tNew Dst IP: %s\n", srcip, dstip);
  357. return 0;
  358. }
  359. /**
  360. * this code will untruncate a packet via padding it with null
  361. * or resetting the actual IPv4 packet len to the snaplen - L2 header.
  362. * return 0 if no change, 1 if change, -1 on error.
  363. */
  364. int
  365. untrunc_packet(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
  366. u_char **pktdata, ipv4_hdr_t *ip_hdr, ipv6_hdr_t *ip6_hdr)
  367. {
  368. int l2len;
  369. int chksum = 1;
  370. u_char *packet;
  371. udp_hdr_t *udp_hdr;
  372. u_char *dataptr = NULL;
  373. assert(tcpedit);
  374. assert(pkthdr);
  375. assert(pktdata);
  376. packet = *pktdata;
  377. assert(packet);
  378. /* if actual len == cap len or there's no IP header, don't do anything */
  379. if ((pkthdr->caplen == pkthdr->len) || (ip_hdr == NULL && ip6_hdr == NULL)) {
  380. /* unless we're in MTU truncate mode */
  381. if (! tcpedit->mtu_truncate)
  382. return(0);
  383. }
  384. if ((l2len = layer2len(tcpedit)) < 0) {
  385. tcpedit_seterr(tcpedit, "Non-sensical layer 2 length: %d", l2len);
  386. return -1;
  387. }
  388. /*
  389. * cannot checksum fragments, but we can do some
  390. * work on UDP fragments. Setting checksum to 0
  391. * means checksum will be ignored.
  392. */
  393. if (ip_hdr) {
  394. if ((htons(ip_hdr->ip_off) & IP_OFFMASK) != 0) {
  395. chksum = 0;
  396. } else if (ip_hdr->ip_p == IPPROTO_UDP &&
  397. (htons(ip_hdr->ip_off) & IP_MF) != 0) {
  398. dataptr = (u_char*)ip_hdr;
  399. dataptr += ip_hdr->ip_hl << 2;
  400. udp_hdr = (udp_hdr_t*)dataptr;
  401. udp_hdr->uh_sum = 0;
  402. chksum = 0;
  403. }
  404. }
  405. /* Pad packet or truncate it */
  406. if (tcpedit->fixlen == TCPEDIT_FIXLEN_PAD) {
  407. /*
  408. * this should be an unnecessary check
  409. * but I've gotten a report that sometimes the caplen > len
  410. * which seems like a corrupted pcap
  411. */
  412. if (pkthdr->len > pkthdr->caplen) {
  413. packet = safe_realloc(packet, pkthdr->len);
  414. memset(packet + pkthdr->caplen, '\0', pkthdr->len - pkthdr->caplen);
  415. pkthdr->caplen = pkthdr->len;
  416. } else if (pkthdr->len < pkthdr->caplen) {
  417. /* i guess this is necessary if we've got a bogus pcap */
  418. //ip_hdr->ip_len = htons(pkthdr->caplen - l2len);
  419. tcpedit_seterr(tcpedit, "%s", "WTF? Why is your packet larger then the capture len?");
  420. chksum = -1;
  421. goto done;
  422. }
  423. }
  424. else if (tcpedit->fixlen == TCPEDIT_FIXLEN_TRUNC) {
  425. if (ip_hdr && pkthdr->len != pkthdr->caplen)
  426. ip_hdr->ip_len = htons(pkthdr->caplen - l2len);
  427. pkthdr->len = pkthdr->caplen;
  428. }
  429. else if (tcpedit->mtu_truncate) {
  430. if (pkthdr->len > (uint32_t)(tcpedit->mtu + l2len)) {
  431. /* first truncate the packet */
  432. pkthdr->len = pkthdr->caplen = l2len + tcpedit->mtu;
  433. /* if ip_hdr exists, update the length */
  434. if (ip_hdr != NULL) {
  435. ip_hdr->ip_len = htons(tcpedit->mtu);
  436. } else if (ip6_hdr != NULL) {
  437. ip6_hdr->ip_len = htons(tcpedit->mtu - sizeof(*ip6_hdr));
  438. } else {
  439. /* for non-IP frames, don't try to fix checksums */
  440. chksum = 0;
  441. goto done;
  442. }
  443. }
  444. }
  445. else {
  446. tcpedit_seterr(tcpedit, "Invalid fixlen value: 0x%x", tcpedit->fixlen);
  447. chksum = -1;
  448. goto done;
  449. }
  450. done:
  451. *pktdata = packet;
  452. return chksum;
  453. }
  454. /**
  455. * Extracts the layer 7 data from the packet for TCP, UDP, ICMP
  456. * returns the number of bytes and a pointer to the layer 7 data.
  457. * Returns 0 for no data
  458. */
  459. int
  460. extract_data(tcpedit_t *tcpedit, const u_char *pktdata, int caplen,
  461. char *l7data[])
  462. {
  463. int datalen = 0; /* amount of data beyond ip header */
  464. ipv4_hdr_t *ip_hdr;
  465. u_char ipbuff[MAXPACKET];
  466. u_char *dataptr;
  467. int ip_len;
  468. assert(tcpedit);
  469. assert(pktdata);
  470. assert(l7data);
  471. /* grab our IPv4 header */
  472. dataptr = ipbuff;
  473. if ((ip_hdr = (ipv4_hdr_t*)get_ipv4(pktdata, caplen,
  474. tcpedit->runtime.dlt1, &dataptr)) == NULL)
  475. return 0;
  476. /*
  477. * figure out the actual datalen which might be < the caplen
  478. * due to ethernet padding
  479. */
  480. ip_len = (int)ntohs(ip_hdr->ip_len);
  481. if (caplen > ip_len) {
  482. datalen = ip_len;
  483. } else {
  484. datalen = caplen - tcpedit->dlt_ctx->l2len;
  485. }
  486. /* update the datlen to not include the IP header len */
  487. datalen -= ip_hdr->ip_hl << 2;
  488. dataptr += ip_hdr->ip_hl << 2;
  489. if (datalen <= 0)
  490. goto nodata;
  491. /* TCP ? */
  492. if (ip_hdr->ip_p == IPPROTO_TCP) {
  493. tcp_hdr_t *tcp_hdr = (tcp_hdr_t *) get_layer4_v4(ip_hdr, datalen);
  494. datalen -= tcp_hdr->th_off << 2;
  495. if (datalen <= 0)
  496. goto nodata;
  497. dataptr += tcp_hdr->th_off << 2;
  498. }
  499. /* UDP ? */
  500. else if (ip_hdr->ip_p == IPPROTO_UDP) {
  501. datalen -= TCPR_UDP_H;
  502. if (datalen <= 0)
  503. goto nodata;
  504. dataptr += TCPR_UDP_H;
  505. }
  506. /* ICMP ? just ignore it for now */
  507. else if (ip_hdr->ip_p == IPPROTO_ICMP) {
  508. dbg(2, "Ignoring any possible data in ICMP packet");
  509. goto nodata;
  510. }
  511. /* unknown proto, just dump everything past the IP header */
  512. else {
  513. dbg(2, "Unknown protocol, dumping everything past the IP header");
  514. dataptr = (u_char *)ip_hdr;
  515. }
  516. dbgx(2, "packet had %d bytes of layer 7 data", datalen);
  517. memcpy(l7data, dataptr, datalen);
  518. return datalen;
  519. nodata:
  520. dbg(2, "packet has no data, skipping...");
  521. return 0;
  522. }
  523. /**
  524. * rewrites an IPv4 packet's TTL based on the rules
  525. * return 0 if no change, 1 if changed
  526. */
  527. int
  528. rewrite_ipv4_ttl(tcpedit_t *tcpedit, ipv4_hdr_t *ip_hdr)
  529. {
  530. volatile uint16_t oldval, newval;
  531. assert(tcpedit);
  532. /* make sure there's something to edit */
  533. if (ip_hdr == NULL || tcpedit->ttl_mode == false)
  534. return(0);
  535. oldval = (uint16_t)ip_hdr->ip_ttl;
  536. switch(tcpedit->ttl_mode) {
  537. case TCPEDIT_TTL_MODE_SET:
  538. if (ip_hdr->ip_ttl == tcpedit->ttl_value)
  539. return 0; /* no change required */
  540. ip_hdr->ip_ttl = tcpedit->ttl_value;
  541. break;
  542. case TCPEDIT_TTL_MODE_ADD:
  543. if (((int)ip_hdr->ip_ttl + tcpedit->ttl_value) > 255) {
  544. ip_hdr->ip_ttl = 255;
  545. } else {
  546. ip_hdr->ip_ttl += tcpedit->ttl_value;
  547. }
  548. break;
  549. case TCPEDIT_TTL_MODE_SUB:
  550. if (ip_hdr->ip_ttl <= tcpedit->ttl_value) {
  551. ip_hdr->ip_ttl = 1;
  552. } else {
  553. ip_hdr->ip_ttl -= tcpedit->ttl_value;
  554. }
  555. break;
  556. default:
  557. errx(1, "invalid ttl_mode: %d", tcpedit->ttl_mode);
  558. }
  559. newval = (uint16_t)ip_hdr->ip_ttl;
  560. csum_replace2(&ip_hdr->ip_sum, oldval, newval);
  561. return 0;
  562. }
  563. /**
  564. * rewrites an IPv6 packet's hop limit based on the rules
  565. * return 0 if no change, 1 if changed
  566. */
  567. int
  568. rewrite_ipv6_hlim(tcpedit_t *tcpedit, ipv6_hdr_t *ip6_hdr)
  569. {
  570. assert(tcpedit);
  571. /* make sure there's something to edit */
  572. if (ip6_hdr == NULL || tcpedit->ttl_mode == TCPEDIT_TTL_MODE_OFF)
  573. return(0);
  574. switch(tcpedit->ttl_mode) {
  575. case TCPEDIT_TTL_MODE_SET:
  576. if (ip6_hdr->ip_hl == tcpedit->ttl_value)
  577. return(0); /* no change required */
  578. ip6_hdr->ip_hl = tcpedit->ttl_value;
  579. break;
  580. case TCPEDIT_TTL_MODE_ADD:
  581. if (((int)ip6_hdr->ip_hl + tcpedit->ttl_value) > 255) {
  582. ip6_hdr->ip_hl = 255;
  583. } else {
  584. ip6_hdr->ip_hl += tcpedit->ttl_value;
  585. }
  586. break;
  587. case TCPEDIT_TTL_MODE_SUB:
  588. if (ip6_hdr->ip_hl <= tcpedit->ttl_value) {
  589. ip6_hdr->ip_hl = 1;
  590. } else {
  591. ip6_hdr->ip_hl -= tcpedit->ttl_value;
  592. }
  593. break;
  594. default:
  595. errx(1, "invalid ttl_mode: %d", tcpedit->ttl_mode);
  596. }
  597. return 0;
  598. }
  599. /**
  600. * takes a CIDR notation netblock and uses that to "remap" given IP
  601. * onto that netblock. ie: 10.0.0.0/8 and 192.168.55.123 -> 10.168.55.123
  602. * while 10.150.9.0/24 and 192.168.55.123 -> 10.150.9.123
  603. */
  604. static uint32_t
  605. remap_ipv4(tcpedit_t *tcpedit, tcpr_cidr_t *cidr, const uint32_t original)
  606. {
  607. uint32_t ipaddr = 0, network = 0, mask = 0, result = 0;
  608. assert(tcpedit);
  609. assert(cidr);
  610. if (cidr->family != AF_INET) {
  611. return 0;
  612. }
  613. /* don't rewrite broadcast addresses */
  614. if (tcpedit->skip_broadcast && !is_unicast_ipv4(tcpedit, original))
  615. return original;
  616. mask = 0xffffffff; /* turn on all the bits */
  617. /* shift over by correct # of bits */
  618. mask = mask << (32 - cidr->masklen);
  619. /* apply the mask to the network */
  620. network = htonl(cidr->u.network) & mask;
  621. /* apply the reverse of the mask to the IP */
  622. mask = mask ^ 0xffffffff;
  623. ipaddr = ntohl(original) & mask;
  624. /* merge the network portion and ip portions */
  625. result = network ^ ipaddr;
  626. /* return the result in network byte order */
  627. return(htonl(result));
  628. }
  629. static int
  630. remap_ipv6(tcpedit_t *tcpedit, tcpr_cidr_t *cidr, struct tcpr_in6_addr *addr)
  631. {
  632. uint32_t i, j, k;
  633. assert(tcpedit);
  634. assert(cidr);
  635. if (cidr->family != AF_INET6) {
  636. return 0;
  637. }
  638. /* don't rewrite broadcast addresses */
  639. if (tcpedit->skip_broadcast && is_multicast_ipv6(tcpedit, addr))
  640. return 0;
  641. j = cidr->masklen / 8;
  642. for (i = 0; i < j; i++)
  643. addr->tcpr_s6_addr[i] = cidr->u.network6.tcpr_s6_addr[i];
  644. if ((k = cidr->masklen % 8) == 0)
  645. return 1;
  646. k = (uint32_t)~0 << (8 - k);
  647. i = addr->tcpr_s6_addr[i] & k;
  648. addr->tcpr_s6_addr[i] = (cidr->u.network6.tcpr_s6_addr[j] & (0xff << (8 - k))) |
  649. (addr->tcpr_s6_addr[i] & (0xff >> k));
  650. return 1;
  651. }
  652. /**
  653. * rewrite IP address (layer3)
  654. * uses -N to rewrite (map) one subnet onto another subnet
  655. * also support --srcipmap and --dstipmap
  656. * return 0 if no change, 1 or 2 if changed
  657. */
  658. int
  659. rewrite_ipv4l3(tcpedit_t *tcpedit, ipv4_hdr_t *ip_hdr, tcpr_dir_t direction,
  660. int len)
  661. {
  662. tcpr_cidrmap_t *cidrmap1 = NULL, *cidrmap2 = NULL;
  663. int didsrc = 0, diddst = 0, loop = 1;
  664. tcpr_cidrmap_t *ipmap;
  665. assert(tcpedit);
  666. assert(ip_hdr);
  667. /* first check the src/dst IP maps */
  668. ipmap = tcpedit->srcipmap;
  669. while (ipmap != NULL) {
  670. if (ip_in_cidr(ipmap->from, ip_hdr->ip_src.s_addr)) {
  671. uint32_t old_ip = ip_hdr->ip_src.s_addr;
  672. ip_hdr->ip_src.s_addr = remap_ipv4(tcpedit, ipmap->to, ip_hdr->ip_src.s_addr);
  673. ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_src.s_addr, len);
  674. dbgx(2, "Remapped src addr to: %s", get_addr2name4(ip_hdr->ip_src.s_addr, RESOLVE));
  675. break;
  676. }
  677. ipmap = ipmap->next;
  678. }
  679. ipmap = tcpedit->dstipmap;
  680. while (ipmap != NULL) {
  681. if (ip_in_cidr(ipmap->from, ip_hdr->ip_dst.s_addr)) {
  682. uint32_t old_ip = ip_hdr->ip_dst.s_addr;
  683. ip_hdr->ip_dst.s_addr = remap_ipv4(tcpedit, ipmap->to, ip_hdr->ip_dst.s_addr);
  684. ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_dst.s_addr, len);
  685. dbgx(2, "Remapped dst addr to: %s", get_addr2name4(ip_hdr->ip_dst.s_addr, RESOLVE));
  686. break;
  687. }
  688. ipmap = ipmap->next;
  689. }
  690. /* anything else to rewrite? */
  691. if (tcpedit->cidrmap1 == NULL)
  692. return(0);
  693. /* don't play with the main pointers */
  694. if (direction == TCPR_DIR_C2S) {
  695. cidrmap1 = tcpedit->cidrmap1;
  696. cidrmap2 = tcpedit->cidrmap2;
  697. } else {
  698. cidrmap1 = tcpedit->cidrmap2;
  699. cidrmap2 = tcpedit->cidrmap1;
  700. }
  701. /* loop through the cidrmap to rewrite */
  702. do {
  703. if ((! diddst) && ip_in_cidr(cidrmap2->from, ip_hdr->ip_dst.s_addr)) {
  704. uint32_t old_ip = ip_hdr->ip_dst.s_addr;
  705. ip_hdr->ip_dst.s_addr = remap_ipv4(tcpedit, cidrmap2->to, ip_hdr->ip_dst.s_addr);
  706. ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_dst.s_addr, len);
  707. dbgx(2, "Remapped dst addr to: %s", get_addr2name4(ip_hdr->ip_dst.s_addr, RESOLVE));
  708. diddst = 1;
  709. }
  710. if ((! didsrc) && ip_in_cidr(cidrmap1->from, ip_hdr->ip_src.s_addr)) {
  711. uint32_t old_ip = ip_hdr->ip_src.s_addr;
  712. ip_hdr->ip_src.s_addr = remap_ipv4(tcpedit, cidrmap1->to, ip_hdr->ip_src.s_addr);
  713. ipv4_addr_csum_replace(ip_hdr, old_ip, ip_hdr->ip_src.s_addr, len);
  714. dbgx(2, "Remapped src addr to: %s", get_addr2name4(ip_hdr->ip_src.s_addr, RESOLVE));
  715. didsrc = 1;
  716. }
  717. /*
  718. * loop while we haven't modified both src/dst AND
  719. * at least one of the cidr maps have a next pointer
  720. */
  721. if ((! (diddst && didsrc)) &&
  722. (! ((cidrmap1->next == NULL) && (cidrmap2->next == NULL)))) {
  723. /* increment our ptr's if possible */
  724. if (cidrmap1->next != NULL)
  725. cidrmap1 = cidrmap1->next;
  726. if (cidrmap2->next != NULL)
  727. cidrmap2 = cidrmap2->next;
  728. } else {
  729. loop = 0;
  730. }
  731. /* Later on we should support various IP protocols which embed
  732. * the IP address in the application layer. Things like
  733. * DNS and FTP.
  734. */
  735. } while (loop);
  736. /* return how many changes we require checksum updates (none) */
  737. return 0;
  738. }
  739. int
  740. rewrite_ipv6l3(tcpedit_t *tcpedit, ipv6_hdr_t *ip6_hdr, tcpr_dir_t direction,
  741. int len)
  742. {
  743. tcpr_cidrmap_t *cidrmap1 = NULL, *cidrmap2 = NULL;
  744. int didsrc = 0, diddst = 0, loop = 1;
  745. tcpr_cidrmap_t *ipmap;
  746. assert(tcpedit);
  747. assert(ip6_hdr);
  748. /* first check the src/dst IP maps */
  749. ipmap = tcpedit->srcipmap;
  750. while (ipmap != NULL) {
  751. if (ip6_in_cidr(ipmap->from, &ip6_hdr->ip_src)) {
  752. struct tcpr_in6_addr old_ip6;
  753. memcpy(&old_ip6, &ip6_hdr->ip_src, sizeof(old_ip6));
  754. remap_ipv6(tcpedit, ipmap->to, &ip6_hdr->ip_src);
  755. ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_src, len);
  756. dbgx(2, "Remapped src addr to: %s", get_addr2name6(&ip6_hdr->ip_src, RESOLVE));
  757. break;
  758. }
  759. ipmap = ipmap->next;
  760. }
  761. ipmap = tcpedit->dstipmap;
  762. while (ipmap != NULL) {
  763. if (ip6_in_cidr(ipmap->from, &ip6_hdr->ip_dst)) {
  764. struct tcpr_in6_addr old_ip6;
  765. memcpy(&old_ip6, &ip6_hdr->ip_dst, sizeof(old_ip6));
  766. remap_ipv6(tcpedit, ipmap->to, &ip6_hdr->ip_dst);
  767. ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_dst, len);
  768. dbgx(2, "Remapped dst addr to: %s", get_addr2name6(&ip6_hdr->ip_dst, RESOLVE));
  769. break;
  770. }
  771. ipmap = ipmap->next;
  772. }
  773. /* anything else to rewrite? */
  774. if (tcpedit->cidrmap1 == NULL)
  775. return(0);
  776. /* don't play with the main pointers */
  777. if (direction == TCPR_DIR_C2S) {
  778. cidrmap1 = tcpedit->cidrmap1;
  779. cidrmap2 = tcpedit->cidrmap2;
  780. } else {
  781. cidrmap1 = tcpedit->cidrmap2;
  782. cidrmap2 = tcpedit->cidrmap1;
  783. }
  784. /* loop through the cidrmap to rewrite */
  785. do {
  786. if ((! diddst) && ip6_in_cidr(cidrmap2->from, &ip6_hdr->ip_dst)) {
  787. struct tcpr_in6_addr old_ip6;
  788. memcpy(&old_ip6, &ip6_hdr->ip_dst, sizeof(old_ip6));
  789. remap_ipv6(tcpedit, cidrmap2->to, &ip6_hdr->ip_dst);
  790. ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_dst, len);
  791. dbgx(2, "Remapped dst addr to: %s", get_addr2name6(&ip6_hdr->ip_dst, RESOLVE));
  792. diddst = 1;
  793. }
  794. if ((! didsrc) && ip6_in_cidr(cidrmap1->from, &ip6_hdr->ip_src)) {
  795. struct tcpr_in6_addr old_ip6;
  796. memcpy(&old_ip6, &ip6_hdr->ip_src, sizeof(old_ip6));
  797. remap_ipv6(tcpedit, cidrmap1->to, &ip6_hdr->ip_src);
  798. ipv6_addr_csum_replace(ip6_hdr, &old_ip6, &ip6_hdr->ip_src, len);
  799. dbgx(2, "Remapped src addr to: %s", get_addr2name6(&ip6_hdr->ip_src, RESOLVE));
  800. didsrc = 1;
  801. }
  802. /*
  803. * loop while we haven't modified both src/dst AND
  804. * at least one of the cidr maps have a next pointer
  805. */
  806. if ((! (diddst && didsrc)) &&
  807. (! ((cidrmap1->next == NULL) && (cidrmap2->next == NULL)))) {
  808. /* increment our ptr's if possible */
  809. if (cidrmap1->next != NULL)
  810. cidrmap1 = cidrmap1->next;
  811. if (cidrmap2->next != NULL)
  812. cidrmap2 = cidrmap2->next;
  813. } else {
  814. loop = 0;
  815. }
  816. /* Later on we should support various IP protocols which embed
  817. * the IP address in the application layer. Things like
  818. * DNS and FTP.
  819. */
  820. } while (loop);
  821. /* return how many changes we made (none) */
  822. return 0;
  823. }
  824. /**
  825. * Randomize the IP addresses in an ARP packet based on the user seed
  826. * return 0 if no change, or 1 for a change
  827. */
  828. int
  829. randomize_iparp(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
  830. u_char *pktdata, int datalink)
  831. {
  832. arp_hdr_t *arp_hdr ;
  833. int l2len;
  834. #ifdef FORCE_ALIGN
  835. uint32_t iptemp;
  836. #endif
  837. assert(tcpedit);
  838. assert(pkthdr);
  839. assert(pktdata);
  840. l2len = get_l2len(pktdata, pkthdr->caplen, datalink);
  841. arp_hdr = (arp_hdr_t *)(pktdata + l2len);
  842. /*
  843. * only rewrite IP addresses from REPLY/REQUEST's
  844. */
  845. if ((ntohs(arp_hdr->ar_pro) == ETHERTYPE_IP) &&
  846. ((ntohs(arp_hdr->ar_op) == ARPOP_REQUEST) ||
  847. (ntohs(arp_hdr->ar_op) == ARPOP_REPLY))) {
  848. /* jump to the addresses */
  849. uint32_t *ip;
  850. u_char *add_hdr = ((u_char *)arp_hdr) + sizeof(arp_hdr_t) +
  851. arp_hdr->ar_hln;
  852. #ifdef FORCE_ALIGN
  853. /* copy IP to a temporary buffer for processing */
  854. memcpy(&iptemp, add_hdr, sizeof(uint32_t));
  855. ip = &iptemp;
  856. #else
  857. ip = (uint32_t *)add_hdr;
  858. #endif
  859. *ip = randomize_ipv4_addr(tcpedit, *ip);
  860. #ifdef FORCE_ALIGN
  861. memcpy(add_hdr, &iptemp, sizeof(uint32_t));
  862. #endif
  863. add_hdr += arp_hdr->ar_pln + arp_hdr->ar_hln;
  864. #ifdef FORCE_ALIGN
  865. /* copy IP2 to a temporary buffer for processing */
  866. memcpy(&iptemp, add_hdr, sizeof(uint32_t));
  867. ip = &iptemp;
  868. #else
  869. ip = (uint32_t *)add_hdr;
  870. #endif
  871. *ip = randomize_ipv4_addr(tcpedit, *ip);
  872. #ifdef FORCE_ALIGN
  873. memcpy(add_hdr, &iptemp, sizeof(uint32_t));
  874. #endif
  875. }
  876. return 1; /* yes we changed the packet */
  877. }
  878. /**
  879. * rewrite IP address (arp)
  880. * uses -a to rewrite (map) one subnet onto another subnet
  881. * pointer must point to the WHOLE and CONTIGUOUS memory buffer
  882. * because the arp_hdr_t doesn't have the space for the IP/MAC
  883. * addresses
  884. * return 0 if no change, 1 or 2 if changed
  885. */
  886. int
  887. rewrite_iparp(tcpedit_t *tcpedit, arp_hdr_t *arp_hdr, int cache_mode)
  888. {
  889. u_char *add_hdr = NULL;
  890. uint32_t *ip1 = NULL, *ip2 = NULL;
  891. uint32_t newip = 0;
  892. tcpr_cidrmap_t *cidrmap1 = NULL, *cidrmap2 = NULL;
  893. int didsrc = 0, diddst = 0, loop = 1;
  894. #ifdef FORCE_ALIGN
  895. uint32_t iptemp;
  896. #endif
  897. assert(tcpedit);
  898. assert(arp_hdr);
  899. /* figure out what mapping to use */
  900. if (cache_mode == TCPR_DIR_C2S) {
  901. cidrmap1 = tcpedit->cidrmap1;
  902. cidrmap2 = tcpedit->cidrmap2;
  903. } else if (cache_mode == TCPR_DIR_S2C) {
  904. cidrmap1 = tcpedit->cidrmap2;
  905. cidrmap2 = tcpedit->cidrmap1;
  906. }
  907. /* anything to rewrite? */
  908. if (cidrmap1 == NULL || cidrmap2 == NULL)
  909. return(0);
  910. /*
  911. * must be IPv4 and request or reply
  912. * Do other op codes use the same subheader stub?
  913. * If so we won't need to check the op code.
  914. */
  915. if ((ntohs(arp_hdr->ar_pro) == ETHERTYPE_IP) &&
  916. ((ntohs(arp_hdr->ar_op) == ARPOP_REQUEST) ||
  917. (ntohs(arp_hdr->ar_op) == ARPOP_REPLY)))
  918. {
  919. /* jump to the addresses */
  920. add_hdr = (u_char *)arp_hdr;
  921. add_hdr += sizeof(arp_hdr_t) + arp_hdr->ar_hln;
  922. ip1 = (uint32_t *)add_hdr;
  923. add_hdr += arp_hdr->ar_pln + arp_hdr->ar_hln;
  924. #ifdef FORCE_ALIGN
  925. /* copy IP2 to a temporary buffer for processing */
  926. memcpy(&iptemp, add_hdr, sizeof(uint32_t));
  927. ip2 = &iptemp;
  928. #else
  929. ip2 = (uint32_t *)add_hdr;
  930. #endif
  931. /* loop through the cidrmap to rewrite */
  932. do {
  933. /* arp request ? */
  934. if (ntohs(arp_hdr->ar_op) == ARPOP_REQUEST) {
  935. if ((!diddst) && ip_in_cidr(cidrmap2->from, *ip1)) {
  936. newip = remap_ipv4(tcpedit, cidrmap2->to, *ip1);
  937. memcpy(ip1, &newip, 4);
  938. diddst = 1;
  939. }
  940. if ((!didsrc) && ip_in_cidr(cidrmap1->from, *ip2)) {
  941. newip = remap_ipv4(tcpedit, cidrmap1->to, *ip2);
  942. memcpy(ip2, &newip, 4);
  943. didsrc = 1;
  944. }
  945. }
  946. /* else it's an arp reply */
  947. else {
  948. if ((!diddst) && ip_in_cidr(cidrmap2->from, *ip2)) {
  949. newip = remap_ipv4(tcpedit, cidrmap2->to, *ip2);
  950. memcpy(ip2, &newip, 4);
  951. diddst = 1;
  952. }
  953. if ((!didsrc) && ip_in_cidr(cidrmap1->from, *ip1)) {
  954. newip = remap_ipv4(tcpedit, cidrmap1->to, *ip1);
  955. memcpy(ip1, &newip, 4);
  956. didsrc = 1;
  957. }
  958. }
  959. #ifdef FORCE_ALIGN
  960. /* copy temporary IP to IP2 location in buffer */
  961. memcpy(add_hdr, &iptemp, sizeof(uint32_t));
  962. #endif
  963. /*
  964. * loop while we haven't modified both src/dst AND
  965. * at least one of the cidr maps have a next pointer
  966. */
  967. if ((! (diddst && didsrc)) &&
  968. (! ((cidrmap1->next == NULL) && (cidrmap2->next == NULL)))) {
  969. /* increment our ptr's if possible */
  970. if (cidrmap1->next != NULL)
  971. cidrmap1 = cidrmap1->next;
  972. if (cidrmap2->next != NULL)
  973. cidrmap2 = cidrmap2->next;
  974. } else {
  975. loop = 0;
  976. }
  977. } while (loop);
  978. } else {
  979. warn("ARP packet isn't for IPv4! Can't rewrite IP's");
  980. }
  981. return(didsrc + diddst);
  982. }
  983. /**
  984. * returns 1 if the IP address is a unicast address, otherwise, returns 0
  985. * for broadcast/multicast addresses. Returns -1 on error
  986. */
  987. static int
  988. is_unicast_ipv4(tcpedit_t *tcpedit, uint32_t ip)
  989. {
  990. assert(tcpedit);
  991. /* multicast/broadcast is 224.0.0.0 or greater */
  992. if (ntohl(ip) > 3758096384)
  993. return 0;
  994. return 1;
  995. }
  996. /**
  997. * returns 1 if the IPv6 address is a multicast address, otherwise, returns 0
  998. * for unicast/anycast addresses. Returns -1 on error
  999. */
  1000. static int
  1001. is_multicast_ipv6(tcpedit_t *tcpedit, struct tcpr_in6_addr *addr)
  1002. {
  1003. assert(tcpedit);
  1004. if (addr->tcpr_s6_addr[0] == 0xff)
  1005. return 1;
  1006. return 0;
  1007. }