Ejemplo n.º 1
0
int check_and_ack(struct dhcpMessage* packet, uint32_t ip)
{
	uint32_t static_ip = 0;
	
	/* There is an Static IP for this guy, whether it is requested or not */
	if ((static_ip = getIpByMac(server_config.static_leases, packet->chaddr)) != 0)
	{
		msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:REQUEST ip %x, static ip %x", ip, static_ip);
		return sendACK(packet, static_ip);
	}

	/* requested ip is reserved by a static lease -- if it is himself, situation above match */
	if (reservedIp(server_config.static_leases, ip))
	{
		msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:REQUEST ip %x is reserved as a static ip", ip);
		return sendNAK(packet);
	}
	
	/* if some one reserve it */
	if ( ip != packet->ciaddr && check_ip(packet, ip) )
	{
		msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:REQUEST ip %x already reserved by someone", ip);
		return sendNAK(packet);
	}

	if (ntohl(ip) < ntohl(server_config.start) || ntohl(ip) > ntohl(server_config.end))
	{
		msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:REQUEST ip %x is not in the address pool", ip);
		return sendNAK(packet);
	}
	
	return sendACK(packet, ip);
}
Ejemplo n.º 2
0
void UDPServer::work(){
    struct pkt temp1;
    struct pkt temp2;
    int lostPkt;

    while(1){
        memset(&recv_buffer, 0, 1500);
        memset( &temp1 , 0, PKT_SIZE);
        memset( &temp2 , 0, PKT_SIZE);
        addr_len = sizeof(client_addr);

        if( (recvfrom(serverFD, recv_buffer, 1500, 0, (struct sockaddr*)&client_addr, &addr_len)) == -1 ){
            perror("receiver recvfrom(): ");
            exit(1);
        }

        memcpy( &temp1, recv_buffer, PKT_SIZE );
        std::cout << "**recv pkt** " << "seq_num: " << temp1.seq_num << ", ack_num: " << temp1.ack_num << ", ack_flag: " << temp1.ack_flag;
        // random drop
        if( randDrop() && dupACK_flag ){
            std::cout << "  ~~~ drop this pkt!! ~~~\n";
            dupACK_flag = 0;
            lostPkt = temp1.seq_num;
            continue;
        }
        //
        if( temp1.seq_num == lostPkt ){
            dupACK_flag = 1;
            dupACK_count = 0;
        }
        // send ack
        if( temp1.seq_num == reqNum ){
            temp2.seq_num = -1;
            temp2.ack_num = temp1.seq_num + 1;
            temp2.ack_flag = FLAG_ACK;
            reqNum++;

            std::cout << " - accepted! send out ack: " << reqNum << std::endl;
            sendACK( &temp2 );
        }else{
            temp2.seq_num = -1;
            temp2.ack_num = reqNum;
            temp2.ack_flag = FLAG_ACK;

            if( dupACK_count == 3 ){
                // already send out 3 dup ack, discard this packet and donot send ack
                std::cout << " - discard! send out ack: " << reqNum << std::endl;
                continue;
            }

            std::cout << " - discard! send out ack: " << reqNum << std::endl;
            sendACK( &temp2 );
            dupACK_count++;
        }
    }
    close(serverFD);
}
Ejemplo n.º 3
0
void Telemetry::receiveConfig(Config& data)
{		
	// Verify checksum
	uint8_t checksum = 0;
	for (uint8_t i = 0; i < ptr_; ++i)
	{
		checksum ^= rx_data_buffer_[i];
	}
	
	if (checksum == 0)
	{
		// PID
		data.pid_roll.kp = Telemetry::readFloat(3);
		data.pid_roll.kd = Telemetry::readFloat(7);
		data.pid_roll.ki = Telemetry::readFloat(11);

		data.pid_pitch.kp = Telemetry::readFloat(15);
		data.pid_pitch.kd = Telemetry::readFloat(19);
		data.pid_pitch.ki = Telemetry::readFloat(23);
		
		data.pid_yaw.kp = Telemetry::readFloat(27);
		data.pid_yaw.kd = Telemetry::readFloat(31);
		data.pid_yaw.ki = Telemetry::readFloat(35);

		// Store config
		EEPROM::storeConfig(data);

		// Send ACK
		sendACK();
	}
}
Ejemplo n.º 4
0
//checks if client does not already exist, and if not so, sends ACK message to client
int checkClient(int connfd){

    struct MessageSBCP joinMessage;
    struct AttributeSBCP joinMessageAttribute;
    char temp[16];
    int status = 0;
    read(connfd,(struct MessageSBCP *) &joinMessage,sizeof(joinMessage));
    //joinMessageAttribute.payload = (char *)malloc(sizeof(char *) * joinMessage.joinMessageAttribute.length);
    joinMessageAttribute = joinMessage.attribute[0];
    //clients[clientCount].username = (char *)malloc(sizeof(char *) * joinMessage.joinMessageAttribute.length);
    strcpy(temp, joinMessageAttribute.payload);
    status = checkUsername(temp);
    if(status == 1)
    {
        printf("\nClient already exists.");
        sendNAK(connfd, 1); // 1 for client already exists 
    }
    else
    {
        strcpy(clients[clientCount].username, temp);
        clients[clientCount].fd = connfd;
        clients[clientCount].clientCount = clientCount;
        clientCount = clientCount + 1;
        sendACK(connfd);
    }
    return status;
}
void Transmitter::parseData(QByteArray *data)
{
  qDebug() << "in" << __FUNCTION__;

  Message msg(*data);

  // isValid() also checks that the packet is exactly as long as expected
  if (!msg.isValid()) {
	qWarning() << "Package not valid, ignoring";
	return;
  }

  qDebug() << __FUNCTION__ << ": type:" << (int)msg.type();

  // Check, whether to ACK the packet
  if (msg.isHighPriority()) {
	sendACK(msg);
  }

  // Handle different message types in different methods
  if (messageHandlers[msg.type()]) {
	messageHandler func = messageHandlers[msg.type()];
	(this->*func)(msg);
  } else {
	qWarning() << "No message handler for type" << msg.type() << ", ignoring";
  }  
}
Ejemplo n.º 6
0
TResult CKKMApi::exec_command(const QByteArray& baCmd, QByteArray& baAnswer, int nTimeOut)
{
	TResult nRet = kResult_Success;
	LOG_DBG("exec_command ==>");

	do
	{
		sendENQ();
		readACK();
		//sendENQ_readACK();

		QByteArray baRawCommand = makeCommand(baCmd);
		LOG_DBG("command : '"<<ba2hex(baRawCommand)<<"'");
		m_pSerial->write(baRawCommand);

		readACK();
		sendEOT();

		readENQ(nTimeOut);
		sendACK();

		nRet = loadKKMData(baAnswer);
		if (nRet == kResult_Success)
		{
			if (baAnswer.size() > 2)
			{
				baAnswer = baAnswer.mid(1, baAnswer.size()-2);
			}
			else
			{
				nRet = kResult_ReadError;
				LOG_ERR("incorrect answer size");
				break;
			}
		}

		sendACK();
		readEOT();
	}
	while (false);
	LOG_DBG("exec_command <==");
	return nRet;
}
Ejemplo n.º 7
0
int recieveData(FILE *file, struct sockaddr_in *sender, int *reciever_socket, char verbose_text[LOG_INFO_SUBJECT_SIZE]) {

    int next_package = RFC1350_BLOCKSIZE + 4;
    int timeout = 5;
    char data[RFC1350_BLOCKSIZE];
    int bytes;
    unsigned short index = 1;

    /* While this package is not the last one */
    while( next_package == RFC1350_BLOCKSIZE + 4 ) {
        if(timeout < 0)
            return -1;

        printf("Current Package: %d", next_package); //debug
        next_package = recieveDataPackage(index, data, sender, reciever_socket, verbose_text);
        printf("Next Package: %d", next_package); //debug

        if( next_package > 4 ) {
            timeout = 5;
            bytes = fwrite(data, sizeof(char), next_package - 4, file);

            if( bytes < 0 ) {
                sendError(RFC1350_ERR_DISKFULL, *sender, reciever_socket, verbose_text);
                return -1;
            }

            sendACK(index, *sender, reciever_socket, verbose_text);
            index++;

        } else if( next_package == -1 ) {
            return -1;

        } else {
            timeout -= 1;
            sendACK(index, *sender, reciever_socket, verbose_text);
        }
    }

    return 0;
}
Ejemplo n.º 8
0
unsigned char Read_AD(unsigned char chn)
{
	unsigned char ad_data;
	start();
	send_byte(0x90);
	send_byte(0x40 | chn);

	start();
	send_byte(0x91);
	ad_data = receive_byte();
	sendACK(1);
	stop();
	return ad_data;
}
Ejemplo n.º 9
0
bool RFM69Manager::loop() {

    boolean ret = false;

    if (receiveDone()) {

        uint8_t senderID = SENDERID;
        int16_t rssi = RSSI;
        uint8_t length = DATALEN;
        char buffer[length + 1];
        strncpy(buffer, (const char *) DATA, length);
        buffer[length] = 0;

        if (ACKRequested()) sendACK();

        uint8_t parts = 1;
        for (uint8_t i=0; i<length; i++) {
            if (buffer[i] == ':') ++parts;
        }

        if (parts > 1) {

            uint8_t packetID = 0;
            char * name = strtok(buffer, ":");
            char * value = strtok(NULL, ":");
            if (parts > 2) {
                char * packet = strtok(NULL, ":");
                packetID = atoi(packet);
            }

            _message.messageID = ++_receiveCount;
            _message.packetID = packetID;
            _message.nodeID = senderID;
            _message.name = name;
            _message.value = value;
            _message.rssi = rssi;
            ret = true;

            if (_callback != NULL) {
                _callback(&_message);
            }

        }

    }

    return ret;

}
Ejemplo n.º 10
0
void slip_main(void)
{
	uchar ret = 0;

	ret = processing_slipcmd();
	if( ret == ERROR_OK)
	{
		sendACK();
		run_cmd();
	}
	else if (ret == ERROR_INVALID_PACKET)
	{
		sendNACK();
	}
	rs485_cmd_finish = 0;
	rs485_cmd_count = 0;
	rs485bufferclear(cmdrspbuffer, RS485BUF_SIZE);
	rs485bufferclear(cmd_bytes, RS485CMD_SIZE);
}
Ejemplo n.º 11
0
int ServerItem::handleData(char *message, int length)
{
	package *pac = (package *)message;
	int index = (int)ntohs(pac->code);
	if (packageIndex + 1 == index) {
		fwrite(message + 4, 1, length - 4, fp);
	}
	else {

	}
	packageIndex = index;
	int ret = sendACK((unsigned short)index);
	if (length - 4 < blksize) {
		return 1;
	}
	else if (ret < 0) {
		return ret;
	}
	else {
		return 0;
	}
}
Ejemplo n.º 12
0
//NOTE: UDP will drop anything that does not fit in the buffer size! so the buffer size must be the maximum
//possible size that this program will send a packet!
void UDP_Socket::receivePackets()
{
	int i = 0;
	while (true)
	{
		int protocolHandler = 0;
#if PLATFORM == WINDOWS
		int receiveLength = sizeof(receive);
#else
		unsigned int receiveLength = sizeof(receive);
#endif
		int bytes = recvfrom(socketHandle, messageBuffer, MAX_PACKET_SIZE, 0, (sockaddr*)&receive, &receiveLength);
		if (bytes <= 0 || (protocolHandler = checkProtocol()) == 0)
			break;
		messageBuffer[bytes] = '\0';
		sendACK();
		//TODO: Save these!
		unsigned int receiveAddress = ntohl(receive.sin_addr.s_addr);
		unsigned int receivePort = ntohs(receive.sin_port);
		parseMessages(messageBuffer, i, bytes);
		i++;
	}
	sortMessageBuffer();
}
Ejemplo n.º 13
0
unsigned char receive_byte()
{
	unsigned char i, temp;
	sda = 1;
	_nop_();
	for(i = 0; i < 8; i++)
	{
		scl = 1;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		temp = (temp<<1) | sda;
		scl = 0;
		_nop_();
		_nop_();
		_nop_();
		_nop_();
		_nop_();	
	}
	sendACK(0);
	return temp;
}
Ejemplo n.º 14
0
bool ShinyFilesystemMediator::handleMessage( zmq::socket_t * sock, std::vector<zmq::message_t *> & msgList ) {
    zmq::message_t * fuseRoute = msgList[0];
    zmq::message_t * blankMsg = msgList[1];
    
    // Following the protocol (briefly) laid out in ShinyFuse.h;
    uint8_t type = parseTypeMsg(msgList[2]);
    switch( type ) {
        case ShinyFilesystemMediator::DESTROY: {
            // No actual response data, just sending response just to be polite
            sendACK( sock, fuseRoute );
            // return false as we're signaling to mediator that it's time to die.  >:}
            return false;
        }
        case ShinyFilesystemMediator::GETATTR: {
            // Let's actually get the data fuse wants!
            char * path = parseStringMsg( msgList[3] );
            
            // If the node even exists;
            ShinyMetaNode * node = fs->findNode( path );
            if( node ) {
                // we're just going to serialize it and send it on it's way!
                // Opportunity for zero-copy here!
                uint64_t len = node->serializedLen();
                char * buff = new char[len];
                node->serialize(buff);
                
                zmq::message_t ackMsg; buildTypeMsg( ShinyFilesystemMediator::ACK, &ackMsg );
                zmq::message_t nodeTypeMsg; buildTypeMsg( node->getNodeType(), &nodeTypeMsg );
                zmq::message_t nodeMsg; buildDataMsg( buff, len, &nodeMsg );
                
                sendMessages( sock, 5, fuseRoute, blankMsg, &ackMsg, &nodeTypeMsg, &nodeMsg );
                delete( buff );
            } else
                sendNACK( sock, fuseRoute );
            
            // cleanup after the parseStringMsg()
            delete( path );
            break;
        }
        case ShinyFilesystemMediator::SETATTR: {
            char * path = parseStringMsg( msgList[3] );
            
            ShinyMetaNode * node = fs->findNode( path );
            if( node ) {
                const char * data = (const char *) msgList[4]->data();
                
                // Apply the data to the node
                node->unserialize( &data );
                
                // Send back ACK
                sendACK( sock, fuseRoute );
            } else
                sendNACK( sock, fuseRoute );
            
            delete( path );
            break;
        }
        case ShinyFilesystemMediator::READDIR: {
            char * path = parseStringMsg( msgList[3] );
            
            // If the node even exists;
            ShinyMetaNode * node = fs->findNode( path );
            if( node && (node->getNodeType() == ShinyMetaNode::TYPE_DIR || node->getNodeType() == ShinyMetaNode::TYPE_ROOTDIR) ) {
                const std::vector<ShinyMetaNode *> * children = ((ShinyMetaDir *) node)->getNodes();
                
                // Here is my crucible, to hold data to be pummeled out of the networking autocannon, ZMQ
                std::vector<zmq::message_t *> list( 1 + 1 + 1 + children->size() );
                list[0] = fuseRoute;
                list[1] = blankMsg;
                
                zmq::message_t ackMsg; buildTypeMsg( ShinyFilesystemMediator::ACK, &ackMsg );
                list[2] = &ackMsg;
                
                for( uint64_t i=0; i<children->size(); ++i ) {
                    zmq::message_t * childMsg = new zmq::message_t(); buildStringMsg( (*children)[i]->getName(), childMsg );
                    list[3+i] = childMsg;
                }
                
                sendMessages( sock, list );
                
                // Free up those childMsg structures and ackMsg while we're at it (ackMsg is list[1])
                for( uint64_t i=3; i<list.size(); ++i ) {
                    delete( list[i] );
                }
            } else
                sendNACK( sock, fuseRoute );
            
            // cleanup, cleanup everybody everywhere!
            delete( path );
            break;
        }
        case ShinyFilesystemMediator::OPEN: {
            // Grab the path, shove it into an std::string for searching openFiles
            char * path = parseStringMsg( msgList[3] );
            std::string pathStr( path );
            
            // This is our file that we'll eventually send back, or not, if we can't find the file
            ShinyMetaNode * node = NULL;
            
            // First, make sure that there is not already an OpenFileInfo corresponding to this path:
            std::map<std::string, OpenFileInfo *>::iterator itty = this->openFiles.find( pathStr );
            
            // If there isn't, let's get one! (if it exists)
            if( itty == this->openFiles.end() ) {
                node = fs->findNode( path );
                if( node && node->getNodeType() == ShinyMetaNode::TYPE_FILE ) {
                    // Create the new OpenFileInfo, initialize it to 1 opens, so only 1 close required to
                    // flush this data out of the map
                    OpenFileInfo * ofi = new OpenFileInfo();
                    ofi->file = (ShinyMetaFile *) node;
                    ofi->opens = 1;
                    
                    // Aaaand, put it into the list!
                    this->openFiles[pathStr] = ofi;
                }
            } else {
                // Check to make sure this guy isn't on death row 'cause of an unlink()
                if( !(*itty).second->shouldDelete ) {
                    // Otherwise, it's in the list, so let's return the cached copy!
                    node = (ShinyMetaNode *) (*itty).second->file;
                    
                    // Increment the number of times this file has been opened...
                    (*itty).second->opens++;
                    
                    // If it was going to be closed, let's stop that from happening now
                    (*itty).second->shouldClose = false;
                }
            }
            
            // If we were indeed able to find the file; write back an ACK, otherwise, NACK it up!
            if( node )
                sendACK( sock, fuseRoute );
            else
                sendNACK( sock, fuseRoute );
            
            // Don't forget this too!
            delete( path );
            break;
        }
        case ShinyFilesystemMediator::CLOSE: {
            // Grab the path, just like in open
            char * path = parseStringMsg( msgList[3] );
            std::string pathStr( path );

            // This time, we _only_ check openFiles
            std::map<std::string, OpenFileInfo *>::iterator itty = this->openFiles.find( pathStr );
            
            // If it's there,
            if( itty != this->openFiles.end() ) {
                OpenFileInfo * ofi = (*itty).second;
                
                // decrement the opens!
                ofi->opens--;
                
                // Should we purge this ofi from the cache?
                if( ofi->opens == 0 ) {
                    // If we are currently write locked, or we have reads ongoing, we must
                    // wait 'till those are exuahsted, and so we will just mark ourselves as suicidal
                    if( ofi->writeLocked || ofi->reads > 0 ) {
                        // This will cause it to be closed once all READs and WRITEs are finished
                        ofi->shouldClose = true;
                    } else
                        this->closeOFI( itty );
                }
                
                // Aaaand, send an ACK, just for fun
                sendACK( sock, fuseRoute );
            } else {
                // NACK!  NACK I SAY!
                sendNACK( sock, fuseRoute );
            }
            
            // You just gotta free it up, fre-fre-free it all up now, 'come on!
            delete( path );
            break;
        }
        case ShinyFilesystemMediator::READREQ:
        case ShinyFilesystemMediator::WRITEREQ:
        case ShinyFilesystemMediator::TRUNCREQ: {
            // Grab the path, and the itty
            char * path = parseStringMsg( msgList[3] );
            std::string pathStr( path );
            std::map<std::string, OpenFileInfo *>::iterator itty = this->openFiles.find( pathStr );
            
            // If it is in openFiles,
            if( itty != this->openFiles.end() ) {
                OpenFileInfo * ofi = (*itty).second;
                
                // first, we put it into our queue of file operations,
                zmq::message_t * savedRoute = new zmq::message_t();
                savedRoute->copy( fuseRoute );
                
                // Queue this request for later
                ofi->queuedFileOperations.push_back( QueuedFO( savedRoute, type ) );
                
                // Then, we try to start up more file operations. the subroutine will check to see
                // if we actually can or not.  It's amazing!  Magical, even.
                this->startQueuedFO( sock, ofi );
            } else
                sendNACK( sock, fuseRoute );
            
            // darn all these paths.  :P
            delete( path );
            break;
        }
        case ShinyFilesystemMediator::READDONE:
        case ShinyFilesystemMediator::WRITEDONE:
        case ShinyFilesystemMediator::TRUNCDONE: {
            // Grab the path, and the itty
            char * path = parseStringMsg( msgList[3] );
            std::string pathStr( path );
            std::map<std::string, OpenFileInfo *>::iterator itty = this->openFiles.find( pathStr );

            // If it is in openFiles,
            if( itty != this->openFiles.end() ) {
                OpenFileInfo * ofi = (*itty).second;
                
                if( type == ShinyFilesystemMediator::WRITEDONE || type == ShinyFilesystemMediator::TRUNCDONE ) {
                    // We're not writelocked!  (at least, util we start writing again. XD)
                    ofi->writeLocked = false;
                } else if( type == ShinyFilesystemMediator::READDONE ) {
                    // Decrease the number of concurrently running READS!
                    ofi->reads--;
                }
                
                // Update the file with the serialized version sent back
                //LOG( "Updating %s due to a %s", path, (type == READDONE ? "READDONE" : (type == WRITEDONE ? "WRITEDONE" : "TRUNCDONE")) );
                const char * data = (const char *) msgList[4]->data();
                ofi->file->unserialize(&data);
                //delete( fs );
                
                if( !ofi->writeLocked || ofi->reads == 0 ) {
                    // Check to see if there's stuff queued, and if the conditions are right, start that queued stuff!
                    if( !ofi->queuedFileOperations.empty() )
                        this->startQueuedFO( sock, ofi );
                    else {
                        // If there is nothing queued, and we should close this file, CLOSE IT!
                        if( ofi->shouldClose )
                            this->closeOFI( itty );
                    }
                }
            }
            delete( path );
            break;
        }
        case ShinyFilesystemMediator::CREATEFILE:
        case ShinyFilesystemMediator::CREATEDIR: {
            // Grab the path,
            char * path = parseStringMsg( msgList[3] );
            
            // See if the file already exists
            ShinyMetaNode * node = fs->findNode( path );
            if( node ) {
                // If it does, I can't very well create a file here, now can I?
                sendNACK( sock, fuseRoute );
            } else {
                // If not, check that the parent exists;
                ShinyMetaDir * parent = fs->findParentNode(path);
                
                if( !parent ) {
                    // If it doesn't, send a NACK!
                    sendNACK( sock, fuseRoute );
                } else {
                    // Otherwise, let's create the dir/file
                    if( type == ShinyFilesystemMediator::CREATEFILE )
                        node = new ShinyMetaFile( ShinyMetaNode::basename( path ), parent );
                    else
                        node = new ShinyMetaDir( ShinyMetaNode::basename( path), parent );
                    
                    // If they have included it, set the permissions away from the defaults
                    if( msgList.size() > 4 ) {
                        uint16_t mode = *((uint16_t *) parseDataMsg( msgList[4] ));
                        node->setPermissions( mode );
                    }
                    
                    // And send back an ACK
                    sendACK( sock, fuseRoute );
                }
            }
            delete( path );
            break;
        }
        case ShinyFilesystemMediator::DELETE: {
            // Grab the path,
            char * path = parseStringMsg( msgList[3] );
            
            // Check to make sure the file exists
            ShinyMetaNode * node = fs->findNode( path );
            if( !node ) {
                // If it doesn'y, I can't very well delete it, can I?
                sendNACK( sock, fuseRoute );
            } else {
                // Since it exists, let's make sure it's not open right now
                std::string pathStr( path );
                std::map<std::string, OpenFileInfo *>::iterator itty = this->openFiles.find( pathStr );
                
                // If it is open, queue the deletion for later
                if( itty != this->openFiles.end() ) {
                    OpenFileInfo * ofi = (*itty).second;
                    ofi->shouldDelete = true;
                } else {
                    // Tell the db to delete him, if it's a file
                    if( node->getNodeType() == ShinyMetaNode::TYPE_FILE )
                        ((ShinyMetaFile *)node)->setLen( 0 );
                    
                    // actually delete the sucker
                    delete( node );
                }
            
                // AFFLACK.  AFFFFFLAACK.
                sendACK( sock, fuseRoute );
            }
            delete( path );
            break;
        }
        case ShinyFilesystemMediator::RENAME: {
            // Grab the path, and the new path
            char * path = parseStringMsg( msgList[3] );
            char * newPath = parseStringMsg( msgList[4] );
            
            // Check that their parents actually exist
            ShinyMetaDir * oldParent = fs->findParentNode( path );
            ShinyMetaDir * newParent = fs->findParentNode( newPath );
            
            if( oldParent && newParent ) {
                // Now that we know the parents are real, find the child
                const char * oldName = ShinyMetaNode::basename( path );
                const char * newName = ShinyMetaNode::basename( newPath );
                ShinyMetaNode * node = oldParent->findNode( oldName );
                
                if( node ) {
                    // Check to make sure we need to move it at all
                    if( oldParent != newParent ) {
                        oldParent->delNode( node );
                        newParent->addNode( node );
                    }
                    
                    // Don't setName to the same thing we had before, lol
                    if( strcmp( oldName, newName) != 0 )
                        node->setName( newName );
                    
                    // Send an ACK, for a job well done
                    sendACK( sock, fuseRoute );
                } else {
                    // We cannae faind tha node cap'n!
                    sendNACK( sock, fuseRoute );
                }

            } else {
                // Oh noes, we couldn't find oldParent or we couldn't find newParent!
                sendNACK( sock, fuseRoute );
            }
            
            delete( path );
            delete( newPath );
            break;
        }
        case ShinyFilesystemMediator::CHMOD: {
            // Grab the path, and the new path
            char * path = parseStringMsg( msgList[3] );
            uint16_t mode = *((uint16_t *) parseDataMsg( msgList[4] ));
            
            // Find node
            ShinyMetaNode * node = fs->findNode( path );
            if( node ) {
                // Set the permissionse
                node->setPermissions( mode );
                
                // ACK
                sendACK( sock, fuseRoute );
            } else
                sendNACK( sock, fuseRoute );

            delete( path );
            break;
        }
        default: {
            WARN( "Unknown ShinyFuse message type! (%d) Sending NACK:", type );
            sendNACK( sock, fuseRoute );
            break;
        }
    }
    
    return true;
}
Ejemplo n.º 15
0
// 这是由stcp_server_init()启动的线程. 它处理所有来自客户端的进入数据. seghandler被设计为一个调用sip_recvseg()的无穷循环, 
// 如果sip_recvseg()失败, 则说明到SIP进程的连接已关闭, 线程将终止. 根据STCP段到达时连接所处的状态, 可以采取不同的动作.
// 请查看服务端FSM以了解更多细节.
void* seghandler(void* arg) 
{
	long i;
	int flag;
	unsigned int client_port;
	seg_t* seg = (seg_t*)malloc(sizeof(seg_t));
	int* src_nodeID = (int*)malloc(sizeof(int));
	while (1) {
		flag = sip_recvseg(sip_conn, src_nodeID, seg);///////////////////////////////////注意src_nodeID的使用
		if (flag == 1) {//报文丢失
			printf("the stcp server does'n receive a segment! segment is lost!\n");
			continue;
		}
		if (checkchecksum(seg) == -1) {
			printf("Checksum error!\n");
			continue;
		}
		if (flag == -1) {//接收不到报文,线程停止
			printf("can't receive anything in tcp level, the seghandler thread is going to end.\n");
			break;
		}
		for (i = 0; i < MAX_TRANSPORT_CONNECTIONS; i++) {
			if ((NULL != server_tcb[i]) && (server_tcb[i]->server_portNum == seg->header.dest_port) && (server_tcb[i]->client_portNum == seg->header.src_port) && (*src_nodeID == server_tcb[i]->client_nodeID)) {
				break;
			}
		}
		if (i == MAX_TRANSPORT_CONNECTIONS) {
			printf("the tcb you want to find does't exist! but...\n");
			if (seg->header.type == SYN) {
				for (i = 0; i < MAX_TRANSPORT_CONNECTIONS; i++) {
					if ((NULL != server_tcb[i]) && (server_tcb[i]->server_portNum == seg->header.dest_port)) {
						break;
					}
				}
				if (i == MAX_TRANSPORT_CONNECTIONS) {
					printf("the tcb you want does't exist really!!\n");
					continue;
				}
			}
			else
				continue;
		}
		switch (seg->header.type) {
			case 0:
				printf("the type stcp server receives is SYN\n");
				break;
			case 1:
				printf("the type stcp server receives is SYNACK\n");
				break;
			case 2:
				printf("the type stcp server receives is FIN\n");
				break;
			case 3:
				printf("the type stcp server receives is FINACK\n");
				break;
			case 4:
				printf("the type stcp server receives is DATA\n");
				break;
			case 5:
				printf("the type stcp server receives is DATAACK\n");
				break;
		}
		client_port = seg->header.src_port;
		switch (server_tcb[i]->state) {
			case CLOSED:
				printf("stcp server now is in CLOSED state!\n");
				break;
			case LISTENING:
				printf("stcp server now is in LISTENING state!\n");
				if (seg->header.type == SYN) {
					printf("receive a SYN!\n");
					server_tcb[i]->state = CONNECTED;
					server_tcb[i]->client_portNum = seg->header.src_port;
					server_tcb[i]->client_nodeID = *src_nodeID;
					sendACK(i, client_port, *src_nodeID, SYNACK, seg);
				}
				break;
			case CONNECTED:
				printf("stcp server now is in CONNECTED state!\n");
				if (seg->header.type == SYN) {
					printf("receive a SYN!\n");
					server_tcb[i]->state = CONNECTED;
					server_tcb[i]->expect_seqNum = seg->header.seq_num;
					sendACK(i, client_port, *src_nodeID, SYNACK, seg);
				}
				else if (seg->header.type == FIN) {
					printf("receive a FIN!\n");
					server_tcb[i]->state = CLOSEWAIT;
					sendACK(i, client_port, *src_nodeID, FINACK, seg);
					pthread_t FINhandle_thread;
					int rc;
					rc = pthread_create(&FINhandle_thread, NULL, FINhandler, (void *)i);
					if (rc) {
						printf("ERROR; return code from pthread_create() is %d\n", rc);
						exit(-1);
					}
					
				}
				else if (seg->header.type == DATA) {
					printf("receive a DATA!\n");
					printf("the expect_seqNum is %d\n", server_tcb[i]->expect_seqNum);
					printf("the seqNum is %d\n", seg->header.seq_num);
					if (seg->header.seq_num == server_tcb[i]->expect_seqNum) {
						printf("the expect_seqNum == seq_num!\n");
						pthread_mutex_lock(server_tcb[i]->bufMutex);
						memcpy(server_tcb[i]->recvBuf + server_tcb[i]->usedBufLen, seg->data, seg->header.length);
						printf("the seg->header.length is %d\n", seg->header.length);
						server_tcb[i]->usedBufLen += seg->header.length;
						server_tcb[i]->expect_seqNum += seg->header.length;
						seg->header.src_port = server_tcb[i]->server_portNum;        //源端口号
						seg->header.dest_port = client_port;       //目的端口号
						seg->header.seq_num = 0;         //序号
						seg->header.ack_num = server_tcb[i]->expect_seqNum;         //确认号
						seg->header.length = 0;    //段数据长度
						seg->header.type = DATAACK;     //段类型
						seg->header.rcv_win = 0;  //当前未使用
						seg->header.checksum = 0;
						seg->header.checksum = checksum(seg);  //这个段的校验和
						sip_sendseg(sip_conn, *src_nodeID, seg);
						printf("stcp server send the changing DATAACK %d succesfully!\n", seg->header.ack_num);
						pthread_mutex_unlock(server_tcb[i]->bufMutex);
					}
					else {
						printf("the expect_seqNum != seq_num!\n");
						seg->header.src_port = server_tcb[i]->server_portNum;        //源端口号
						seg->header.dest_port = client_port;       //目的端口号
						seg->header.seq_num = 0;         //序号
						seg->header.ack_num = server_tcb[i]->expect_seqNum;         //确认号
						seg->header.length = 0;    //段数据长度
						seg->header.type = DATAACK;     //段类型
						seg->header.rcv_win = 0;  //当前未使用
						seg->header.checksum = 0;
						seg->header.checksum = checksum(seg);  //这个段的校验和
						sip_sendseg(sip_conn, *src_nodeID, seg);
						printf("stcp server send the not changed DATAACK %d succesfully!\n", seg->header.ack_num);
					}
				}
				break;
			case CLOSEWAIT:
				printf("stcp server now is in CLOSEWAIT state!\n");
				if (seg->header.type == FIN) {
					printf("receive a FIN!\n");
					sendACK(i, client_port, *src_nodeID, FINACK, seg);
				}
				break;
		}
	}
  	return 0;
}
int udhcpd_main(int argc, char **argv)
{
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1, bytes, retval, max_sock;
	struct dhcpMessage packet;
	uint8_t *state, *server_id, *requested;
	uint32_t server_id_align, requested_align, static_lease_ip;
	unsigned timeout_end;
	unsigned num_ips;
	unsigned opt;
	struct option_set *option;
	struct dhcpOfferedAddr *lease, static_lease;

	opt = getopt32(argv, "fS");
	argv += optind;

	if (!(opt & 1)) { /* no -f */
		bb_daemonize_or_rexec(0, argv);
		logmode &= ~LOGMODE_STDIO;
	}

	if (opt & 2) { /* -S */
		openlog(applet_name, LOG_PID, LOG_LOCAL0);
		logmode |= LOGMODE_SYSLOG;
	}

	/* Would rather not do read_config before daemonization -
	 * otherwise NOMMU machines will parse config twice */
	read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE);

	/* Make sure fd 0,1,2 are open */
	bb_sanitize_stdio();
	/* Equivalent of doing a fflush after every \n */
	setlinebuf(stdout);

	/* Create pidfile */
	write_pidfile(server_config.pidfile);
	/* if (!..) bb_perror_msg("cannot create pidfile %s", pidfile); */

	bb_info_msg("%s (v"BB_VER") started", applet_name);

	option = find_option(server_config.options, DHCP_LEASE_TIME);
	server_config.lease = LEASE_TIME;
	if (option) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}

	/* Sanity check */
	num_ips = server_config.end_ip - server_config.start_ip + 1;
	if (server_config.max_leases > num_ips) {
		bb_error_msg("max_leases=%u is too big, setting to %u",
			(unsigned)server_config.max_leases, num_ips);
		server_config.max_leases = num_ips;
	}

	leases = xzalloc(server_config.max_leases * sizeof(*leases));
	read_leases(server_config.lease_file);

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp)) {
		retval = 1;
		goto ret;
	}

	/* Setup the signal pipe */
	udhcp_sp_setup();

	timeout_end = monotonic_sec() + server_config.auto_time;
	while (1) { /* loop until universe collapses */

		if (server_socket < 0) {
			server_socket = listen_socket(/*INADDR_ANY,*/ SERVER_PORT,
					server_config.interface);
		}

		max_sock = udhcp_sp_fd_set(&rfds, server_socket);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - monotonic_sec();
			tv.tv_usec = 0;
		}
		retval = 0;
		if (!server_config.auto_time || tv.tv_sec > 0) {
			retval = select(max_sock + 1, &rfds, NULL, NULL,
					server_config.auto_time ? &tv : NULL);
		}
		if (retval == 0) {
			write_leases();
			timeout_end = monotonic_sec() + server_config.auto_time;
			continue;
		}
		if (retval < 0 && errno != EINTR) {
			DEBUG("error on select");
			continue;
		}

		switch (udhcp_sp_read(&rfds)) {
		case SIGUSR1:
			bb_info_msg("Received a SIGUSR1");
			write_leases();
			/* why not just reset the timeout, eh */
			timeout_end = monotonic_sec() + server_config.auto_time;
			continue;
		case SIGTERM:
			bb_info_msg("Received a SIGTERM");
			goto ret0;
		case 0: break;		/* no signal */
		default: continue;	/* signal or error (probably EINTR) */
		}

		bytes = udhcp_recv_packet(&packet, server_socket); /* this waits for a packet - idle */
		if (bytes < 0) {
			if (bytes == -1 && errno != EINTR) {
				DEBUG("error on read, %s, reopening socket", strerror(errno));
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		state = get_option(&packet, DHCP_MESSAGE_TYPE);
		if (state == NULL) {
			bb_error_msg("cannot get option from packet, ignoring");
			continue;
		}

		/* Look for a static lease */
		static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr);

		if (static_lease_ip) {
			bb_info_msg("Found static lease: %x", static_lease_ip);

			memcpy(&static_lease.chaddr, &packet.chaddr, 16);
			static_lease.yiaddr = static_lease_ip;
			static_lease.expires = 0;

			lease = &static_lease;
		} else {
			lease = find_lease_by_chaddr(packet.chaddr);
		}

		switch (state[0]) {
		case DHCPDISCOVER:
			DEBUG("Received DISCOVER");

			if (sendOffer(&packet) < 0) {
				bb_error_msg("send OFFER failed");
			}
            /* circle test Stat. add by wangpu begin */
            g_offercount ++;
            printf("Circle test: [DHCPS] send OFFER packet num:[%d]\n",g_offercount);
            memset(g_acCmd,0,sizeof(g_acCmd));
            memset(g_interface,0,sizeof(g_interface));
            sprintf(g_interface,"%s",server_config.interface);
            sprintf(g_acCmd,"echo %d > /var/circle/%s",g_offercount,g_interface);
            system(g_acCmd);
            /* circle test Stat. add by wangpu end */
			break;
		case DHCPREQUEST:
			DEBUG("received REQUEST");
			#if 0
			/* ?¡¤??2a¨º? add by wangpu begin */
			   g_offercount ++;
               printf("Circle test: [DHCPS] send OFFER packet num:[%d]\n",g_offercount);
			   memset(g_acCmd,0,sizeof(g_acCmd));
			   memset(g_interface,0,sizeof(g_interface));
			   sprintf(g_interface,"%s",server_config.interface);
			   sprintf(g_acCmd,"echo %d > /var/circle/%s",g_offercount,g_interface);
		       system(g_acCmd);
		    /* ?¡¤??2a¨º? add by wangpu begin */
            #endif
			requested = get_option(&packet, DHCP_REQUESTED_IP);
			server_id = get_option(&packet, DHCP_SERVER_ID);

			if (requested) memcpy(&requested_align, requested, 4);
			if (server_id) memcpy(&server_id_align, server_id, 4);

			if (lease) {
				if (server_id) {
					/* SELECTING State */
					DEBUG("server_id = %08x", ntohl(server_id_align));
					if (server_id_align == server_config.server && requested
					 && requested_align == lease->yiaddr
					) {
						sendACK(&packet, lease->yiaddr);
					}
				} else if (requested) {
					/* INIT-REBOOT State */
					if (lease->yiaddr == requested_align)
						sendACK(&packet, lease->yiaddr);
					else
						sendNAK(&packet);
				} else if (lease->yiaddr == packet.ciaddr) {
					/* RENEWING or REBINDING State */
					sendACK(&packet, lease->yiaddr);
				} else {
					/* don't know what to do!!!! */
					sendNAK(&packet);
				}

			/* what to do if we have no record of the client */
			} else if (server_id) {
				/* SELECTING State */

			} else if (requested) {
				/* INIT-REBOOT State */
				lease = find_lease_by_yiaddr(requested_align);
				if (lease) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} else
						sendNAK(&packet);
				} else {
					uint32_t r = ntohl(requested_align);
					if (r < server_config.start_ip
				         || r > server_config.end_ip
					) {
						sendNAK(&packet);
					}
					/* else remain silent */
				}

			} else {
				/* RENEWING or REBINDING State */
			}
			break;
		case DHCPDECLINE:
			DEBUG("Received DECLINE");
			if (lease) {
				memset(lease->chaddr, 0, 16);
				lease->expires = time(0) + server_config.decline_time;
			}
			break;
		case DHCPRELEASE:
			DEBUG("Received RELEASE");
			if (lease)
				lease->expires = time(0);
			break;
		case DHCPINFORM:
			DEBUG("Received INFORM");
			send_inform(&packet);
			break;
		default:
			bb_info_msg("Unsupported DHCP message (%02x) - ignoring", state[0]);
		}
	}
 ret0:
	retval = 0;
 ret:
	/*if (server_config.pidfile) - server_config.pidfile is never NULL */
		remove_pidfile(server_config.pidfile);
	return retval;
}
Ejemplo n.º 17
0
void SIPClient::doInviteStateMachine(unsigned responseCode) {
  // Implement the state transition diagram (RFC 3261, Figure 5)
  TaskScheduler& sched = envir().taskScheduler(); // abbrev.
  switch (fInviteClientState) {
    case Calling: {
      if (responseCode == timerAFires) {
	// Restart timer A (with double the timeout interval):
	fTimerALen *= 2;
	fTimerA
	  = sched.scheduleDelayedTask(fTimerALen, timerAHandler, this);

	fInviteClientState = Calling;
	if (!sendINVITE()) doInviteStateTerminated(0);
      } else {
	// Turn off timers A & B before moving to a new state:
	sched.unscheduleDelayedTask(fTimerA);
	sched.unscheduleDelayedTask(fTimerB);

	if (responseCode == timerBFires) {
	  envir().setResultMsg("No response from server");
	  doInviteStateTerminated(0);
	} else if (responseCode >= 100 && responseCode <= 199) {
	  fInviteClientState = Proceeding;
	} else if (responseCode >= 200 && responseCode <= 299) {
	  doInviteStateTerminated(responseCode);
	} else if (responseCode >= 400 && responseCode <= 499) {
	  doInviteStateTerminated(responseCode);
	      // this isn't what the spec says, but it seems right...
	} else if (responseCode >= 300 && responseCode <= 699) {
	  fInviteClientState = Completed;
	  fTimerD
	    = sched.scheduleDelayedTask(32000000, timerDHandler, this);
	  if (!sendACK()) doInviteStateTerminated(0);
	}
      }
      break;
    }

    case Proceeding: {
      if (responseCode >= 100 && responseCode <= 199) {
	fInviteClientState = Proceeding;
      } else if (responseCode >= 200 && responseCode <= 299) {
	doInviteStateTerminated(responseCode);
      } else if (responseCode >= 400 && responseCode <= 499) {
	doInviteStateTerminated(responseCode);
	    // this isn't what the spec says, but it seems right...
      } else if (responseCode >= 300 && responseCode <= 699) {
	fInviteClientState = Completed;
	fTimerD = sched.scheduleDelayedTask(32000000, timerDHandler, this);
	if (!sendACK()) doInviteStateTerminated(0);
      }
      break;
    }

    case Completed: {
      if (responseCode == timerDFires) {
	envir().setResultMsg("Transaction terminated");
	doInviteStateTerminated(0);
      } else if (responseCode >= 300 && responseCode <= 699) {
	fInviteClientState = Completed;
	if (!sendACK()) doInviteStateTerminated(0);
      }
      break;
    }

    case Terminated: {
	doInviteStateTerminated(responseCode);
	break;
    }
  }
}
Ejemplo n.º 18
0
ServerItem::ServerItem(SOCKET *socket, SOCKADDR_IN addr, char *message, int length)
{
	fileError = false;
	blksize = 512;
	finished = false;
	this->socket = socket;
	this->addr = addr;
	package *pac = (package *)message;
	unsigned short op = ntohs(pac->opCode);
	int i = 2;
	
	for (i = 2; i < length; i++) {
		if (message[i] == 0) {
			break;
		}
	}
	filename = (char *)malloc(i - 1);
	strcpy(filename, message + 2);
	strcpy(mode, message + 2 + strlen(filename) + 1);
	int index = 2 + strlen(filename) + 1 + strlen(mode) + 1;
	while (index < length) {
		char *x = (char *)malloc(strlen(message + index) + 1);
		index += strlen(x) + 1;
		char *y = (char *)malloc(strlen(message + index) + 1);
		index += strlen(y) + 1;
		if (strcmp(x, "blksize") == 0) {
			sscanf(y, "%d", &blksize);
		}
	}
	if (op == TFTP_OP_READ || op == TFTP_OP_WRITE) {
		string x = string();
		x.append(inet_ntoa(addr.sin_addr));
		x.append(" Client connected");
		logMessage((char *)x.c_str());
	}

	if (op == TFTP_OP_READ) {
		fp = fopen(filename, "r");
		int err = errno;
		if (fp == NULL) {
			if (err == EACCES) {
				sendErr(TFTP_ERR_ACCESS_DENIED);
			}
			else if (err == ENOENT) {
				sendErr(TFTP_ERR_FILE_NOT_FOUND);
			}
			else if (err == EEXIST) {
				sendErr(TFTP_ERR_FILE_ALREADY_EXISTS);
			}
			else {
				sendErr(TFTP_ERR_UNDEFINED);
			}
			fileError = true;
		}
		else {
			sendPackage(1);
		}
	}
	else if (op == TFTP_OP_WRITE) {
		fp = fopen(filename, "w");
		int err = errno;
		if (fp == NULL) {
			if (err == EACCES) {
				sendErr(TFTP_ERR_ACCESS_DENIED);
			}
			else if (err == ENOENT) {
				sendErr(TFTP_ERR_FILE_NOT_FOUND);
			}
			else if (err == EEXIST) {
				sendErr(TFTP_ERR_FILE_ALREADY_EXISTS);
			}
			else {
				sendErr(TFTP_ERR_UNDEFINED);
			}
			fileError = true;
		}
		else {
			sendACK(0);
			packageIndex = 0;
		}
	}
	else {
		sendErr(TFTP_ERR_UNEXPECTED_OPCODE);
	}
}
Ejemplo n.º 19
0
void CommClass::receiveMsg() {
  char buff[1024];
  unsigned char prev_char = 0;
  unsigned char curr_char = 0;
  unsigned char char_count = 0;
  unsigned char checksum = 0;
  int lastFoundIndex = 0;
  unsigned char preamble_found = 0;
  int numBytes;

  struct_message message;

  numBytes = serialPort->bytesAvailable();

  if(numBytes > 0) {
    rxTimeout = 0;

    if(numBytes > 1024)
      numBytes = 1024;

    int i = serialPort->read(buff, numBytes);

    rxMessage.append(buff,i);

/*    for (int i=0;i<rxMessage.size();i++)
      printf("CHAR: 0x%02X\n\r",(unsigned char)(rxMessage.at(i)));//qDebug() << "CHAR: " << i << ": " << rxMessage.at(i);

    qDebug() << "SIZE: " << rxMessage.size();*/
  }

  for (int i=0;i<rxMessage.size();i++) {
    curr_char = rxMessage.at(i);

    if (preamble_found) {
      if ((curr_char == COMM_CLASS_POSTAMBLE) && (message.length == (char_count - 3))){
				//qDebug("POSTAMBLE FOUND");
        if (checksum == message.checksum) {
					//qDebug("CHECKSUM OK");
          if (message.cmd == COMM_CLASS_ACK) {
					 // qDebug() << "ACK #" << ackCount++ << " RXED";
            if (txQueue.size() > 0)
              txQueue.removeFirst();  //Remove the first message in the queue

            txMsgAcked = 1;
            resendFlag = 0;
            resendCount = 0;
          }
          else if (message.cmd == COMM_CLASS_NACK) {
            resendFlag = 1;
						//qDebug("CHECKSUM FAIL");
          }
          else {
						//qDebug("ADDED MSG\n\r");

						//qDebug() << "CMD: " << message.cmd;
						//qDebug() << "LENGTH: " << message.length;
					 // for (unsigned char i=0;i<message.length;i++)
						 // qDebug() << "DATA[" << i << "]: " << message.data[i];

            rxQueue.append(message);
            sendACK();
          }

          checksum = 0;
          char_count = 0;
        }
        else {
					//qDebug("RX CHECKSUM FAIL");
          resendFlag = 1;
          resendCount = 0;
          lastFoundIndex = i;
        }

        lastFoundIndex = i;
      }
      else {
        if (char_count < (COMM_INTERFACE_DATA_LENGTH+3)) {
          switch(char_count) {
            case 0:
              message.checksum = curr_char;
              break;
          case 1:
              message.cmd = curr_char;
              checksum += curr_char;
              break;
          case 2:
              message.length = curr_char;
              checksum += curr_char;
              break;
          default:
              message.data[char_count-3] = curr_char;
              checksum += curr_char;
              break;
          }

          char_count++;
        }
        else {
          char_count = 0;
          checksum = 0;
          curr_char = 0;
        }
      }
    }
    else if ((prev_char == COMM_CLASS_PREAMBLE) && (curr_char == COMM_CLASS_PREAMBLE)) {
      preamble_found = 1;
      checksum = 0;
      char_count = 0;
    }

    prev_char = curr_char;


//      qDebug() << "Loop: " << i;
  }

  if (lastFoundIndex != 0)
    rxMessage.remove(0,lastFoundIndex+1);
}
Ejemplo n.º 20
0
int main(int argc, char *argv[])
#endif
{	
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	unsigned char *state;
	unsigned char *server_id, *requested, *hostname;
	u_int32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	int pid_fd;
	int max_sock;
	int sig;
	
	OPEN_LOG("udhcpd");
	LOG(LOG_INFO, "udhcp server (v%s) started", VERSION);

	memset(&server_config, 0, sizeof(struct server_config_t));
	
	if (argc < 2)
		read_config(DHCPD_CONF_FILE);
	else read_config(argv[1]);

	pid_fd = pidfile_acquire(server_config.pidfile);
	pidfile_write_release(pid_fd);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;
	
	leases = malloc(sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	memset(leases, 0, sizeof(struct dhcpOfferedAddr) * server_config.max_leases);

	// Added by Joey to load static lease
	if (argc>=3)
	{
		load_leases(argv[2]);
	}

	read_leases(server_config.lease_file);

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		exit_server(1);

#ifndef DEBUGGING
	pid_fd = pidfile_acquire(server_config.pidfile); /* hold lock during fork. */
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit_server(1);
	}
	pidfile_write_release(pid_fd);
#endif

	/* ensure that stdin/stdout/stderr are never returned by pipe() */
	if (fcntl(STDIN_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_RDONLY);
	if (fcntl(STDOUT_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_WRONLY);
	if (fcntl(STDERR_FILENO, F_GETFL) == -1)
		(void) open("/dev/null", O_WRONLY);

	/* setup signal handlers */
	pipe(signal_pipe);
	signal(SIGUSR1, signal_handler);
	signal(SIGTERM, signal_handler);

	timeout_end = uptime() + server_config.auto_time;
	while(1) { /* loop until universe collapses */

		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %s", strerror(errno));
				exit_server(0);
			}			

		FD_ZERO(&rfds);
		FD_SET(server_socket, &rfds);
		FD_SET(signal_pipe[0], &rfds);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - uptime();
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			max_sock = server_socket > signal_pipe[0] ? server_socket : signal_pipe[0];
			retval = select(max_sock + 1, &rfds, NULL, NULL, 
					server_config.auto_time ? &tv : NULL);
		} else retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = uptime() + server_config.auto_time;
			continue;
		} else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}
		
		if (FD_ISSET(signal_pipe[0], &rfds)) {
			if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
				continue; /* probably just EINTR */
			switch (sig) {
			case SIGUSR1:
				LOG(LOG_INFO, "Received a SIGUSR1");
				write_leases();
				/* why not just reset the timeout, eh */
				timeout_end = uptime() + server_config.auto_time;
				continue;
			case SIGTERM:
				LOG(LOG_INFO, "Received a SIGTERM");
				exit_server(0);
			}
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}
		
		server_id = get_option(&packet, DHCP_SERVER_ID);
		if (server_id) {
			memcpy(&server_id_align, server_id, 4);
			if (server_id_align != server_config.server) {
				/* client talks to somebody else */
				DEBUG(LOG_INFO,"server ID %08x doesn't match, ignoring", ntohl(server_id_align));
				continue;
			}
		}

		/* ADDME: look for a static lease */
		lease = find_lease_by_chaddr(packet.chaddr);
		switch (state[0]) {
		case DHCPDISCOVER:
			DEBUG(LOG_INFO,"received DISCOVER");
			
			if (sendOffer(&packet) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;			
 		case DHCPREQUEST:
			DEBUG(LOG_INFO, "received REQUEST");

			requested = get_option(&packet, DHCP_REQUESTED_IP);
			hostname = get_option(&packet, DHCP_HOST_NAME);

			if (requested) memcpy(&requested_align, requested, 4);
		
			if (lease) { /*ADDME: or static lease */
				if (server_id) {
					/* SELECTING State */
					if (requested && 
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
				} else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else sendNAK(&packet);
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
						else {
							/* don't know what to do!!!! */
							sendNAK(&packet);
						}
					}						
				}
				if (hostname) {
					bytes = hostname[-1];
					if (bytes >= (int) sizeof(lease->hostname))
						bytes = sizeof(lease->hostname) - 1;
					strncpy(lease->hostname, hostname, bytes);
					lease->hostname[bytes] = '\0';

					if (!is_valid_hostname(lease->hostname))
						lease->hostname[0] = '\0';

				} else
					lease->hostname[0] = '\0';
			
			/* what to do if we have no record of the client */
			} else if (server_id) {
				/* SELECTING State */
				if (requested)
					sendNAK(&packet);

			} else if (requested) {
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} else sendNAK(&packet);
				} else if (requested_align < server_config.start || 
					   requested_align > server_config.end) {
					sendNAK(&packet);
				} else {
					sendNAK(&packet);
				}
			} else if (packet.ciaddr) {
				/* RENEWING or REBINDING State */
				sendNAK(&packet);
			}
			break;
		case DHCPDECLINE:
			DEBUG(LOG_INFO,"received DECLINE");
			if (lease) {
				memset(lease->chaddr, 0, 16);
				lease->expires = uptime() + server_config.decline_time;
			}			
			break;
		case DHCPRELEASE:
			DEBUG(LOG_INFO,"received RELEASE");
			if (lease) lease->expires = uptime();
			break;
		case DHCPINFORM:
			DEBUG(LOG_INFO,"received INFORM");
			send_inform(&packet);
			break;	
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}
Ejemplo n.º 21
0
void CommClass::receiveMsg() {
  char buff[1024];
  quint8 prev_char = 0;
  quint8 curr_char = 0;
  quint8 char_count = 0;
  quint8 checksum = 0;
  qint32 lastFoundIndex = 0;
  quint8 preamble_found = 0;
  int numBytes;

  StructMessage message;

  numBytes = serialPort->bytesAvailable();

  if(numBytes > 0) {
    rxTimeout = 0;

    if(numBytes > 1024)
      numBytes = 1024;

    int i = serialPort->read(buff, numBytes);

    rxMessage.append(buff,i);
  }

  for (int i=0;i<rxMessage.size();i++) {
    curr_char = rxMessage.at(i);

    if (preamble_found) {
      if ((curr_char == COMM_CLASS_POSTAMBLE) && (message.length == (char_count - 3))){
        //qDebug("FOUND POSTAMBLE");

        if (checksum == message.checksum) {
          if (message.cmd == COMM_CLASS_ACK) {
            if (txQueue.size() > 0)
              txQueue.removeFirst();  //Remove the first message in the queue

            txMsgAcked = 1;
            resendFlag = 0;
            resendCount = 0;
          }
          else if (message.cmd == COMM_CLASS_NACK) {
            resendFlag = 1;
          }
          else {
            rxQueue.append(message);
            //qDebug("SEND ACK");
            sendACK();

            rxMessage.clear();
          }

          checksum = 0;
          char_count = 0;
        }
        else {
          resendFlag = 1;
          resendCount = 0;
          lastFoundIndex = i;
          //qDebug("CHECK FAILED");
        }

        lastFoundIndex = i;
      }
      else {
        if (char_count < (COMM_INTERFACE_DATA_LENGTH+3)) {
          switch(char_count) {
            case 0:
              message.checksum = curr_char;
              break;
          case 1:
              message.cmd = curr_char;
              checksum += curr_char;
              break;
          case 2:
              message.length = curr_char;
              checksum += curr_char;
              break;
          default:
              message.data[char_count-3] = curr_char;
              checksum += curr_char;
              break;
          }

          char_count++;
        }
        else {
          char_count = 0;
          checksum = 0;
          curr_char = 0;
        }
      }
    }
    else if ((prev_char == COMM_CLASS_PREAMBLE) && (curr_char == COMM_CLASS_PREAMBLE)) {
      preamble_found = 1;
      checksum = 0;
      char_count = 0;
    }

    prev_char = curr_char;
  }

  if (lastFoundIndex != 0)
    rxMessage.remove(0,lastFoundIndex+1);
}
Ejemplo n.º 22
0
/*
 * int linestream_receiveFrame(unsigned char *dest, unsigned maxsize)
 * receive a full frame
 * 
 */ 
