2 * Mausezahn - A fast versatile traffic generator
3 * Copyright (C) 2008-2010 Herbert Haas
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License version 2 as published by the
7 * Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html
25 // Initialization function - specify defaults here!
27 int mops_init_pdesc_bpdu(struct mops
*mp
)
29 struct mops_ext_bpdu
* pd
;
33 if (mp
->p_desc
== NULL
) return 1; // p_desc not properly assigned
36 // 1. - Initialize Ethernet header
37 str2hex("01:80:C2:00:00:00",mp
->eth_dst
, 6);
39 // 2. - Initialize BPDU fields
41 pd
->version
= 0; // 0=802.1D, 2=RSTP(802.1w)
42 pd
->bpdu_type
= 0x80; // 0=conf, 0x80=topology change, 2=RSTP/MSTP
43 pd
->flags
= 0; // X... .... = TCN ACK
44 // .X.. .... = Agreement
45 // ..X. .... = Forwarding
46 // ...X .... = Learning
47 // .... XX.. = Port Role (e. g. 11=Desgn)
48 // .... ..X. = Proposal
51 i
= mops_get_device_index(tx
.device
);
53 memcpy((void*) &pd
->root_id
[2], (void*) device_list
[i
].mac_mops
, 6);
54 memcpy((void*) &pd
->bridge_id
[2], (void*) device_list
[i
].mac_mops
, 6);
56 str2hex("00:00:00:00:00:00", &pd
->root_id
[2], 6);
57 str2hex("00:00:00:00:00:00", &pd
->bridge_id
[2], 6);
60 pd
->root_id
[0] = 0x00;
61 pd
->root_id
[1] = 0x00;
63 pd
->bridge_id
[0] = 0x00;
64 pd
->bridge_id
[1] = 0x00;
66 pd
->root_pc
= 0; // Root Path Cost
67 pd
->port_id
= 0; // Port Identifier
68 pd
->message_age
= 0; // All timers are multiples of 1/256 sec. Thus times range from 0 to 256 seconds.
69 pd
->max_age
= 5120; // 20 seconds
73 str2hex("00:00:00:00:00:00:00:00", pd
->trailer
, 8);
74 // either all-zero or 00:00:00:00:02:VLAN(16bit) when PVST+
75 pd
->rstp
= 0; // 1 = RSTP
76 pd
->pvst
= 0; // 1=PVST+ , 0 = 802.1D
77 pd
->mstp
= 0; // 1 = Multiple Instance STP
83 /////////////////////////////////////////////////////////////////////////////////
84 /////////////////////////////// Update functions ////////////////////////////////
86 // **** Here is a summary of mops tool functions: ****
88 // Adds single byte to msg
89 // int mops_msg_add_byte (struct mops *mp, u_int8_t data);
91 // Adds bit field in *previous* msg-byte using optional left-shift
92 // int mops_msg_add_field (struct mops *mp, u_int8_t data, int shift);
94 // Adds two bytes in network byte order to msg
95 // int mops_msg_add_2bytes (struct mops *mp, u_int16_t data);
97 // Adds four bytes in network byte order to msg
98 // int mops_msg_add_4bytes (struct mops *mp, u_int32_t data);
100 // Adds string of bytes with lenght len
101 // int mops_msg_add_string (struct mops *mp, u_int8_t *str, int len);
103 int mops_update_bpdu(struct mops
* mp
)
106 struct mops_ext_bpdu
* pd
;
109 if (pd
==NULL
) return 1; // no valid pointer to a p_desc
110 mp
->msg_s
= 0; // important! Otherwise the msg would get longer and longer after each call!
113 // NOTE: the length field does not include the trailer!
116 str2hex("01:00:0C:CC:CC:CD", mp
->eth_dst
, 6);
118 str2hex("aa:aa:03:00:00:0c:01:0b",mp
->eth_snap
, 8);
123 str2hex("01:80:C2:00:00:00",mp
->eth_dst
, 6);
125 str2hex("42:42:03",mp
->eth_snap
, 3);
129 mops_msg_add_2bytes (mp
, pd
->id
);
130 mops_msg_add_byte (mp
, pd
->version
);
131 mops_msg_add_byte (mp
, pd
->bpdu_type
);
133 if (pd
->bpdu_type
& 0x80) // if TCN then don't add more fields
135 if (pd
->pvst
) mp
->eth_len
=12; else mp
->eth_len
=7;
139 mops_msg_add_byte (mp
, pd
->flags
);
140 mops_msg_add_string (mp
, pd
->root_id
, 8);
141 mops_msg_add_4bytes (mp
, pd
->root_pc
);
142 mops_msg_add_string (mp
, pd
->bridge_id
, 8);
143 mops_msg_add_2bytes (mp
, pd
->port_id
);
144 mops_msg_add_2bytes (mp
, pd
->message_age
);
145 mops_msg_add_2bytes (mp
, pd
->max_age
);
146 mops_msg_add_2bytes (mp
, pd
->hello_time
);
147 mops_msg_add_2bytes (mp
, pd
->f_delay
);
150 // we always add the trailer
151 mops_msg_add_string (mp
, pd
->trailer
, 8);
158 // Create RID or BID based on priority, ext-sys-id, and MAC address.
159 // The last parameter selects BID (0) or RID (1)
163 // mac .... XX:XX:XX:XX:XX:XX or interface name
165 // NOTE: Invalid parameters will result in default values
167 // RETURN VALUE: Only informational; identifies which parameter
168 // was errourness, using the following values:
170 // 0 ... all parameters valid
171 // 1 ... priority exceeded range
172 // 2 ... ext-sys-id exceeded range
173 // 3 ... invalid MAC address or invalid interface
176 int mops_create_bpdu_bid(struct mops
* mp
, int pri
, int esi
, char *mac
, int bid_or_rid
)
179 struct mops_ext_bpdu
* pd
= mp
->p_desc
;
183 if ((pri
<0)||(pri
>15)) return 1;
184 if ((esi
<0)||(esi
>4095)) return 2;
187 // first check if an interface is specified:
188 i
= mops_get_device_index(mac
);
189 if (i
!=-1) { // found
190 memcpy((void*) &rid
[2], (void*) device_list
[i
].mac_mops
, 6);
192 else { // MAC address given?
193 if (mops_pdesc_mac(&rid
[2], mac
)) {
197 } else { // mac==NULL
198 // use MAC of default interface!
199 i
= mops_get_device_index(tx
.device
);
200 if (i
!=-1) { // found
201 memcpy((void*) &rid
[2], (void*) device_list
[i
].mac_mops
, 6);
204 str2hex("00:00:00:00:00:00", &rid
[2], 6);
209 // now prepend pri, esi
215 mops_hton2 (&p16
, &rid
[0]);
217 memcpy((void*) pd
->root_id
, (void*) rid
, 8);
219 memcpy((void*) pd
->bridge_id
, (void*) rid
, 8);
224 int mops_create_bpdu_trailer (struct mops
* mp
, u_int16_t vlan
)
226 struct mops_ext_bpdu
* pd
= mp
->p_desc
;
228 // PVST+ requires a trailer with either all-zero
229 // or 00:00:00:00:02:VLAN(16bit)
231 // trailer already initialized with zeroes
239 mops_hton2 (&vlan
, &pd
->trailer
[5]);