📄 pmf.c
字号:
/****************************************************************************** * * (C)Copyright 1998,1999 SysKonnect, * a business unit of Schneider & Koch & Co. Datensysteme GmbH. * * See the file "skfddi.c" for further information. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************//* Parameter Management Frame processing for SMT 7.2*/#include "h/types.h"#include "h/fddi.h"#include "h/smc.h"#include "h/smt_p.h"#define KERNEL#include "h/smtstate.h"#ifndef SLIM_SMT#ifndef lintstatic const char ID_sccs[] = "@(#)pmf.c 1.37 97/08/04 (C) SK " ;#endifstatic int smt_authorize(struct s_smc *smc, struct smt_header *sm);static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm);static const struct s_p_tab* smt_get_ptab(u_short para);static int smt_mib_phys(struct s_smc *smc);int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, int local, int set);void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, int index, int local);static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, int set, int local);#define MOFFSS(e) ((int)&(((struct fddi_mib *)0)->e))#define MOFFSA(e) ((int) (((struct fddi_mib *)0)->e))#define MOFFMS(e) ((int)&(((struct fddi_mib_m *)0)->e))#define MOFFMA(e) ((int) (((struct fddi_mib_m *)0)->e))#define MOFFAS(e) ((int)&(((struct fddi_mib_a *)0)->e))#define MOFFAA(e) ((int) (((struct fddi_mib_a *)0)->e))#define MOFFPS(e) ((int)&(((struct fddi_mib_p *)0)->e))#define MOFFPA(e) ((int) (((struct fddi_mib_p *)0)->e))#define AC_G 0x01 /* Get */#define AC_GR 0x02 /* Get/Set */#define AC_S 0x04 /* Set */#define AC_NA 0x08#define AC_GROUP 0x10 /* Group */#define MS2BCLK(x) ((x)*12500L)/* F LFag (byte) B byte S u_short 16 bit C Counter 32 bit L Long 32 bit T Timer_2 32 bit P TimeStamp ; A LongAddress (6 byte) E Enum 16 bit R ResId 16 Bit*/static const struct s_p_tab { u_short p_num ; /* parameter code */ u_char p_access ; /* access rights */ u_short p_offset ; /* offset in mib */ char p_swap[3] ; /* format string */} p_tab[] = { /* StationIdGrp */ { SMT_P100A,AC_GROUP } , { SMT_P100B,AC_G, MOFFSS(fddiSMTStationId), "8" } , { SMT_P100D,AC_G, MOFFSS(fddiSMTOpVersionId), "S" } , { SMT_P100E,AC_G, MOFFSS(fddiSMTHiVersionId), "S" } , { SMT_P100F,AC_G, MOFFSS(fddiSMTLoVersionId), "S" } , { SMT_P1010,AC_G, MOFFSA(fddiSMTManufacturerData), "D" } , { SMT_P1011,AC_GR, MOFFSA(fddiSMTUserData), "D" } , { SMT_P1012,AC_G, MOFFSS(fddiSMTMIBVersionId), "S" } , /* StationConfigGrp */ { SMT_P1014,AC_GROUP } , { SMT_P1015,AC_G, MOFFSS(fddiSMTMac_Ct), "B" } , { SMT_P1016,AC_G, MOFFSS(fddiSMTNonMaster_Ct), "B" } , { SMT_P1017,AC_G, MOFFSS(fddiSMTMaster_Ct), "B" } , { SMT_P1018,AC_G, MOFFSS(fddiSMTAvailablePaths), "B" } , { SMT_P1019,AC_G, MOFFSS(fddiSMTConfigCapabilities),"S" } , { SMT_P101A,AC_GR, MOFFSS(fddiSMTConfigPolicy), "wS" } , { SMT_P101B,AC_GR, MOFFSS(fddiSMTConnectionPolicy),"wS" } , { SMT_P101D,AC_GR, MOFFSS(fddiSMTTT_Notify), "wS" } , { SMT_P101E,AC_GR, MOFFSS(fddiSMTStatRptPolicy), "bB" } , { SMT_P101F,AC_GR, MOFFSS(fddiSMTTrace_MaxExpiration),"lL" } , { SMT_P1020,AC_G, MOFFSA(fddiSMTPORTIndexes), "II" } , { SMT_P1021,AC_G, MOFFSS(fddiSMTMACIndexes), "I" } , { SMT_P1022,AC_G, MOFFSS(fddiSMTBypassPresent), "F" } , /* StatusGrp */ { SMT_P1028,AC_GROUP } , { SMT_P1029,AC_G, MOFFSS(fddiSMTECMState), "E" } , { SMT_P102A,AC_G, MOFFSS(fddiSMTCF_State), "E" } , { SMT_P102C,AC_G, MOFFSS(fddiSMTRemoteDisconnectFlag),"F" } , { SMT_P102D,AC_G, MOFFSS(fddiSMTStationStatus), "E" } , { SMT_P102E,AC_G, MOFFSS(fddiSMTPeerWrapFlag), "F" } , /* MIBOperationGrp */ { SMT_P1032,AC_GROUP } , { SMT_P1033,AC_G, MOFFSA(fddiSMTTimeStamp),"P" } , { SMT_P1034,AC_G, MOFFSA(fddiSMTTransitionTimeStamp),"P" } , /* NOTE : SMT_P1035 is already swapped ! SMT_P_SETCOUNT */ { SMT_P1035,AC_G, MOFFSS(fddiSMTSetCount),"4P" } , { SMT_P1036,AC_G, MOFFSS(fddiSMTLastSetStationId),"8" } , { SMT_P103C,AC_S, 0, "wS" } , /* * PRIVATE EXTENSIONS * only accessible locally to get/set passwd */ { SMT_P10F0,AC_GR, MOFFSA(fddiPRPMFPasswd), "8" } , { SMT_P10F1,AC_GR, MOFFSS(fddiPRPMFStation), "8" } ,#ifdef ESS { SMT_P10F2,AC_GR, MOFFSS(fddiESSPayload), "lL" } , { SMT_P10F3,AC_GR, MOFFSS(fddiESSOverhead), "lL" } , { SMT_P10F4,AC_GR, MOFFSS(fddiESSMaxTNeg), "lL" } , { SMT_P10F5,AC_GR, MOFFSS(fddiESSMinSegmentSize), "lL" } , { SMT_P10F6,AC_GR, MOFFSS(fddiESSCategory), "lL" } , { SMT_P10F7,AC_GR, MOFFSS(fddiESSSynchTxMode), "wS" } ,#endif#ifdef SBA { SMT_P10F8,AC_GR, MOFFSS(fddiSBACommand), "bF" } , { SMT_P10F9,AC_GR, MOFFSS(fddiSBAAvailable), "bF" } ,#endif /* MAC Attributes */ { SMT_P200A,AC_GROUP } , { SMT_P200B,AC_G, MOFFMS(fddiMACFrameStatusFunctions),"S" } , { SMT_P200D,AC_G, MOFFMS(fddiMACT_MaxCapabilitiy),"T" } , { SMT_P200E,AC_G, MOFFMS(fddiMACTVXCapabilitiy),"T" } , /* ConfigGrp */ { SMT_P2014,AC_GROUP } , { SMT_P2016,AC_G, MOFFMS(fddiMACAvailablePaths), "B" } , { SMT_P2017,AC_G, MOFFMS(fddiMACCurrentPath), "S" } , { SMT_P2018,AC_G, MOFFMS(fddiMACUpstreamNbr), "A" } , { SMT_P2019,AC_G, MOFFMS(fddiMACDownstreamNbr), "A" } , { SMT_P201A,AC_G, MOFFMS(fddiMACOldUpstreamNbr), "A" } , { SMT_P201B,AC_G, MOFFMS(fddiMACOldDownstreamNbr),"A" } , { SMT_P201D,AC_G, MOFFMS(fddiMACDupAddressTest), "E" } , { SMT_P2020,AC_GR, MOFFMS(fddiMACRequestedPaths), "wS" } , { SMT_P2021,AC_G, MOFFMS(fddiMACDownstreamPORTType),"E" } , { SMT_P2022,AC_G, MOFFMS(fddiMACIndex), "S" } , /* AddressGrp */ { SMT_P2028,AC_GROUP } , { SMT_P2029,AC_G, MOFFMS(fddiMACSMTAddress), "A" } , /* OperationGrp */ { SMT_P2032,AC_GROUP } , { SMT_P2033,AC_G, MOFFMS(fddiMACT_Req), "T" } , { SMT_P2034,AC_G, MOFFMS(fddiMACT_Neg), "T" } , { SMT_P2035,AC_G, MOFFMS(fddiMACT_Max), "T" } , { SMT_P2036,AC_G, MOFFMS(fddiMACTvxValue), "T" } , { SMT_P2038,AC_G, MOFFMS(fddiMACT_Pri0), "T" } , { SMT_P2039,AC_G, MOFFMS(fddiMACT_Pri1), "T" } , { SMT_P203A,AC_G, MOFFMS(fddiMACT_Pri2), "T" } , { SMT_P203B,AC_G, MOFFMS(fddiMACT_Pri3), "T" } , { SMT_P203C,AC_G, MOFFMS(fddiMACT_Pri4), "T" } , { SMT_P203D,AC_G, MOFFMS(fddiMACT_Pri5), "T" } , { SMT_P203E,AC_G, MOFFMS(fddiMACT_Pri6), "T" } , /* CountersGrp */ { SMT_P2046,AC_GROUP } , { SMT_P2047,AC_G, MOFFMS(fddiMACFrame_Ct), "C" } , { SMT_P2048,AC_G, MOFFMS(fddiMACCopied_Ct), "C" } , { SMT_P2049,AC_G, MOFFMS(fddiMACTransmit_Ct), "C" } , { SMT_P204A,AC_G, MOFFMS(fddiMACToken_Ct), "C" } , { SMT_P2051,AC_G, MOFFMS(fddiMACError_Ct), "C" } , { SMT_P2052,AC_G, MOFFMS(fddiMACLost_Ct), "C" } , { SMT_P2053,AC_G, MOFFMS(fddiMACTvxExpired_Ct), "C" } , { SMT_P2054,AC_G, MOFFMS(fddiMACNotCopied_Ct), "C" } , { SMT_P2056,AC_G, MOFFMS(fddiMACRingOp_Ct), "C" } , /* FrameErrorConditionGrp */ { SMT_P205A,AC_GROUP } , { SMT_P205F,AC_GR, MOFFMS(fddiMACFrameErrorThreshold),"wS" } , { SMT_P2060,AC_G, MOFFMS(fddiMACFrameErrorRatio), "S" } , /* NotCopiedConditionGrp */ { SMT_P2064,AC_GROUP } , { SMT_P2067,AC_GR, MOFFMS(fddiMACNotCopiedThreshold),"wS" } , { SMT_P2069,AC_G, MOFFMS(fddiMACNotCopiedRatio), "S" } , /* StatusGrp */ { SMT_P206E,AC_GROUP } , { SMT_P206F,AC_G, MOFFMS(fddiMACRMTState), "S" } , { SMT_P2070,AC_G, MOFFMS(fddiMACDA_Flag), "F" } , { SMT_P2071,AC_G, MOFFMS(fddiMACUNDA_Flag), "F" } , { SMT_P2072,AC_G, MOFFMS(fddiMACFrameErrorFlag), "F" } , { SMT_P2073,AC_G, MOFFMS(fddiMACNotCopiedFlag), "F" } , { SMT_P2074,AC_G, MOFFMS(fddiMACMA_UnitdataAvailable),"F" } , { SMT_P2075,AC_G, MOFFMS(fddiMACHardwarePresent), "F" } , { SMT_P2076,AC_GR, MOFFMS(fddiMACMA_UnitdataEnable),"bF" } , /* * PRIVATE EXTENSIONS * only accessible locally to get/set TMIN */ { SMT_P20F0,AC_NA } , { SMT_P20F1,AC_GR, MOFFMS(fddiMACT_Min), "lT" } , /* Path Attributes */ /* * DON't swap 320B,320F,3210: they are already swapped in swap_para() */ { SMT_P320A,AC_GROUP } , { SMT_P320B,AC_G, MOFFAS(fddiPATHIndex), "r" } , { SMT_P320F,AC_GR, MOFFAS(fddiPATHSbaPayload), "l4" } , { SMT_P3210,AC_GR, MOFFAS(fddiPATHSbaOverhead), "l4" } , /* fddiPATHConfiguration */ { SMT_P3212,AC_G, 0, "" } , { SMT_P3213,AC_GR, MOFFAS(fddiPATHT_Rmode), "lT" } , { SMT_P3214,AC_GR, MOFFAS(fddiPATHSbaAvailable), "lL" } , { SMT_P3215,AC_GR, MOFFAS(fddiPATHTVXLowerBound), "lT" } , { SMT_P3216,AC_GR, MOFFAS(fddiPATHT_MaxLowerBound),"lT" } , { SMT_P3217,AC_GR, MOFFAS(fddiPATHMaxT_Req), "lT" } , /* Port Attributes */ /* ConfigGrp */ { SMT_P400A,AC_GROUP } , { SMT_P400C,AC_G, MOFFPS(fddiPORTMy_Type), "E" } , { SMT_P400D,AC_G, MOFFPS(fddiPORTNeighborType), "E" } , { SMT_P400E,AC_GR, MOFFPS(fddiPORTConnectionPolicies),"bB" } , { SMT_P400F,AC_G, MOFFPS(fddiPORTMacIndicated), "2" } , { SMT_P4010,AC_G, MOFFPS(fddiPORTCurrentPath), "E" } , { SMT_P4011,AC_GR, MOFFPA(fddiPORTRequestedPaths), "l4" } , { SMT_P4012,AC_G, MOFFPS(fddiPORTMACPlacement), "S" } , { SMT_P4013,AC_G, MOFFPS(fddiPORTAvailablePaths), "B" } , { SMT_P4016,AC_G, MOFFPS(fddiPORTPMDClass), "E" } , { SMT_P4017,AC_G, MOFFPS(fddiPORTConnectionCapabilities), "B"} , { SMT_P401D,AC_G, MOFFPS(fddiPORTIndex), "R" } , /* OperationGrp */ { SMT_P401E,AC_GROUP } , { SMT_P401F,AC_GR, MOFFPS(fddiPORTMaint_LS), "wE" } , { SMT_P4021,AC_G, MOFFPS(fddiPORTBS_Flag), "F" } , { SMT_P4022,AC_G, MOFFPS(fddiPORTPC_LS), "E" } , /* ErrorCtrsGrp */ { SMT_P4028,AC_GROUP } , { SMT_P4029,AC_G, MOFFPS(fddiPORTEBError_Ct), "C" } , { SMT_P402A,AC_G, MOFFPS(fddiPORTLCTFail_Ct), "C" } , /* LerGrp */ { SMT_P4032,AC_GROUP } , { SMT_P4033,AC_G, MOFFPS(fddiPORTLer_Estimate), "F" } , { SMT_P4034,AC_G, MOFFPS(fddiPORTLem_Reject_Ct), "C" } , { SMT_P4035,AC_G, MOFFPS(fddiPORTLem_Ct), "C" } , { SMT_P403A,AC_GR, MOFFPS(fddiPORTLer_Cutoff), "bB" } , { SMT_P403B,AC_GR, MOFFPS(fddiPORTLer_Alarm), "bB" } , /* StatusGrp */ { SMT_P403C,AC_GROUP } , { SMT_P403D,AC_G, MOFFPS(fddiPORTConnectState), "E" } , { SMT_P403E,AC_G, MOFFPS(fddiPORTPCMStateX), "E" } , { SMT_P403F,AC_G, MOFFPS(fddiPORTPC_Withhold), "E" } , { SMT_P4040,AC_G, MOFFPS(fddiPORTLerFlag), "F" } , { SMT_P4041,AC_G, MOFFPS(fddiPORTHardwarePresent),"F" } , { SMT_P4046,AC_S, 0, "wS" } , { 0, AC_GROUP } , { 0 }} ;void smt_pmf_received_pack(struct s_smc *smc, SMbuf *mb, int local){ struct smt_header *sm ; SMbuf *reply ; sm = smtod(mb,struct smt_header *) ; DB_SMT("SMT: processing PMF frame at %x len %d\n",sm,mb->sm_len) ;#ifdef DEBUG dump_smt(smc,sm,"PMF Received") ;#endif /* * Start the watchdog: It may be a long, long packet and * maybe the watchdog occurs ... */ smt_start_watchdog(smc) ; if (sm->smt_class == SMT_PMF_GET || sm->smt_class == SMT_PMF_SET) { reply = smt_build_pmf_response(smc,sm, sm->smt_class == SMT_PMF_SET,local) ; if (reply) { sm = smtod(reply,struct smt_header *) ;#ifdef DEBUG dump_smt(smc,sm,"PMF Reply") ;#endif smt_send_frame(smc,reply,FC_SMT_INFO,local) ; } }}static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, int set, int local){ SMbuf *mb ; struct smt_header *smt ; struct smt_para *pa ; struct smt_p_reason *res ; const struct s_p_tab *pt ; int len ; int index ; int idx_end ; int error ; int range ; SK_LOC_DECL(struct s_pcon,pcon) ; SK_LOC_DECL(struct s_pcon,set_pcon) ; /* * build SMT header */ if (!(mb = smt_get_mbuf(smc))) return(mb) ; smt = smtod(mb, struct smt_header *) ; smt->smt_dest = req->smt_source ; /* DA == source of request */ smt->smt_class = req->smt_class ; /* same class (GET/SET) */ smt->smt_type = SMT_REPLY ; smt->smt_version = SMT_VID_2 ; smt->smt_tid = req->smt_tid ; /* same TID */ smt->smt_pad = 0 ; smt->smt_len = 0 ; /* * setup parameter status */ pcon.pc_len = SMT_MAX_INFO_LEN ; /* max para length */ pcon.pc_err = 0 ; /* no error */ pcon.pc_badset = 0 ; /* no bad set count */ pcon.pc_p = (void *) (smt + 1) ; /* paras start here */ /* * check authoriziation and set count */ error = 0 ; if (set) { if (!local && smt_authorize(smc,req)) error = SMT_RDF_AUTHOR ; else if (smt_check_set_count(smc,req)) pcon.pc_badset = SMT_RDF_BADSET ; } /* * add reason code and all mandatory parameters */ res = (struct smt_p_reason *) pcon.pc_p ; smt_add_para(smc,&pcon,(u_short) SMT_P_REASON,0,0) ; smt_add_para(smc,&pcon,(u_short) SMT_P1033,0,0) ; /* update 1035 and 1036 later if set */ set_pcon = pcon ; smt_add_para(smc,&pcon,(u_short) SMT_P1035,0,0) ; smt_add_para(smc,&pcon,(u_short) SMT_P1036,0,0) ; pcon.pc_err = error ; len = req->smt_len ; pa = (struct smt_para *) (req + 1) ; /* * process list of paras */ while (!pcon.pc_err && len > 0 ) { if (((u_short)len < pa->p_len + PARA_LEN) || (pa->p_len & 3)) { pcon.pc_err = SMT_RDF_LENGTH ; break ; } if (((range = (pa->p_type & 0xf000)) == 0x2000) || range == 0x3000 || range == 0x4000) { /* * get index for PART,MAC ad PATH group */ index = *((u_char *)pa + PARA_LEN + 3) ;/* index */ idx_end = index ; if (!set && (pa->p_len != 4)) { pcon.pc_err = SMT_RDF_LENGTH ; break ; } if (!index && !set) { switch (range) { case 0x2000 : index = INDEX_MAC ; idx_end = index - 1 + NUMMACS ; break ; case 0x3000 : index = INDEX_PATH ; idx_end = index - 1 + NUMPATHS ; break ; case 0x4000 : index = INDEX_PORT ; idx_end = index - 1 + NUMPHYS ;#ifndef CONCENTRATOR if (smc->s.sas == SMT_SAS) idx_end = INDEX_PORT ;#endif break ; } } } else { /* * smt group has no index */ if (!set && (pa->p_len != 0)) { pcon.pc_err = SMT_RDF_LENGTH ; break ; } index = 0 ; idx_end = 0 ; } while (index <= idx_end) { /* * if group * add all paras of group */ pt = smt_get_ptab(pa->p_type) ; if (pt && pt->p_access == AC_GROUP && !set) { pt++ ; while (pt->p_access == AC_G || pt->p_access == AC_GR) { smt_add_para(smc,&pcon,pt->p_num, index,local); pt++ ; } } /* * ignore * AUTHORIZATION in get/set * SET COUNT in set */ else if (pa->p_type != SMT_P_AUTHOR && (!set || (pa->p_type != SMT_P1035))) { int st ; if (pcon.pc_badset) { smt_add_para(smc,&pcon,pa->p_type, index,local) ; } else if (set) { st = smt_set_para(smc,pa,index,local,1); /* * return para even if error */ smt_add_para(smc,&pcon,pa->p_type, index,local) ; pcon.pc_err = st ; } else { if (pt && pt->p_access == AC_S) { pcon.pc_err = SMT_RDF_ILLEGAL ; } smt_add_para(smc,&pcon,pa->p_type, index,local) ; } } if (pcon.pc_err) break ; index++ ; } len -= pa->p_len + PARA_LEN ; pa = (struct smt_para *) ((char *)pa + pa->p_len + PARA_LEN) ; } smt->smt_len = SMT_MAX_INFO_LEN - pcon.pc_len ; mb->sm_len = smt->smt_len + sizeof(struct smt_header) ; /* update reason code */ res->rdf_reason = pcon.pc_badset ? pcon.pc_badset : pcon.pc_err ? pcon.pc_err : SMT_RDF_SUCCESS ; if (set && (res->rdf_reason == SMT_RDF_SUCCESS)) { /* * increment set count * set time stamp * store station id of last set */ smc->mib.fddiSMTSetCount.count++ ; smt_set_timestamp(smc,smc->mib.fddiSMTSetCount.timestamp) ; smc->mib.fddiSMTLastSetStationId = req->smt_sid ; smt_add_para(smc,&set_pcon,(u_short) SMT_P1035,0,0) ; smt_add_para(smc,&set_pcon,(u_short) SMT_P1036,0,0) ; } return(mb) ;}static int smt_authorize(struct s_smc *smc, struct smt_header *sm){ struct smt_para *pa ; int i ; char *p ; /* * check source station id if not zero */ p = (char *) &smc->mib.fddiPRPMFStation ; for (i = 0 ; i < 8 && !p[i] ; i++) ; if (i != 8) { if (memcmp((char *) &sm->smt_sid, (char *) &smc->mib.fddiPRPMFStation,8)) return(1) ; } /* * check authoriziation parameter if passwd not zero */ p = (char *) smc->mib.fddiPRPMFPasswd ; for (i = 0 ; i < 8 && !p[i] ; i++) ; if (i != 8) { pa = (struct smt_para *) sm_to_para(smc,sm,SMT_P_AUTHOR) ; if (!pa) return(1) ; if (pa->p_len != 8) return(1) ; if (memcmp((char *)(pa+1),(char *)smc->mib.fddiPRPMFPasswd,8)) return(1) ; } return(0) ;}static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm){ struct smt_para *pa ; struct smt_p_setcount *sc ; pa = (struct smt_para *) sm_to_para(smc,sm,SMT_P1035) ; if (pa) { sc = (struct smt_p_setcount *) pa ; if ((smc->mib.fddiSMTSetCount.count != sc->count) || memcmp((char *) smc->mib.fddiSMTSetCount.timestamp, (char *)sc->timestamp,8)) return(1) ; } return(0) ;}void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, int index, int local){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -