int main() { // TEST PACKET TYPES // TRN char *testData = "hello world!"; Packet trn; trn.isAck = false; trn.isFin = false; trn.seq = 118; trn.data = (uint8_t*)testData; trn.length = 13; // Don't need to free 'trn' packet because the data wasn't malloc'd // However, usually will need to free it pretendSend(&trn); // ACK Packet ack = makeAck(118); pretendSend(&ack); freePacket(&ack); // FIN Packet fin = makeFin(); pretendSend(&fin); freePacket(&fin); // FINACK Packet finAck = makeFinAck(); pretendSend(&finAck); freePacket(&finAck); }
UInt32 MolEnet::outputPacket( struct mbuf *pkt, void *param ) { struct IOPhysicalSegment segVector[2]; int n; assert( pkt && netifEnabled ); //printm("outputPacket %d\n", tx_tail ); if( tx_ring[tx_tail].psize ) { /* Ring full. The txIRQ should call transmitQueue->service to unstall * the queue. At the moment we transmit each packet synchronously * to the linux side. Thus the ring will never be full... */ printm("output stalled\n"); return kIOReturnOutputStall; } n = txMBufCursor->getPhysicalSegmentsWithCoalesce( pkt, segVector ); if( n < 0 || n > 2 ) { printm("getPhysicalSegments returned an error (%d)\n", n ); freePacket(pkt); return kIOReturnOutputDropped; } tx_ring[tx_tail].flags = 0; if( n == 2 ) { tx_of_ring[tx_tail].buf = segVector[1].location; tx_of_ring[tx_tail].bsize = segVector[1].length; tx_of_ring[tx_tail].psize = segVector[1].length; tx_of_ring[tx_tail].flags = 0; tx_ring[tx_tail].flags = kEnet2SplitBufferFlag; } tx_ring[tx_tail].buf = segVector[0].location; tx_ring[tx_tail].bsize = segVector[0].length; eieio(); // gcc scheduling barrier tx_ring[tx_tail].psize = segVector[0].length; // Increase tail marker tx_tail = (tx_tail + 1) & TX_MASK; if( OSI_Enet2Kick() ) printm("transmission error\n"); freePacket( pkt ); return kIOReturnOutputSuccess; }
void CLASS::free( void ) { #define RELEASE(x) do { if(x) { (x)->release(); (x) = 0; } } while(0) DEBUG_LOG("%s::free\n", getName()); assert(fEnabledForKDP == false); assert(fEnabledForBSD == false); if (fInterruptSource && fWorkLoop) { fWorkLoop->removeEventSource(fInterruptSource); } RELEASE( fInterruptSource ); RELEASE( fKDPNub ); RELEASE( fNetif ); RELEASE( fRxMbufCursor ); RELEASE( fTxMbufCursor ); RELEASE( fPCINub ); RELEASE( fWorkLoop ); RELEASE( fRegMap ); RELEASE( fMediumDict ); RELEASE( fWatchdogTimer ); RELEASE( fKDPQueue ); if (fKDPMbuf) { freePacket(fKDPMbuf); fKDPMbuf = 0; fKDPMbufSeg.location = 0; } super::free(); }
Packet *newPacketIHAVE(Packet *pktWHOHAS) { uint8_t numHash = getPacketNumHash(pktWHOHAS); int i = 0; int idx; uint8_t *hash; Packet *thisObj = newPacketDefault(); incPacketSize(thisObj, 4); setPacketType(thisObj, "IHAVE"); for(i = 0; i < numHash; i++) { hash = getPacketHash(pktWHOHAS, i); idx = searchHash(hash, &hasChunk, -1); if(idx >= 0) { printf("Has[%d]", i); insertPacketHash(thisObj, hash); } } if(i == 0 || getPacketSize(thisObj) == 20) { freePacket(thisObj); return NULL; } else { setPacketDest(thisObj, &(pktWHOHAS->src), sizeof(pktWHOHAS->src)); return thisObj; } }
void FilesManager::ProcessPacket(PACKET * packet) { switch (packet->_header.subCommand) { case drivesList: { SendDrivesList(); break; } case browsePath: { SendBrowsePath((char*)packet->data); break; } case renameFile: { RenameFileFromPath((char*)packet->data); break; } case deleteFile: { DeleteFileFromPath((char*)packet->data); break; } default: { break; } } freePacket(packet); }
void HoRNDIS::receivePacket(void *packet, UInt32 size) { mbuf_t m; UInt32 submit; IOReturn rv; LOG(V_DEBUG, "sz %d", (int)size); if (size > MAX_BLOCK_SIZE) { LOG(V_ERROR, "packet size error, packet dropped"); fpNetStats->inputErrors++; return; } while (size) { struct rndis_data_hdr *hdr = (struct rndis_data_hdr *)packet; uint32_t msg_len, data_ofs, data_len; msg_len = le32_to_cpu(hdr->msg_len); data_ofs = le32_to_cpu(hdr->data_offset); data_len = le32_to_cpu(hdr->data_len); if (hdr->msg_type != RNDIS_MSG_PACKET) { LOG(V_ERROR, "non-PACKET over data channel? (msg_type %08x)", hdr->msg_type); return; } if (hdr->msg_len > size) { LOG(V_ERROR, "msg_len too big?"); return; } if ((data_ofs + data_len + 8) > msg_len) { LOG(V_ERROR, "data bigger than msg?"); return; } m = allocatePacket(data_len); if (!m) { LOG(V_ERROR, "allocatePacket for data_len %d failed", data_len); fpNetStats->inputErrors++; return; } rv = mbuf_copyback(m, 0, data_len, (char *)packet + data_ofs + 8, MBUF_WAITOK); if (rv) { LOG(V_ERROR, "mbuf_copyback failed, rv %08x", rv); fpNetStats->inputErrors++; freePacket(m); return; } submit = fNetworkInterface->inputPacket(m, data_len); LOG(V_DEBUG, "submitted pkt sz %d", data_len); fpNetStats->inputPackets++; size -= hdr->msg_len; packet = (char *)packet + hdr->msg_len; } }
UInt32 AgereET131x::outputPacket(mbuf_t m, void * param) { int status = 0; /************************************************************************** Queue is not empty or TCB is not available *************************************************************************/ if( MP_TCB_RESOURCES_NOT_AVAILABLE( &adapter )) { /********************************************************************** NOTE - If there's an error on send, no need to queue the packet under Linux; if we just send an error up to the netif layer, it will resend the skb to us. *********************************************************************/ // IOLog("TCB Resources Not Available\n" ); freePacket(m); netStats->outputErrors += 1; return kIOReturnOutputDropped; } /********************************************************************** We need to see if the link is up; if it's not, make the netif layer think we're good and drop the packet *********************************************************************/ if( MP_SHOULD_FAIL_SEND( &adapter ) ){ freePacket( m ); netStats->outputErrors += 1; return kIOReturnOutputDropped; } status = send_packet( m ); if( status != 0 ){ IOLog( "General error, drop packet(%d)\n", status ); freePacket( m ); netStats->outputErrors += 1; return kIOReturnOutputDropped; } return kIOReturnSuccess; }
UInt32 VoodooIntel3945::outputPacket( mbuf_t m, void* param ) { struct wpi_softc* sc = &fSelfData; struct ieee80211com* ic = &sc->sc_ic; struct ieee80211_node *ni; DPRINTF(("TX: mbuf len=%u\n", mbuf_len(m))); if (m == 0) return kIOReturnOutputDropped; // ??? ExtraMbufParams* p = (ExtraMbufParams*)param; if (p->is80211ManagementFrame) { ni = (struct ieee80211_node *)mbuf_pkthdr_rcvif(m); } else { if (sc->qfullmsk != 0) { freePacket(m); return kIOReturnOutputDropped; } if (ic->ic_state != IEEE80211_S_RUN) { freePacket(m); return kIOReturnOutputDropped; } /* Encapsulate and send data frames. */ if ((m = ieee80211_encap(ic, m, &ni)) == NULL) return kIOReturnOutputDropped; } if (wpi_tx(sc, m, ni) != 0) { ieee80211_release_node(ic, ni); if (m) freePacket(m); return kIOReturnOutputDropped; } else { DPRINTF(("(prev tx success)\n")); sc->sc_tx_timer = 5; return kIOReturnOutputSuccess; } }
void ReorderingPacketBuffer::releaseUsedPacket(BufferedPacket* packet) { // ASSERT: packet == fHeadPacket // ASSERT: fNextExpectedSeqNo == packet->rtpSeqNo() ++fNextExpectedSeqNo; // because we're finished with this packet now fHeadPacket = fHeadPacket->nextPacket(); if (!fHeadPacket) { fTailPacket = NULL; } packet->nextPacket() = NULL; freePacket(packet); }
void CLASS::releaseTxMemory( void ) { if (fTxDescMemory) { for (UInt32 i = 0; i < kTxDescCount; i++) { if (fTxDescBase[i].packet) freePacket(fTxDescBase[i].packet); } memset(fTxDescBase, 0, kTxDescCount * sizeof(TxDesc)); fTxDescMemory->complete(); fTxDescMemory->release(); fTxDescMemory = 0; fTxDescBase = 0; } }
/*! Vett keret feldolgozása */ void processReceive() { Packet *packet = getNextPacket(); // az aktualis vett keret lekerese if (!packet) // valaki szorakozik NULL ertek return; if (packet->address == clientAddress) { // jo a cim, fel kell dolgozni switch (packet->cmd) { case cmPing : replyPing(); // ping parancs jott break; case cmGetTerm : replyTerm(); // homerseklet lekerdezes parancs jott break; case cmGetPressure : replyPressure(); // nyomas lekerdezes parancs jott break; } } freePacket(); // jelzes, hogy fel van dolgozva, johet a kovetkezo keret }
void MolEnet::free() { int i; if( is_open ) { OSI_Enet2Cntrl( kEnet2Reset ); OSI_Enet2Close(); } if( getWorkLoop() ) getWorkLoop()->disableAllEventSources(); if( _irq ) _irq->release(); if( transmitQueue ) transmitQueue->release(); if( networkInterface ) networkInterface->release(); if( rxMBufCursor ) rxMBufCursor->release(); if( txMBufCursor ) txMBufCursor->release(); if( mediumDict ) mediumDict->release(); if( rx_ring ) IOFreeContiguous( rx_ring, sizeof(enet2_ring_t) * RX_NUM_EL ); if( tx_ring ) IOFreeContiguous( tx_ring, sizeof(enet2_ring_t) * TX_NUM_EL ); if( workLoop ) { workLoop->release(); workLoop = 0; } for( i=0; i<RX_NUM_EL; i++ ) if( rxMBuf[i] ) freePacket( rxMBuf[i] ); // free packets in progress super::free(); }
void CLASS::serviceTxInterrupt( void ) { TxDesc * descPtr; UInt32 headIndex = fTxHeadIndex; UInt32 busyCount = TX_RING_BUSY(headIndex, fTxTailIndex); UInt32 doneCount = 0; UInt32 txStatus; while (doneCount < busyCount) { descPtr = &fTxDescBase[ headIndex ]; assert(descPtr->descLast); assert(descPtr->descCount); // Examine ownership bit in the last descriptor for this chain. txStatus = OSReadLittleInt32(&descPtr->descLast->cmdStatus, 0); if (txStatus & kDescOwn) break; // transmit not done yet if (txStatus & kDescTxAbnormalMask) { recordTxDescriptorErrors(txStatus); } if (descPtr->packet) { freePacket(descPtr->packet, kDelayFree); descPtr->packet = 0; } // Skip to the start of the next transmit slot. headIndex = descPtr->nextIndex; doneCount += descPtr->descCount; } if (doneCount) { fTxHeadIndex = headIndex; fTransmitQueue->service(); releaseFreePackets(); DEBUG_LOG("TX ISR: retired %lu\n", doneCount); } }
void pretendSend(Packet *p) { uint8_t *buffer; size_t length = serializePacket(p, &buffer); Packet rec; parsePacket(buffer, length, &rec); printf("\nSent:\n"); printPacket(p); printf("Received:\n"); printPacket(p); printf("\n"); // Fail the test if the packets are different after being serialized assert(comparePackets(p, &rec)); freePacket(&rec); free(buffer); }
void CLASS::releaseRxMemory( void ) { if (fRxDescMemory) { for (UInt32 i = 0; i < kRxDescCount; i++) { if (fRxDescBase[i].packet) freePacket(fRxDescBase[i].packet); } memset(fRxDescBase, 0, kRxDescCount * sizeof(RxDesc)); fRxDescMemory->complete(); fRxDescMemory->release(); fRxDescMemory = 0; fRxDescBase = 0; fRxDescPhysAddr = 0; } }
void updateACKQueue(Packet *pkt, int peerID) { sendWindow *sw = &(uploadPool[peerID].sw); uint32_t ack = getPacketAck(pkt); queue *ackWaitQueue = uploadPool[peerID].ackWaitQueue; queue *dataQueue = uploadPool[peerID].dataQueue; Packet *ackWait = peek(ackWaitQueue); struct timeval cur_time; gettimeofday(&cur_time, NULL); logger(peerID, uploadPool[peerID].connID, diffTimevalMilli(&cur_time, &(uploadPool[peerID].startTime)), sw->ctrl.windowSize); expandWindow(&(sw->ctrl)); uploadPool[peerID].timeoutCount = 0; fprintf(stderr,"Received ACK %d. Last ACK: %d. Next up: %d\n", ack, sw->lastPacketAcked, ackWait == NULL ? 65535 : getPacketSeq(ackWait)); if(ackWait != NULL) { if(ack >= getPacketSeq(ackWait)) { sw->dupCount = 0; while(ackWait != NULL && ack >= getPacketSeq(ackWait)) { dequeue(ackWaitQueue); freePacket(ackWait); ackWait = peek(ackWaitQueue); } sw->lastPacketAcked = ack; updateSendWindow(sw); if(ack == BT_CHUNK_SIZE / PACKET_DATA_SIZE + 1) { fprintf(stderr,"Finished sending current chunk!"); numConnUp--; initWindows(&(downloadPool[peerID].rw), &(uploadPool[peerID].sw)); assert(dequeue(ackWaitQueue) == NULL); } } else { // Unexpected ACK number if(ack == sw->lastPacketAcked) { // Dupliate ACK sw->dupCount++; fprintf(stderr,"Received duplicate packets %d\n", ack); if(sw->dupCount == MAX_DUPLICATE) { // Trigger a fast retransmit fprintf(stderr,"Received 3 duplicates acks %d retransmitting\n", ack); sw->dupCount = 0; mergeAtFront(ackWaitQueue, dataQueue); shrinkWindow(&(sw->ctrl)); } } } } }
void flushQueue(int sock, queue *sendQueue) { int i = 0; int retVal = -1; int count = sendQueue->size; int noLoss = 0; Packet *pkt = dequeue(sendQueue); if(pkt == NULL) { return; } peerList_t *list = peerInfo.peerList; while(count > 0) { if(pkt->dest != NULL) { // IHAVE retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) (pkt->dest), sizeof(*(pkt->dest))); } else { // WHOHAS for(i = 0; i < peerInfo.numPeer; i++) { if(list[i].isMe == 0) { retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) & (list[i].addr), sizeof(list[i].addr)); if(retVal == -1) { enqueue(sendQueue, pkt); noLoss = 1; } } } } if(noLoss == 0) { fprintf(stderr,"spiffy_sendto() returned -1. This is broken!"); } freePacket(pkt); pkt = dequeue(sendQueue); count--; } }
Packet *newPacketSingleDATA(int seqNo, int seqChunk, size_t size) { size_t retSize; long offset = seqChunk * BT_CHUNK_SIZE + (seqNo - 1) * PACKET_DATA_SIZE; Packet *pkt = newPacketDefault(); setPacketType(pkt, "DATA"); incPacketSize(pkt, size); setPacketSeq(pkt, seqNo); FILE *mf = masterChunk.filePtr; rewind(mf); fseek(mf, offset, SEEK_SET); retSize = fread(pkt->payload + 16, sizeof(uint8_t), size, mf); if(retSize != size) { printf("IO Error reading chunk\n"); freePacket(pkt); return NULL; } else { return pkt; } }
UInt32 HoRNDIS::outputPacket(mbuf_t packet, void *param) { mbuf_t m; size_t pktlen = 0; IOReturn ior = kIOReturnSuccess; UInt32 poolIndx; int i; LOG(V_DEBUG, ""); /* Count the total size of this packet */ m = packet; while (m) { pktlen += mbuf_len(m); m = mbuf_next(m); } LOG(V_DEBUG, "%ld bytes", pktlen); if (pktlen > (mtu + 14)) { LOG(V_ERROR, "packet too large (%ld bytes, but I told you you could have %d!)", pktlen, mtu); fpNetStats->outputErrors++; return false; } /* Find an output buffer in the pool */ IOLockLock(outbuf_lock); for (i = 0; i < OUT_BUF_MAX_TRIES; i++) { AbsoluteTime ivl, deadl; for (poolIndx = 0; poolIndx < N_OUT_BUFS; poolIndx++) if (!outbufs[poolIndx].inuse) { outbufs[poolIndx].inuse = true; break; } if (poolIndx != N_OUT_BUFS) break; /* "while", not "if". See Symphony X's seminal work on this topic, /Paradise Lost/ (2007). */ nanoseconds_to_absolutetime(OUT_BUF_WAIT_TIME, &ivl); clock_absolutetime_interval_to_deadline(ivl, &deadl); LOG(V_NOTE, "waiting for buffer..."); IOLockSleepDeadline(outbuf_lock, outbufs, deadl, THREAD_INTERRUPTIBLE); } IOLockUnlock(outbuf_lock); if (poolIndx == N_OUT_BUFS) { LOG(V_ERROR, "timed out waiting for buffer"); return kIOReturnTimeout; } /* Start filling in the send buffer */ struct rndis_data_hdr *hdr; hdr = (struct rndis_data_hdr *)outbufs[poolIndx].buf; outbufs[poolIndx].inuse = true; outbufs[poolIndx].mdp->setLength(pktlen + sizeof *hdr); memset(hdr, 0, sizeof *hdr); hdr->msg_type = RNDIS_MSG_PACKET; hdr->msg_len = cpu_to_le32(pktlen + sizeof *hdr); hdr->data_offset = cpu_to_le32(sizeof(*hdr) - 8); hdr->data_len = cpu_to_le32(pktlen); mbuf_copydata(packet, 0, pktlen, hdr + 1); freePacket(packet); /* Now, fire it off! */ outbufs[poolIndx].comp.target = this; outbufs[poolIndx].comp.parameter = (void *)poolIndx; outbufs[poolIndx].comp.action = dataWriteComplete; ior = fOutPipe->Write(outbufs[poolIndx].mdp, &outbufs[poolIndx].comp); if (ior != kIOReturnSuccess) { LOG(V_ERROR, "write failed"); if (ior == kIOUSBPipeStalled) { fOutPipe->Reset(); ior = fOutPipe->Write(outbufs[poolIndx].mdp, &outbufs[poolIndx].comp); if (ior != kIOReturnSuccess) { LOG(V_ERROR, "write really failed"); fpNetStats->outputErrors++; return ior; } } } fpNetStats->outputPackets++; return kIOReturnOutputSuccess; }
UInt32 darwin_iwi3945::outputPacket(mbuf_t m, void * param) { //IOLog("outputPacket\n"); if((fNetif->getFlags() & IFF_RUNNING)!=0 || m==NULL) { if (m) if (!(mbuf_type(m) == MBUF_TYPE_FREE) ) freePacket(m); m=NULL; netStats->outputErrors++; return kIOReturnOutputDropped; } mbuf_t nm; int ret = kIOReturnOutputDropped; //checking supported packet IWI_DEBUG("outputPacket t: %d f:%04x\n",mbuf_type(m),mbuf_flags(m)); //drop mbuf is not PKTHDR if (!(mbuf_flags(m) & MBUF_PKTHDR) ){ IWI_ERR("BUG: dont support mbuf without pkthdr and dropped \n"); netStats->outputErrors++; goto finish; } if(mbuf_type(m) == MBUF_TYPE_FREE){ IWI_ERR("BUG: this is freed packet and dropped \n"); netStats->outputErrors++; goto finish; } nm = mergePacket(m); if (nm==NULL) { netStats->outputErrors++; goto finish; } if(mbuf_next(nm)){ IWI_ERR("BUG: dont support chains mbuf\n"); IWI_ERR("BUG: tx packet is not single mbuf mbuf_len(%d) mbuf_pkthdr_len(%d)\n",mbuf_len(nm) , mbuf_pkthdr_len(nm) ); IWI_ERR("BUG: next mbuf size %d\n",mbuf_len(mbuf_next(nm))); } IWI_DEBUG_FULL("call ieee80211_xmit - not done yet\n"); //ret = ieee80211_xmit(nm,priv->net_dev); //struct ieee80211_tx_control ctrl; //ret=ipw_tx_skb(priv, nm, &ctrl); finish: /* free finished packet */ //freePacket(m); //m=NULL; if (ret == kIOReturnOutputDropped) { //if (nm) //if (!(mbuf_type(nm) == MBUF_TYPE_FREE) ) freePacket(nm); //nm=NULL; } return ret; }
void handlePacket(Packet *pkt) { if(verifyPacket(pkt)) { int type = getPacketType(pkt); switch(type) { case 0: { // WHOHAS fprintf(stderr,"->WHOHAS\n"); Packet *pktIHAVE = newPacketIHAVE(pkt); enqueue(nonCongestQueue, (void *)pktIHAVE); break; } case 1: { // IHAVE fprintf(stderr,"->IHAVE\n"); int peerIndex = searchPeer(&(pkt->src)); int peerID = peerInfo.peerList[peerIndex].peerID; newPacketGET(pkt, downloadPool[peerID].getQueue); idle = 0; break; } case 2: { // GET fprintf(stderr,"->GET\n"); if(numConnUp == maxConn){ fprintf(stderr,"->GET request denied.\n"); freePacket(pkt); break; } numConnUp++; int peerIndex = searchPeer(&(pkt->src)); int peerID = peerInfo.peerList[peerIndex].peerID; if(downloadPool[peerID].connected == 0){ clearQueue(uploadPool[peerID].ackWaitQueue); initWindows(&(downloadPool[peerID].rw), &(uploadPool[peerID].sw)); newPacketDATA(pkt, uploadPool[peerID].dataQueue); uploadPool[peerID].connID++; gettimeofday(&(uploadPool[peerID].startTime), NULL); } else { fprintf(stderr,"Only one-way connection is allowed.\n"); freePacket(pkt); } break; } case 3: { // DATA fprintf(stderr,"->DATA"); int peerIndex = searchPeer(&(pkt->src)); int peerID = peerInfo.peerList[peerIndex].peerID; if(1 == updateGetSingleChunk(pkt, peerID)) { downloadPool[peerID].connected = 0; numConnDown--; updateGetChunk(); } break; } case 4: { // ACK fprintf(stderr,"->ACK\n"); int peerIndex = searchPeer(&(pkt->src)); int peerID = peerInfo.peerList[peerIndex].peerID; updateACKQueue(pkt, peerID); break; } case 5: // DENIED default: fprintf(stderr,"DENIED\n"); } } else { fprintf(stderr,"Invalid packet!\n"); } freePacket(pkt); return; }
DecoderData::~DecoderData() { freePacket(); pthread_mutex_destroy(&m_pktMutex); }
mbuf_t darwin_iwi3945::mergePacket(mbuf_t m) { mbuf_t nm,nm2; int offset; if(!mbuf_next(m)) { offset = (4 - ((int)(mbuf_data(m)) & 3)) % 4; //packet needs to be 4 byte aligned if (offset==0) return m; IWI_DEBUG_FULL("this packet dont have mbuf_next, merge is not required\n"); goto copy_packet; } /* allocate and Initialize New mbuf */ nm = allocatePacket(mbuf_pkthdr_len(m)); if (nm==0) return NULL; //if (mbuf_getpacket(MBUF_WAITOK, &nm)!=0) return NULL; mbuf_setlen(nm,0); mbuf_pkthdr_setlen(nm,0); if( mbuf_next(nm)) IWI_ERR("merged mbuf_next\n"); /* merging chains to single mbuf */ for (nm2 = m; nm2; nm2 = mbuf_next(nm2)) { memcpy (skb_put (nm, mbuf_len(nm2)), (UInt8*)mbuf_data(nm2), mbuf_len(nm2)); } /* checking if merged or not. */ if( mbuf_len(nm) == mbuf_pkthdr_len(m) ) { if (m!=NULL) if (!(mbuf_type(m) == MBUF_TYPE_FREE)) freePacket(m); m=NULL; return nm; } /* merging is not completed. */ IWI_LOG("mergePacket is failed: data copy dont work collectly\n"); //IWI_LOG("orig_len %d orig_pktlen %d new_len %d new_pktlen %d\n", // mbuf_len(m),mbuf_pkthdr_len(m), // mbuf_len(nm),mbuf_pkthdr_len(nm) ); if (m!=NULL) if (!(mbuf_type(m) == MBUF_TYPE_FREE)) freePacket(m); m=NULL; if (nm!=NULL) if (!(mbuf_type(nm) == MBUF_TYPE_FREE) ) freePacket(nm); nm=NULL; return NULL; copy_packet: if (mbuf_dup(m, MBUF_WAITOK , &nm)!=0) { if (m!=NULL) if (!(mbuf_type(m) == MBUF_TYPE_FREE)) freePacket(m); m=NULL; return NULL; } if (m!=NULL) if (!(mbuf_type(m) == MBUF_TYPE_FREE) ) freePacket(m); m=NULL; return nm; //return copyPacket(m, 0); }
UInt32 CLASS::outputPacket( mbuf_t packet, void * param ) { TxDesc * descNext; TxDesc * descHead; TxDesc * descLast; UInt segCount; UInt32 cmdStatus; UInt32 tailIndex; IOPhysicalSegment vectors[ kTxMaxSegmentCount ]; IODebuggerLockState state; state = IOKernelDebugger::lock(this); tailIndex = fTxTailIndex; // Check if there are enough descriptors to describe the packet // buffers. kTxMaxSegmentCount should be large enough to reduce // the need to coalesce mbufs. if (TX_RING_FREE(fTxHeadIndex, tailIndex) < kTxMaxSegmentCount) { IOKernelDebugger::unlock(state); return kIOReturnOutputStall; } // Get the next transmit descriptor owned by the driver. descHead = &fTxDescBase[tailIndex]; descNext = descHead; // Use the mbuf cursor to generate a list of physical address and // length vectors for the network buffers. segCount = fTxMbufCursor->getPhysicalSegmentsWithCoalesce( packet, vectors, kTxMaxSegmentCount); if (segCount == 0) { DEBUG_LOG("TX Cursor returned 0 segments\n"); goto drop_packet; } assert(segCount <= kTxMaxSegmentCount); // Update the first (head) descriptor. // Do not set the OWN bit until the rest of the descriptors are done. OSWriteLittleInt32(&descHead->bufferPtr, 0, vectors[0].location); cmdStatus = (vectors[0].length & kDescBufferSizeMask); tailIndex = (tailIndex + 1) & (kTxDescCount - 1); descLast = descHead; descNext = &fTxDescBase[tailIndex]; for (UInt seg = 1; seg < segCount; seg++) { // Write cmdStatus for previous descriptor with MORE bit set. OSWriteLittleInt32(&descLast->cmdStatus, 0, cmdStatus | kDescMore); // Update current descriptor. OSWriteLittleInt32(&descNext->bufferPtr, 0, vectors[seg].location); cmdStatus = (vectors[seg].length & kDescBufferSizeMask) | kDescOwn; tailIndex = (tailIndex + 1) & (kTxDescCount - 1); descLast = descNext; descNext = &fTxDescBase[tailIndex]; } // Last descriptor must have MORE bit cleared. if (++fTxInterruptInterval >= (kTxDescCount/kTxMaxSegmentCount/4)) { cmdStatus |= kDescInterrupt; fTxInterruptInterval = 0; } OSWriteLittleInt32(&descLast->cmdStatus, 0, cmdStatus); // Set OWN bit on head descriptor after all descriptors following it // have been prepared. descHead->cmdStatus |= OSSwapHostToLittleConstInt32(kDescOwn); // Update Head Descriptor. descHead->packet = packet; descHead->descLast = descLast; descHead->descCount = segCount; descHead->nextIndex = tailIndex; // Update free descriptor count after completing the descriptor chain. // The order is important otherwise we may race with interrupt handler. fTxTailIndex = tailIndex; DEBUG_LOG("TX DESC:%d-%ld (size %d)\n", descHead-fTxDescBase, fTxTailIndex, mbuf_pkthdr_len(packet)); // Enable transmitter in case its in txIdle state. WriteReg(CR, CR_TXE); IOKernelDebugger::unlock(state); NET_STAT(outputPackets, 1); return kIOReturnOutputSuccess; drop_packet: IOKernelDebugger::unlock(state); freePacket(packet); ETH_STAT(dot3TxExtraEntry.resourceErrors, 1); return kIOReturnOutputDropped; }
void ClientUDP::run() { //init(); assert(init()); //open(); assert(open()); //resolveHost(); assert(resolveHost()); //allocatePacket(); assert(allocatePacket()); //SDL_CreateWindow("Client Window", 0, 0, 100, 100, SDL_WINDOW_OPENGL); /* Main loop */ m_quit = 0; while (!m_quit) { //while (SDL_PollEvent(&m_evt)) //{ // m_clientPackage->e = m_evt; // switch (m_clientPackage->e.type) // { // case SDL_KEYDOWN: // printf("Key press detected\n"); // break; // case SDL_KEYUP: // printf("Key release detected\n"); // break; // case SDL_MOUSEMOTION: // printf("Mouse Moved\n"); // break; // default: // break; // } //} //m_packet->len = (sizeof(Package)); //m_packet->address.host = m_srvadd.host; /* Set the destination host */ //m_packet->address.port = m_srvadd.port; /* And destination port */ printf("Type Message: \n>"); //scanf("%s", (char *)m_packet->data); std::getline(std::cin, m_input); m_packet->address.host = m_srvadd.host; /* Set the destination host */ m_packet->address.port = m_srvadd.port; /* And destination port */ m_packet->len = m_input.length() + 256; memcpy(m_packet->data, m_input.c_str(), m_packet->len); //memcpy(m_packet->data, m_clientPackage->data, sizeof(Package)); if (!(SDLNet_UDP_Send(m_socketDescriptor, -1, m_packet) > 0)) { printf("SDLNet_UDP_Send failed...\n"); } } freePacket(*m_packet); SDLNet_Quit(); }
UInt32 AtherosL1Ethernet::outputPacket(mbuf_t m, void *prm) { u32 buf_len; at_adapter *adapter=&adapter_; u16 next_to_use; u16 tpd_req = 1; TpdDescr *pTpd ; struct at_buffer *buffer_info; if(tpd_avail(&adapter->tpd_ring) < tpd_req) { // no enough descriptor DbgPrint("no enough resource!!\n"); freePacket(m); return kIOReturnOutputDropped; } // init tpd flags struct at_tpd_ring* tpd_ring = &adapter->tpd_ring; pTpd = AT_TPD_DESC(tpd_ring, ((u16)atomic_read(&tpd_ring->next_to_use))); //memset(pTpd, 0, sizeof(TpdDescr)); memset(((u8*)pTpd + sizeof(pTpd->addr)), 0, (sizeof(TpdDescr) - sizeof(pTpd->addr))); //addr don't clear next_to_use = (u16)atomic_read(&tpd_ring->next_to_use); buffer_info = tpd_ring->buffer_info+next_to_use; if (!buffer_info->memDesc) { DbgPrint("Tx buffer is null!!\n"); freePacket(m); return kIOReturnOutputDropped; } if (mbuf_pkthdr_len(m) <= AT_TX_BUF_LEN) buf_len = mbuf_pkthdr_len(m); else { DbgPrint("Tx Packet size is too big, droping\n"); freePacket(m); return kIOReturnOutputDropped; } DbgPrint("outputPacket() length %d next_to_use=%d\n", buf_len, next_to_use); UInt8 *data_ptr = (UInt8 *)buffer_info->memDesc->getBytesNoCopy(); UInt32 pkt_snd_len = 0; mbuf_t cur_buf = m; do { if (mbuf_data(cur_buf)) bcopy(mbuf_data(cur_buf), data_ptr, mbuf_len(cur_buf)); data_ptr += mbuf_len(cur_buf); pkt_snd_len += mbuf_len(cur_buf); } while(((cur_buf = mbuf_next(cur_buf)) != NULL) && ((pkt_snd_len + mbuf_len(cur_buf)) <= buf_len)); buf_len = pkt_snd_len; buffer_info->length = (UInt16)buf_len; pTpd->buf_len= OSSwapHostToLittleInt16((UInt16)buf_len); pTpd->eop = 1; if(++next_to_use == tpd_ring->count) next_to_use = 0; atomic_set(&tpd_ring->next_to_use, next_to_use); // update mailbox at_update_mailbox(adapter); OSSynchronizeIO(); freePacket(m); return kIOReturnOutputSuccess; }
void flushDownload(int sock) { int i = 0; int idx; uint8_t *hash; Packet *pkt; connDown *pool = downloadPool; for(i = 0; i < peerInfo.numPeer; i++) { int peerID = peerInfo.peerList[i].peerID; Packet *ack = peek(pool[peerID].ackSendQueue); while(ack != NULL) { peerList_t *p = &(peerInfo.peerList[i]); fprintf(stderr,"Sending ACK %d\n", getPacketAck(ack)); int retVal = spiffy_sendto(sock, ack->payload, getPacketSize(ack), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); fprintf(stderr,"Sent ACK %d\n", getPacketAck(ack)); if(retVal == -1) { // spiffy_sendto() does not work!! fprintf(stderr,"spiffy_sendto() returned -1.\n"); enqueue(pool[peerID].ackSendQueue, dequeue(pool[peerID].ackSendQueue)); } else { dequeue(pool[peerID].ackSendQueue); freePacket(ack); ack = dequeue(pool[peerID].ackSendQueue); } } switch(pool[peerID].state) { case 0: // Ready pkt = dequeue(pool[peerID].getQueue); while(pkt != NULL) { hash = getPacketHash(pkt, 0); printHash(hash); idx = searchHash(hash, &getChunk, 0); if(idx == -1) { // Someone else is sending or has sent this chunk freePacket(pkt); pkt = dequeue(pool[peerID].getQueue); } else if(numConnDown < maxConn){ getChunk.list[idx].fetchState = 2; if(downloadPool[peerID].connected == 1) fprintf(stderr,"NOT SUPPOSED TO BE CONNECTEED! \n\n\n\n\n\n"); downloadPool[peerID].connected = 1; numConnDown++; break; } else { // Cannot allow more download connections fprintf(stderr,"->No more download connection allowed!\n"); pool[peerID].state = 2; break; } } if(pool[peerID].state == 2) break; if(pkt != NULL) { fprintf(stderr,"Sending a GET\n"); peerList_t *p = &(peerInfo.peerList[i]); hash = pkt->payload + 16; char buf[50]; bzero(buf, 50); binary2hex(hash, 20, buf); fprintf(stderr,"GET hash:%s\n", buf); pool[peerID].curChunkID = searchHash(hash, &getChunk, -1); int retVal = spiffy_sendto(sock, pkt->payload, getPacketSize(pkt), 0, (struct sockaddr *) & (p->addr), sizeof(p->addr)); if(retVal == -1) { // Spiffy is broken! fprintf(stderr,"spiffy_snetto() returned -1.\n"); newPacketWHOHAS(nonCongestQueue); freePacket(pkt); cleanUpConnDown(&(pool[peerID])); numConnDown--; return; } setPacketTime(pkt); enqueue(pool[peerID].timeoutQueue, pkt); pool[peerID].state = 1; } break; case 1: { // Downloading pkt = peek(pool[peerID].timeoutQueue); struct timeval curTime; gettimeofday(&curTime, NULL); long dt = diffTimeval(&curTime, &(pkt->timestamp)); if(dt > GET_TIMEOUT_SEC) { pool[peerID].timeoutCount++; fprintf(stderr,"GET request timed out %d times!\n", pool[peerID].timeoutCount); setPacketTime(pkt); if(pool[peerID].timeoutCount == 3) { getChunk.list[pool[peerID].curChunkID].fetchState = 0; pool[peerID].state = 0; newPacketWHOHAS(nonCongestQueue); freePacket(pkt); cleanUpConnDown(&(pool[peerID])); numConnDown--; } } break; } case 2: { break; } default: break; } } }
/* returns 0 on success, error message on failure */ char* secureidcheck(char *user, char *response) { Packet *req = nil, *resp = nil; ulong u[4]; uchar x[16]; char *radiussecret; char ruser[ 64]; char dest[3*IPaddrlen+20]; Secret shared, pass; char *rv = "authentication failed"; Ndbs s; Ndbtuple *t, *nt, *tt; uchar *ip; static Ndb *netdb; if(netdb == nil) netdb = ndbopen(0); /* bad responses make them disable the fob, avoid silly checks */ if(strlen(response) < 4 || strpbrk(response,"abcdefABCDEF") != nil) goto out; /* get radius secret */ radiussecret = ndbgetvalue(db, &s, "radius", "lra-radius", "secret", &t); if(radiussecret == nil){ syslog(0, AUTHLOG, "secureidcheck: nil radius secret: %r"); goto out; } /* translate user name if we have to */ strcpy(ruser, user); for(nt = t; nt; nt = nt->entry){ if(strcmp(nt->attr, "uid") == 0 && strcmp(nt->val, user) == 0) for(tt = nt->line; tt != nt; tt = tt->line) if(strcmp(tt->attr, "rid") == 0){ strcpy(ruser, tt->val); break; } } ndbfree(t); u[0] = fastrand(); u[1] = fastrand(); u[2] = fastrand(); u[3] = fastrand(); req = newRequest((uchar*)u); if(req == nil) goto out; shared.s = (uchar*)radiussecret; shared.len = strlen(radiussecret); ip = getipv4addr(); if(ip == nil){ syslog(0, AUTHLOG, "no interfaces: %r\n"); goto out; } if(setAttribute(req, R_NASIPAddress, ip + IPv4off, 4) < 0) goto out; if(setAttribute(req, R_UserName, (uchar*)ruser, strlen(ruser)) < 0) goto out; pass.s = (uchar*)response; pass.len = strlen(response); hide(&shared, req->authenticator, &pass, x); if(setAttribute(req, R_UserPassword, x, 16) < 0) goto out; t = ndbsearch(netdb, &s, "sys", "lra-radius"); if(t == nil){ syslog(0, AUTHLOG, "secureidcheck: nil radius sys search: %r\n"); goto out; } for(nt = t; nt; nt = nt->entry){ if(strcmp(nt->attr, "ip") != 0) continue; snprint(dest,sizeof dest,"udp!%s!oradius", nt->val); resp = rpc(dest, &shared, req); if(resp == nil){ syslog(0, AUTHLOG, "%s nil response", dest); continue; } if(resp->ID != req->ID){ syslog(0, AUTHLOG, "%s mismatched ID req=%d resp=%d", dest, req->ID, resp->ID); freePacket(resp); resp = nil; continue; } switch(resp->code){ case R_AccessAccept: syslog(0, AUTHLOG, "%s accepted ruser=%s", dest, ruser); rv = nil; break; case R_AccessReject: syslog(0, AUTHLOG, "%s rejected ruser=%s %s", dest, ruser, replymsg(resp)); rv = "secureid failed"; break; case R_AccessChallenge: syslog(0, AUTHLOG, "%s challenge ruser=%s %s", dest, ruser, replymsg(resp)); rv = "secureid out of sync"; break; default: syslog(0, AUTHLOG, "%s code=%d ruser=%s %s", dest, resp->code, ruser, replymsg(resp)); break; } break; /* we have a proper reply, no need to ask again */ } ndbfree(t); free(radiussecret); out: freePacket(req); freePacket(resp); return rv; }
Packet * rpc(char *dest, Secret *shared, Packet *req) { uchar buf[4096], buf2[4096], *b, *e; Packet *resp; Attribute *a; int m, n, fd, try; /* marshal request */ e = buf + sizeof buf; buf[0] = req->code; buf[1] = req->ID; memmove(buf+4, req->authenticator, 16); b = buf+20; for(a = &req->first; a; a = a->next){ if(b + 2 + a->len > e) return nil; *b++ = a->type; *b++ = 2 + a->len; memmove(b, a->val, a->len); b += a->len; } n = b-buf; buf[2] = n>>8; buf[3] = n; /* send request, wait for reply */ fd = dial(dest, 0, 0, 0); if(fd < 0){ syslog(0, AUTHLOG, "%s: rpc can't get udp channel", dest); return nil; } atnotify(ding, 1); m = -1; for(try = 0; try < 2; try++){ alarm(4000); m = write(fd, buf, n); if(m != n){ syslog(0, AUTHLOG, "%s: rpc write err %d %d: %r", dest, m, n); m = -1; break; } m = read(fd, buf2, sizeof buf2); alarm(0); if(m < 0){ syslog(0, AUTHLOG, "%s rpc read err %d: %r", dest, m); break; /* failure */ } if(m == 0 || buf2[1] != buf[1]){ /* need matching ID */ syslog(0, AUTHLOG, "%s unmatched reply %d", dest, m); continue; } if(authcmp(shared, buf2, m, buf+4) == 0) break; syslog(0, AUTHLOG, "%s bad rpc chksum", dest); } close(fd); if(m <= 0) return nil; /* unmarshal reply */ b = buf2; e = buf2+m; resp = (Packet*)malloc(sizeof(*resp)); if(resp == nil) return nil; resp->code = *b++; resp->ID = *b++; n = *b++; n = (n<<8) | *b++; if(m != n){ syslog(0, AUTHLOG, "rpc got %d bytes, length said %d", m, n); if(m > n) e = buf2+n; } memmove(resp->authenticator, b, 16); b += 16; a = &resp->first; a->type = 0; while(1){ if(b >= e){ a->next = nil; break; /* exit loop */ } a->type = *b++; a->len = (*b++) - 2; if(b + a->len > e){ /* corrupt packet */ a->next = nil; freePacket(resp); return nil; } memmove(a->val, b, a->len); b += a->len; if(b < e){ /* any more attributes? */ a->next = (Attribute*)malloc(sizeof(*a)); if(a->next == nil){ free(req); return nil; } a = a->next; } } return resp; } int setAttribute(Packet *p, uchar type, uchar *s, int n) { Attribute *a; a = &p->first; if(a->type != 0){ a = (Attribute*)malloc(sizeof(*a)); if(a == nil) return -1; a->next = p->first.next; p->first.next = a; } a->type = type; a->len = n; if(a->len > 253 ) /* RFC2138, section 5 */ a->len = 253; memmove(a->val, s, a->len); return 0; }
UInt32 AttansicL2Ethernet::outputPacket(mbuf_t m, void *prm) { at_adapter *adapter=&adapter_; tx_pkt_header_t* txph; u32 offset, copy_len; int txs_unused; int txbuf_unused; u32 buf_len; if (mbuf_pkthdr_len(m) <= MAX_TX_BUF_LEN) buf_len = mbuf_pkthdr_len(m); else { DbgPrint("Tx Packet size is too big, droping\n"); freePacket(m); return kIOReturnOutputDropped; } txs_unused = TxsFreeUnit(adapter); txbuf_unused = TxdFreeBytes(adapter); if (txs_unused < 1 || buf_len > txbuf_unused) { // no enough resource DbgPrint("no enough resource!!\n"); freePacket(m); return kIOReturnOutputDropped; } offset = adapter->txd_write_ptr; DbgPrint("outputPacket() begin, txd_write_ptr %d txs_next_clear %d length %d \n" , adapter->txd_write_ptr,adapter->txs_next_clear,buf_len); txph = (tx_pkt_header_t*) (((u8*)adapter->txd_ring)+offset); offset += 4; if (offset >= adapter->txd_ring_size) offset -= adapter->txd_ring_size; u32 pkt_snd_len = 0; mbuf_t cur_buf = m; do { if (mbuf_data(cur_buf)){ copy_len = adapter->txd_ring_size - offset; if (copy_len >=mbuf_len(cur_buf)) { memcpy((u8*)adapter->txd_ring+offset, mbuf_data(cur_buf), mbuf_len(cur_buf)); } else { memcpy((u8*)adapter->txd_ring+offset, mbuf_data(cur_buf), copy_len); memcpy((u8*)adapter->txd_ring, ((u8*)mbuf_data(cur_buf))+copy_len, mbuf_len(cur_buf)-copy_len); } offset += mbuf_len(cur_buf); if (offset >= adapter->txd_ring_size) offset -= adapter->txd_ring_size; pkt_snd_len += mbuf_len(cur_buf); } } while(((cur_buf = mbuf_next(cur_buf)) != NULL) && ((pkt_snd_len + mbuf_len(cur_buf)) <= buf_len)); buf_len = pkt_snd_len; *(u32*)txph = 0; txph->pkt_size = buf_len; offset = ((offset+3)&~3); if (offset >= adapter->txd_ring_size) offset -= adapter->txd_ring_size; adapter->txd_write_ptr = offset; // clear txs before send adapter->txs_ring[adapter->txs_next_clear].update = 0; if (++adapter->txs_next_clear == adapter->txs_ring_size) adapter->txs_next_clear = 0; AT_WRITE_REGW( &adapter->hw, REG_MB_TXD_WR_IDX, (adapter->txd_write_ptr>>2)); OSSynchronizeIO(); freePacket(m); return kIOReturnOutputSuccess; }