rewrite_l2.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. /* $Id: rewrite_l2.c 1550 2006-07-31 02:58:32Z aturner $ */
  2. /*
  3. * Copyright (c) 2005 Aaron Turner.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the names of the copyright owners nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  20. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  23. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  25. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  27. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include "config.h"
  32. #include "defines.h"
  33. #include "common.h"
  34. /*
  35. * rewrite_l2.c can be compiled for tcprewrite or tcpbridge
  36. * in both cases, it requires a number of variables to be
  37. * available in the global options structure
  38. */
  39. #include "tcpedit.h"
  40. #include "lib/sll.h"
  41. #include "dlt.h"
  42. #include "rewrite_l2.h"
  43. #include <string.h>
  44. extern int maxpacket;
  45. static int check_pkt_len(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
  46. int oldl2len, int newl2len);
  47. static int is_unicast_l2(tcpedit_t *, const u_char *);
  48. /*
  49. * Do all the layer 2 rewriting. Change ethernet header or even
  50. * rewrite mac addresses
  51. * return layer 2 length on success or 0 on don't send packet
  52. * or -1 on critical failure
  53. */
  54. int
  55. rewrite_l2(tcpedit_t *tcpedit, struct pcap_pkthdr **pkthdr,
  56. u_char **pktdata, int direction)
  57. {
  58. u_char *l2data = NULL; /* ptr to the user specified layer2 data if any */
  59. int newl2len = 0;
  60. pcap_t *pcap;
  61. /* do we need a ptr for l2data ? */
  62. if (tcpedit->l2.dlt == DLT_USER) {
  63. if (direction == CACHE_SECONDARY) {
  64. l2data = tcpedit->l2.data2;
  65. } else {
  66. l2data = tcpedit->l2.data1;
  67. }
  68. }
  69. pcap = direction == CACHE_PRIMARY ? tcpedit->runtime.pcap1 :
  70. tcpedit->runtime.pcap2;
  71. /*
  72. * figure out what the CURRENT packet encapsulation is and we'll call
  73. * the appropriate function to:
  74. * 1) resize the L2 header
  75. * 2) copy over existing L2 header info (protocol, MAC's) to a new
  76. * standard 802.3 ethernet header where applicable
  77. * We do NOT apply any src/dst mac rewriting, as that is common
  78. * to all conversions, so that happens at the bottom of this function
  79. */
  80. switch (pcap_datalink(pcap)) {
  81. case DLT_EN10MB: /* Standard 802.3 Ethernet */
  82. newl2len = rewrite_en10mb(tcpedit, pktdata, pkthdr, l2data);
  83. break;
  84. case DLT_LINUX_SLL: /* Linux Cooked sockets */
  85. newl2len = rewrite_linux_sll(tcpedit, pktdata, pkthdr, l2data);
  86. break;
  87. case DLT_RAW: /* No ethernet header, raw IP */
  88. newl2len = rewrite_raw(tcpedit, pktdata, pkthdr, l2data);
  89. break;
  90. case DLT_C_HDLC: /* Cisco HDLC */
  91. newl2len = rewrite_c_hdlc(tcpedit, pktdata, pkthdr, l2data);
  92. break;
  93. default:
  94. tcpedit_seterr(tcpedit, "Unsupported DLT type: %d",
  95. pcap_datalink(pcap));
  96. return -1;
  97. } /* switch (dlt) */
  98. /* if newl2len == 0, then return zero so we don't send the packet */
  99. if (! newl2len)
  100. return 0;
  101. /*
  102. * Okay... we've got our new layer 2 header
  103. * if required. The next question, is do we have to
  104. * replace the src/dst MAC??
  105. */
  106. switch (direction) {
  107. case CACHE_PRIMARY:
  108. if ((tcpedit->mac_mask & TCPEDIT_MAC_MASK_SMAC1) &&
  109. ((tcpedit->skip_broadcast && is_unicast_l2(tcpedit, (*pktdata + ETHER_ADDR_LEN))) ||
  110. !tcpedit->skip_broadcast)) {
  111. memcpy(*pktdata + ETHER_ADDR_LEN, tcpedit->intf1_smac, ETHER_ADDR_LEN);
  112. }
  113. if ((tcpedit->mac_mask & TCPEDIT_MAC_MASK_DMAC1) &&
  114. ((tcpedit->skip_broadcast && is_unicast_l2(tcpedit, *pktdata)) ||
  115. !tcpedit->skip_broadcast)) {
  116. memcpy(*pktdata, tcpedit->intf1_dmac, ETHER_ADDR_LEN);
  117. }
  118. break;
  119. case CACHE_SECONDARY:
  120. if ((tcpedit->mac_mask & TCPEDIT_MAC_MASK_SMAC2) &&
  121. ((tcpedit->skip_broadcast && is_unicast_l2(tcpedit, (*pktdata + ETHER_ADDR_LEN))) ||
  122. !tcpedit->skip_broadcast)) {
  123. memcpy(*pktdata + ETHER_ADDR_LEN, tcpedit->intf2_smac, ETHER_ADDR_LEN);
  124. }
  125. if ((tcpedit->mac_mask & TCPEDIT_MAC_MASK_DMAC2) &&
  126. ((tcpedit->skip_broadcast && is_unicast_l2(tcpedit, *pktdata)) ||
  127. !tcpedit->skip_broadcast)) {
  128. memcpy(*pktdata, tcpedit->intf2_dmac, ETHER_ADDR_LEN);
  129. }
  130. break;
  131. default:
  132. tcpedit_seterr(tcpedit, "Unknown/supported cache value: %d", direction);
  133. break;
  134. }
  135. /* return the updated layer 2 len */
  136. return (newl2len);
  137. }
  138. /*
  139. * All of these functions return the NEW layer two length and update the
  140. * total packet length in (*pkthdr)->caplen
  141. */
  142. /*
  143. * logic to rewrite packets using DLT_EN10MB
  144. * returns -1 on error
  145. * returns 0 un unable to rewrite
  146. * returns length of new layer 2 header on success
  147. */
  148. int
  149. rewrite_en10mb(tcpedit_t *tcpedit, u_char **pktdata,
  150. struct pcap_pkthdr **pkthdr, u_char *l2data)
  151. {
  152. eth_hdr_t *eth_hdr = NULL;
  153. vlan_hdr_t *vlan_hdr = NULL;
  154. int oldl2len = 0, newl2len = 0, lendiff;
  155. u_char tmpbuff[MAXPACKET];
  156. /*
  157. * is the header ethernet or 802.1q?
  158. */
  159. eth_hdr = (eth_hdr_t *)(*pktdata);
  160. if (eth_hdr->ether_type == ETHERTYPE_VLAN) {
  161. newl2len = oldl2len = TCPR_802_1Q_H;
  162. } else {
  163. newl2len = oldl2len = TCPR_ETH_H;
  164. }
  165. switch (tcpedit->l2.dlt) {
  166. case DLT_USER:
  167. /* track the new L2 len */
  168. newl2len = tcpedit->l2.len;
  169. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  170. return 0; /* unable to send packet */
  171. /*
  172. * remove the old header and copy our header back
  173. */
  174. dbg(3, "Rewriting packet via --dlink...");
  175. /* do we need a temp buff? */
  176. if (newl2len > oldl2len) {
  177. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  178. memcpy(*pktdata, l2data, tcpedit->l2.len);
  179. memcpy(*pktdata + newl2len, (tmpbuff + oldl2len),
  180. (*pkthdr)->caplen);
  181. } else if (newl2len < oldl2len) {
  182. memcpy(*pktdata, l2data, newl2len);
  183. memmove(*pktdata + newl2len, *pktdata + oldl2len,
  184. (*pkthdr)->caplen);
  185. } else { // same size
  186. memcpy(*pktdata, l2data, newl2len);
  187. }
  188. break;
  189. case DLT_VLAN:
  190. /* are we adding/modifying a VLAN header? */
  191. if (tcpedit->vlan == TCPEDIT_VLAN_ADD) {
  192. newl2len = TCPR_802_1Q_H;
  193. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  194. return 0; /* unable to send packet */
  195. vlan_hdr = (vlan_hdr_t *)*pktdata;
  196. /* do we modify the VLAN header? */
  197. if (oldl2len == newl2len) {
  198. /* user must always specify a tag */
  199. vlan_hdr->vlan_priority_c_vid |=
  200. htons((u_int16_t)tcpedit->l2.vlan_tag & TCPR_802_1Q_VIDMASK);
  201. /* these are optional */
  202. if (tcpedit->l2.vlan_pri)
  203. vlan_hdr->vlan_priority_c_vid |=
  204. htons((u_int16_t)tcpedit->l2.vlan_pri) << 13;
  205. if (tcpedit->l2.vlan_cfi)
  206. vlan_hdr->vlan_priority_c_vid |=
  207. htons((u_int16_t)tcpedit->l2.vlan_cfi) << 12;
  208. }
  209. /* else we are adding a VLAN header */
  210. else if (oldl2len == TCPR_ETH_H) {
  211. /* zero out our L2 header */
  212. memset(tmpbuff, 0, newl2len);
  213. /* copy the dst/src MAC's over to our temp buffer */
  214. memcpy(tmpbuff, *pktdata, ETHER_ADDR_LEN * 2);
  215. vlan_hdr = (vlan_hdr_t *)tmpbuff;
  216. eth_hdr = (eth_hdr_t *)*pktdata;
  217. /* these fields are always set this way */
  218. vlan_hdr->vlan_tpi = htons(ETHERTYPE_VLAN);
  219. vlan_hdr->vlan_len = eth_hdr->ether_type;
  220. /* user must always specify a tag */
  221. vlan_hdr->vlan_priority_c_vid |=
  222. htons((u_int16_t)tcpedit->l2.vlan_tag & TCPR_802_1Q_VIDMASK);
  223. /* other things are optional */
  224. if (tcpedit->l2.vlan_pri)
  225. vlan_hdr->vlan_priority_c_vid |=
  226. htons((u_int16_t)tcpedit->l2.vlan_pri) << 13;
  227. if (tcpedit->l2.vlan_cfi)
  228. vlan_hdr->vlan_priority_c_vid |=
  229. htons((u_int16_t)tcpedit->l2.vlan_cfi) << 12;
  230. /* move around our buffers */
  231. memcpy(&tmpbuff[newl2len], (*pktdata + oldl2len), ((*pkthdr)->caplen - oldl2len));
  232. memcpy(*pktdata, tmpbuff, ((*pkthdr)->caplen + newl2len - oldl2len));
  233. } else {
  234. err(1, "Uh, how are we supposed to rewrite the header when the oldl2len != TCPR_ETH_H?");
  235. }
  236. }
  237. else {
  238. /* remove VLAN header */
  239. newl2len = TCPR_ETH_H;
  240. /* we still verify packet len incase MTU has shrunk */
  241. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  242. return 0; /* unable to send packet */
  243. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  244. eth_hdr = (eth_hdr_t *)*pktdata;
  245. vlan_hdr = (vlan_hdr_t *)tmpbuff;
  246. eth_hdr->ether_type = vlan_hdr->vlan_len;
  247. memcpy(*pktdata + TCPR_ETH_H, (tmpbuff + TCPR_802_1Q_H), (*pkthdr)->caplen - oldl2len);
  248. }
  249. break;
  250. case DLT_EN10MB:
  251. /* nothing to do here since we're already ethernet! */
  252. break;
  253. default:
  254. tcpedit_seterr(tcpedit, "Invalid tcpedit->l2.dlt value: 0x%04x", tcpedit->l2.dlt);
  255. return -1;
  256. break;
  257. }
  258. /* new packet len */
  259. lendiff = newl2len - oldl2len;
  260. (*pkthdr)->caplen += lendiff;
  261. (*pkthdr)->len += lendiff;
  262. return newl2len;
  263. }
  264. /*
  265. * logic to rewrite packets using DLT_RAW
  266. * returns -1 on error
  267. * returns 0 un unable to rewrite
  268. * returns length of new layer 2 header on success
  269. */
  270. int
  271. rewrite_raw(tcpedit_t *tcpedit, u_char **pktdata,
  272. struct pcap_pkthdr **pkthdr, u_char *l2data)
  273. {
  274. int oldl2len = 0, newl2len = 0, lendiff;
  275. u_char tmpbuff[MAXPACKET];
  276. vlan_hdr_t *vlan_hdr = NULL;
  277. eth_hdr_t *eth_hdr = NULL;
  278. /* we have no ethernet header, but we know we're IP */
  279. switch (tcpedit->l2.dlt) {
  280. case DLT_USER:
  281. newl2len = tcpedit->l2.len;
  282. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  283. return 0; /* unable to send packet */
  284. /*
  285. * add our user specified header
  286. */
  287. dbg(3, "Rewriting packet via --dlink...");
  288. /* backup the old packet */
  289. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  290. memcpy(*pktdata, l2data, newl2len);
  291. memcpy(*pktdata + newl2len, tmpbuff, (*pkthdr)->caplen);
  292. break;
  293. case DLT_VLAN:
  294. newl2len = TCPR_802_1Q_H;
  295. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  296. return 0; /* unable to send packet */
  297. /* prep a 802.1q tagged frame */
  298. /* make space for the header */
  299. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  300. memcpy(*pktdata + TCPR_802_1Q_H, tmpbuff, (*pkthdr)->caplen);
  301. vlan_hdr = (vlan_hdr_t *)*pktdata;
  302. /* these fields are always set this way */
  303. vlan_hdr->vlan_tpi = ETHERTYPE_VLAN;
  304. vlan_hdr->vlan_len = tcpedit->l2proto;
  305. /* user must always specify a tag */
  306. vlan_hdr->vlan_priority_c_vid |=
  307. htons((u_int16_t)tcpedit->l2.vlan_tag & TCPR_802_1Q_VIDMASK);
  308. /* other things are optional */
  309. if (tcpedit->l2.vlan_pri)
  310. vlan_hdr->vlan_priority_c_vid |=
  311. htons((u_int16_t)tcpedit->l2.vlan_pri) << 13;
  312. if (tcpedit->l2.vlan_cfi)
  313. vlan_hdr->vlan_priority_c_vid |=
  314. htons((u_int16_t)tcpedit->l2.vlan_cfi) << 12;
  315. /* new packet len */
  316. newl2len = TCPR_802_1Q_H;
  317. break;
  318. case DLT_EN10MB:
  319. newl2len = TCPR_ETH_H;
  320. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  321. return 0; /* unable to send packet */
  322. /* make room for L2 header */
  323. memmove(*pktdata + TCPR_ETH_H, *pktdata, (*pkthdr)->caplen);
  324. /* these fields are always set this way */
  325. eth_hdr = (eth_hdr_t *)*pktdata;
  326. eth_hdr->ether_type = tcpedit->l2proto;
  327. break;
  328. default:
  329. tcpedit_seterr(tcpedit, "Invalid tcpedit->l2.dlt value: 0x%x", tcpedit->l2.dlt);
  330. return -1;
  331. break;
  332. }
  333. /* new packet len */
  334. lendiff = newl2len - oldl2len;
  335. (*pkthdr)->caplen += lendiff;
  336. (*pkthdr)->len += lendiff;
  337. return newl2len;
  338. }
  339. /*
  340. * logic to rewrite packets using DLT_LINUX_SLL
  341. * returns -1 on error
  342. * returns 0 un unable to rewrite
  343. * returns length of new layer 2 header on success
  344. */
  345. int
  346. rewrite_linux_sll(tcpedit_t *tcpedit, u_char **pktdata,
  347. struct pcap_pkthdr **pkthdr, u_char *l2data)
  348. {
  349. int oldl2len = 0, newl2len = 0, lendiff;
  350. u_char tmpbuff[MAXPACKET];
  351. vlan_hdr_t *vlan_hdr = NULL;
  352. eth_hdr_t *eth_hdr = NULL;
  353. sll_hdr_t *sll_hdr = NULL;
  354. newl2len = oldl2len = SLL_HDR_LEN;
  355. switch (tcpedit->l2.dlt) {
  356. case DLT_USER:
  357. newl2len = tcpedit->l2.len;
  358. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  359. return 0; /* unable to send packet */
  360. /*
  361. * add our user specified header
  362. */
  363. dbg(3, "Rewriting packet via --dlink...");
  364. /* backup the old packet */
  365. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  366. memcpy(*pktdata, l2data, newl2len);
  367. memcpy(*pktdata + newl2len, tmpbuff, (*pkthdr)->caplen);
  368. break;
  369. case DLT_VLAN:
  370. /* prep a 802.1q tagged frame */
  371. newl2len = TCPR_802_1Q_H;
  372. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  373. return 0; /* unable to send packet */
  374. /* make space for the header */
  375. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  376. memcpy(*pktdata + TCPR_802_1Q_H, tmpbuff, (*pkthdr)->caplen - oldl2len);
  377. vlan_hdr = (vlan_hdr_t *)*pktdata;
  378. sll_hdr = (sll_hdr_t *)tmpbuff;
  379. /* these fields are always set this way */
  380. vlan_hdr->vlan_tpi = ETHERTYPE_VLAN;
  381. vlan_hdr->vlan_len = sll_hdr->sll_protocol;
  382. /* the sll header might have a src mac */
  383. if (sll_hdr->sll_halen == ETHER_ADDR_LEN)
  384. memcpy(vlan_hdr->vlan_shost, sll_hdr->sll_addr, ETHER_ADDR_LEN);
  385. /* user must always specify a tag */
  386. vlan_hdr->vlan_priority_c_vid |=
  387. htons((u_int16_t)(tcpedit->l2.vlan_tag & TCPR_802_1Q_VIDMASK));
  388. /* other things are optional */
  389. if (tcpedit->l2.vlan_pri)
  390. vlan_hdr->vlan_priority_c_vid |=
  391. htons((u_int16_t)tcpedit->l2.vlan_pri) << 13;
  392. if (tcpedit->l2.vlan_cfi)
  393. vlan_hdr->vlan_priority_c_vid |=
  394. htons((u_int16_t)tcpedit->l2.vlan_cfi) << 12;
  395. break;
  396. case DLT_EN10MB:
  397. newl2len = TCPR_ETH_H;
  398. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  399. return 0; /* unable to send packet */
  400. /* make room for L2 header */
  401. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  402. memcpy(*pktdata + TCPR_ETH_H, (tmpbuff + oldl2len), (*pkthdr)->caplen - oldl2len);
  403. /* these fields are always set this way */
  404. sll_hdr = (sll_hdr_t *)tmpbuff;
  405. eth_hdr = (eth_hdr_t *)*pktdata;
  406. eth_hdr->ether_type = sll_hdr->sll_protocol;
  407. /* the sll header might have a src mac */
  408. if (sll_hdr->sll_halen == ETHER_ADDR_LEN)
  409. memcpy(eth_hdr->ether_shost, sll_hdr->sll_addr, ETHER_ADDR_LEN);
  410. break;
  411. default:
  412. tcpedit_seterr(tcpedit, "Invalid tcpedit->l2.dlt value: 0x%x", tcpedit->l2.dlt);
  413. return -1;
  414. break;
  415. }
  416. /* new packet len */
  417. lendiff = newl2len - oldl2len;
  418. (*pkthdr)->caplen += lendiff;
  419. (*pkthdr)->len += lendiff;
  420. return newl2len;
  421. }
  422. /*
  423. * logic to rewrite packets using DLT_C_HDLC
  424. * returns -1 on error or 0 on unable to send packet. Returns length of new
  425. * layer 2 header
  426. */
  427. int
  428. rewrite_c_hdlc(tcpedit_t *tcpedit, u_char **pktdata,
  429. struct pcap_pkthdr **pkthdr, u_char *l2data)
  430. {
  431. int oldl2len = 0, newl2len = 0, lendiff;
  432. u_char tmpbuff[MAXPACKET];
  433. hdlc_hdr_t *hdlc_hdr = NULL;
  434. eth_hdr_t *eth_hdr = NULL;
  435. vlan_hdr_t *vlan_hdr = NULL;
  436. newl2len = oldl2len = dlt2layer2len(tcpedit, DLT_C_HDLC);
  437. switch (tcpedit->l2.dlt) {
  438. case DLT_USER:
  439. /* track the new L2 len */
  440. newl2len = dlt2layer2len(tcpedit, DLT_USER);
  441. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  442. return 0; /* unable to send packet */
  443. /*
  444. * add our user specified header
  445. */
  446. dbg(3, "Rewriting packet via --dlink...");
  447. /* backup the old packet */
  448. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  449. memcpy(*pktdata, l2data, tcpedit->l2.len);
  450. memcpy(*pktdata + tcpedit->l2.len, (tmpbuff + oldl2len), (*pkthdr)->caplen - oldl2len);
  451. break;
  452. case DLT_VLAN:
  453. /* new l2 len */
  454. newl2len = dlt2layer2len(tcpedit, DLT_VLAN);
  455. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  456. return 0; /* unable to send packet */
  457. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  458. hdlc_hdr = (hdlc_hdr_t *)tmpbuff;
  459. vlan_hdr = (vlan_hdr_t *)*pktdata;
  460. memcpy(*pktdata + TCPR_802_1Q_H, tmpbuff + oldl2len, (*pkthdr)->caplen - oldl2len);
  461. vlan_hdr->vlan_tpi = ETHERTYPE_VLAN;
  462. vlan_hdr->vlan_len = hdlc_hdr->protocol;
  463. /* user must always specify a tag */
  464. vlan_hdr->vlan_priority_c_vid |=
  465. htons((u_int16_t)tcpedit->l2.vlan_tag & TCPR_802_1Q_VIDMASK);
  466. /* other things are optional */
  467. if (tcpedit->l2.vlan_pri)
  468. vlan_hdr->vlan_priority_c_vid |=
  469. htons((u_int16_t)tcpedit->l2.vlan_pri) << 13;
  470. if (tcpedit->l2.vlan_cfi)
  471. vlan_hdr->vlan_priority_c_vid |=
  472. htons((u_int16_t)tcpedit->l2.vlan_cfi) << 12;
  473. break;
  474. case DLT_EN10MB:
  475. newl2len = dlt2layer2len(tcpedit, DLT_EN10MB);
  476. if (! check_pkt_len(tcpedit, *pkthdr, oldl2len, newl2len))
  477. return 0; /* unable to send packet */
  478. memcpy(tmpbuff, *pktdata, (*pkthdr)->caplen);
  479. hdlc_hdr = (hdlc_hdr_t *)tmpbuff;
  480. eth_hdr = (eth_hdr_t *)*pktdata;
  481. memcpy(*pktdata + TCPR_ETH_H, tmpbuff + oldl2len, (*pkthdr)->caplen - oldl2len);
  482. eth_hdr->ether_type = hdlc_hdr->protocol;
  483. break;
  484. default:
  485. tcpedit_seterr(tcpedit, "Invalid tcpedit->l2.dlt value: 0x%x", tcpedit->l2.dlt);
  486. return -1;
  487. break;
  488. }
  489. /* new packet len */
  490. lendiff = newl2len - oldl2len;
  491. (*pkthdr)->caplen += lendiff;
  492. (*pkthdr)->len += lendiff;
  493. return newl2len;
  494. }
  495. /*
  496. * will the new packet be too big?
  497. * If so, we have to change the (*pkthdr)->caplen to be artifically lower
  498. * so we don't go beyond tcpedit->maxpacket
  499. */
  500. static int
  501. check_pkt_len(tcpedit_t *tcpedit, struct pcap_pkthdr *pkthdr,
  502. int oldl2len, int newl2len)
  503. {
  504. /*
  505. * is new packet too big?
  506. */
  507. if ((pkthdr->caplen - oldl2len + newl2len) > (u_int)tcpedit->maxpacket) {
  508. if (tcpedit->fixlen) {
  509. warnx("Packet length (%u) is greater then MTU (%u); "
  510. "truncating packet.",
  511. (pkthdr->caplen - oldl2len + newl2len), tcpedit->maxpacket);
  512. /* set our packet length to the max packet size */
  513. pkthdr->caplen = tcpedit->maxpacket;
  514. }
  515. else {
  516. warnx("Packet length (%u) is greater then MTU (%u); "
  517. "skipping packet.",
  518. (pkthdr->caplen - oldl2len + newl2len), tcpedit->maxpacket);
  519. return (0);
  520. }
  521. }
  522. /* all is fine */
  523. return 1;
  524. }
  525. /*
  526. * takes a ptr to an ethernet address and returns
  527. * 1 if it is unicast or 0 if it is multicast or
  528. * broadcast.
  529. */
  530. static int
  531. is_unicast_l2(tcpedit_t *tcpedit, const u_char *ether)
  532. {
  533. assert(tcpedit);
  534. assert(ether);
  535. /* is broadcast? */
  536. if (memcmp(ether, BROADCAST_MAC, ETHER_ADDR_LEN) == 0)
  537. return 0;
  538. /* Multicast addresses' leading octet are odd */
  539. if ((ether[0] & 0x01) == 0x01)
  540. return 0;
  541. /* everything else is unicast */
  542. return 1;
  543. }
  544. /*
  545. Local Variables:
  546. mode:c
  547. indent-tabs-mode:nil
  548. c-basic-offset:4
  549. End:
  550. */