📄 smt.c
字号:
*/void smt_clear_una_dna(struct s_smc *smc){ smc->mib.m[MAC0].fddiMACUpstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACDownstreamNbr = SMT_Unknown ;}static void smt_clear_old_una_dna(struct s_smc *smc){ smc->mib.m[MAC0].fddiMACOldUpstreamNbr = SMT_Unknown ; smc->mib.m[MAC0].fddiMACOldDownstreamNbr = SMT_Unknown ;}u_long smt_get_tid(struct s_smc *smc){ u_long tid ; while ((tid = ++(smc->sm.smt_tid) ^ SMT_TID_MAGIC) == 0) ; return(tid & 0x3fffffffL) ;}/* * table of parameter lengths */static const struct smt_pdef { int ptype ; int plen ; const char *pswap ;} smt_pdef[] = { { SMT_P_UNA, sizeof(struct smt_p_una) , SWAP_SMT_P_UNA } , { SMT_P_SDE, sizeof(struct smt_p_sde) , SWAP_SMT_P_SDE } , { SMT_P_STATE, sizeof(struct smt_p_state) , SWAP_SMT_P_STATE } , { SMT_P_TIMESTAMP,sizeof(struct smt_p_timestamp) , SWAP_SMT_P_TIMESTAMP } , { SMT_P_POLICY, sizeof(struct smt_p_policy) , SWAP_SMT_P_POLICY } , { SMT_P_LATENCY, sizeof(struct smt_p_latency) , SWAP_SMT_P_LATENCY } , { SMT_P_NEIGHBORS,sizeof(struct smt_p_neighbor) , SWAP_SMT_P_NEIGHBORS } , { SMT_P_PATH, sizeof(struct smt_p_path) , SWAP_SMT_P_PATH } , { SMT_P_MAC_STATUS,sizeof(struct smt_p_mac_status) , SWAP_SMT_P_MAC_STATUS } , { SMT_P_LEM, sizeof(struct smt_p_lem) , SWAP_SMT_P_LEM } , { SMT_P_MAC_COUNTER,sizeof(struct smt_p_mac_counter) , SWAP_SMT_P_MAC_COUNTER } , { SMT_P_MAC_FNC,sizeof(struct smt_p_mac_fnc) , SWAP_SMT_P_MAC_FNC } , { SMT_P_PRIORITY,sizeof(struct smt_p_priority) , SWAP_SMT_P_PRIORITY } , { SMT_P_EB,sizeof(struct smt_p_eb) , SWAP_SMT_P_EB } , { SMT_P_MANUFACTURER,sizeof(struct smp_p_manufacturer) , SWAP_SMT_P_MANUFACTURER } , { SMT_P_REASON, sizeof(struct smt_p_reason) , SWAP_SMT_P_REASON } , { SMT_P_REFUSED, sizeof(struct smt_p_refused) , SWAP_SMT_P_REFUSED } , { SMT_P_VERSION, sizeof(struct smt_p_version) , SWAP_SMT_P_VERSION } ,#ifdef ESS { SMT_P0015, sizeof(struct smt_p_0015) , SWAP_SMT_P0015 } , { SMT_P0016, sizeof(struct smt_p_0016) , SWAP_SMT_P0016 } , { SMT_P0017, sizeof(struct smt_p_0017) , SWAP_SMT_P0017 } , { SMT_P0018, sizeof(struct smt_p_0018) , SWAP_SMT_P0018 } , { SMT_P0019, sizeof(struct smt_p_0019) , SWAP_SMT_P0019 } , { SMT_P001A, sizeof(struct smt_p_001a) , SWAP_SMT_P001A } , { SMT_P001B, sizeof(struct smt_p_001b) , SWAP_SMT_P001B } , { SMT_P001C, sizeof(struct smt_p_001c) , SWAP_SMT_P001C } , { SMT_P001D, sizeof(struct smt_p_001d) , SWAP_SMT_P001D } ,#endif#if 0 { SMT_P_FSC, sizeof(struct smt_p_fsc) , SWAP_SMT_P_FSC } ,#endif { SMT_P_SETCOUNT,0, SWAP_SMT_P_SETCOUNT } , { SMT_P1048, 0, SWAP_SMT_P1048 } , { SMT_P208C, 0, SWAP_SMT_P208C } , { SMT_P208D, 0, SWAP_SMT_P208D } , { SMT_P208E, 0, SWAP_SMT_P208E } , { SMT_P208F, 0, SWAP_SMT_P208F } , { SMT_P2090, 0, SWAP_SMT_P2090 } ,#ifdef ESS { SMT_P320B, sizeof(struct smt_p_320b) , SWAP_SMT_P320B } , { SMT_P320F, sizeof(struct smt_p_320f) , SWAP_SMT_P320F } , { SMT_P3210, sizeof(struct smt_p_3210) , SWAP_SMT_P3210 } ,#endif { SMT_P4050, 0, SWAP_SMT_P4050 } , { SMT_P4051, 0, SWAP_SMT_P4051 } , { SMT_P4052, 0, SWAP_SMT_P4052 } , { SMT_P4053, 0, SWAP_SMT_P4053 } ,} ;#define N_SMT_PLEN (sizeof(smt_pdef)/sizeof(smt_pdef[0]))int smt_check_para(struct s_smc *smc, struct smt_header *sm, const u_short list[]){ const u_short *p = list ; while (*p) { if (!sm_to_para(smc,sm,(int) *p)) { DB_SMT("SMT: smt_check_para - missing para %x\n",*p,0); return(-1) ; } p++ ; } return(0) ;}void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para){ char *p ; int len ; int plen ; void *found = NULL; SK_UNUSED(smc) ; len = sm->smt_len ; p = (char *)(sm+1) ; /* pointer to info */ while (len > 0 ) { if (((struct smt_para *)p)->p_type == para) found = (void *) p ; plen = ((struct smt_para *)p)->p_len + PARA_LEN ; p += plen ; len -= plen ; if (len < 0) { DB_SMT("SMT : sm_to_para - length error %d\n",plen,0) ; return NULL; } if ((plen & 3) && (para != SMT_P_ECHODATA)) { DB_SMT("SMT : sm_to_para - odd length %d\n",plen,0) ; return NULL; } if (found) return(found) ; } return NULL;}#if 0/* * send ANTC data test frame */void fddi_send_antc(struct s_smc *smc, struct fddi_addr *dest){ SK_UNUSED(smc) ; SK_UNUSED(dest) ;#if 0 SMbuf *mb ; struct smt_header *smt ; int i ; char *p ; mb = smt_get_mbuf() ; mb->sm_len = 3000+12 ; p = smtod(mb, char *) + 12 ; for (i = 0 ; i < 3000 ; i++) *p++ = 1 << (i&7) ; smt = smtod(mb, struct smt_header *) ; smt->smt_dest = *dest ; smt->smt_source = smc->mib.m[MAC0].fddiMACSMTAddress ; smt_send_mbuf(smc,mb,FC_ASYNC_LLC) ;#endif}#endif#ifdef DEBUG#define hextoasc(x) "0123456789abcdef"[x]char *addr_to_string(struct fddi_addr *addr){ int i ; static char string[6*3] = "****" ; for (i = 0 ; i < 6 ; i++) { string[i*3] = hextoasc((addr->a[i]>>4)&0xf) ; string[i*3+1] = hextoasc((addr->a[i])&0xf) ; string[i*3+2] = ':' ; } string[5*3+2] = 0 ; return(string) ;}#endif#ifdef AM29Ksmt_ifconfig(int argc, char *argv[]){ if (argc >= 2 && !strcmp(argv[0],"opt_bypass") && !strcmp(argv[1],"yes")) { smc->mib.fddiSMTBypassPresent = 1 ; return(0) ; } return(amdfddi_config(0,argc,argv)) ;}#endif/* * return static mac index */static int mac_index(struct s_smc *smc, int mac){ SK_UNUSED(mac) ;#ifdef CONCENTRATOR SK_UNUSED(smc) ; return(NUMPHYS+1) ;#else return((smc->s.sas == SMT_SAS) ? 2 : 3) ;#endif}/* * return static phy index */static int phy_index(struct s_smc *smc, int phy){ SK_UNUSED(smc) ; return(phy+1);}/* * return dynamic mac connection resource index */static int mac_con_resource_index(struct s_smc *smc, int mac){#ifdef CONCENTRATOR SK_UNUSED(smc) ; SK_UNUSED(mac) ; return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_MAC))) ;#else SK_UNUSED(mac) ; switch (smc->mib.fddiSMTCF_State) { case SC9_C_WRAP_A : case SC5_THRU_B : case SC11_C_WRAP_S : return(1) ; case SC10_C_WRAP_B : case SC4_THRU_A : return(2) ; } return(smc->s.sas == SMT_SAS ? 2 : 3) ;#endif}/* * return dynamic phy connection resource index */static int phy_con_resource_index(struct s_smc *smc, int phy){#ifdef CONCENTRATOR return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_PHY(phy)))) ;#else switch (smc->mib.fddiSMTCF_State) { case SC9_C_WRAP_A : return(phy == PA ? 3 : 2) ; case SC10_C_WRAP_B : return(phy == PA ? 1 : 3) ; case SC4_THRU_A : return(phy == PA ? 3 : 1) ; case SC5_THRU_B : return(phy == PA ? 2 : 3) ; case SC11_C_WRAP_S : return(2) ; } return(phy) ;#endif}#ifdef CONCENTRATORstatic int entity_to_index(struct s_smc *smc, int e){ if (e == ENTITY_MAC) return(mac_index(smc,1)) ; else return(phy_index(smc,e - ENTITY_PHY(0))) ;}#endif#ifdef LITTLE_ENDIANstatic int smt_swap_short(u_short s){ return(((s>>8)&0xff)|((s&0xff)<<8)) ;}void smt_swap_para(struct smt_header *sm, int len, int direction)/* int direction; 0 encode 1 decode */{ struct smt_para *pa ; const struct smt_pdef *pd ; char *p ; int plen ; int type ; int i ;/* printf("smt_swap_para sm %x len %d dir %d\n", sm,len,direction) ; */ smt_string_swap((char *)sm,SWAP_SMTHEADER,len) ; /* swap args */ len -= sizeof(struct smt_header) ; p = (char *) (sm + 1) ; while (len > 0) { pa = (struct smt_para *) p ; plen = pa->p_len ; type = pa->p_type ; pa->p_type = smt_swap_short(pa->p_type) ; pa->p_len = smt_swap_short(pa->p_len) ; if (direction) { plen = pa->p_len ; type = pa->p_type ; } /* * note: paras can have 0 length ! */ if (plen < 0) break ; plen += PARA_LEN ; for (i = N_SMT_PLEN, pd = smt_pdef; i ; i--,pd++) { if (pd->ptype == type) break ; } if (i && pd->pswap) { smt_string_swap(p+PARA_LEN,pd->pswap,len) ; } len -= plen ; p += plen ; }}static void smt_string_swap(char *data, const char *format, int len){ const char *open_paren = 0 ; int x ; while (len > 0 && *format) { switch (*format) { case '[' : open_paren = format ; break ; case ']' : format = open_paren ; break ; case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : data += *format - '0' ; len -= *format - '0' ; break ; case 'c': data++ ; len-- ; break ; case 's' : x = data[0] ; data[0] = data[1] ; data[1] = x ; data += 2 ; len -= 2 ; break ; case 'l' : x = data[0] ; data[0] = data[3] ; data[3] = x ; x = data[1] ; data[1] = data[2] ; data[2] = x ; data += 4 ; len -= 4 ; break ; } format++ ; }}#elsevoid smt_swap_para(struct smt_header *sm, int len, int direction)/* int direction; 0 encode 1 decode */{ SK_UNUSED(sm) ; SK_UNUSED(len) ; SK_UNUSED(direction) ;}#endif/* * PMF actions */int smt_action(struct s_smc *smc, int class, int code, int index){ int event ; int port ; DB_SMT("SMT: action %d code %d\n",class,code) ; switch(class) { case SMT_STATION_ACTION : switch(code) { case SMT_STATION_ACTION_CONNECT : smc->mib.fddiSMTRemoteDisconnectFlag = FALSE ; queue_event(smc,EVENT_ECM,EC_CONNECT) ; break ; case SMT_STATION_ACTION_DISCONNECT : queue_event(smc,EVENT_ECM,EC_DISCONNECT) ; smc->mib.fddiSMTRemoteDisconnectFlag = TRUE ; RS_SET(smc,RS_DISCONNECT) ; AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long) FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_DISCONNECT, smt_get_event_word(smc)); break ; case SMT_STATION_ACTION_PATHTEST : AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long) FDDI_SMT_EVENT, (u_long) FDDI_PATH_TEST, smt_get_event_word(smc)); break ; case SMT_STATION_ACTION_SELFTEST : AIX_EVENT(smc, (u_long) FDDI_RING_STATUS, (u_long) FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_SELF_TEST, smt_get_event_word(smc)); break ; case SMT_STATION_ACTION_DISABLE_A : if (smc->y[PA].pc_mode == PM_PEER) { RS_SET(smc,RS_EVENT) ; queue_event(smc,EVENT_PCM+PA,PC_DISABLE) ; } break ; case SMT_STATION_ACTION_DISABLE_B : if (smc->y[PB].pc_mode == PM_PEER) { RS_SET(smc,RS_EVENT) ; queue_event(smc,EVENT_PCM+PB,PC_DISABLE) ; } break ; case SMT_STATION_ACTION_DISABLE_M : for (port = 0 ; port < NUMPHYS ; port++) { if (smc->mib.p[port].fddiPORTMy_Type != TM) continue ; RS_SET(smc,RS_EVENT) ; queue_event(smc,EVENT_PCM+port,PC_DISABLE) ; } break ; default : return(1) ; } break ; case SMT_PORT_ACTION : switch(code) { case SMT_PORT_ACTION_ENABLE : event = PC_ENABLE ; break ; case SMT_PORT_ACTION_DISABLE : event = PC_DISABLE ; break ; case SMT_PORT_ACTION_MAINT : event = PC_MAINT ; break ; case SMT_PORT_ACTION_START : event = PC_START ; break ; case SMT_PORT_ACTION_STOP : event = PC_STOP ; break ; default : return(1) ; } queue_event(smc,EVENT_PCM+index,event) ; break ; default : return(1) ; } return(0) ;}/* * change tneg * set T_Req in MIB (Path Attribute) * calculate new values for MAC * if change required * disconnect * set reconnect * end */void smt_change_t_neg(struct s_smc *smc, u_long tneg){ smc->mib.a[PATH0].fddiPATHMaxT_Req = tneg ; if (smt_set_mac_opvalues(smc)) { RS_SET(smc,RS_EVENT) ; smc->sm.please_reconnect = 1 ; queue_event(smc,EVENT_ECM,EC_DISCONNECT) ; }}/* * canonical conversion of <len> bytes beginning form *data */#ifdef USE_CAN_ADDRvoid hwm_conv_can(struct s_smc *smc, char *data, int len){ int i ; SK_UNUSED(smc) ; for (i = len; i ; i--, data++) { *data = canonical[*(u_char *)data] ; }}#endif#endif /* no SLIM_SMT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -