edit_packet.c 34 KB

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