1 /************************************************************************ 2 * RSTP library - Rapid Spanning Tree (802.1t, 802.1w) 3 * Copyright (C) 2001-2003 Optical Access 4 * Author: Alex Rozin 5 * 6 * This file is part of RSTP library. 7 * 8 * RSTP library is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU Lesser General Public License as published by the 10 * Free Software Foundation; version 2.1 11 * 12 * RSTP library is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with RSTP library; see the file COPYING. If not, write to the Free 19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 20 * 02111-1307, USA. 21 **********************************************************************/ 22 23 /* STP priority vectors API : 17.4.2 */ 24 25 #include "base.h" 26 #include "stp_bpdu.h" 27 #include "vector.h" 28 #include "stp_vectors.h" 29 30 int 31 STP_VECT_compare_bridge_id (BRIDGE_ID* b1, BRIDGE_ID* b2) 32 { 33 if (b1->prio < b2->prio) 34 return -1; 35 36 if (b1->prio > b2->prio) 37 return 1; 38 return memcmp (b1->addr, b2->addr, 6); 39 } 40 41 void 42 STP_VECT_copy (OUT PRIO_VECTOR_T* t, IN PRIO_VECTOR_T* f) 43 { 44 (void) memcpy (t, f, sizeof (PRIO_VECTOR_T)); 45 } 46 47 void 48 STP_VECT_create (OUT PRIO_VECTOR_T* t, 49 IN BRIDGE_ID* root_br, 50 IN unsigned long root_path_cost, 51 IN BRIDGE_ID* design_bridge, 52 IN PORT_ID design_port, 53 IN PORT_ID bridge_port) 54 { 55 (void) memcpy (&t->root_bridge, root_br, sizeof (BRIDGE_ID)); 56 t->root_path_cost = root_path_cost; 57 (void) memcpy (&t->design_bridge, design_bridge, sizeof (BRIDGE_ID)); 58 t->design_port = design_port; 59 t->bridge_port = bridge_port; 60 } 61 62 int 63 STP_VECT_compare_vector (PRIO_VECTOR_T* v1, PRIO_VECTOR_T* v2) 64 { 65 int bridcmp; 66 67 bridcmp = STP_VECT_compare_bridge_id (&v1->root_bridge, &v2->root_bridge); 68 if (bridcmp < 0) return bridcmp; 69 70 if (! bridcmp) { 71 bridcmp = v1->root_path_cost - v2->root_path_cost; 72 if (bridcmp < 0) return bridcmp; 73 if (! bridcmp) { 74 bridcmp = STP_VECT_compare_bridge_id (&v1->design_bridge, &v2->design_bridge); 75 if (bridcmp < 0) return bridcmp; 76 if (! bridcmp) { 77 bridcmp = v1->design_port - v2->design_port; 78 if (bridcmp < 0) return bridcmp; 79 if (! bridcmp) 80 return v1->bridge_port - v2->bridge_port; 81 } 82 } 83 } 84 85 return bridcmp; 86 } 87 88 static unsigned short 89 stp_vect_get_short (IN unsigned char* f) 90 { 91 /* LINTED: alignment */ 92 return ntohs (*(unsigned short *)f); 93 } 94 95 static void 96 stp_vect_set_short (IN unsigned short f, OUT unsigned char* t) 97 { 98 /* LINTED: alignment */ 99 *(unsigned short *)t = htons (f); 100 } 101 102 static void 103 stp_vect_get_bridge_id (IN unsigned char* c_br, OUT BRIDGE_ID* bridge_id) 104 { 105 bridge_id->prio = stp_vect_get_short (c_br); 106 (void) memcpy (bridge_id->addr, c_br + 2, 6); 107 } 108 109 static void 110 stp_vect_set_bridge_id (IN BRIDGE_ID* bridge_id, OUT unsigned char* c_br) 111 { 112 stp_vect_set_short (bridge_id->prio, c_br); 113 (void) memcpy (c_br + 2, bridge_id->addr, 6); 114 } 115 116 void 117 STP_VECT_get_vector (IN BPDU_BODY_T* b, OUT PRIO_VECTOR_T* v) 118 { 119 stp_vect_get_bridge_id (b->root_id, &v->root_bridge); 120 121 /* LINTED: alignment */ 122 v->root_path_cost = ntohl (*((long*) b->root_path_cost)); 123 124 stp_vect_get_bridge_id (b->bridge_id, &v->design_bridge); 125 126 v->design_port = stp_vect_get_short (b->port_id); 127 } 128 129 void 130 STP_VECT_set_vector (IN PRIO_VECTOR_T* v, OUT BPDU_BODY_T* b) 131 { 132 unsigned long root_path_cost; 133 134 stp_vect_set_bridge_id (&v->root_bridge, b->root_id); 135 136 root_path_cost = htonl (v->root_path_cost); 137 (void) memcpy (b->root_path_cost, &root_path_cost, 4); 138 139 stp_vect_set_bridge_id (&v->design_bridge, b->bridge_id); 140 141 stp_vect_set_short (v->design_port, b->port_id); 142 } 143 144 #ifdef STP_DBG 145 146 /*ARGSUSED*/ 147 void 148 STP_VECT_br_id_print (IN char *title, IN BRIDGE_ID* br_id, IN Bool cr) 149 { 150 stp_trace ("%s=%04lX-%02x%02x%02x%02x%02x%02x", 151 title, 152 (unsigned long) br_id->prio, 153 (unsigned char) br_id->addr[0], 154 (unsigned char) br_id->addr[1], 155 (unsigned char) br_id->addr[2], 156 (unsigned char) br_id->addr[3], 157 (unsigned char) br_id->addr[4], 158 (unsigned char) br_id->addr[5]); 159 #ifndef __SUN__ 160 stp_trace (cr ? "\n" : " "); 161 #endif 162 } 163 164 void 165 STP_VECT_print (IN char *title, IN PRIO_VECTOR_T *v) 166 { 167 stp_trace ("%s:", title); 168 STP_VECT_br_id_print ("rootBr", &v->root_bridge, False); 169 170 /**** 171 stp_trace (" rpc=%ld ", (long) v->root_path_cost); 172 ****/ 173 174 STP_VECT_br_id_print ("designBr", &v->design_bridge, False); 175 176 /****/ 177 stp_trace (" dp=%lx bp=%lx ", 178 (unsigned long) v->design_port, 179 (unsigned long) v->bridge_port); 180 /***********/ 181 stp_trace ("\n"); 182 } 183 #endif 184