1: /*
2: * $Id: libnet_build_bgp.c,v 1.1.1.2 2013/07/22 11:54:42 misho Exp $
3: *
4: * libnet
5: * libnet_build_bgp.c - BGP packet assembler (RFC 1771)
6: *
7: * Copyright (c) 2003 Frederic Raynal <pappy@security-labs.org>
8: * All rights reserved.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: *
31: */
32:
33: #if (HAVE_CONFIG_H)
34: #include "../include/config.h"
35: #endif
36: #if (!(_WIN32) || (__CYGWIN__))
37: #include "../include/libnet.h"
38: #else
39: #include "../include/win32/libnet.h"
40: #endif
41:
42: libnet_ptag_t
43: libnet_build_bgp4_header(uint8_t marker[LIBNET_BGP4_MARKER_SIZE],
44: uint16_t len, uint8_t type, const uint8_t *payload, uint32_t payload_s,
45: libnet_t *l, libnet_ptag_t ptag)
46: {
47: uint32_t n, h;
48: libnet_pblock_t *p;
49: struct libnet_bgp4_header_hdr bgp4_hdr;
50:
51: if (l == NULL)
52: {
53: return (-1);
54: }
55:
56: n = LIBNET_BGP4_HEADER_H + payload_s; /* size of memory block */
57: h = 0; /* BGP headers have no checksum */
58:
59: /*
60: * Find the existing protocol block if a ptag is specified, or create
61: * a new one.
62: */
63: p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_HEADER_H);
64: if (p == NULL)
65: {
66: return (-1);
67: }
68:
69: memset(&bgp4_hdr, 0, sizeof(bgp4_hdr));
70: memcpy(bgp4_hdr.marker, marker, LIBNET_BGP4_MARKER_SIZE * sizeof(uint8_t));
71: bgp4_hdr.len = htons(len);
72: bgp4_hdr.type = type;
73:
74: n = libnet_pblock_append(l, p, (uint8_t *)&bgp4_hdr, LIBNET_BGP4_HEADER_H);
75: if (n == -1)
76: {
77: goto bad;
78: }
79:
80: /* boilerplate payload sanity check / append macro */
81: LIBNET_DO_PAYLOAD(l, p);
82:
83: return (ptag ? ptag : libnet_pblock_update(l, p, h,
84: LIBNET_PBLOCK_BGP4_HEADER_H));
85: bad:
86: libnet_pblock_delete(l, p);
87: return (-1);
88: }
89:
90: libnet_ptag_t
91: libnet_build_bgp4_open(uint8_t version, uint16_t src_as, uint16_t hold_time,
92: uint32_t bgp_id, uint8_t opt_len, const uint8_t *payload, uint32_t payload_s,
93: libnet_t *l, libnet_ptag_t ptag)
94: {
95: uint32_t n, h;
96: libnet_pblock_t *p;
97: uint16_t val;
98:
99: if (l == NULL)
100: {
101: return (-1);
102: }
103:
104: n = LIBNET_BGP4_OPEN_H + payload_s; /* size of memory block */
105: h = 0; /* BGP msg have no checksum */
106:
107: /*
108: * Find the existing protocol block if a ptag is specified, or create
109: * a new one.
110: */
111: p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_OPEN_H);
112: if (p == NULL)
113: {
114: return (-1);
115: }
116:
117: /* for memory alignment reason, we need to append each field separately */
118: n = libnet_pblock_append(l, p, (uint8_t *)&version, sizeof (version));
119: if (n == -1)
120: {
121: goto bad;
122: }
123:
124: val = htons(src_as);
125: n = libnet_pblock_append(l, p, (uint8_t *)&val, sizeof(src_as));
126: if (n == -1)
127: {
128: goto bad;
129: }
130:
131: val = htons(hold_time);
132: n = libnet_pblock_append(l, p, (uint8_t *)&val, sizeof(hold_time));
133: if (n == -1)
134: {
135: goto bad;
136: }
137:
138: n = htonl(bgp_id);
139: n = libnet_pblock_append(l, p, (uint8_t *)&n, sizeof(bgp_id));
140: if (n == -1)
141: {
142: goto bad;
143: }
144:
145: n = libnet_pblock_append(l, p, (uint8_t *)&opt_len, sizeof(opt_len));
146: if (n == -1)
147: {
148: goto bad;
149: }
150:
151: /* boilerplate payload sanity check / append macro */
152: LIBNET_DO_PAYLOAD(l, p);
153:
154: return (ptag ? ptag : libnet_pblock_update(l, p, h,
155: LIBNET_PBLOCK_BGP4_OPEN_H));
156: bad:
157: libnet_pblock_delete(l, p);
158: return (-1);
159: }
160:
161: libnet_ptag_t
162: libnet_build_bgp4_update(uint16_t unfeasible_rt_len, const uint8_t *withdrawn_rt,
163: uint16_t total_path_attr_len, const uint8_t *path_attributes, uint16_t info_len,
164: uint8_t *reachability_info, const uint8_t *payload, uint32_t payload_s,
165: libnet_t *l, libnet_ptag_t ptag)
166: {
167: uint32_t n, h;
168: libnet_pblock_t *p;
169: uint16_t length;
170:
171: if (l == NULL)
172: {
173: return (-1);
174: }
175:
176: /* size of memory block */
177: n = LIBNET_BGP4_UPDATE_H + unfeasible_rt_len + total_path_attr_len +
178: info_len + payload_s;
179:
180: /* BGP msg have no checksum */
181: h = 0;
182:
183: /*
184: * Find the existing protocol block if a ptag is specified, or create
185: * a new one.
186: */
187: p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_UPDATE_H);
188: if (p == NULL)
189: {
190: return (-1);
191: }
192:
193: /* for memory alignment reason, we need to append each field separately */
194: length = htons(unfeasible_rt_len);
195: n = libnet_pblock_append(l, p, (uint8_t *)&length,
196: sizeof (unfeasible_rt_len));
197: if (n == -1)
198: {
199: goto bad;
200: }
201:
202: if (unfeasible_rt_len && withdrawn_rt)
203: {
204: n = libnet_pblock_append(l, p, withdrawn_rt, unfeasible_rt_len);
205: if (n == -1)
206: {
207: goto bad;
208: }
209: }
210:
211: length = htons(total_path_attr_len);
212: n = libnet_pblock_append(l, p, (uint8_t *)&length,
213: sizeof (total_path_attr_len));
214: if (n == -1)
215: {
216: goto bad;
217: }
218:
219: if (total_path_attr_len && path_attributes)
220: {
221: n = libnet_pblock_append(l, p, path_attributes, total_path_attr_len);
222: if (n == -1)
223: {
224: goto bad;
225: }
226: }
227:
228: if (info_len && reachability_info)
229: {
230: n = libnet_pblock_append(l, p, reachability_info, info_len);
231: if (n == -1)
232: {
233: goto bad;
234: }
235: }
236:
237: /* boilerplate payload sanity check / append macro */
238: LIBNET_DO_PAYLOAD(l, p);
239:
240: return (ptag ? ptag : libnet_pblock_update(l, p, h,
241: LIBNET_PBLOCK_BGP4_UPDATE_H));
242: bad:
243: libnet_pblock_delete(l, p);
244: return (-1);
245: }
246:
247: libnet_ptag_t
248: libnet_build_bgp4_notification(uint8_t err_code, uint8_t err_subcode,
249: const uint8_t *payload, uint32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
250: {
251: uint32_t n, h;
252: libnet_pblock_t *p;
253: struct libnet_bgp4_notification_hdr bgp4_hdr;
254:
255: if (l == NULL)
256: {
257: return (-1);
258: }
259:
260: n = LIBNET_BGP4_NOTIFICATION_H + + payload_s; /* size of memory block */
261: h = 0;
262:
263: /*
264: * Find the existing protocol block if a ptag is specified, or create
265: * a new one.
266: */
267: p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_NOTIFICATION_H);
268: if (p == NULL)
269: {
270: return (-1);
271: }
272:
273: memset(&bgp4_hdr, 0, sizeof(bgp4_hdr));
274: bgp4_hdr.err_code = err_code;
275: bgp4_hdr.err_subcode = err_subcode;
276:
277: n = libnet_pblock_append(l, p, (uint8_t *)&bgp4_hdr,
278: LIBNET_BGP4_NOTIFICATION_H);
279: if (n == -1)
280: {
281: goto bad;
282: }
283:
284: /* boilerplate payload sanity check / append macro */
285: LIBNET_DO_PAYLOAD(l, p);
286:
287: return (ptag ? ptag : libnet_pblock_update(l, p, h,
288: LIBNET_PBLOCK_BGP4_NOTIFICATION_H));
289: bad:
290: libnet_pblock_delete(l, p);
291: return (-1);
292: }
293:
294: /* EOF */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>