edit_packet.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134
  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, tempip;
  793. u_char *add_hdr;
  794. assert(tcpedit);
  795. assert(pkthdr);
  796. assert(pktdata);
  797. l2len = get_l2len(pktdata, pkthdr->caplen, datalink);
  798. arp_hdr = (arp_hdr_t *)(pktdata + l2len);
  799. /*
  800. * only rewrite IP addresses from REPLY/REQUEST's
  801. */
  802. if ((ntohs(arp_hdr->ar_pro) == ETHERTYPE_IP) &&
  803. ((ntohs(arp_hdr->ar_op) == ARPOP_REQUEST) ||
  804. (ntohs(arp_hdr->ar_op) == ARPOP_REPLY))) {
  805. /* jump to the addresses */
  806. add_hdr = (u_char *)arp_hdr;
  807. add_hdr += sizeof(arp_hdr_t) + arp_hdr->ar_hln;
  808. ip = (uint32_t *)add_hdr;
  809. tempip = randomize_ipv4_addr(tcpedit, *ip);
  810. memcpy(ip, &tempip, sizeof(uint32_t));
  811. add_hdr += arp_hdr->ar_pln + arp_hdr->ar_hln;
  812. ip = (uint32_t *)add_hdr;
  813. tempip = randomize_ipv4_addr(tcpedit, *ip);
  814. memcpy(ip, &tempip, sizeof(uint32_t));
  815. }
  816. return 1; /* yes we changed the packet */
  817. }
  818. /**
  819. * rewrite IP address (arp)
  820. * uses -a to rewrite (map) one subnet onto another subnet
  821. * pointer must point to the WHOLE and CONTIGOUS memory buffer
  822. * because the arp_hdr_t doesn't have the space for the IP/MAC
  823. * addresses
  824. * return 0 if no change, 1 or 2 if changed
  825. */
  826. int
  827. rewrite_iparp(tcpedit_t *tcpedit, arp_hdr_t *arp_hdr, int cache_mode)
  828. {
  829. u_char *add_hdr = NULL;
  830. uint32_t *ip1 = NULL, *ip2 = NULL;
  831. uint32_t newip = 0;
  832. tcpr_cidrmap_t *cidrmap1 = NULL, *cidrmap2 = NULL;
  833. int didsrc = 0, diddst = 0, loop = 1;
  834. #ifdef FORCE_ALIGN
  835. uint32_t iptemp;
  836. #endif
  837. assert(tcpedit);
  838. assert(arp_hdr);
  839. /* figure out what mapping to use */
  840. if (cache_mode == TCPR_DIR_C2S) {
  841. cidrmap1 = tcpedit->cidrmap1;
  842. cidrmap2 = tcpedit->cidrmap2;
  843. } else if (cache_mode == TCPR_DIR_S2C) {
  844. cidrmap1 = tcpedit->cidrmap2;
  845. cidrmap2 = tcpedit->cidrmap1;
  846. }
  847. /* anything to rewrite? */
  848. if (cidrmap1 == NULL || cidrmap2 == NULL)
  849. return(0);
  850. /*
  851. * must be IPv4 and request or reply
  852. * Do other op codes use the same subheader stub?
  853. * If so we won't need to check the op code.
  854. */
  855. if ((ntohs(arp_hdr->ar_pro) == ETHERTYPE_IP) &&
  856. ((ntohs(arp_hdr->ar_op) == ARPOP_REQUEST) ||
  857. (ntohs(arp_hdr->ar_op) == ARPOP_REPLY)))
  858. {
  859. /* jump to the addresses */
  860. add_hdr = (u_char *)arp_hdr;
  861. add_hdr += sizeof(arp_hdr_t) + arp_hdr->ar_hln;
  862. ip1 = (uint32_t *)add_hdr;
  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. ip2 = &iptemp;
  868. #else
  869. ip2 = (uint32_t *)add_hdr;
  870. #endif
  871. /* loop through the cidrmap to rewrite */
  872. do {
  873. /* arp request ? */
  874. if (ntohs(arp_hdr->ar_op) == ARPOP_REQUEST) {
  875. if ((!diddst) && ip_in_cidr(cidrmap2->from, *ip1)) {
  876. newip = remap_ipv4(tcpedit, cidrmap2->to, *ip1);
  877. memcpy(ip1, &newip, 4);
  878. diddst = 1;
  879. }
  880. if ((!didsrc) && ip_in_cidr(cidrmap1->from, *ip2)) {
  881. newip = remap_ipv4(tcpedit, cidrmap1->to, *ip2);
  882. memcpy(ip2, &newip, 4);
  883. didsrc = 1;
  884. }
  885. }
  886. /* else it's an arp reply */
  887. else {
  888. if ((!diddst) && ip_in_cidr(cidrmap2->from, *ip2)) {
  889. newip = remap_ipv4(tcpedit, cidrmap2->to, *ip2);
  890. memcpy(ip2, &newip, 4);
  891. diddst = 1;
  892. }
  893. if ((!didsrc) && ip_in_cidr(cidrmap1->from, *ip1)) {
  894. newip = remap_ipv4(tcpedit, cidrmap1->to, *ip1);
  895. memcpy(ip1, &newip, 4);
  896. didsrc = 1;
  897. }
  898. }
  899. #ifdef FORCE_ALIGN
  900. /* copy temporary IP to IP2 location in buffer */
  901. memcpy(add_hdr, &iptemp, sizeof(uint32_t));
  902. #endif
  903. /*
  904. * loop while we haven't modified both src/dst AND
  905. * at least one of the cidr maps have a next pointer
  906. */
  907. if ((! (diddst && didsrc)) &&
  908. (! ((cidrmap1->next == NULL) && (cidrmap2->next == NULL)))) {
  909. /* increment our ptr's if possible */
  910. if (cidrmap1->next != NULL)
  911. cidrmap1 = cidrmap1->next;
  912. if (cidrmap2->next != NULL)
  913. cidrmap2 = cidrmap2->next;
  914. } else {
  915. loop = 0;
  916. }
  917. } while (loop);
  918. } else {
  919. warn("ARP packet isn't for IPv4! Can't rewrite IP's");
  920. }
  921. return(didsrc + diddst);
  922. }
  923. /**
  924. * returns 1 if the IP address is a unicast address, otherwise, returns 0
  925. * for broadcast/multicast addresses. Returns -1 on error
  926. */
  927. static int
  928. is_unicast_ipv4(tcpedit_t *tcpedit, uint32_t ip)
  929. {
  930. assert(tcpedit);
  931. /* multicast/broadcast is 224.0.0.0 or greater */
  932. if (ntohl(ip) > 3758096384)
  933. return 0;
  934. return 1;
  935. }
  936. /**
  937. * returns 1 if the IPv6 address is a multicast address, otherwise, returns 0
  938. * for unicast/anycast addresses. Returns -1 on error
  939. */
  940. static int
  941. is_multicast_ipv6(tcpedit_t *tcpedit, struct tcpr_in6_addr *addr)
  942. {
  943. assert(tcpedit);
  944. if (addr->tcpr_s6_addr[0] == 0xff)
  945. return 1;
  946. return 0;
  947. }