📄 pppoethernet.c
字号:
pStackData->userHandle = userHandle; pStackData->stackObjCallbacks = callbacks; pComponent->pppOEServiceNameMap[i] = pComponentState; pProfileData=(PPPOE_PROFILE_DATA *)pComponentState->profileData; if (strlen(pProfileData->acNameTag) == 0) { /* profile has no name for the AC, use default name */ sprintf(pProfileData->acNameTag,PPPOE_DEFAULT_AC_NAME); } pComponent->pppOEServices++; return OK; } } } printf("PPPOE: Too many services; Max allowed = %d\n", pComponent->pppOEMaxServices); return ERROR; }/********************************************************************************* pppOEServiceNameDelete - delete a service name and all corresponding stacks ** This routine deletes the stacks corresponding to the svcName** RETURNS: OK on success and ERROR otherwise*/STATUS pppOEServiceNameDelete ( PFW_OBJ * pfw, /* pfw from which to delete service */ char * svcName /* service name we're deleting */ ) { PPPOE_STACK_DATA * pStackData = NULL; PFW_PLUGIN_OBJ_STATE * pComponentState; int i; char service[32]; PPPOE_COMPONENT *pComponent; BOOL found = FALSE; if (pfw == NULL) { printf ("PPPOE: Null framework object \n"); return ERROR; } pComponent =(PPPOE_COMPONENT *)pfwPluginObjGet(pfw,"PPP_O_ETHERNET"); bzero(service,32); if (strlen(svcName)) strcpy(service,svcName); else sprintf(service,"%s","ANY"); for (i = 1 ; i <= pComponent->pppOEMaxServices ; i++) { if ((pComponentState = pComponent->pppOEServiceNameMap[i]) == NULL) { continue; } pStackData = (PPPOE_STACK_DATA *)pComponentState->stackData; if (!strcmp(pStackData->serviceName,service)) { /* delete connection */ pfwStackDelete (pComponentState->stackObj); found = TRUE; } } if (!found) { printf("PPPOE: No such service: %s\n",svcName); return (ERROR); } else return (OK); }/******************************************************************************** pppOEStackObjResolve - obtain stack object from received PPPOE frame ** This is the stack object resolver and it returns a valid stack object* within which the frame will be processed further or ERROR if cannot* determine the stack object** RETURNS: The stack object if successful and ERROR otherwise */LOCAL PFW_STACK_OBJ * pppOEStackObjResolve ( PFW_PLUGIN_OBJ * pPluginObj, /* this component */ M_BLK_ID pFrame, /* the received ethernet frame */ ULONG portId ) { struct ether_header * pEtherHdr = NULL; PPPOE_HEADER * pPPPOEHeader = NULL; PPPOE_TLV * pTlv = NULL; PPPOE_TLV * foundTlv = NULL; PFW_STACK_OBJ * stackObj; PPPOE_COMPONENT * pComponent = (PPPOE_COMPONENT *)pPluginObj; PFW_STACK_STATUS stackStatus = PFW_STACK_ADD_IN_PROGRESS; PFW_PLUGIN_OBJ_STATE * pppoeACState = NULL; if (pFrame == NULL) return NULL; /* if we dont have the headers in the first MBLK drop the packet */ if (pFrame->mBlkHdr.mLen >= (sizeof(struct ether_header) + sizeof(PPPOE_HEADER))) { pEtherHdr = mtod (pFrame, struct ether_header *); } else return NULL; /* ethertype field has to indicate session or a discovery frame */ if ((ntohs(pEtherHdr->ether_type) != ETHERTYPE_PPPOE_DISCOVERY) && (ntohs(pEtherHdr->ether_type) != ETHERTYPE_PPPOE_SESSION)) return NULL; /* * check the PPPOE header and in the case of DISCOVERY packets * PPPOE expects a contiguous buffer!! */ pPPPOEHeader = (PPPOE_HEADER *)(pFrame->mBlkHdr.mData + sizeof(struct ether_header)); /* check if we have as much data as the header says we do */ if (pFrame->mBlkHdr.mLen < (ntohs(pPPPOEHeader->pppOE_length) + sizeof(PPPOE_HEADER) + sizeof(struct ether_header))) return NULL; /* point to the first tlv */ pTlv = (PPPOE_TLV *)((char *)pPPPOEHeader + sizeof(PPPOE_HEADER)); /* * try to find the stack object depending on the type of PPOE packet */ switch (pPPPOEHeader->pppOE_code) { /* these two cases are encountered by the Access concentarator */ case PPPOE_CODE_PADI: /* incoming PADI must have a service name tag */ if ((foundTlv = pppOEFindTlv(PPPOE_TAG_SVC_NAME,pTlv,pFrame))!=NULL) { return (pppOESvcStackObjGet(pComponent, foundTlv, portId)); } /* this will return NULL */ break; case PPPOE_CODE_PADR: /* search for and return the AC cookie we inserted in the PADO */ if ((foundTlv=pppOEFindTlv(PPPOE_TAG_AC_COOKIE,pTlv,pFrame)) !=NULL) { bcopy(PPPOE_TAG_VALUE(foundTlv),(char *)&stackObj, sizeof(PFW_STACK_OBJ *)); /* verify if AC cookie is valid */ if (pppOEVerifyACCookie (pComponent, stackObj) != OK) break; else { PPPOE_STACK_DATA * pStackData; pppoeACState = pfwPluginObjStateGet(stackObj,pPluginObj); if (pppoeACState == NULL) break; pStackData = pppoeACState->stackData; /* * if we've received a request based on our PADO with * multiple serviceNames in it and we need to find the * stack based on the serviceName in this request */ if (!strcmp(pStackData->serviceName,"ANY")) { if ((foundTlv = pppOEFindTlv(PPPOE_TAG_SVC_NAME, pTlv,pFrame))!=NULL) { /* * we dont accept a zero length service name tag * in a PADR */ if (PPPOE_TAG_LENGTH(foundTlv) == 0) break; return (pppOESvcStackObjGet(pComponent, foundTlv, portId)); } else break; /* cant find a service name in this frame */ } return (stackObj); } } /* this will return NULL */ break; /* these two cases are encountered by the client/host */ case PPPOE_CODE_PADO: /* * a PADO must have a AC name tag; if it does we find * the host unique cookie that we sent out in the PADI * and return it as our stack object */ if ((foundTlv=pppOEFindTlv(PPPOE_TAG_AC_NAME,pTlv,pFrame)) !=NULL) { if ((foundTlv = pppOEFindTlv(PPPOE_TAG_HOST_UNIQ,pTlv,pFrame)) !=NULL) { /* the host cookie is the stack object that sent the PADI */ bcopy(PPPOE_TAG_VALUE(foundTlv),(char *)&stackObj, sizeof(PFW_STACK_OBJ *)); /* verify that stack is valid */ if (pfwStackStatusGet (stackObj, &stackStatus) != OK) break; else return (stackObj); } } /* this will return NULL */ break; case PPPOE_CODE_PADS: /* * check session ID to be non NULL. If it is NULL an AC error * occured; return NULL after printing any AC system errors */ if (ntohs(pPPPOEHeader->pppOE_session) == PPPOE_SESSION_DISCOVERY) /*|| (pPPPOEHeader->pppOE_code == 0))*/ { if ((foundTlv=pppOEFindTlv(PPPOE_TAG_AC_SYSTEM_ERROR,pTlv, pFrame)) != NULL) { char message[256]; bzero(message,sizeof(message)); strncpy(message,PPPOE_TAG_VALUE(foundTlv),255); if (message[0] != '\0') printf ("PPPOE: AC SYSTEM ERROR: %s\n",message); } break; } /* Once again the host cookie is our stack object */ if ((foundTlv=pppOEFindTlv(PPPOE_TAG_HOST_UNIQ,pTlv,pFrame)) !=NULL) { bcopy(PPPOE_TAG_VALUE(foundTlv), (char *)&stackObj, sizeof(PFW_STACK_OBJ *)); /* verify that stack is valid */ if (pfwStackStatusGet (stackObj, &stackStatus) != OK) break; else return (stackObj); } /* this will return NULL */ break; /* encountered by both AC and host during the session phase */ case PPPOE_CODE_SESSION: case PPPOE_CODE_PADT: /* find the stackObj from the MAP(sessionID,stack object) */ stackObj = pppOEStackObjGet(pComponent, ntohs(pPPPOEHeader->pppOE_session), pEtherHdr->ether_shost); /* verify that stack is valid and ready */ if ((pfwStackStatusGet (stackObj, &stackStatus) != OK) || (stackStatus != PFW_STACK_READY)) break; else return (stackObj); default: break; } return NULL; }/******************************************************************************** pppOEProfileDataConstruct - initialize profile data for PPP over Ethernet** This function is called by the framework to get default values for the* parameters managed and supported by this component** RETURNS: OK on success and ERROR otherwise*/LOCAL STATUS pppOEProfileDataConstruct ( PFW_OBJ * pfw, void * pProfileData /* reference to this component's profile data */ ) { PPPOE_PROFILE_DATA * pPPPOEProfileData = (PPPOE_PROFILE_DATA *)pProfileData; bzero((void *)pPPPOEProfileData, sizeof(PPPOE_PROFILE_DATA)); /* set some default values */ pPPPOEProfileData->connectionMode = PPPOE_HOST_MODE; pPPPOEProfileData->discoveryRetries = PPPOE_DISCOVERY_RETRIES; pPPPOEProfileData->minDiscTimeout = PPPOE_MIN_TIMEOUT; return OK; }/******************************************************************************** pppOEStackDataConstruct - initialize stack data for PPP over Ethernet** This function is called by the framework at the time this component is* included in a stack for the purpose of allowing the component to initialize* its stack data** RETURNS: OK on success and ERROR otherwise*/LOCAL STATUS pppOEStackDataConstruct ( PFW_OBJ * pfw, void * stackData, /* reference to this component's stack data */ void * profileData /* reference to this component's profile data */ ) { PPPOE_STACK_DATA * pStackData = (PPPOE_STACK_DATA *)stackData; bzero((void *)pStackData, sizeof(PPPOE_STACK_DATA)); pStackData->collectPppAttributesEvent = NULL; pStackData->lcpUpFlag = FALSE; pStackData->sendPADT = TRUE; if ((pStackData->netPoolId = pfwNetPoolIdGet(pfw)) == NULL) { printf ("PPPOE: must have a valid netPoolId; see pfwCreate()\n"); return ERROR; } if (NULL == (pStackData->pppSubordinateLayerDeadEvent = pfwEventObjGet(pfw, "PPP_SUB_LAYER_DEAD_EVENT"))) return(ERROR); return OK; }/******************************************************************************** pppOEStackDataDestruct - clean up and close stack data** This function is called by the framework at the time this component is* removed from a stack for the purpose of allowing the component to cleanup* its stack data** RETURNS: OK on success and ERROR otherwise*/LOCAL STATUS pppOEStackDataDestruct ( PFW_OBJ * pfw, void * stackData, /* reference to this component's stack data */ void * profileData /* reference to this component's profile data */ ) { PPPOE_STACK_DATA * pStackData = (PPPOE_STACK_DATA *)stackData; PPPOE_FREE_RECVD_PKT(pStackData); PPPOE_FREE_RETRY_PKT(pStackData); return OK; }/******************************************************************************** pppOEStackDel - Delete an established PPPOE session** This is the first interface invoked by the framework when deleting a * PPP connection* * RETURNS: OK on success and ERROR otherwise*/LOCAL STATUS pppOEStackDel ( PFW_PLUGIN_OBJ_STATE * pComponentState /* our state for this stack */ ) { PPPOE_COMPONENT * pComponent = (PPPOE_COMPONENT *)pComponentState->pluginObj; PPPOE_STACK_DATA * pStackData = (PPPOE_STACK_DATA *)(pComponentState->stackData);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -