bool GREv0Layer::setKey(uint32_t key) { gre_basic_header* header = getGreHeader(); bool needToExtendLayer = false; if (header->keyBit == 0) needToExtendLayer = true; uint8_t* offsetPtr = getFieldValue(GreKey, true); int offset = offsetPtr - m_Data; if (needToExtendLayer && !extendLayer(offset, sizeof(uint32_t))) { header->keyBit = 0; LOG_ERROR("Couldn't extend layer to set key"); return false; } header = getGreHeader(); header->keyBit = 1; uint32_t* keyPtr = (uint32_t*)(m_Data + offset); *keyPtr = htonl(key); return true; }
bool GreLayer::setSequenceNumber(uint32_t seqNumber) { gre_basic_header* header = (gre_basic_header*)m_Data; bool needToExtendLayer = false; if (header->sequenceNumBit == 0) needToExtendLayer = true; uint8_t* offsetPtr = getFieldValue(GreSeq, true); int offset = offsetPtr - m_Data; if (needToExtendLayer && !extendLayer(offset, sizeof(uint32_t))) { header->sequenceNumBit = 0; LOG_ERROR("Couldn't extend layer to set sequence number"); return false; } header = (gre_basic_header*)m_Data; header->sequenceNumBit = 1; uint32_t* seqPtr = (uint32_t*)(m_Data + offset); *seqPtr = htonl(seqNumber); return true; }
bool GREv0Layer::setChecksum(uint16_t checksum) { gre_basic_header* header = getGreHeader(); bool needToExtendLayer = false; if (header->routingBit == 0 && header->checksumBit == 0) needToExtendLayer = true; uint8_t* offsetPtr = getFieldValue(GreChecksumOrRouting, true); int offset = offsetPtr - m_Data; // extend layer in 4 bytes to keep 4-byte alignment if (needToExtendLayer && !extendLayer(offset, sizeof(uint32_t))) { LOG_ERROR("Couldn't extend layer to set checksum"); return false; } uint16_t* checksumPtr = (uint16_t*)(m_Data + offset); *checksumPtr = htons(checksum); // if layer was extended in 4 bytes, make sure the offset field stays 0 if (needToExtendLayer) { checksumPtr++; *checksumPtr = 0; } header = getGreHeader(); header->checksumBit = 1; return true; }
DnsQuery* DnsLayer::addQuery(const std::string& name, DnsType dnsType, DnsClass dnsClass) { // create new query on temporary buffer uint8_t newQueryRawData[256]; DnsQuery* newQuery = new DnsQuery(newQueryRawData); newQuery->setDnsClass(dnsClass); newQuery->setDnsType(dnsType); // cannot return false since layer shouldn't be extended or shortened in this stage newQuery->setName(name); // find the offset in the layer to insert the new query size_t newQueryOffsetInLayer = sizeof(dnshdr); DnsQuery* curQuery = getFirstQuery(); while (curQuery != NULL) { newQueryOffsetInLayer += curQuery->getSize(); DnsQuery* nextQuery = getNextQuery(curQuery); if (nextQuery == NULL) break; curQuery = nextQuery; } // set next resource for new query. This must happen here for extendLayer to succeed if (curQuery != NULL) newQuery->setNexResource(curQuery->getNextResource()); else newQuery->setNexResource(m_ResourceList); // extend layer to make room for the new query if (!extendLayer(newQueryOffsetInLayer, newQuery->getSize(), newQuery)) { LOG_ERROR("Couldn't extend DNS layer, addQuery failed"); delete newQuery; return NULL; } // connect the new query to layer newQuery->setDnsLayer(this, newQueryOffsetInLayer); // connect the new query to the layer's resource list if (curQuery != NULL) curQuery->setNexResource(newQuery); else // curQuery == NULL, meaning this is the first query { m_ResourceList = newQuery; m_FirstQuery = newQuery; } // increase number of queries getDnsHeader()->numberOfQuestions = htons(getQueryCount() + 1); return newQuery; }
void LuaEngine::extendLuaObject() { if ( NULL == _stack || NULL == _stack->getLuaState()) return; lua_State* lua_S = _stack->getLuaState(); extendNode(lua_S); extendMenuItem(lua_S); extendLayer(lua_S); extendControl(lua_S); extendWebsocket(lua_S); extendGLNode(lua_S); extendScrollView(lua_S); extendDrawNode(lua_S); _stack->clean(); }
void TcpLayer::adjustTcpOptionTrailer(size_t totalOptSize) { int newNumberOfTrailingBytes = 0; while ((totalOptSize + newNumberOfTrailingBytes) % 4 != 0) newNumberOfTrailingBytes++; if (newNumberOfTrailingBytes < m_NumOfTrailingBytes) shortenLayer(sizeof(tcphdr)+totalOptSize, m_NumOfTrailingBytes - newNumberOfTrailingBytes); else if (newNumberOfTrailingBytes > m_NumOfTrailingBytes) extendLayer(sizeof(tcphdr)+totalOptSize, newNumberOfTrailingBytes - m_NumOfTrailingBytes); m_NumOfTrailingBytes = newNumberOfTrailingBytes; for (int i = 0; i < m_NumOfTrailingBytes; i++) m_Data[sizeof(tcphdr) + totalOptSize + i] = TCPOPT_DUMMY; getTcpHeader()->dataOffset = (sizeof(tcphdr) + totalOptSize + m_NumOfTrailingBytes)/4; }
TcpOptionData* TcpLayer::addTcpOptionAt(TcpOption optionType, uint8_t optionLength, const uint8_t* optionData, int offset) { if ((optionType == PCPP_TCPOPT_EOL || optionType == PCPP_TCPOPT_NOP) && optionLength != PCPP_TCPOLEN_NOP) { LOG_ERROR("Can't set TCP NOP option or TCP EOL option with size different than 1, tried to set size %d", optionLength); return NULL; } // calculate total TCP option size TcpOptionData* curOpt = getFirstTcpOptionData(); size_t totalOptSize = 0; while (curOpt != NULL) { totalOptSize += curOpt->getTotalSize(); curOpt = getNextTcpOptionData(curOpt); } totalOptSize += optionLength; if (!extendLayer(offset, optionLength)) { LOG_ERROR("Could not extend TcpLayer in [%d] bytes", optionLength); return NULL; } uint8_t optionTypeVal = (uint8_t)optionType; memcpy(m_Data + offset, &optionTypeVal, sizeof(uint8_t)); if (optionLength > 1) { memcpy(m_Data + offset + sizeof(uint8_t), &optionLength, sizeof(uint8_t)); if (optionLength > 2 && optionData != NULL) memcpy(m_Data + offset + 2*sizeof(uint8_t), optionData, optionLength-2*sizeof(uint8_t)); } adjustTcpOptionTrailer(totalOptSize); uint8_t* newOptPtr = m_Data + offset; m_TcpOptionsCount++; return castPtrToTcpOptionData(newOptPtr); }
bool GREv1Layer::setAcknowledgmentNum(uint32_t ackNum) { bool needToExtendLayer = false; gre1_header* header = getGreHeader(); if (header->ackSequenceNumBit == 0) needToExtendLayer = true; uint8_t* offsetPtr = getFieldValue(GreAck, true); int offset = offsetPtr - m_Data; if (needToExtendLayer && !extendLayer(offset, sizeof(uint32_t))) { LOG_ERROR("Couldn't extend layer to set ack number"); return false; } header = getGreHeader(); header->ackSequenceNumBit = 1; uint32_t* ackPtr = (uint32_t*)(m_Data + offset); *ackPtr = htonl(ackNum); return true; }
PPPoEDiscoveryLayer::PPPoETag* PPPoEDiscoveryLayer::addTagAt(PPPoETagTypes tagType, uint16_t tagLength, const uint8_t* tagData, int offset) { size_t tagTotalLength = 2*sizeof(uint16_t) + tagLength; if (!extendLayer(offset, tagTotalLength)) { LOG_ERROR("Could not extend PPPoEDiscoveryLayer in [%d] bytes", tagTotalLength); return NULL; } uint16_t tagTypeVal = htons((uint16_t)tagType); tagLength = htons(tagLength); memcpy(m_Data + offset, &tagTypeVal, sizeof(uint16_t)); memcpy(m_Data + offset + sizeof(uint16_t), &tagLength, sizeof(uint16_t)); if (tagLength > 0 && tagData != NULL) memcpy(m_Data + offset + 2*sizeof(uint16_t), tagData, ntohs(tagLength)); uint8_t* newTagPtr = m_Data + offset; getPPPoEHeader()->payloadLength += htons(tagTotalLength); m_TagCount++; return castPtrToPPPoETag(newTagPtr); }
TcpOption TcpLayer::addTcpOptionAt(const TcpOptionBuilder& optionBuilder, int offset) { TcpOption newOption = optionBuilder.build(); if (newOption.isNull()) return newOption; // calculate total TCP option size TcpOption curOpt = getFirstTcpOption(); size_t totalOptSize = 0; while (!curOpt.isNull()) { totalOptSize += curOpt.getTotalSize(); curOpt = getNextTcpOption(curOpt); } totalOptSize += newOption.getTotalSize(); size_t sizeToExtend = newOption.getTotalSize(); if (!extendLayer(offset, sizeToExtend)) { LOG_ERROR("Could not extend TcpLayer in [%d] bytes", (int)sizeToExtend); newOption.purgeRecordData(); return TcpOption(NULL); } memcpy(m_Data + offset, newOption.getRecordBasePtr(), newOption.getTotalSize()); newOption.purgeRecordData(); adjustTcpOptionTrailer(totalOptSize); m_OptionReader.changeTLVRecordCount(1); uint8_t* newOptPtr = m_Data + offset; return TcpOption(newOptPtr); }
DnsResource* DnsLayer::addResource(IDnsResource::ResourceType resType, const std::string& name, DnsType dnsType, DnsClass dnsClass, uint32_t ttl, const std::string& data) { // create new query on temporary buffer uint8_t newResourceRawData[256]; memset(newResourceRawData, 0, 256); DnsResource* newResource = new DnsResource(newResourceRawData, resType); newResource->setDnsClass(dnsClass); newResource->setDnsType(dnsType); // cannot return false since layer shouldn't be extended or shortened in this stage newResource->setName(name); newResource->setTTL(ttl); if (!newResource->setData(data)) { delete newResource; LOG_ERROR("Couldn't set new resource data"); return NULL; } size_t newResourceOffsetInLayer = sizeof(dnshdr); IDnsResource* curResource = m_ResourceList; while (curResource != NULL && curResource->getType() <= resType) { newResourceOffsetInLayer += curResource->getSize(); IDnsResource* nextResource = curResource->getNextResource(); if (nextResource == NULL || nextResource->getType() > resType) break; curResource = nextResource; } // set next resource for new resource. This must happen here for extendLayer to succeed if (curResource != NULL) { if (curResource->getType() > newResource->getType()) newResource->setNexResource(m_ResourceList); else newResource->setNexResource(curResource->getNextResource()); } else //curResource != NULL newResource->setNexResource(m_ResourceList); // extend layer to make room for the new resource if (!extendLayer(newResourceOffsetInLayer, newResource->getSize(), newResource)) { LOG_ERROR("Couldn't extend DNS layer, addResource failed"); delete newResource; return NULL; } // connect the new resource to layer newResource->setDnsLayer(this, newResourceOffsetInLayer); // connect the new resource to the layer's resource list if (curResource != NULL) { curResource->setNexResource(newResource); // this means the new resource is the first of it's type if (curResource->getType() < newResource->getType()) { setFirstResource(resType, newResource); } // this means the new resource should be the first resource in the packet else if (curResource->getType() > newResource->getType()) { m_ResourceList = newResource; setFirstResource(resType, newResource); } } else // curResource != NULL, meaning this is the first resource in layer { m_ResourceList = newResource; setFirstResource(resType, newResource); } return newResource; }