Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / env / common / vera / niu_ippktgen / C / libnet / src / libnet_build_ospf.c
CommitLineData
86530b38
AT
1/*
2 * $Id: libnet_build_ospf.c,v 1.21 2005/11/29 22:01:00 carlosc Exp $
3 *
4 * libnet
5 * libnet_build_ospf.c - OSPF packet assembler
6 *
7 * Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
8 * All rights reserved.
9 *
10 * Copyright (c) 1999, 2000 Andrew Reiter <areiter@bindview.com>
11 * Bindview Development
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 */
35
36#if (HAVE_CONFIG_H)
37#include "../include/config.h"
38#endif
39#if (!(_WIN32) || (__CYGWIN__))
40#include "../include/libnet.h"
41#else
42#include "../include/win32/libnet.h"
43#endif
44
45libnet_ptag_t
46libnet_build_ospfv2(u_int16_t len, u_int8_t type, u_int32_t rtr_id,
47u_int32_t area_id, u_int16_t sum, u_int16_t autype, u_int8_t *payload,
48u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
49{
50 u_int32_t n, h;
51 libnet_pblock_t *p;
52 struct libnet_ospf_hdr ospf_hdr;
53
54 if (l == NULL)
55 {
56 return (-1);
57 }
58
59 n = LIBNET_OSPF_H + payload_s;
60 h = LIBNET_OSPF_H + payload_s + len;
61
62 /*
63 * Find the existing protocol block if a ptag is specified, or create
64 * a new one.
65 */
66 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_H);
67 if (p == NULL)
68 {
69 return (-1);
70 }
71
72 memset(&ospf_hdr, 0, sizeof(ospf_hdr));
73 ospf_hdr.ospf_v = 2; /* OSPF version 2 */
74 ospf_hdr.ospf_type = type; /* Type of pkt */
75 ospf_hdr.ospf_len = htons(h); /* Pkt len */
76 ospf_hdr.ospf_rtr_id.s_addr = htonl(rtr_id); /* Router ID */
77 ospf_hdr.ospf_area_id.s_addr = htonl(area_id); /* Area ID */
78 ospf_hdr.ospf_sum = (sum ? htons(sum) : 0);
79 ospf_hdr.ospf_auth_type = htons(autype); /* Type of auth */
80
81 n = libnet_pblock_append(l, p, (u_int8_t *)&ospf_hdr, LIBNET_OSPF_H);
82 if (n == -1)
83 {
84 goto bad;
85 }
86
87 if ((payload && !payload_s) || (!payload && payload_s))
88 {
89 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
90 "%s(): payload inconsistency\n", __func__);
91 goto bad;
92 }
93
94 if (payload && payload_s)
95 {
96 n = libnet_pblock_append(l, p, payload, payload_s);
97 if (n == -1)
98 {
99 goto bad;
100 }
101 }
102
103 if (sum == 0)
104 {
105 /*
106 * If checksum is zero, by default libnet will compute a checksum
107 * for the user. The programmer can override this by calling
108 * libnet_toggle_checksum(l, ptag, 1);
109 */
110 libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
111 }
112 return (ptag ? ptag : libnet_pblock_update(l, p, h, LIBNET_PBLOCK_OSPF_H));
113bad:
114 libnet_pblock_delete(l, p);
115 return (-1);
116}
117
118
119libnet_ptag_t
120libnet_build_ospfv2_hello(u_int32_t netmask, u_int16_t interval, u_int8_t opts,
121u_int8_t priority, u_int32_t dead_int, u_int32_t des_rtr, u_int32_t bkup_rtr,
122u_int32_t neighbor, u_int8_t *payload, u_int32_t payload_s, libnet_t *l,
123libnet_ptag_t ptag)
124{
125 u_int32_t n, h;
126 libnet_pblock_t *p;
127 struct libnet_ospf_hello_hdr hello_hdr;
128
129 if (l == NULL)
130 {
131 return (-1);
132 }
133
134 n = LIBNET_OSPF_HELLO_H + payload_s;
135 h = 0;
136
137 /*
138 * Find the existing protocol block if a ptag is specified, or create
139 * a new one.
140 */
141 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_HELLO_H);
142 if (p == NULL)
143 {
144 return (-1);
145 }
146
147 memset(&hello_hdr, 0, sizeof(hello_hdr));
148 hello_hdr.hello_nmask.s_addr = htonl(netmask); /* Netmask */
149 hello_hdr.hello_intrvl = htons(interval); /* # seconds since last packet sent */
150 hello_hdr.hello_opts = opts; /* OSPF_* options */
151 hello_hdr.hello_rtr_pri = priority; /* If 0, can't be backup */
152 hello_hdr.hello_dead_intvl = htonl(dead_int); /* Time til router is deemed down */
153 hello_hdr.hello_des_rtr.s_addr = htonl(des_rtr); /* Networks designated router */
154 hello_hdr.hello_bkup_rtr.s_addr = htonl(bkup_rtr); /* Networks backup router */
155 hello_hdr.hello_nbr.s_addr = htonl(neighbor);
156
157 n = libnet_pblock_append(l, p, (u_int8_t *)&hello_hdr, LIBNET_OSPF_HELLO_H);
158 if (n == -1)
159 {
160 goto bad;
161 }
162
163 if ((payload && !payload_s) || (!payload && payload_s))
164 {
165 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
166 "%s(): payload inconsistency\n", __func__);
167 goto bad;
168 }
169
170 if (payload && payload_s)
171 {
172 n = libnet_pblock_append(l, p, payload, payload_s);
173 if (n == -1)
174 {
175 goto bad;
176 }
177 }
178
179 return (ptag ? ptag : libnet_pblock_update(l, p, h,
180 LIBNET_PBLOCK_OSPF_HELLO_H));
181bad:
182 libnet_pblock_delete(l, p);
183 return (-1);
184}
185
186
187libnet_ptag_t
188libnet_build_ospfv2_dbd(u_int16_t dgram_len, u_int8_t opts, u_int8_t type,
189u_int32_t seqnum, u_int8_t *payload, u_int32_t payload_s, libnet_t *l,
190libnet_ptag_t ptag)
191{
192 u_int32_t n, h;
193 libnet_pblock_t *p;
194 struct libnet_dbd_hdr dbd_hdr;
195
196 if (l == NULL)
197 {
198 return (-1);
199 }
200
201 n = LIBNET_OSPF_DBD_H + payload_s;
202 h = 0;
203
204 /*
205 * Find the existing protocol block if a ptag is specified, or create
206 * a new one.
207 */
208 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_DBD_H);
209 if (p == NULL)
210 {
211 return (-1);
212 }
213
214 memset(&dbd_hdr, 0, sizeof(dbd_hdr));
215 dbd_hdr.dbd_mtu_len = htons(dgram_len); /* Max length of IP packet IF can use */
216 dbd_hdr.dbd_opts = opts; /* OSPF_* options */
217 dbd_hdr.dbd_type = type; /* Type of exchange occuring */
218 dbd_hdr.dbd_seq = htonl(seqnum); /* DBD sequence number */
219
220 n = libnet_pblock_append(l, p, (u_int8_t *)&dbd_hdr, LIBNET_OSPF_DBD_H);
221 if (n == -1)
222 {
223 goto bad;
224 }
225
226 if ((payload && !payload_s) || (!payload && payload_s))
227 {
228 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
229 "%s(): payload inconsistency\n", __func__);
230 goto bad;
231 }
232
233 if (payload && payload_s)
234 {
235 n = libnet_pblock_append(l, p, payload, payload_s);
236 if (n == -1)
237 {
238 goto bad;
239 }
240 }
241
242 return (ptag ? ptag : libnet_pblock_update(l, p, h,
243 LIBNET_PBLOCK_OSPF_DBD_H));
244bad:
245 libnet_pblock_delete(l, p);
246 return (-1);
247}
248
249
250libnet_ptag_t
251libnet_build_ospfv2_lsr(u_int32_t type, u_int lsid, u_int32_t advrtr,
252u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
253{
254 u_int32_t n, h;
255 libnet_pblock_t *p;
256 struct libnet_lsr_hdr lsr_hdr;
257
258 if (l == NULL)
259 {
260 return (-1);
261 }
262
263 n = LIBNET_OSPF_LSR_H + payload_s;
264 h = 0;
265
266 /*
267 * Find the existing protocol block if a ptag is specified, or create
268 * a new one.
269 */
270 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_LSR_H);
271 if (p == NULL)
272 {
273 return (-1);
274 }
275
276 memset(&lsr_hdr, 0, sizeof(lsr_hdr));
277 lsr_hdr.lsr_type = htonl(type); /* Type of LS being requested */
278 lsr_hdr.lsr_lsid = htonl(lsid); /* Link State ID */
279 lsr_hdr.lsr_adrtr.s_addr = htonl(advrtr); /* Advertising router */
280
281 n = libnet_pblock_append(l, p, (u_int8_t *)&lsr_hdr, LIBNET_OSPF_LSR_H);
282 if (n == -1)
283 {
284 goto bad;
285 }
286
287 if ((payload && !payload_s) || (!payload && payload_s))
288 {
289 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
290 "%s(): payload inconsistency\n", __func__);
291 goto bad;
292 }
293
294 if (payload && payload_s)
295 {
296 n = libnet_pblock_append(l, p, payload, payload_s);
297 if (n == -1)
298 {
299 goto bad;
300 }
301 }
302
303 return (ptag ? ptag : libnet_pblock_update(l, p, h,
304 LIBNET_PBLOCK_OSPF_LSR_H));
305bad:
306 libnet_pblock_delete(l, p);
307 return (-1);
308}
309
310
311libnet_ptag_t
312libnet_build_ospfv2_lsu(u_int32_t num, u_int8_t *payload, u_int32_t payload_s,
313libnet_t *l, libnet_ptag_t ptag)
314{
315 u_int32_t n, h;
316 libnet_pblock_t *p;
317 struct libnet_lsu_hdr lh_hdr;
318
319 if (l == NULL)
320 {
321 return (-1);
322 }
323
324 n = LIBNET_OSPF_LSU_H + payload_s;
325 h = 0;
326
327 /*
328 * Find the existing protocol block if a ptag is specified, or create
329 * a new one.
330 */
331 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_LSU_H);
332 if (p == NULL)
333 {
334 return (-1);
335 }
336
337 memset(&lh_hdr, 0, sizeof(lh_hdr));
338 lh_hdr.lsu_num = htonl(num); /* Number of LSAs that will be bcasted */
339
340 n = libnet_pblock_append(l, p, (u_int8_t *)&lh_hdr, LIBNET_OSPF_LSU_H);
341 if (n == -1)
342 {
343 goto bad;
344 }
345
346 if ((payload && !payload_s) || (!payload && payload_s))
347 {
348 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
349 "%s(): payload inconsistency\n", __func__);
350 goto bad;
351 }
352
353 if (payload && payload_s)
354 {
355 n = libnet_pblock_append(l, p, payload, payload_s);
356 if (n == -1)
357 {
358 goto bad;
359 }
360 }
361
362 return (ptag ? ptag : libnet_pblock_update(l, p, h,
363 LIBNET_PBLOCK_OSPF_LSU_H));
364bad:
365 libnet_pblock_delete(l, p);
366 return (-1);
367}
368
369
370libnet_ptag_t
371libnet_build_ospfv2_lsa(u_int16_t age, u_int8_t opts, u_int8_t type, u_int lsid,
372u_int32_t advrtr, u_int32_t seqnum, u_int16_t sum, u_int16_t len,
373u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
374{
375 u_int32_t n, h;
376 libnet_pblock_t *p;
377 struct libnet_lsa_hdr lsa_hdr;
378
379 if (l == NULL)
380 {
381 return (-1);
382 }
383
384 n = LIBNET_OSPF_LSA_H + payload_s;
385 h = len + payload_s;
386
387 /*
388 * Find the existing protocol block if a ptag is specified, or create
389 * a new one.
390 */
391 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_OSPF_LSA_H);
392 if (p == NULL)
393 {
394 return (-1);
395 }
396
397 memset(&lsa_hdr, 0, sizeof(lsa_hdr));
398 lsa_hdr.lsa_age = htons(age);
399 lsa_hdr.lsa_opts = opts;
400 lsa_hdr.lsa_type = type;
401 lsa_hdr.lsa_id = htonl(lsid);
402 lsa_hdr.lsa_adv.s_addr = htonl(advrtr);
403 lsa_hdr.lsa_seq = htonl(seqnum);
404 lsa_hdr.lsa_sum = (sum ? htons(sum) : 0);
405 lsa_hdr.lsa_len = htons(h);
406
407 n = libnet_pblock_append(l, p, (u_int8_t *)&lsa_hdr, LIBNET_OSPF_LSA_H);
408 if (n == -1)
409 {
410 goto bad;
411 }
412
413 if ((payload && !payload_s) || (!payload && payload_s))
414 {
415 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
416 "%s(): payload inconsistency\n", __func__);
417 goto bad;
418 }
419
420 if (payload && payload_s)
421 {
422 n = libnet_pblock_append(l, p, payload, payload_s);
423 if (n == -1)
424 {
425 goto bad;
426 }
427 }
428
429 if (sum == 0)
430 {
431 /*
432 * If checksum is zero, by default libnet will compute a checksum
433 * for the user. The programmer can override this by calling
434 * libnet_toggle_checksum(l, ptag, 1);
435 */
436 libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM);
437 }
438 return (ptag ? ptag : libnet_pblock_update(l, p, h,
439 LIBNET_PBLOCK_OSPF_LSA_H));
440bad:
441 libnet_pblock_delete(l, p);
442 return (-1);
443}
444
445
446libnet_ptag_t
447libnet_build_ospfv2_lsa_rtr(u_int16_t flags, u_int16_t num, u_int32_t id,
448u_int32_t data, u_int8_t type, u_int8_t tos, u_int16_t metric,
449u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
450{
451 u_int32_t n, h;
452 libnet_pblock_t *p;
453 struct libnet_rtr_lsa_hdr rtr_lsa_hdr;
454
455 if (l == NULL)
456 {
457 return (-1);
458 }
459
460 n = LIBNET_OSPF_LS_RTR_H + payload_s;
461 h = 0;
462
463 /*
464 * Find the existing protocol block if a ptag is specified, or create
465 * a new one.
466 */
467 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_RTR_H);
468 if (p == NULL)
469 {
470 return (-1);
471 }
472
473 memset(&rtr_lsa_hdr, 0, sizeof(rtr_lsa_hdr));
474 rtr_lsa_hdr.rtr_flags = htons(flags);
475 rtr_lsa_hdr.rtr_num = htons(num);
476 rtr_lsa_hdr.rtr_link_id = htonl(id);
477 rtr_lsa_hdr.rtr_link_data = htonl(data);
478 rtr_lsa_hdr.rtr_type = type;
479 rtr_lsa_hdr.rtr_tos_num = tos;
480 rtr_lsa_hdr.rtr_metric = htons(metric);
481
482 n = libnet_pblock_append(l, p, (u_int8_t *)&rtr_lsa_hdr,
483 LIBNET_OSPF_LS_RTR_H);
484 if (n == -1)
485 {
486 goto bad;
487 }
488
489 if ((payload && !payload_s) || (!payload && payload_s))
490 {
491 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
492 "%s(): payload inconsistency\n", __func__);
493 goto bad;
494 }
495
496 if (payload && payload_s)
497 {
498 n = libnet_pblock_append(l, p, payload, payload_s);
499 if (n == -1)
500 {
501 goto bad;
502 }
503 }
504
505 return (ptag ? ptag : libnet_pblock_update(l, p, h,
506 LIBNET_PBLOCK_LS_RTR_H));
507bad:
508 libnet_pblock_delete(l, p);
509 return (-1);
510}
511
512
513libnet_ptag_t
514libnet_build_ospfv2_lsa_net(u_int32_t nmask, u_int32_t rtrid,
515u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
516{
517 u_int32_t n, h;
518 libnet_pblock_t *p;
519 struct libnet_net_lsa_hdr net_lsa_hdr;
520
521 if (l == NULL)
522 {
523 return (-1);
524 }
525
526 n = LIBNET_OSPF_LS_NET_H + payload_s;
527 h = 0;
528
529 /*
530 * Find the existing protocol block if a ptag is specified, or create
531 * a new one.
532 */
533 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_NET_H);
534 if (p == NULL)
535 {
536 return (-1);
537 }
538
539 memset(&net_lsa_hdr, 0, sizeof(net_lsa_hdr));
540 net_lsa_hdr.net_nmask.s_addr = htonl(nmask);
541 net_lsa_hdr.net_rtr_id = htonl(rtrid);
542
543 n = libnet_pblock_append(l, p, (u_int8_t *)&net_lsa_hdr,
544 LIBNET_OSPF_LS_NET_H);
545 if (n == -1)
546 {
547 goto bad;
548 }
549
550 if ((payload && !payload_s) || (!payload && payload_s))
551 {
552 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
553 "%s(): payload inconsistency\n", __func__);
554 goto bad;
555 }
556
557 if (payload && payload_s)
558 {
559 n = libnet_pblock_append(l, p, payload, payload_s);
560 if (n == -1)
561 {
562 goto bad;
563 }
564 }
565
566 return (ptag ? ptag : libnet_pblock_update(l, p, h,
567 LIBNET_PBLOCK_LS_NET_H));
568bad:
569 libnet_pblock_delete(l, p);
570 return (-1);
571}
572
573
574libnet_ptag_t
575libnet_build_ospfv2_lsa_sum(u_int32_t nmask, u_int32_t metric, u_int tos,
576u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
577{
578 u_int32_t n, h;
579 libnet_pblock_t *p;
580 struct libnet_sum_lsa_hdr sum_lsa_hdr;
581
582 if (l == NULL)
583 {
584 return (-1);
585 }
586
587 n = LIBNET_OSPF_LS_SUM_H + payload_s;
588 h = 0;
589
590 /*
591 * Find the existing protocol block if a ptag is specified, or create
592 * a new one.
593 */
594 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_SUM_H);
595 if (p == NULL)
596 {
597 return (-1);
598 }
599
600 memset(&sum_lsa_hdr, 0, sizeof(sum_lsa_hdr));
601 sum_lsa_hdr.sum_nmask.s_addr = htonl(nmask);
602 sum_lsa_hdr.sum_metric = htonl(metric);
603 sum_lsa_hdr.sum_tos_metric = htonl(tos);
604
605 n = libnet_pblock_append(l, p, (u_int8_t *)&sum_lsa_hdr,
606 LIBNET_OSPF_LS_SUM_H);
607 if (n == -1)
608 {
609 goto bad;
610 }
611
612 if ((payload && !payload_s) || (!payload && payload_s))
613 {
614 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
615 "%s(): payload inconsistency\n", __func__);
616 goto bad;
617 }
618
619 if (payload && payload_s)
620 {
621 n = libnet_pblock_append(l, p, payload, payload_s);
622 if (n == -1)
623 {
624 goto bad;
625 }
626 }
627
628 return (ptag ? ptag : libnet_pblock_update(l, p, h,
629 LIBNET_PBLOCK_LS_SUM_H));
630bad:
631 libnet_pblock_delete(l, p);
632 return (-1);
633}
634
635
636libnet_ptag_t
637libnet_build_ospfv2_lsa_as(u_int32_t nmask, u_int metric, u_int32_t fwdaddr,
638u_int32_t tag, u_int8_t *payload, u_int32_t payload_s, libnet_t *l,
639libnet_ptag_t ptag)
640{
641 u_int32_t n, h;
642 libnet_pblock_t *p;
643 struct libnet_as_lsa_hdr as_lsa_hdr;
644
645 if (l == NULL)
646 {
647 return (-1);
648 }
649
650 n = LIBNET_OSPF_LS_AS_EXT_H + payload_s;
651 h = 0;
652
653 /*
654 * Find the existing protocol block if a ptag is specified, or create
655 * a new one.
656 */
657 p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_LS_AS_EXT_H);
658 if (p == NULL)
659 {
660 return (-1);
661 }
662
663 memset(&as_lsa_hdr, 0, sizeof(as_lsa_hdr));
664 as_lsa_hdr.as_nmask.s_addr = htonl(nmask);
665 as_lsa_hdr.as_metric = htonl(metric);
666 as_lsa_hdr.as_fwd_addr.s_addr = htonl(fwdaddr);
667 as_lsa_hdr.as_rte_tag = htonl(tag);
668
669 n = libnet_pblock_append(l, p, (u_int8_t *)&as_lsa_hdr,
670 LIBNET_OSPF_LS_AS_EXT_H);
671 if (n == -1)
672 {
673 goto bad;
674 }
675
676 if ((payload && !payload_s) || (!payload && payload_s))
677 {
678 snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
679 "%s(): payload inconsistency\n", __func__);
680 goto bad;
681 }
682
683 if (payload && payload_s)
684 {
685 n = libnet_pblock_append(l, p, payload, payload_s);
686 if (n == -1)
687 {
688 goto bad;
689 }
690 }
691
692 return (ptag ? ptag : libnet_pblock_update(l, p, h,
693 LIBNET_PBLOCK_LS_AS_EXT_H));
694bad:
695 libnet_pblock_delete(l, p);
696 return (-1);
697}
698
699/* EOF */