int linestream_receiveFrame(unsigned char *dest, unsigned maxsize)
{
	unsigned char *dptr = dest;
	unsigned int bIn;
	unsigned int ctrl = 0;
	unsigned int checksum=0;

	state = CONTROL;

	do 
	{
		bIn = readData();

		if (bIn==HDLC_escapeFlag) 
		{
			unEscaping=1;
			continue;
		}
		if (bIn==HDLC_frameFlag && !unEscaping) 
		{
			if (inFrame) 
			{
				inFrame = 0;				
				/* Check frame type */
				if (state==CONTROL)	return -1; /* Error, no data */
				state = CONTROL;
				
				/* Checksum computation */
				if (checksum!=0) 
				{
					continue;
				}				
				
				if (!(ctrl & 0x80)) 
				{				
					/* Control frame */
					handleControl(ctrl,dest, dptr-dest);
					if (ctrl==HDLC_Control_Reset) 
					{
						/* Reset Ack frame */						
						*--dptr;
					}						
					continue;
				} 
				else 
				{
					/* Data frame */
					if ( (ctrl & 0x7) != rxSeq ) 
					{
						/* out of order */
						sendNAK();
						continue;
					}
				}
				
				/* Ack this frame */
				rxSeq++;
				rxSeq &= 0x7;

				sendACK();
				
				// removing chk
				*--dptr = '\0';				

				return dptr - dest;

			} 
			else 
			{
				/* Beginning of packet */
				inFrame = 1;
				state = CONTROL;
		    	checksum=0xaa;
			}
		} 
		else 
		{
			if (!inFrame)
                continue;
			if (unEscaping) 
			{
				bIn^=HDLC_escapeXOR;
				unEscaping=0;
			}
			checksum^=bIn;
			
			/* State processing */
			switch (state) 
			{
				case CONTROL:
					ctrl = bIn;
					state=DATA;
					break;
				case DATA:
					if (maxsize-- == 0) 
					{
						return -1;  /* Overflow */
					}
					*dptr++=bIn;
					break;
			}
		}
	} 
	while (1);
}
Ejemplo n.º 23
0
int main(int argc, char *argv[])
#endif
{	
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	unsigned char *state;
	unsigned char *server_id, *requested, *hostname;
	u_int32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	int pid_fd;
	int max_sock;
	int sig;

	/* DD-WRT (belanger) : ignore signals until we're ready */
	signal(SIGUSR1, SIG_IGN);
	signal(SIGUSR2, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGTERM, SIG_IGN);

	OPEN_LOG("udhcpd");
	LOG(LOG_INFO, "udhcp server (v%s) started", VERSION);

	memset(&server_config, 0, sizeof(struct server_config_t));

	if (argc < 2)
		read_config(DHCPD_CONF_FILE);
	else 
		read_config(argv[1]);

	pid_fd = pidfile_acquire(server_config.pidfile);
	pidfile_write_release(pid_fd);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;

	leases = malloc(sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	memset(leases, 0, sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
	read_leases(server_config.lease_file);
	read_statics(server_config.statics_file);

	/* DD-WRT (belanger) : write leases now */
	write_leases();

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		exit_server(1);

#ifndef DEBUGGING
	pid_fd = pidfile_acquire(server_config.pidfile); /* hold lock during fork. */
	if (daemon(0, 0) == -1) {
		perror("fork");
		exit_server(1);
	}
	pidfile_write_release(pid_fd);
#endif


	socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
	signal(SIGUSR1, signal_handler);
	signal(SIGUSR2, signal_handler);
	signal(SIGTERM, signal_handler);
	signal(SIGHUP, signal_handler);

	timeout_end = get_time(0) + server_config.auto_time;
	while(1) { /* loop until universe collapses */

		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %s", strerror(errno));
				exit_server(0);
			}			

		FD_ZERO(&rfds);
		FD_SET(server_socket, &rfds);
		FD_SET(signal_pipe[0], &rfds);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - get_time(0);
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			max_sock = server_socket > signal_pipe[0] ? server_socket : signal_pipe[0];
			retval = select(max_sock + 1, &rfds, NULL, NULL, 
					server_config.auto_time ? &tv : NULL);
		} 
		else 
			retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = get_time(0) + server_config.auto_time;
			continue;
		} 
		else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}
		
		if (FD_ISSET(signal_pipe[0], &rfds)) {
			if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
				continue; /* probably just EINTR */
			switch (sig) {
			case SIGUSR1:
				LOG(LOG_INFO, "Received a SIGUSR1");
				write_leases();
				/* why not just reset the timeout, eh */
				timeout_end = get_time(0) + server_config.auto_time;
				continue;
			case SIGUSR2:
				LOG(LOG_INFO, "Received a SIGUSR2");
				delete_leases();
				continue;
			case SIGHUP:
				LOG(LOG_INFO, "Received a SIGHUP");
				read_leases(server_config.lease_file);
				read_statics(server_config.statics_file);
				continue;
			case SIGTERM:
				LOG(LOG_INFO, "Received a SIGTERM");
				exit_server(0);
			}
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}

		hostname = get_option(&packet, DHCP_HOST_NAME);

		/* ADDME: look for a static lease */
		    
		/* If a hostname is supplied, and that hostname is a static lease, and that
		   static lease has an FF:FF:FF:FF:FF:FF MAC address, then use that entry. */
		if ( NULL == hostname ||
		     NULL == (lease = find_lease_by_hostname(hostname)) || 
		     (lease->expires != EXPIRES_NEVER) ||
		     0 != memcmp(lease->chaddr, MAC_BCAST_ADDR, strlen(MAC_BCAST_ADDR))) {
		  
		  /* Otherwise, look up the table using the supplied MAC address. */
		  lease = find_lease_by_chaddr(packet.chaddr);

		}

		switch (state[0]) {
		case DHCPDISCOVER:
			LOG(LOG_INFO,"received DISCOVER from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			
			if (sendOffer(&packet, lease) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;			
 		case DHCPREQUEST:
			requested = get_option(&packet, DHCP_REQUESTED_IP);
			server_id = get_option(&packet, DHCP_SERVER_ID);

			if (requested) memcpy(&requested_align, requested, 4);
			if (server_id) memcpy(&server_id_align, server_id, 4);
		
			if (requested) {
			  struct in_addr addr;
			  addr.s_addr = requested_align;
			  LOG(LOG_INFO, "received REQUEST for %s from %02x:%02x:%02x:%02x:%02x:%02x",
			      inet_ntoa(addr),
			      packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			      packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);
			}
			else {
			  LOG(LOG_INFO, "received REQUEST from %02x:%02x:%02x:%02x:%02x:%02x",
			      packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			      packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);
			}

			if (lease) { /*ADDME: or static lease */
				if (server_id) {
					/* SELECTING State */
					DEBUG(LOG_INFO, "server_id = %08x", ntohl(server_id_align));
					if (server_id_align == server_config.server && requested && 
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
					else
						sendNAK(&packet); //Sveasoft - shouldn't we let them know we don't like the request?
				} 
				else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else 
							sendNAK(&packet);
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
//						else if (!packet.ciaddr)
							/* Accept an invalid request in RENEWING state,
							   where the ciaddr should be set, but is not. */
							/* e.g. Linksys Print Server */
//							sendACK(&packet, lease->yiaddr); //note: let's not support broken stuff - Sveasoft 2005-01-19
						else {
							/* don't know what to do!!!! */
							sendNAK(&packet);
						}
					}						
				}
				if (lease->expires != EXPIRES_NEVER) {
					/* Don't change hostname of static leases */
					if (hostname) {
						bytes = hostname[-1];
						if (bytes >= (int) sizeof(lease->hostname))
							bytes = sizeof(lease->hostname) - 1;
						strncpy(lease->hostname, hostname, bytes);
							lease->hostname[bytes] = '\0';
					} else
						lease->hostname[0] = '\0';
				}
			
			/* what to do if we have no record of the client */
			} 
			else if (server_id) {
				/* SELECTING State */
				sendNAK(&packet);       // by honor

			} 
			else if (requested) {
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} 
					else 
						sendNAK(&packet);
				} 
				else if (requested_align < server_config.start || 
					 requested_align > server_config.end) {
					sendNAK(&packet);
				} 
				else {
					sendNAK(&packet);
				}

			} 
			else if (packet.ciaddr) {

				/* RENEWING or REBINDING State */
				sendNAK(&packet);
			}
			break;
		case DHCPDECLINE:
			LOG(LOG_INFO,"received DECLINE from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			if (lease && lease->expires != EXPIRES_NEVER) {
				memset(lease->chaddr, 0, 16);
				lease->expires = get_time(0) + server_config.decline_time;
			}			
			break;
		case DHCPRELEASE:
			LOG(LOG_INFO,"received RELEASE from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			if (lease && lease->expires != EXPIRES_NEVER) 
				lease->expires = get_time(0);
			break;
		case DHCPINFORM:
			LOG(LOG_INFO,"received INFORM from %02x:%02x:%02x:%02x:%02x:%02x",
			    packet.chaddr[0], packet.chaddr[1], packet.chaddr[2], 
			    packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);	// modify by honor
			send_inform(&packet);
			break;	
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}
Ejemplo n.º 24
0
int main(int argc, char *argv[])
#endif
{
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	uint8_t *state;
	uint8_t *server_id, *requested;
	uint32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	struct dhcpOfferedAddr static_lease;
	int max_sock;
	unsigned long num_ips;

	uint32_t static_lease_ip;
	
	memset(&server_config, 0, sizeof(struct server_config_t));
	read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);

	/* Start the log, sanitize fd's, and write a pid file */
	start_log_and_pid("udhcpd", server_config.pidfile);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;

	/* it is not impossible */
	if (server_config.end < server_config.start)
	{
		uint32_t tmp_ip = server_config.start;
		server_config.start = server_config.end ;
		server_config.end = tmp_ip;
	}
	
	/* Sanity check */
	num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1;
	if (server_config.max_leases > num_ips) {
		LOG(LOG_ERR, "max_leases value (%lu) not sane, "
			"setting to %lu instead",
			server_config.max_leases, num_ips);
		server_config.max_leases = num_ips;
	}

	if (dhcps_shm_init() != 0)
		return -1;
	
	leases = xcalloc(server_config.max_leases, sizeof(struct dhcpOfferedAddr));
	memset(leases, 0, server_config.max_leases * sizeof(struct dhcpOfferedAddr));

	//read_leases(server_config.lease_file);

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		return 1;

