Annotation of embedaddon/libnet/src/libnet_build_bgp.c, revision 1.1.1.1
1.1 misho 1: /*
2: * $Id: libnet_build_bgp.c,v 1.7 2003/10/30 23:26:32 mike 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(u_int8_t marker[LIBNET_BGP4_MARKER_SIZE],
44: u_int16_t len, u_int8_t type, u_int8_t *payload, u_int32_t payload_s,
45: libnet_t *l, libnet_ptag_t ptag)
46: {
47: u_int32_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 (u_int8_t));
71: bgp4_hdr.len = htons(len);
72: bgp4_hdr.type = type;
73:
74: n = libnet_pblock_append(l, p, (u_int8_t *)&bgp4_hdr, LIBNET_BGP4_HEADER_H);
75: if (n == -1)
76: {
77: goto bad;
78: }
79:
80: if ((payload && !payload_s) || (!payload && payload_s))
81: {
82: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
83: "%s(): payload inconsistency\n", __func__);
84: goto bad;
85: }
86:
87: if (payload && payload_s)
88: {
89: n = libnet_pblock_append(l, p, payload, payload_s);
90: if (n == -1)
91: {
92: /* err msg set in libnet_pblock_append() */
93: goto bad;
94: }
95: }
96:
97: return (ptag ? ptag : libnet_pblock_update(l, p, h,
98: LIBNET_PBLOCK_BGP4_HEADER_H));
99: bad:
100: libnet_pblock_delete(l, p);
101: return (-1);
102: }
103:
104: libnet_ptag_t
105: libnet_build_bgp4_open(u_int8_t version, u_int16_t src_as, u_int16_t hold_time,
106: u_int32_t bgp_id, u_int8_t opt_len, u_int8_t *payload, u_int32_t payload_s,
107: libnet_t *l, libnet_ptag_t ptag)
108: {
109: u_int32_t n, h;
110: libnet_pblock_t *p;
111: u_int16_t val;
112:
113: if (l == NULL)
114: {
115: return (-1);
116: }
117:
118: n = LIBNET_BGP4_OPEN_H + payload_s; /* size of memory block */
119: h = 0; /* BGP msg have no checksum */
120:
121: /*
122: * Find the existing protocol block if a ptag is specified, or create
123: * a new one.
124: */
125: p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_OPEN_H);
126: if (p == NULL)
127: {
128: return (-1);
129: }
130:
131: /* for memory alignment reason, we need to append each field separately */
132: n = libnet_pblock_append(l, p, (u_int8_t *)&version, sizeof (version));
133: if (n == -1)
134: {
135: goto bad;
136: }
137:
138: val = htons(src_as);
139: n = libnet_pblock_append(l, p, (u_int8_t *)&val, sizeof(src_as));
140: if (n == -1)
141: {
142: goto bad;
143: }
144:
145: val = htons(hold_time);
146: n = libnet_pblock_append(l, p, (u_int8_t *)&val, sizeof(hold_time));
147: if (n == -1)
148: {
149: goto bad;
150: }
151:
152: n = htonl(bgp_id);
153: n = libnet_pblock_append(l, p, (u_int8_t *)&n, sizeof(bgp_id));
154: if (n == -1)
155: {
156: goto bad;
157: }
158:
159: n = libnet_pblock_append(l, p, (u_int8_t *)&opt_len, sizeof(opt_len));
160: if (n == -1)
161: {
162: goto bad;
163: }
164:
165: if ((payload && !payload_s) || (!payload && payload_s))
166: {
167: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
168: "%s(): payload inconsistency\n", __func__);
169: goto bad;
170: }
171:
172: if (payload && payload_s)
173: {
174: n = libnet_pblock_append(l, p, payload, payload_s);
175: if (n == -1)
176: {
177: /* err msg set in libnet_pblock_append() */
178: goto bad;
179: }
180: }
181:
182: return (ptag ? ptag : libnet_pblock_update(l, p, h,
183: LIBNET_PBLOCK_BGP4_OPEN_H));
184: bad:
185: libnet_pblock_delete(l, p);
186: return (-1);
187: }
188:
189: libnet_ptag_t
190: libnet_build_bgp4_update(u_int16_t unfeasible_rt_len, u_int8_t *withdrawn_rt,
191: u_int16_t total_path_attr_len, u_int8_t *path_attributes,
192: u_int16_t info_len, u_int8_t *reachability_info,
193: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
194: {
195: u_int32_t n, h;
196: libnet_pblock_t *p;
197: u_int16_t length;
198:
199: if (l == NULL)
200: {
201: return (-1);
202: }
203:
204: /* size of memory block */
205: n = LIBNET_BGP4_UPDATE_H + unfeasible_rt_len + total_path_attr_len +
206: info_len + payload_s;
207:
208: /* BGP msg have no checksum */
209: h = 0;
210:
211: /*
212: * Find the existing protocol block if a ptag is specified, or create
213: * a new one.
214: */
215: p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_UPDATE_H);
216: if (p == NULL)
217: {
218: return (-1);
219: }
220:
221: /* for memory alignment reason, we need to append each field separately */
222: length = htons(unfeasible_rt_len);
223: n = libnet_pblock_append(l, p, (u_int8_t *)&length,
224: sizeof (unfeasible_rt_len));
225: if (n == -1)
226: {
227: goto bad;
228: }
229:
230: if (unfeasible_rt_len && withdrawn_rt)
231: {
232: n = libnet_pblock_append(l, p, withdrawn_rt, unfeasible_rt_len);
233: if (n == -1)
234: {
235: goto bad;
236: }
237: }
238:
239: length = htons(total_path_attr_len);
240: n = libnet_pblock_append(l, p, (u_int8_t *)&length,
241: sizeof (total_path_attr_len));
242: if (n == -1)
243: {
244: goto bad;
245: }
246:
247: if (total_path_attr_len && path_attributes)
248: {
249: n = libnet_pblock_append(l, p, path_attributes, total_path_attr_len);
250: if (n == -1)
251: {
252: goto bad;
253: }
254: }
255:
256: if (info_len && reachability_info)
257: {
258: n = libnet_pblock_append(l, p, reachability_info, info_len);
259: if (n == -1)
260: {
261: goto bad;
262: }
263: }
264:
265: if ((payload && !payload_s) || (!payload && payload_s))
266: {
267: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
268: "%s(): payload inconsistency\n", __func__);
269: goto bad;
270: }
271:
272: if (payload && payload_s)
273: {
274: n = libnet_pblock_append(l, p, payload, payload_s);
275: if (n == -1)
276: {
277: /* err msg set in libnet_pblock_append() */
278: goto bad;
279: }
280: }
281:
282: return (ptag ? ptag : libnet_pblock_update(l, p, h,
283: LIBNET_PBLOCK_BGP4_UPDATE_H));
284: bad:
285: libnet_pblock_delete(l, p);
286: return (-1);
287: }
288:
289: libnet_ptag_t
290: libnet_build_bgp4_notification(u_int8_t err_code, u_int8_t err_subcode,
291: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
292: {
293: u_int32_t n, h;
294: libnet_pblock_t *p;
295: struct libnet_bgp4_notification_hdr bgp4_hdr;
296:
297: if (l == NULL)
298: {
299: return (-1);
300: }
301:
302: n = LIBNET_BGP4_NOTIFICATION_H + + payload_s; /* size of memory block */
303: h = 0;
304:
305: /*
306: * Find the existing protocol block if a ptag is specified, or create
307: * a new one.
308: */
309: p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_BGP4_NOTIFICATION_H);
310: if (p == NULL)
311: {
312: return (-1);
313: }
314:
315: memset(&bgp4_hdr, 0, sizeof(bgp4_hdr));
316: bgp4_hdr.err_code = err_code;
317: bgp4_hdr.err_subcode = err_subcode;
318:
319: n = libnet_pblock_append(l, p, (u_int8_t *)&bgp4_hdr,
320: LIBNET_BGP4_NOTIFICATION_H);
321: if (n == -1)
322: {
323: goto bad;
324: }
325:
326: if ((payload && !payload_s) || (!payload && payload_s))
327: {
328: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
329: "%s(): payload inconsistency\n", __func__);
330: goto bad;
331: }
332:
333: if (payload && payload_s)
334: {
335: n = libnet_pblock_append(l, p, payload, payload_s);
336: if (n == -1)
337: {
338: /* err msg set in libnet_pblock_append() */
339: goto bad;
340: }
341: }
342:
343: return (ptag ? ptag : libnet_pblock_update(l, p, h,
344: LIBNET_PBLOCK_BGP4_NOTIFICATION_H));
345: bad:
346: libnet_pblock_delete(l, p);
347: return (-1);
348: }
349:
350: /* EOF */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>