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); }
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); }
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(); } }
//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"; } }
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; }
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; }
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; }
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; }
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); }
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; } }
//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(); }
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; }
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; }
// 这是由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; }
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; } } }
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); } }
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); }
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; }
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); }
/* * 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); }
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; }
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; }
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; }
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,ð->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); }
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; }