#ifndef UDHCP_DEBUG
	background(server_config.pidfile); /* hold lock during fork. */
#endif

	/* Setup the signal pipe */
	udhcp_sp_setup();

	timeout_end = uptime()/*time(0)*/ + server_config.auto_time;
	while(1) { /* loop until universe collapses */		
		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %m");
				return 2;
			}

		max_sock = udhcp_sp_fd_set(&rfds, server_socket);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - uptime()/*time(0)*/;
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			retval = select(max_sock + 1, &rfds, NULL, NULL,
					server_config.auto_time ? &tv : NULL);
		} else retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = uptime()/*time(0)*/ + server_config.auto_time;
			continue;
		} else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}

		switch (udhcp_sp_read(&rfds)) {
		case SIGUSR1:
			LOG(LOG_INFO, "Received a SIGUSR1");
			
			write_leases();
			/* why not just reset the timeout, eh */
			timeout_end = uptime()/*time(0)*/ + server_config.auto_time;
			continue;
		case SIGUSR2:
			LOG(LOG_INFO, "Received a SIGUSR2, now DHCP SERVER restart");
			
			if (execv(argv[0], argv) == -1)
				printf("errno:%d\n", errno);
			/* NEVER reach here except execv failed! */			
			break;
		case SIGTERM:
			LOG(LOG_INFO, "Received a SIGTERM");
			
			return 0;
		case 0: break;		/* no signal */
		default: continue;	/* signal or error (probably EINTR) */
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %m, reopening socket");
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}

		//printBuf(&packet, sizeof(struct dhcpMessage));
		
		lease = find_lease_by_chaddr(packet.chaddr);

		if (!lease)
		{
			/* Look for a static lease */
			static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr);

			/* found */
			if(static_lease_ip)
			{
				memcpy(&static_lease.chaddr, &packet.chaddr, 16);
				static_lease.yiaddr = static_lease_ip;
				static_lease.expires = 0;

				lease = &static_lease;
			}
			/*
			else
			{
				lease = find_lease_by_chaddr(packet.chaddr);
			}
			*/
		}
		
		
		switch (state[0]) {
		case DHCPDISCOVER:
			//DEBUG(LOG_INFO,"received DISCOVER");
			msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:Recv DISCOVER from %02X:%02X:%02X:%02X:%02X:%02X", packet.chaddr[0],
				packet.chaddr[1], packet.chaddr[2], packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);

			if (sendOffer(&packet) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;
 		case DHCPREQUEST:
			//DEBUG(LOG_INFO, "received REQUEST");			
			msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:Recv REQUEST from %02X:%02X:%02X:%02X:%02X:%02X", packet.chaddr[0],
							packet.chaddr[1], packet.chaddr[2], packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);

			requested = get_option(&packet, DHCP_REQUESTED_IP);
			server_id = get_option(&packet, DHCP_SERVER_ID);

			if (requested) memcpy(&requested_align, requested, 4);
			if (server_id) memcpy(&server_id_align, server_id, 4);

			if (lease) {
				if (server_id) {
					/* SELECTING State */
					DEBUG(LOG_INFO, "server_id = %08x", ntohl(server_id_align));
					if (server_id_align == server_config.server && requested &&
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
					else 
					{
						msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:Wrong Server id or request an invalid ip");
						sendNAK(&packet);
					}
				} else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else 
						{
							msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:Server id not found and request an invalid ip");
							sendNAK(&packet);
						}
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
						else {
							/* don't know what to do!!!! */
							msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:Server id and requested ip not found");
							msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:%x %x", lease->yiaddr, packet.ciaddr);
							sendNAK(&packet);
						}
					}
				}

			/* what to do if we have no record of the client */
			} else if (server_id) {
				/* SELECTING State */

			}
			else if (requested) 
			{
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) 
				{
					/* Requested IP already reserved by other one */
					
					if (lease_expired(lease))
					{
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);

						check_and_ack(&packet, requested_align);
					/* make some contention for this address */
					} 
					else	/* still reserved by someone */
					{
						msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:REQUEST ip %x already reserved by %02X:%02X:%02X:%02X:%02X:%02X",
							requested_align, lease->chaddr[0], lease->chaddr[1], lease->chaddr[2],
							lease->chaddr[3], lease->chaddr[4], lease->chaddr[5]);
						sendNAK(&packet);
					}
				}
				else /*if (requested_align < server_config.start ||
					   requested_align > server_config.end)*/ 
				{
					check_and_ack(&packet, requested_align);
				} /* else remain silent */
			} 
			else 
			{
                /* error state, just reply NAK modified by tiger 20090927 */
                 sendNAK(&packet);
			}
			break;
		case DHCPDECLINE:
			//DEBUG(LOG_INFO,"received DECLINE");
			msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:Recv DECLINE from %02X:%02X:%02X:%02X:%02X:%02X", packet.chaddr[0],
										packet.chaddr[1], packet.chaddr[2], packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);
			
			if (lease) {
				memset(lease->chaddr, 0, 16);
				lease->expires = uptime()/*time(0)*/ + server_config.decline_time;
			}
			break;
		case DHCPRELEASE:
			//DEBUG(LOG_INFO,"received RELEASE");			
			msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:Recv RELEASE from %02X:%02X:%02X:%02X:%02X:%02X", packet.chaddr[0],
										packet.chaddr[1], packet.chaddr[2], packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);
			if (lease)
			{
				/* Delete the lease, lsz 080221 */
				#if 1
				memset(lease, 0, sizeof(struct dhcpOfferedAddr));
				#else
				lease->expires = uptime()/*time(0)*/;
				#endif
			}
			
			break;
		case DHCPINFORM:
			//DEBUG(LOG_INFO,"received INFORM");
			msglogd(LOG_INFO, LOGTYPE_DHCP, "DHCPS:Recv INFORM from %02X:%02X:%02X:%02X:%02X:%02X", packet.chaddr[0],
										packet.chaddr[1], packet.chaddr[2], packet.chaddr[3], packet.chaddr[4], packet.chaddr[5]);
			send_inform(&packet);
			break;
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}
Ejemplo n.º 25
0
int main(int argc, char *argv[])
#endif
{
	fd_set rfds;
	struct timeval tv;
	int server_socket = -1;
	int bytes, retval;
	struct dhcpMessage packet;
	uint8_t *state;
	uint8_t *server_id, *requested;
	uint8_t *hostname;
	uint32_t server_id_align, requested_align;
	unsigned long timeout_end;
	struct option_set *option;
	struct dhcpOfferedAddr *lease;
	struct dhcpOfferedAddr static_lease;
	int max_sock;
	unsigned long num_ips;

	uint32_t static_lease_ip;

	memset(&server_config, 0, sizeof(struct server_config_t));
	read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);
	read_config_static_leases(DHCPD_STATIC_LEASES_FILE);

	/* Start the log, sanitize fd's, and write a pid file */
	start_log_and_pid("udhcpd", server_config.pidfile);

	if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
		memcpy(&server_config.lease, option->data + 2, 4);
		server_config.lease = ntohl(server_config.lease);
	}
	else server_config.lease = LEASE_TIME;

	/* Sanity check */
	num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1;
	if (server_config.max_leases > num_ips) {
//		LOG(LOG_ERR, "max_leases value (%lu) not sane, "
//			"setting to %lu instead",
//			server_config.max_leases, num_ips);
		server_config.max_leases = num_ips;
	}

	leases = xcalloc(server_config.max_leases, sizeof(struct dhcpOfferedAddr));
	read_leases(server_config.lease_file);

	if (read_interface(server_config.interface, &server_config.ifindex,
			   &server_config.server, server_config.arp) < 0)
		return 1;

