📄 pppoethernet.c
字号:
M_BLK_ID packet; if (pStackData->sendPADT == TRUE) { if ((packet = pppOEMakePADT(pComponentState)) != NULL) { ADAPTER_DEST_ADDR_AND_PROTOCOL_SET(pStackData, ETHERTYPE_PPPOE_DISCOVERY); pfwSend(pComponentState,packet); } } /* clear the session MAP */ pppOEStackIdMapClear (pComponentState); /* if this is an AC daemon connection remove it from the service map */ if (pStackData->serviceMapId > 0) { pComponent->pppOEServiceNameMap[pStackData->serviceMapId] = NULL; pStackData->serviceMapId = 0; pComponent->pppOEServices--; } if (pStackData->pfwRFC2233CountTest) pfwInterfaceReferenceDelete( pStackData->pfwRFC2233CountPair.interfaceObj); pfwInterfaceReferenceDelete(pStackData->adapterInterface.interfaceObj); PPPOE_STACK_DELETE_DONE(pComponentState); return OK; }/******************************************************************************** pppOEStackAdd - initialize a connection via a ethernet interface** This is the first interface invoked by the framework when initializing a* connection over an Ethernet interface. The profileData for this connection* contained in the componentState parameter has service names and other* parameters required to establish a connection.* * This component behaves as an Access Concentrator or a Host depending on* the configuration in the profile. In the former case the connection add phase* simply returns and in the latter case Discovery packets are initiated* to find the peer.** RETURNS: OK on success and ERROR otherwise*/LOCAL STATUS pppOEStackAdd ( PFW_PLUGIN_OBJ_STATE * pComponentState, /* our state for this connection */ PFW_PLUGIN_OBJ_CALLBACKS * callbacks ) { PPPOE_PROFILE_DATA * pProfileData = (PPPOE_PROFILE_DATA *)(pComponentState->profileData); PPPOE_STACK_DATA * pStackData = (PPPOE_STACK_DATA *)(pComponentState->stackData); PPPOE_COMPONENT * pComponent =(PPPOE_COMPONENT *)pComponentState->pluginObj; M_BLK_ID pPacket = NULL; int id; PFW_EVENT_OBJ * pPfwEventObj; ULONG adapterInfoGetInterfaceId; PFW_INTERFACE_STATE_PAIR adapterInfoGetInterfaceStatePair; if (pStackData->collectPppAttributesEvent == NULL) { if ((pStackData->collectPppAttributesEvent = pfwEventObjGet(pComponentState->pluginObj->pfwObj, "COLLECT_PPP_ATTRIBUTES_EVENT")) != NULL) { pfwEventStackSubscribe(pComponentState, pStackData->collectPppAttributesEvent, pppOEFramingTypeHandler); } } /* initialize stack Data */ pStackData->connectionMode = pProfileData->connectionMode; if (pComponent->operatingMode == PPPOE_HOST_MODE && pStackData->connectionMode == PPPOE_AC_MODE) { printf("PPPOE:Configured in PPPOE_HOST_MODE: Bad Connection mode 0x%x\n" ,pStackData->connectionMode); return ERROR; } else if (pComponent->operatingMode == PPPOE_AC_MODE&& pStackData->connectionMode == PPPOE_HOST_MODE) { printf("PPPOE:Configured in PPPOE_AC_MODE: Bad Connection mode 0x%x\n" ,pStackData->connectionMode); return ERROR; } pStackData->pfwState = pComponentState; pStackData->state = PPPOE_STATE_PADI; bzero(pStackData->serviceName, sizeof(pStackData->serviceName)); bzero(pStackData->acName, sizeof(pStackData->acName)); strncpy(pStackData->acName,pProfileData->acNameTag, sizeof(pStackData->acName) -1); memset(pStackData->srcEnet,0, ENET_LEN); memset(pStackData->destEnet,0, ENET_LEN); pStackData->more = NULL; pStackData->pTimer = NULL; pStackData->remPADIRetries = (pProfileData->discoveryRetries + 1) ; pStackData->serviceMapId = 0; pStackData->profileObj = NULL; pStackData->pRecvdDiscPkt = NULL; pStackData->pRetryDiscPkt = NULL; pStackData->callbacks = callbacks; /* get adapterInterface if it exists */ if ((id = pfwInterfaceIdGet(pComponentState->pluginObj->pfwObj, "ADAPTER_DESTINATION_AND_PROTOCOL_SET_INTERFACE")) > 0) { pfwInterfaceObjAndStateGetViaStackObj(pComponentState->stackObj, id, &pStackData->adapterInterface); } if ((adapterInfoGetInterfaceId = pfwInterfaceIdGet(pComponentState->pluginObj->pfwObj, "ADAPTER_INFO_GET_INTERFACE")) > 0) { pfwInterfaceObjAndStateGetViaStackObj(pComponentState->stackObj, adapterInfoGetInterfaceId, &adapterInfoGetInterfaceStatePair); ((ADAPTER_INFO_GET_INTERFACE *)(adapterInfoGetInterfaceStatePair.interfaceObj))-> adapterPortIdGet (adapterInfoGetInterfaceStatePair.state, &(pStackData->portId)); } /* get PPP administrative open event object and subcribe to it*/ if (NULL != (pPfwEventObj = pfwEventObjGet(pComponentState->pluginObj->pfwObj, "LCP_OPEN_EVENT"))) { pfwEventStackSubscribe(pComponentState, pPfwEventObj, lcpOpenEventHandler); } else { return(ERROR); } /* get PPP administrative up event object and subcribe to it*/ if (NULL != (pPfwEventObj = pfwEventObjGet(pComponentState->pluginObj->pfwObj, "LCP_UP_EVENT"))) { pfwEventStackSubscribe(pComponentState, pPfwEventObj, lcpUpEventHandler); } else { return(ERROR); } /* get PPP administrative up event object and subcribe to it*/ if (NULL != (pPfwEventObj = pfwEventObjGet(pComponentState->pluginObj->pfwObj, "LCP_DOWN_EVENT"))) { pfwEventStackSubscribe(pComponentState, pPfwEventObj, lcpDownEventHandler); } else { return(ERROR); } /* Get pfwRFC2233CountPair and set pfwRFC2233CountTest */ RFC2233_COUNT_PAIR_GET(pComponentState, pStackData->pfwAuxIfId, pStackData->pfwRFC2233CountPair, pStackData->pfwRFC2233CountTest); /* if we are an Access Concentrator.... there is nothing to do */ if (pProfileData->connectionMode & PPPOE_AC_MODE) { if (strlen(pProfileData->svcNameTag)) strncpy(pStackData->serviceName, pProfileData->svcNameTag, (sizeof(pStackData->serviceName) - 1) ); else sprintf (pStackData->serviceName,"%s","ANY"); return OK; } else if (pProfileData->connectionMode & PPPOE_HOST_MODE) { /* well it looks like we are the host/client */ /* hosts need a retry timer */ if ((pStackData->pTimer = pfwTimerCreate(pComponentState)) == NULL) { return ERROR; } /* set destination ethernet address to the broadcast address */ memcpy (pStackData->destEnet, etherBroadcastAddr, ENET_LEN); if ((pPacket = pppOEMakePADI(pComponentState)) == NULL) return ERROR; /* Send PADI packet */ pStackData->pRetryDiscPkt = pPacket; return (pppOESendDiscPkt(pComponentState,0)); } return ERROR; }/******************************************************************************** pppOEReceive - PPPOE component receive interface* * This is interface handles all PPPOE frames received. This routine receives* the entire ethernet frame. Source and destination ethernet address are* retrieved and stored and the requisite response in the form of a PADR,* PADO or PADS packet is sent out by invoking the framework pppSend()** RETURNS: OK if successful and ERROR otherwise*/LOCAL STATUS pppOEReceive ( PFW_PLUGIN_OBJ_STATE * pComponentState,/* our state for this connection */ M_BLK_ID * pMblkId /* pointer to packet received */ ) { PPPOE_COMPONENT * pComponent = (PPPOE_COMPONENT *)pComponentState->pluginObj; PPPOE_STACK_DATA * pStackData = (PPPOE_STACK_DATA *)(pComponentState->stackData); PPPOE_PROFILE_DATA * pProfileData = (PPPOE_PROFILE_DATA *)pComponentState->profileData; M_BLK_ID pFrame = NULL; PFW_STACK_OBJ * newStackObj = 0; struct ether_header etherHdr; struct ether_header * pEtherHdr; PPPOE_HEADER pppOEHeader; PPPOE_HEADER * pPPPOEHeader; M_BLK_ID pMblk = NULL; PFW_PLUGIN_OBJ_STATE * pNewComponentState = NULL; PPPOE_STACK_DATA * pNewStackData; PPPOE_PROFILE_DATA * pNewProfileData; PPPOE_TLV * firstTlv = NULL; PPPOE_TLV * foundTlv; if ((pMblkId == NULL) || ((pFrame = *pMblkId) == NULL)) { RFC2233_COUNTER_UPDATE(pStackData->pfwRFC2233CountTest, pStackData->pfwRFC2233CountPair, M2_ctrId_ifInErrors, 1); return ERROR; } /* Update counters */ pStackData->inputPackets ++; pStackData->inputOctets += pFrame->mBlkPktHdr.len; /* * intial checks on the ethernet header etc. have already been done by * the stack object resolver so we dont repeat it here. */ pEtherHdr = mtod(pFrame, struct ether_header *); bcopy(pFrame->mBlkHdr.mData, (char *)ðerHdr,sizeof(struct ether_header)); etherHdr.ether_type = ntohs(pEtherHdr->ether_type); /* strip ethernet header from the received packet */ pFrame->mBlkHdr.mData += sizeof(struct ether_header); pFrame->mBlkHdr.mLen -= sizeof(struct ether_header); pFrame->mBlkPktHdr.len -= sizeof(struct ether_header); /* * copy PPPOE header */ pPPPOEHeader = mtod(pFrame, PPPOE_HEADER *); pppOEHeader.pppOE_ver = pPPPOEHeader->pppOE_ver; pppOEHeader.pppOE_type = pPPPOEHeader->pppOE_type; pppOEHeader.pppOE_code = pPPPOEHeader->pppOE_code; pppOEHeader.pppOE_session = ntohs(pPPPOEHeader->pppOE_session); pppOEHeader.pppOE_length = ntohs(pPPPOEHeader->pppOE_length); /* strip PPPOE header */ pFrame->mBlkHdr.mData += sizeof(PPPOE_HEADER); pFrame->mBlkHdr.mLen -= sizeof(PPPOE_HEADER); pFrame->mBlkPktHdr.len -= sizeof(PPPOE_HEADER); /* set packet length to length in PPPOE_HEADER */ if (pppOEHeader.pppOE_length < pFrame->mBlkHdr.mLen) pFrame->mBlkHdr.mLen = pppOEHeader.pppOE_length; /* * retain the received Packet minus the headers; except in the case * of PPPOE session packets */ if (pppOEHeader.pppOE_code != PPPOE_CODE_SESSION) { pStackData->pRecvdDiscPkt = pFrame; firstTlv = mtod(pFrame,PPPOE_TLV *); } /* * save source and destination ethernet address if necessary * and send the appropriate response in the case of PADI, PADR or PADO pkts. */ switch (pppOEHeader.pppOE_code) { /* the first two cases are encountered by an AC */ case PPPOE_CODE_PADI: /* * service name is already validated by stack object resolver */ /* copy address of sender as our destination address */ memcpy(pStackData->destEnet, etherHdr.ether_shost, ENET_LEN); /* make an offer */ if ((pMblk = pppOEMakePADO(pComponentState)) == NULL) break; /* else */ ADAPTER_DEST_ADDR_AND_PROTOCOL_SET(pStackData, ETHERTYPE_PPPOE_DISCOVERY); if (pfwSend (pComponentState, pMblk) != ERROR) { /* done with received discovery frame */ return PFW_OK_TERMINATE; } else { break; } case PPPOE_CODE_PADR: /* VALIDATE SERVICE NAME AGAIN, RETURN SERVICE-NAME ERROR*/ if ((((foundTlv = pppOEFindTlv(PPPOE_TAG_SVC_NAME,firstTlv,pFrame)) == NULL)) || (strncmp(pStackData->serviceName,PPPOE_TAG_VALUE(foundTlv), PPPOE_TAG_LENGTH(foundTlv)))) { /* send SERVICE NAME error */ if ((pMblk = pppOEAddSvcNameError(pComponentState)) != NULL) { pfwSend(pComponentState,pMblk); return PFW_OK_TERMINATE; } break; } /* * create a new stack using the same profile object that created * this daemon stack and offer a session */ if ((newStackObj = pfwStackAdd(pStackData->profileObj, pStackData->stackObjCallbacks,pStackData->userHandle)) == NULL) break; /* else; get component state for the new connection */ pNewComponentState = pfwPluginObjStateGet (newStackObj, (PFW_PLUGIN_OBJ *)pComponent); pfwPluginObjStateLock(pNewComponentState); pNewStackData = (PPPOE_STACK_DATA *)(pNewComponentState->stackData); pNewProfileData = (PPPOE_PROFILE_DATA *) (pNewComponentState->profileData); /* copy address of sender as our destination address */ memcpy(pNewStackData->destEnet, etherHdr.ether_shost, ENET_LEN); /* copy the address at which we received this PADR */ memcpy(pNewStackData->srcEnet, etherHdr.ether_dhost, ENET_LEN); /* hand over received packet to the new connection */ pNewStackData->pRecvdDiscPkt = pStackData->pRecvdDiscPkt; pStackData->pRecvdDiscPkt = NULL; /* * set the stack object in the MAP (sessionID, stackObj) * for an AC the lower 16 bits of its stack object ID is the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -