1: /*
2: * libnet
3: * libnet_build_token_ring.c - Token Ring (802.5) packet assembler
4: *
5: * Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
6: * Jason Damron <jsdamron@hushmail.com>
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28: * SUCH DAMAGE.
29: *
30: */
31:
32: #if (HAVE_CONFIG_H)
33: #include "../include/config.h"
34: #endif
35: #if (!(_WIN32) || (__CYGWIN__))
36: #include "../include/libnet.h"
37: #else
38: #include "../include/win32/libnet.h"
39: #endif
40:
41: libnet_ptag_t
42: libnet_build_token_ring(u_int8_t ac, u_int8_t fc, u_int8_t *dst, u_int8_t *src,
43: u_int8_t dsap, u_int8_t ssap, u_int8_t cf, u_int8_t *org, u_int16_t type,
44: u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag)
45: {
46: u_int32_t n, h;
47: libnet_pblock_t *p;
48: struct libnet_token_ring_hdr token_ring_hdr;
49:
50: if (l == NULL)
51: {
52: return (-1);
53: }
54:
55: /* sanity check injection type if we're not in advanced mode */
56: if (l->injection_type != LIBNET_LINK &&
57: !(((l->injection_type) & LIBNET_ADV_MASK)))
58: {
59: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
60: "%s(): called with non-link layer wire injection primitive\n",
61: __func__);
62: p = NULL;
63: goto bad;
64: }
65:
66: n = LIBNET_TOKEN_RING_H + payload_s;
67: h = 0;
68:
69: /*
70: * Find the existing protocol block if a ptag is specified, or create
71: * a new one.
72: */
73: p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_TOKEN_RING_H);
74: if (p == NULL)
75: {
76: return (-1);
77: }
78:
79: memset(&token_ring_hdr, 0, sizeof(token_ring_hdr));
80: token_ring_hdr.token_ring_access_control = ac;
81: token_ring_hdr.token_ring_frame_control = fc;
82: memcpy(token_ring_hdr.token_ring_dhost, dst, TOKEN_RING_ADDR_LEN);
83: memcpy(token_ring_hdr.token_ring_shost, src, TOKEN_RING_ADDR_LEN);
84: token_ring_hdr.token_ring_llc_dsap = dsap;
85: token_ring_hdr.token_ring_llc_ssap = ssap;
86: token_ring_hdr.token_ring_llc_control_field = cf;
87: memcpy(&token_ring_hdr.token_ring_llc_org_code, org, LIBNET_ORG_CODE_SIZE);
88: token_ring_hdr.token_ring_type = htons(type);
89:
90: n = libnet_pblock_append(l, p, (u_int8_t *)&token_ring_hdr,
91: LIBNET_TOKEN_RING_H);
92: if (n == -1)
93: {
94: goto bad;
95: }
96:
97: if ((payload && !payload_s) || (!payload && payload_s))
98: {
99: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
100: "%s(): payload inconsistency\n", __func__);
101: goto bad;
102: }
103:
104: if (payload && payload_s)
105: {
106: n = libnet_pblock_append(l, p, payload, payload_s);
107: if (n == -1)
108: {
109: goto bad;
110: }
111: }
112:
113: return (ptag ? ptag : libnet_pblock_update(l, p, h,
114: LIBNET_PBLOCK_TOKEN_RING_H));
115: bad:
116: libnet_pblock_delete(l, p);
117: return (-1);
118: }
119:
120:
121: libnet_ptag_t
122: libnet_autobuild_token_ring(u_int8_t ac, u_int8_t fc, u_int8_t *dst,
123: u_int8_t dsap, u_int8_t ssap, u_int8_t cf, u_int8_t *org, u_int16_t type,
124: libnet_t *l)
125: {
126: u_int32_t n, h;
127: struct libnet_token_ring_addr *src;
128: libnet_pblock_t *p;
129: libnet_ptag_t ptag;
130: struct libnet_token_ring_hdr token_ring_hdr;
131:
132: if (l == NULL)
133: {
134: return (-1);
135: }
136:
137: /* sanity check injection type if we're not in advanced mode */
138: if (l->injection_type != LIBNET_LINK &&
139: !(((l->injection_type) & LIBNET_ADV_MASK)))
140: {
141: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
142: "%s(): called with non-link layer wire injection primitive\n",
143: __func__);
144: p = NULL;
145: goto bad;
146: }
147:
148: n = LIBNET_TOKEN_RING_H;
149: h = 0;
150: ptag = LIBNET_PTAG_INITIALIZER;
151:
152: /* Token Ring and Ethernet have the same address size - so just typecast */
153: src = (struct libnet_token_ring_addr *) libnet_get_hwaddr(l);
154: if (src == NULL)
155: {
156: /* err msg set in libnet_get_hwaddr() */
157: return (-1);
158: }
159:
160: /*
161: * Create a new pblock.
162: */
163: p = libnet_pblock_probe(l, ptag, n, LIBNET_PBLOCK_TOKEN_RING_H);
164: if (p == NULL)
165: {
166: return (-1);
167: }
168:
169: memset(&token_ring_hdr, 0, sizeof(token_ring_hdr));
170: token_ring_hdr.token_ring_access_control = ac;
171: token_ring_hdr.token_ring_frame_control = fc;
172: memcpy(token_ring_hdr.token_ring_dhost, dst, TOKEN_RING_ADDR_LEN);
173: memcpy(token_ring_hdr.token_ring_shost, src, TOKEN_RING_ADDR_LEN);
174: token_ring_hdr.token_ring_llc_dsap = dsap;
175: token_ring_hdr.token_ring_llc_ssap = ssap;
176: token_ring_hdr.token_ring_llc_control_field = cf;
177: memcpy(&token_ring_hdr.token_ring_llc_org_code, org, LIBNET_ORG_CODE_SIZE);
178: token_ring_hdr.token_ring_type = htons(type);
179:
180:
181: n = libnet_pblock_append(l, p, (u_int8_t *)&token_ring_hdr,
182: LIBNET_TOKEN_RING_H);
183: if (n == -1)
184: {
185: goto bad;
186: }
187:
188: return (libnet_pblock_update(l, p, h, LIBNET_PBLOCK_TOKEN_RING_H));
189: bad:
190: libnet_pblock_delete(l, p);
191: return (-1);
192: }
193: /* EOF */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>