#ifndef UDHCP_DEBUG
	background(server_config.pidfile); /* hold lock during fork. */
#endif

	/* Setup the signal pipe */
	udhcp_sp_setup();

	timeout_end = time(0) + server_config.auto_time;
	while(1) { /* loop until universe collapses */

		if (server_socket < 0)
			if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
				LOG(LOG_ERR, "FATAL: couldn't create server socket, %m");
				return 2;
			}

		max_sock = udhcp_sp_fd_set(&rfds, server_socket);
		if (server_config.auto_time) {
			tv.tv_sec = timeout_end - time(0);
			tv.tv_usec = 0;
		}
		if (!server_config.auto_time || tv.tv_sec > 0) {
			retval = select(max_sock + 1, &rfds, NULL, NULL,
					server_config.auto_time ? &tv : NULL);
		} else retval = 0; /* If we already timed out, fall through */

		if (retval == 0) {
			write_leases();
			timeout_end = time(0) + server_config.auto_time;
			continue;
		} else if (retval < 0 && errno != EINTR) {
			DEBUG(LOG_INFO, "error on select");
			continue;
		}

		switch (udhcp_sp_read(&rfds)) {
		case SIGUSR1:
			LOG(LOG_INFO, "Received a SIGUSR1");
			write_leases();
			/* why not just reset the timeout, eh */
			timeout_end = time(0) + server_config.auto_time;
			continue;
		case SIGTERM:
			LOG(LOG_INFO, "Received a SIGTERM");
			return 0;
		case 0: break;		/* no signal */
		default: continue;	/* signal or error (probably EINTR) */
		}

		if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
			if (bytes == -1 && errno != EINTR) {
				DEBUG(LOG_INFO, "error on read, %m, reopening socket");
				close(server_socket);
				server_socket = -1;
			}
			continue;
		}

		if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
			DEBUG(LOG_ERR, "couldn't get option from packet, ignoring");
			continue;
		}

		/* Look for a static lease */
		static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr);

		if(static_lease_ip)
		{
			printf("Found static lease: %x\n", static_lease_ip);

			memcpy(&static_lease.chaddr, &packet.chaddr, 16);
			static_lease.yiaddr = static_lease_ip;
			static_lease.expires = 0;

			lease = &static_lease;

		}
		else
		{
		lease = find_lease_by_chaddr(packet.chaddr);
		}

		switch (state[0]) {
		case DHCPDISCOVER:
			DEBUG(LOG_INFO,"received DISCOVER");

			if (sendOffer(&packet) < 0) {
				LOG(LOG_ERR, "send OFFER failed");
			}
			break;
 		case DHCPREQUEST:
			DEBUG(LOG_INFO, "received REQUEST");

			requested = get_option(&packet, DHCP_REQUESTED_IP);
			server_id = get_option(&packet, DHCP_SERVER_ID);
			hostname = get_option(&packet, DHCP_HOST_NAME);
			if (requested) memcpy(&requested_align, requested, 4);
			if (server_id) memcpy(&server_id_align, server_id, 4);

			if (lease) {
				if (server_id) {
					/* SELECTING State */
					DEBUG(LOG_INFO, "server_id = %08x", ntohl(server_id_align));
					if (server_id_align == server_config.server && requested &&
					    requested_align == lease->yiaddr) {
						sendACK(&packet, lease->yiaddr);
					}
				} else {
					if (requested) {
						/* INIT-REBOOT State */
						if (lease->yiaddr == requested_align)
							sendACK(&packet, lease->yiaddr);
						else sendNAK(&packet);
					} else {
						/* RENEWING or REBINDING State */
						if (lease->yiaddr == packet.ciaddr)
							sendACK(&packet, lease->yiaddr);
						else {
							/* don't know what to do!!!! */
							sendNAK(&packet);
						}
					}
				}
				if (hostname) {
					bytes = hostname[-1];
					if (bytes >= (int) sizeof(lease->hostname))
						bytes = sizeof(lease->hostname) - 1;
					strncpy(lease->hostname, hostname, bytes);
					lease->hostname[bytes] = '\0';
				} else
					lease->hostname[0] = '\0';

			/* what to do if we have no record of the client */
			} else if (server_id) {
				/* SELECTING State */

			} else if (requested) {
				/* INIT-REBOOT State */
				if ((lease = find_lease_by_yiaddr(requested_align))) {
					if (lease_expired(lease)) {
						/* probably best if we drop this lease */
						memset(lease->chaddr, 0, 16);
					/* make some contention for this address */
					} else sendNAK(&packet);
				} else if (requested_align < server_config.start ||
					   requested_align > server_config.end) {
					sendNAK(&packet);
				} /* else remain silent */

			} else {
				 /* RENEWING or REBINDING State */
			}
			break;
		case DHCPDECLINE:
			DEBUG(LOG_INFO,"received DECLINE");
			if (lease) {
				memset(lease->chaddr, 0, 16);
				lease->expires = time(0) + server_config.decline_time;
			}
			break;
		case DHCPRELEASE:
			DEBUG(LOG_INFO,"received RELEASE");
			if (lease) lease->expires = time(0);
			break;
		case DHCPINFORM:
			DEBUG(LOG_INFO,"received INFORM");
			send_inform(&packet);
			break;
		default:
			LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]);
		}
	}

	return 0;
}
Ejemplo n.º 26
0
void NetGuard_DHCPD::packet_in(struct user_data *u_data, int *mode, unsigned int *vlanid, struct tpacket_hdr *h, struct ether_header *eth, struct iphdr *ip, struct tcphdr *tcp, void *data)
{
	if (!security) {
		ng_logerror_buff(0,"missing Security Module!");
		exit(-1);
		return;
	}

	//we only want it once
	if (*mode == TRAFFIC_INCOMING || *mode == TRAFFIC_OUTGOING ) return;
	//if (!(*mode == TRAFFIC_OUTGOING )) return;

	if (eth->ether_type != htons_ETHERTYPE_IP) return; //only ip
	if (ip->protocol!=IPPROTO_UDP) return; //udp only
	if (ntohs(tcp->dest) != LISTEN_PORT) return; //only the dhcpd port

	if ((ip->daddr != zero_ip) && (ip->daddr != ntohl(my_ip)) && (ip->daddr != b_ip)) return; //only send to us
	//if ((ip->saddr != zero_ip)) return; //only send from zero ip

	//so we got an dhcp package it seams like dest and port is correct

	struct dhcpMessage *packet;
	//void *data2 = data; //it crashes else?
	packet = (struct dhcpMessage *)((char*)data-12);  //TODO check why 12?! crashes?
	unsigned char *state; //, *hw_addr;
	unsigned char *server_id;


	if(htonl(packet->cookie) != MAGIC) {
		ng_logdebug_spam("ignoring dhcp message with wrong cookie %x",htonl(packet->cookie));
		return;
	}

	ng_logdebug_spam("got package -- processing");
	char *tmpstr = (char*)malloc(5000);
	sprint_package(tmpstr,vlanid,h,eth,ip,tcp,data);
	ng_logdebug_spam("%s",tmpstr);
	free(tmpstr);
	tmpstr = (char*)malloc(5000);
	sprint_dhcp_package(tmpstr,packet);
	ng_logdebug_spam("%s",tmpstr);
	free(tmpstr);
	

	if((state = getOption(packet->options, DHCP_MESSAGE_TYPE)) == NULL) {
		ng_logdebug_spam("couldnt get option from packet (MSG_TYPE) -- ignoring");
		return;
	}

	sec_data_idx idx;
	memcpy(&idx.hw_addr,&eth->ether_shost,sizeof(mac_addr));
	idx.vlan_id = (*vlanid);
	user_data *m_u_data = (user_data *)security->get_data(&idx);

	u_int32_t offerip;
	//lets see if we can find the ip to offer
	if (!m_u_data) {
		ng_logdebug("got client message - but we dont have any known user for that mac %02x:%02x:%02x:%02x:%02x:%02x in vlan %d",printf_mac_params(eth->ether_shost),(*vlanid));
		return; //todo look at port etc
	}
	offerip = m_u_data->saddr;

/*
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message Option 53, length 1: Request
            CLASS Option 77, length 14: "RRAS.Microsoft"
            Client-ID Option 61, length 17: ether 52:41:53:20:00:14:0b:3b:43:00:00:00:01:00:00:00
            Requested-IP Option 50, length 4: 141.30.225.74
            Server-ID Option 54, length 4: 141.30.225.1
            Hostname Option 12, length 7: "Lins-PC"
            FQDN Option 81, length 10: [N] "Lins-PC"
            Vendor-Class Option 60, length 8: "MSFT 5.0"
            Parameter-Request Option 55, length 12:
              Subnet-Mask, Domain-Name, Default-Gateway, Domain-Name-Server
              Netbios-Name-Server, Netbios-Node, Netbios-Scope, Router-Discovery
              Static-Route, Classless-Static-Route, Classless-Static-Route-Microsoft, Vendor-Option

          Client-Ethernet-Address 08:10:75:0a:3a:33
          Vendor-rfc1048 Extensions
            Magic Cookie 0x63825363
            DHCP-Message Option 53, length 1: Request
            Client-ID Option 61, length 7: ether 08:10:75:0a:3a:33
            Hostname Option 12, length 9: "Routerata"
            Domain-Name Option 15, length 12: "RouterDomain"
            FQDN Option 81, length 13: "Routerata."
            Vendor-Class Option 60, length 8: "MSFT 5.0"
            Requested-IP Option 50, length 4: 141.30.225.42
            Subnet-Mask Option 1, length 4: 255.255.255.0
            Default-Gateway Option 3, length 4: 141.30.225.1
            Domain-Name-Server Option 6, length 8: 141.30.225.3,141.30.66.135
            Server-ID Option 54, length 4: 141.30.225.1
            Parameter-Request Option 55, length 11:
              Subnet-Mask, Domain-Name, Default-Gateway, Domain-Name-Server
              Netbios-Name-Server, Netbios-Node, Netbios-Scope, Router-Discovery
              Static-Route, Classless-Static-Route-Microsoft, Vendor-Option

*/

	unsigned char *host = getOption(packet->options, 12);
	unsigned int hostl = getOptionLength(packet->options, 12);
	unsigned char *fqdn = getOption(packet->options, 15);
	unsigned int fqdnl = getOptionLength(packet->options, 15);
	unsigned char *vendor = getOption(packet->options, 60);
	unsigned int vendorl = getOptionLength(packet->options, 60);
	unsigned char *dclass = getOption(packet->options, 77);
	unsigned int dclassl = getOptionLength(packet->options, 77);
	if (vendor != NULL)
	{
		if (strlen((const char*)vendor) == strlen("Adobe Flash Proxy Auto-Discovery"))
		{
			if (strncmp("Adobe Flash Proxy Auto-Discovery",(const char*)vendor,strlen("Adobe Flash Proxy Auto-Discovery")))	{

				ng_logdebug_spam("ignoring Adobe Flash Proxy Auto-Discovery");
				return;
			}
		}
	}
	ng_log_ext_buff(0,500,"offer %s to mac %02x:%02x:%02x:%02x:%02x:%02x - host:%.*s fqdn: %.*s vendor:%.*s class:%.*s", inet_ntoa(*(struct in_addr *)&offerip),printf_mac_params(eth->ether_shost),hostl,host,fqdnl,fqdn,vendorl,vendor,dclassl,dclass);

	int client_socket;
	if((client_socket = clientSocket(LISTEN_PORT, SEND_PORT)) == -1) {
		//syslog(LOG_ERR, "couldn't create client socket -- i'll try again");
		return;
	}

	struct ifreq intf;
	//syslog(LOG_INFO, "Binding to interface '%s'\n", interface_name);
	bzero(&intf, sizeof(intf));
	strncpy(intf.ifr_name, interface_name.c_str(), IFNAMSIZ);
	if (setsockopt(client_socket, SOL_SOCKET, SO_BINDTODEVICE, &intf, sizeof(intf)) < 0)
	{
		//syslog(LOG_INFO, "setsockopt(SO_BINDTODEVICE) %d\n", errno);
		close(client_socket);
		return;
	};

	switch(state[0]) {
		case DHCPDISCOVER:
			ng_logdebug_spam("received DISCOVER");
			if(sendOffer(client_socket, packet,offerip,subnet_ip,my_ip,dns_ip1,dns_ip2,wins_ip) == -1) {
				ng_logerror("send OFFER failed -- ignoring");
			} else 	ng_logdebug_spam("send sendOffer");
			break;
		case DHCPREQUEST:
			ng_logdebug_spam("received DHCPREQUEST");
			//syslog(LOG_INFO,"received REQUEST");
			server_id = getOption(packet->options, 0x36);
			if(server_id == NULL) {
				ng_logdebug("get option on 0x36 failed! NAKing");
				sendNAK(client_socket, packet,my_ip);
				/* Let's send an offer as well */
				if(sendOffer(client_socket, packet,offerip,subnet_ip,my_ip,dns_ip1,dns_ip2,wins_ip) == -1) {
					ng_logerror("send OFFER failed -- ignoring");
				}
			} else {
				ng_logdebug_spam("server_id = %02x%02x%02x%02x", server_id[0], server_id[1],server_id[2], server_id[3]);
				if(memcmp(server_id, (char *)&my_ip, 4) == 0) {
					ng_logdebug_spam("sending ACK - server_id matched");
					if (sendACK(client_socket, packet,offerip,subnet_ip,my_ip,dns_ip1,dns_ip2,wins_ip) == -1) {
						ng_logdebug("send ACK failed - sending NAK");
						sendNAK(client_socket, packet,my_ip);
					} else {
						ng_logdebug_spam("send ACK");
					}
				} else {
					ng_logdebug_spam("sending NAK - server_id missmatch");
					sendNAK(client_socket,packet,my_ip);
				}
			}
			break;
		default:
			ng_logdebug("unsupported DHCP message (%02x) -- ignoring",state[0]);
			break;
	}
	close(client_socket);
}
Ejemplo n.º 27
0
int main(int argc, char *argv[])
{
  int sockfd, portno, n;
  struct sockaddr_in serv_addr, sdr_addr; 
  socklen_t addrlen;
	int payloadSize = 1000;
	char packet[packetSize];
	char *filename;
	FILE *f;
	void *file;

  if(argc != 3) { 
    fprintf(stderr,"Usage: %s <port> <filename>\n", argv[0]);
    return 1;
  } 
	filename = argv[2];
	f = fopen(filename,"wb");
	if(f==NULL) syserr("cannot open file for writing");

  portno = atoi(argv[1]);

  sockfd = socket(AF_INET, SOCK_DGRAM, 0); 
  if(sockfd < 0) syserr("can't open socket"); 

  memset(&serv_addr, 0, sizeof(serv_addr));
  serv_addr.sin_family = AF_INET;
  serv_addr.sin_addr.s_addr = INADDR_ANY;
  serv_addr.sin_port = htons(portno);

  if(bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) 
    syserr("can't bind");
  addrlen = sizeof(sdr_addr); 

	int numPackets;
	int packetsReceived = 0;
	int bytes_remaining;
	uint32_t fileSize;
	fd_set set;
	struct timeval tv;
	FD_ZERO(&set);
	FD_SET(sockfd,&set);
	n = select(sockfd+1,&set,NULL,NULL,NULL);
	head = malloc(sizeof(struct filepackets));
	head->next = NULL;
	tail = head;
	while(1){
		memset(packet,0,sizeof(packet));
		FD_ZERO(&set);
		FD_SET(sockfd,&set);
		tv.tv_sec = 5;
		tv.tv_usec = 0;
		n = select(sockfd+1,&set,NULL,NULL,&tv);
		if(n==0) break;
		n = receivePacket(sockfd,packet,sizeof(packet),(struct sockaddr*)&sdr_addr,addrlen);
		if(n<0) syserr ("failed to receive packet\n");
		if(n>0){
			void *offset = packet;
			uint32_t seq_num;
			uint32_t seq_num_in;
			memcpy(&seq_num_in,offset,sizeof(uint32_t));
			seq_num = ntohl(seq_num_in);
			int alr_recvd;
			if(!rfp && seq_num == 0){
				offset+=sizeof(uint32_t);
				offset+=sizeof(uint16_t);
				uint32_t sizeIn;
				memcpy(&sizeIn,offset,sizeof(uint32_t));
				fileSize = ntohl(sizeIn);
				bytes_remaining = fileSize;
				FD_ZERO(&set);
				FD_SET(sockfd,&set);
				n = select(sockfd+1,NULL,&set,NULL,NULL);
				sendACK((int)seq_num,sockfd,(struct sockaddr*)&sdr_addr,addrlen);
				numPackets = fileSize/payloadSize;
				if(fileSize%payloadSize!=0) numPackets++;
				printf("filesize: %d\nexpecting %d packets\n",fileSize,numPackets);
				packetsReceived++;
				file = malloc(fileSize);
				receivedPackets = malloc(sizeof(int)*numPackets);
				memset(receivedPackets,0,sizeof(int)*numPackets);
				receivedPackets[seq_num] = seq_num;
				head->seq_num = seq_num;
				rfp = 1;
			}
			else if(!alreadyReceived(seq_num)){
				head->next = malloc(sizeof(struct filepackets));
				head = head->next;
				head->seq_num = seq_num;
				offset+=sizeof(uint32_t);
				offset+=sizeof(uint16_t);
				char payload[payloadSize];
				memcpy(payload,offset,payloadSize);
				offset = file;
				offset+=((seq_num-1)*payloadSize);
				if(bytes_remaining < payloadSize){
					memcpy(offset,payload,bytes_remaining);
					bytes_remaining-=bytes_remaining;
				}
				else{
					memcpy(offset,payload,payloadSize);
					bytes_remaining-=payloadSize;
				}
				FD_ZERO(&set);
				FD_SET(sockfd,&set);
				n = select(sockfd+1,NULL,&set,NULL,NULL);
				n = sendACK((int)seq_num,sockfd,(struct sockaddr*)&sdr_addr,addrlen);
				if(n<0) printf("ERROR\n");
				if(n==0) printf("ERROR\n");
				receivedPackets[seq_num] == seq_num;
				packetsReceived++;
				//printf("Received packet %d\n",seq_num);
				//printf("%d bytes remaining to be received\n",bytes_remaining);
				if(packetsReceived%1000==0) printf("%d packets received\n",packetsReceived);
			}
			else{
				FD_ZERO(&set);
				FD_SET(sockfd,&set);
				n = select(sockfd+1,NULL,&set,NULL,NULL);
				n = sendACK((int)seq_num,sockfd,(struct sockaddr*)&sdr_addr,addrlen);
			}
		}
	}
	printf("filesize: %d\nexpecting %d packets\n",fileSize,numPackets);
	printf("Transmission complete... %d packets received.\n",packetsReceived);
	n = fwrite(file,fileSize,1,f);
	if(n<0) syserr("cannot write file");
	fclose(f);
  close(sockfd); 
  return 0;
}