static int send_rcv(int opcode, int size) { //COMENTDEBUG //printf("sending rcv\n"); int s = requestConnection(&c); int qtyrec, qtysent; p.opc = opcode; qtysent = sendPacket(&c, &p, size + sizeof(opcode)); qtyrec = receivePacket(&c, &p, sizeof(PACKET)); endConnection(&c); int ret_opcode = p.opc; if(ret_opcode = RET_CURAR) { //COMENTDEBUG //printf("pokemones curados\n"); } return qtyrec - sizeof ( OPC ); }
int receiveFile(int fd, char* out_imagename, char** out_imagebuffer, unsigned int* out_image_buffer_length, unsigned int* out_already_received_imgbytes) { char* packet; int sizePacket; unsigned int infoSize; unsigned char N = 0; char fileName[255]; unsigned char fileNameSize; unsigned int fileSize; if (receivePacket(fd, &packet, &sizePacket) == OK) { if (packet[0] != CS) return -1; if (packet[1] != TSIZE) return -1; unsigned char sizeFileSize = packet[2]; fileSize = 0; unsigned int multiply = 1; unsigned int i; for (i = 0; i < sizeFileSize; i++) { //printf("\n>>> %u\n", ((unsigned int)packet[3 + i])); /*char to uint faz signal extend!!!*/ fileSize += (0x00ff&((unsigned int)packet[3 + i])) * multiply; multiply *= 256; } //return -1; *out_already_received_imgbytes = 0; *out_image_buffer_length = fileSize; *out_imagebuffer = (char*)malloc(fileSize); DEBUG_SECTION(DEBUG_RECEIVE_STEPS, printf("\nfileSize: %d\n", fileSize);); if (packet[3 + sizeFileSize] != TNAME)return -1; fileNameSize = packet[4 + sizeFileSize]; for (i = 0; i < fileNameSize; i++) fileName[i] = packet[5 + sizeFileSize + i]; memmove(out_imagename, fileName, (int) fileNameSize); out_imagename[(int)((int)fileNameSize>255 ? 255 : fileNameSize)] = 0;//some extra precaution DEBUG_SECTION(DEBUG_RECEIVE_STEPS, printf("\nfileName: %s\n", out_imagename););
void GameCore::run() { sf::Time elapsed; if (!_network->initSocket()) return ; _clock.restart(); while (_running) { _clockAlive.restart(); this->updateMap(); while (_running && ((elapsed = getElapsedTimeSinceLoop()) > sf::microseconds(0))) { receivePacket(); } if (_firstClient) this->updateAliveClients(_clockAlive.getElapsedTime()); } _mutex->LockMutex(); *_end = true; _mutex->UnlockMutex(); }
__interrupt void PORT2 (void) { char res ; // CRC Check if (P2IFG & 0x01) // Check P2IFG Bit P2.0 - CC1100 Rx Packet { CLEAR(P2IFG, 0x01); LEDTOGGLE; res = receivePacket(); // CRC Rückgabe if (res) // wenn Packet OK ... { printPacket(); // Packet auf Terminal ausgeben } else { spiStrobe(CC1100_SIDLE); // Switch to IDLE spiStrobe(CC1100_SFRX); // Flush the RX FIFO } } else { CLEAR(P2IFG, 0xFF); // Clear all flags } spiStrobe(CC1100_SRX); // Switch to RX Mode }
//----------------------------------------------------------------------------- // Test if *portName is the correct serial port //----------------------------------------------------------------------------- bool testPort(char *portName) { printf("Trying to open %s\n", portName); serial_fd = serialport_init(portName, 115200); sleep_ms(500); if (serial_fd < 0) return 0; for (int i = 0; i < 5; i++) //try at least 5 times { sendPacket(); sleep_ms(400); if (receivePacket()) { close(serial_fd); return 1; } sleep_ms(30); } printf("The port didn't respond properly\n"); close(serial_fd); return 0; }
int ActuatorSvcHandler::open(void *arg) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%T)INFO: ActuatorSvcHandler::open\n"))); int ret = PacketChannel<SthenoStreamPacket, SthenoStreamHeader, //DiscoveryPacketFactory, ACE_SOCK_Stream, ACE_MT_SYNCH>::open(arg); if (ret == -1) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%T)INFO: ActuatorSvcHandler::open failed\n"))); return -1; } //ACE_Time_Value receiveTimeout(0, MAX_OPEN_TIMEOUT_MS * 1000); ACE_Time_Value receiveTimeout; receiveTimeout.msec(MAX_OPEN_TIMEOUT_MS); SthenoStreamPacket* recvPacket = 0; receivePacket(recvPacket, &receiveTimeout); if (recvPacket == 0) { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t|%T)INFO: ActuatorSvcHandler::open - no init packet\n"))); return -1; } switch (recvPacket->getPacketHeader()->getType()) { case InitSessionPacket::INIT_SESSION_PACKET_OP: { InitSessionPacket* initSessionPacket = static_cast<InitSessionPacket*> (recvPacket); m_pid = initSessionPacket->getUUID(); ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t|%T)INFO: ActuatorSvcHandler::open - PID=%s\n"), m_pid->toString().c_str())); m_fid = initSessionPacket->getFID(); ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t|%T)INFO: ActuatorSvcHandler::open - OK PID=%s\n"), m_pid->toString().c_str())); return 0; } default: { ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t|%T)ERROR: ActuatorSvcHandler::open() - processJoinCell packet not known, calling close()\n"))); close(); return -1; } } }
__interrupt void ISR_Port2 (void) { char res ; // CRC Check if (P2IFG & 0x01) // Check P2IFG Bit P2.0 - CC1100 Rx Packet { CLEAR(P2IFG, 0x01); res = receivePacket(); // CRC Rückgabe if (res) // wenn Packet OK ... { // wenn ein Packet Empfangen wurde die Ausgabe // einleiten do_output=1; } else { spiStrobe(CC1100_SIDLE); // Switch to IDLE spiStrobe(CC1100_SFRX); // Flush the RX FIFO } } else { CLEAR(P2IFG, 0xFF); // Clear all flags } spiStrobe(CC1100_SRX); // Switch to RX Mode }
/********************************************************************** *%FUNCTION: waitForPADS *%ARGUMENTS: * conn -- PPPoE connection info * timeout -- how long to wait (in seconds) *%RETURNS: * Nothing *%DESCRIPTION: * Waits for a PADS packet and copies useful information ***********************************************************************/ static void waitForPADS(PPPoEConnection *conn, int timeout) { fd_set readable; int r; struct timeval tv; struct timeval expire_at; PPPoEPacket packet; int len; if (gettimeofday(&expire_at, NULL) < 0) { error("gettimeofday (waitForPADS): %m"); return; } expire_at.tv_sec += timeout; conn->error = 0; do { if (BPF_BUFFER_IS_EMPTY) { if (!time_left(&tv, &expire_at)) return; /* Timed out */ FD_ZERO(&readable); FD_SET(conn->discoverySocket, &readable); while(1) { r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); if (r >= 0 || errno != EINTR) break; } if (r < 0) { error("select (waitForPADS): %m"); return; } if (r == 0) return; /* Timed out */ } /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); /* Check length */ if (ntohs(packet.length) + HDR_SIZE > len) { error("Bogus PPPoE length field (%u)", (unsigned int) ntohs(packet.length)); continue; } #ifdef USE_BPF /* If it's not a Discovery packet, loop again */ if (etherType(&packet) != Eth_PPPOE_Discovery) continue; #endif /* If it's not from the AC, it's not for me */ if (memcmp(packet.ethHdr.h_source, conn->peerEth, ETH_ALEN)) continue; /* If it's not for us, loop again */ if (!packetIsForMe(conn, &packet)) continue; /* Is it PADS? */ if (packet.code == CODE_PADS) { /* Parse for goodies */ if (parsePacket(&packet, parsePADSTags, conn) < 0) return; if (conn->error) return; conn->discoveryState = STATE_SESSION; break; } } while (conn->discoveryState != STATE_SESSION); /* Don't bother with ntohs; we'll just end up converting it back... */ conn->session = packet.session; info("PPP session is %d", (int) ntohs(conn->session)); /* RFC 2516 says session id MUST NOT be zero or 0xFFFF */ if (ntohs(conn->session) == 0 || ntohs(conn->session) == 0xFFFF) { error("Access concentrator used a session value of %x -- the AC is violating RFC 2516", (unsigned int) ntohs(conn->session)); } }
/********************************************************************** *%FUNCTION: waitForPADO *%ARGUMENTS: * conn -- PPPoEConnection structure * timeout -- how long to wait (in seconds) *%RETURNS: * Nothing *%DESCRIPTION: * Waits for a PADO packet and copies useful information ***********************************************************************/ void waitForPADO(PPPoEConnection *conn, int timeout) { fd_set readable; int r; struct timeval tv; struct timeval expire_at; PPPoEPacket packet; int len; struct PacketCriteria pc; pc.conn = conn; pc.acNameOK = (conn->acName) ? 0 : 1; pc.serviceNameOK = (conn->serviceName) ? 0 : 1; pc.seenACName = 0; pc.seenServiceName = 0; conn->seenMaxPayload = 0; conn->error = 0; if (gettimeofday(&expire_at, NULL) < 0) { error("gettimeofday (waitForPADO): %m"); return; } expire_at.tv_sec += timeout; do { if (BPF_BUFFER_IS_EMPTY) { if (!time_left(&tv, &expire_at)) return; /* Timed out */ FD_ZERO(&readable); FD_SET(conn->discoverySocket, &readable); while(1) { r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); if (r >= 0 || errno != EINTR) break; } if (r < 0) { error("select (waitForPADO): %m"); return; } if (r == 0) return; /* Timed out */ } /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); /* Check length */ if (ntohs(packet.length) + HDR_SIZE > len) { error("Bogus PPPoE length field (%u)", (unsigned int) ntohs(packet.length)); continue; } #ifdef USE_BPF /* If it's not a Discovery packet, loop again */ if (etherType(&packet) != Eth_PPPOE_Discovery) continue; #endif /* If it's not for us, loop again */ if (!packetIsForMe(conn, &packet)) continue; if (packet.code == CODE_PADO) { if (NOT_UNICAST(packet.ethHdr.h_source)) { error("Ignoring PADO packet from non-unicast MAC address"); continue; } if (conn->req_peer && memcmp(packet.ethHdr.h_source, conn->req_peer_mac, ETH_ALEN) != 0) { warn("Ignoring PADO packet from wrong MAC address"); continue; } if (parsePacket(&packet, parsePADOTags, &pc) < 0) return; if (conn->error) return; if (!pc.seenACName) { error("Ignoring PADO packet with no AC-Name tag"); continue; } if (!pc.seenServiceName) { error("Ignoring PADO packet with no Service-Name tag"); continue; } conn->numPADOs++; if (pc.acNameOK && pc.serviceNameOK) { memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); conn->discoveryState = STATE_RECEIVED_PADO; break; } } } while (conn->discoveryState != STATE_RECEIVED_PADO); }
/********************************************************************** *%FUNCTION: main *%ARGUMENTS: * argc, argv -- count and values of command-line arguments *%RETURNS: * Nothing *%DESCRIPTION: * Main program ***********************************************************************/ int main(int argc, char *argv[]) { int opt; int sock; PPPoEPacket pkt; int size; #ifdef USE_DLPI long buf[MAXDLBUF]; #endif if (getuid() != geteuid() || getgid() != getegid()) { fprintf(stderr, "SECURITY WARNING: pppoe-sniff will NOT run suid or sgid. Fix your installation.\n"); exit(1); } while((opt = getopt(argc, argv, "I:V")) != -1) { switch(opt) { case 'I': SET_STRING(IfName, optarg); break; case 'V': printf("pppoe-sniff: Roaring Penguin PPPoE Version %s\n", VERSION); exit(0); default: usage(argv[0]); } } /* Pick a default interface name */ if (!IfName) { IfName = DEFAULT_IF; } /* Open the interface */ #ifdef USE_DLPI sock = openInterface(IfName, Eth_PPPOE_Discovery, NULL); dlpromisconreq(sock, DL_PROMISC_PHYS); dlokack(sock, (char *)buf); dlpromisconreq(sock, DL_PROMISC_SAP); dlokack(sock, (char *)buf); #else sock = openInterface(IfName, ETH_P_ALL, NULL); #endif /* We assume interface is in promiscuous mode -- use ifconfig to ensure this */ fprintf(stderr, "Sniffing for PADR. Start your connection on another machine...\n"); while (!SeenPADR) { if (receivePacket(sock, &pkt, &size) < 0) continue; if (ntohs(pkt.length) + HDR_SIZE > size) continue; if (pkt.ver != 1 || pkt.type != 1) continue; if (pkt.code != CODE_PADR) continue; /* Looks promising... parse it */ if (parsePacket(&pkt, parsePADRTags, NULL) < 0) { continue; } DiscType = ntohs(pkt.ethHdr.h_proto); fprintf(stderr, "\nExcellent! Sniffed a likely-looking PADR.\n"); break; } while (!SeenSess) { if (receivePacket(sock, &pkt, &size) < 0) continue; if (ntohs(pkt.length) + HDR_SIZE > size) continue; if (pkt.ver != 1 || pkt.type != 1) continue; if (pkt.code != CODE_SESS) continue; /* Cool! */ SessType = ntohs(pkt.ethHdr.h_proto); break; } fprintf(stderr, "Wonderful! Sniffed a likely-looking session packet.\n"); if ((ServiceName == NULL || *ServiceName == 0) && DiscType == ETH_PPPOE_DISCOVERY && SessType == ETH_PPPOE_SESSION) { fprintf(stderr, "\nGreat! It looks like a standard PPPoE service.\nYou should not need anything special in the configuration file.\n"); return 0; } fprintf(stderr, "\nOK, looks like you need something special in the configuration file.\nTry this:\n\n"); if (ServiceName != NULL && *ServiceName != 0) { fprintf(stderr, "SERVICENAME='%s'\n", ServiceName); } if (DiscType != ETH_PPPOE_DISCOVERY || SessType != ETH_PPPOE_SESSION) { fprintf(stderr, " PPPOE_EXTRA='-f %x:%x'\n", DiscType, SessType); } return 0; }
int main(int argc, char **argv) { char filename[256]; char *newline; int abort; FILE *file_to_send; int fd_serial; uint8_t *packet_buffer; long int size; long int i; struct termios options; if (argc != 2) { printf("Hardware BitCoin wallet tester\n"); printf("Usage: %s <serial device>\n", argv[0]); printf("\n"); printf("Example: %s /dev/ttyUSB0\n", argv[0]); exit(1); } // Attempt to open serial link. fd_serial = open(argv[1], O_RDWR | O_NOCTTY); if (fd_serial == -1) { printf("Could not open device \"%s\"\n", argv[1]); printf("Make sure you have permission to open it. In many systems, only\n"); printf("root can access devices by default.\n"); exit(1); } fcntl(fd_serial, F_SETFL, 0); // block on reads tcgetattr(fd_serial, &options); cfsetispeed(&options, B57600); // baud rate 57600 cfsetospeed(&options, B57600); options.c_cflag |= (CLOCAL | CREAD); // enable receiver and set local mode on options.c_cflag &= ~PARENB; // no parity options.c_cflag &= ~CSTOPB; // 1 stop bit options.c_cflag &= ~CSIZE; // character size mask options.c_cflag |= CS8; // 8 data bits options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // raw input options.c_iflag &= ~(IXON | IXOFF | IXANY); // no software flow control options.c_oflag &= ~OPOST; // raw output tcsetattr(fd_serial, TCSANOW, &options); tx_bytes_to_ack = DEFAULT_ACKNOWLEDGE_INTERVAL; rx_bytes_to_ack = DEFAULT_ACKNOWLEDGE_INTERVAL; abort = 0; do { // Get filename from user. printf("Enter file to send (blank to quit): "); fgets(filename, sizeof(filename), stdin); newline = strrchr(filename, '\r'); if (newline != NULL) { *newline = '\0'; } newline = strrchr(filename, '\n'); if (newline != NULL) { *newline = '\0'; } if (strcmp(filename, "")) { file_to_send = fopen(filename, "rb"); if (file_to_send == NULL) { printf("Couldn't open file \"%s\"\n", filename); } else { // Get file length then read entire contents of file. fseek(file_to_send, 0, SEEK_END); size = ftell(file_to_send); fseek(file_to_send, 0, SEEK_SET); packet_buffer = malloc(size); fread(packet_buffer, size, 1, file_to_send); fclose(file_to_send); printf("Sending packet: "); displayPacket(packet_buffer, size); // Send the packet. for (i = 0; i < size; i++) { sendByte(packet_buffer[i], fd_serial); } free(packet_buffer); // Get and display response packet. packet_buffer = receivePacket(fd_serial); size = 5 + readU32LittleEndian(&(packet_buffer[1])); printf("Received packet: "); displayPacket(packet_buffer, size); free(packet_buffer); } } else { abort = 1; } } while (!abort); close(fd_serial); exit(0); }
/****************************************************************************** ** startServer() ** Description: A function that listens on inputed port, and interacts with ** one client user, and remains open after the user connection terminates for ** more client users. Used in main function. ** Parameters: port that server user enters ** Output: none ******************************************************************************/ void startServer(int port){ // endpoint socket that receives requests int serverSocket; int status; // set up signal for handling ctrl c exit struct sigaction interrupt; // get server address struct sockaddr_in serverAddress; // specify what type of socket addressing used (IPv4) serverAddress.sin_family = AF_INET; // convert address host to network short serverAddress.sin_port = htons(port); // bind socket to INNADD_ANY (all available interfaces, not just localhost) // source: http://stackoverflow.com/questions/16508685/understanding-inaddr-any-for-socket-programming-c serverAddress.sin_addr.s_addr = INADDR_ANY; // set the server side socket serverSocket = socket(AF_INET, SOCK_STREAM, 0); if (serverSocket == -1) { perror("socket"); exit(1); } // bind the new server socket with the port status = bind(serverSocket, (struct sockaddr*) &serverAddress, sizeof(serverAddress)); if (status == -1) { perror("bind"); exit(1); } // listen for client user connections, up to 10 status = listen(serverSocket, 10); if (status == -1) { perror("listen"); exit(1); } // ready stopServer() to catch any interrupt signals interrupt.sa_handler = &stopServer; interrupt.sa_flags = 0; sigemptyset(&interrupt.sa_mask); status = sigaction(SIGINT, &interrupt, 0); if (status == -1) { perror("sigaction"); exit(1); } // start running on port, waiting for client user connections (data or control) printf("ftserver: Server open on port %d\n", port); while (1) { // variable for printing client IP (in decimal form) char *clientIPv4; // variables for command tags and filename buffers char userCommand[TAG_LENGTH + 1]; char filename[PAYLOAD_LENGTH + 1]; // server side socket endpoints int controlSocket, dataSocket; // client data port number int dataPort; // address struct length // http://pubs.opengroup.org/onlinepubs/7908799/xns/syssocket.h.html socklen_t addrLen; struct sockaddr_in clientAddress; // start file transfer connection with client addrLen = sizeof(struct sockaddr_in); controlSocket = accept(serverSocket, (struct sockaddr *) &clientAddress, &addrLen); if (controlSocket == -1) { perror("accept"); exit(1); } // clientIPv4 = inet_ntoa(clientAddress.sin_addr); printf("\nftserver: Control connection established with \"%s\"\n", clientIPv4); // controlConnection() to send/receive packets with client user requests status = controlConnection(controlSocket, userCommand, &dataPort, filename); // if packets understood, proceed to the data connection (where fileList or files are sent) if (status != -1) { int connectionAttempts; // set server side endpoint for data connection dataSocket = socket(AF_INET, SOCK_STREAM, 0); if (dataSocket == -1) { perror("socket"); exit(1); } // start data connection with client user clientAddress.sin_port = htons(dataPort); connectionAttempts = 0; do { status = connect(dataSocket, (struct sockaddr *) &clientAddress, sizeof(clientAddress)); // max number of connection attempts is set at 10 } while (status == -1 && connectionAttempts < 10); if (status == -1) { perror("connect"); exit(1); } printf("ftserver: Data connection established with \"%s\"\n", clientIPv4); // call dataConnection to transfer file list or files to client user dataConnection(controlSocket, dataSocket, userCommand, filename); // wait to receive packet from user that the trasfer or listing is DONE (in tag) receivePacket(controlSocket, NULL, NULL); // close the data connection, client can reconnect for more interactions status = close(dataSocket); if (status == -1) { perror("close"); exit(1); } printf("ftserver: Data connection closed\n"); } } }
static void waitForPADS(PPPoEConnection * conn, int timeout) { fd_set readable; int r; struct timeval tv; PPPoEPacket packet; int len; d_dbg("[%d]: waitForPADS: >>> \n", getpid()); do { tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&readable); FD_SET(conn->discoverySocket, &readable); while (1) { r = select(conn->discoverySocket + 1, &readable, NULL, NULL, &tv); if (r >= 0 || errno != EINTR) break; } if (r < 0) { d_error("[%d]: select (waitForPADS)\n", getpid()); return; } if (r == 0) return; /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); if (packet.code == CODE_PADS) d_dbg("[%d]: GOT a PADS!\n", getpid()); /* Check length */ if (ntohs(packet.length) + HDR_SIZE > len) { d_error("[%d]: Bogus PPPoE length field (%u)\n", getpid(), (unsigned int)ntohs(packet.length)); continue; } /* If it's not from the AC, it's not for me */ if (memcmp(packet.ethHdr.h_source, conn->peerEth, ETH_ALEN)) continue; /* If it's not for us, loop again */ if (!packetIsForMe(conn, &packet)) continue; /* Is it PADS ? */ if (packet.code == CODE_PADS) { /* Parse for goodies */ kpppoe_parsePacket(&packet, parsePADSTags, conn); conn->discoveryState = STATE_SESSION; break; } } while (conn->discoveryState != STATE_SESSION); /* Don't bother with ntohs; we'll just end up converting it back... */ conn->session = packet.session; d_info("[%d]: PPP session is %d\n", getpid(), (int)ntohs(conn->session)); #ifndef LOGNUM #ifdef ELBOX_PROGS_GPL_SYSLOGD_AP syslog(ALOG_NOTICE|LOG_NOTICE,"[Notice]PPPoE: Received PADS for %s. (Session ID: %x)", linkname, (int)ntohs(conn->session)); #else syslog(ALOG_NOTICE|LOG_NOTICE,"PPPoE: Received PADS for %s. (Session ID: %x)", linkname, (int)ntohs(conn->session)); #endif #else syslog(ALOG_NOTICE|LOG_NOTICE,"NTC:028[%s][%x]", linkname, (int)ntohs(conn->session)); #endif sts_session_id = conn->session; /* RFC 2516 says session id MUST NOT be zero of 0xffff */ if (ntohs(conn->session) == 0 || ntohs(conn->session) == 0xffff) d_info("[%d]: Access concentrator used a session value of %x -- the AC is violating RFC 2516\n", getpid(), (unsigned int) ntohs(conn->session)); d_dbg("[%d]: waitForPADS: <<< \n", getpid()); }
/********************************************************************** *%FUNCTION: waitForPADO *%ARGUMENTS: * conn -- PPPoEConnection structure * timeout -- how long to wait (in seconds) *%RETURNS: * Nothing *%DESCRIPTION: * Waits for a PADO packet and copies useful information ***********************************************************************/ void waitForPADO(PPPoEConnection *conn, int timeout) { fd_set readable; int r; struct timeval tv; PPPoEPacket packet; int len; struct PacketCriteria pc; pc.conn = conn; pc.acNameOK = (conn->acName) ? 0 : 1; pc.serviceNameOK = (conn->serviceName) ? 0 : 1; pc.seenACName = 0; pc.seenServiceName = 0; do { if (BPF_BUFFER_IS_EMPTY) { tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&readable); FD_SET(conn->discoverySocket, &readable); while(1) { r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); if (r >= 0 || errno != EINTR) break; } if (r < 0) { fatalSys("select (waitForPADO)"); } if (r == 0) return; /* Timed out */ } /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); /* Check length */ if (ntohs(packet.length) + HDR_SIZE > len) { syslog(LOG_ERR, "Bogus PPPoE length field (%u)", (unsigned int) ntohs(packet.length)); continue; } #ifdef USE_BPF /* If it's not a Discovery packet, loop again */ if (etherType(&packet) != Eth_PPPOE_Discovery) continue; #endif if (conn->debugFile) { dumpPacket(conn->debugFile, &packet, "RCVD"); fprintf(conn->debugFile, "\n"); fflush(conn->debugFile); } /* If it's not for us, loop again */ if (!packetIsForMe(conn, &packet)) continue; if (packet.code == CODE_PADO) { if (NOT_UNICAST(packet.ethHdr.h_source)) { printErr("Ignoring PADO packet from non-unicast MAC address"); continue; } parsePacket(&packet, parsePADOTags, &pc); if (!pc.seenACName) { printErr("Ignoring PADO packet with no AC-Name tag"); continue; } if (!pc.seenServiceName) { printErr("Ignoring PADO packet with no Service-Name tag"); continue; } conn->numPADOs++; if (conn->printACNames) { printf("--------------------------------------------------\n"); } if (pc.acNameOK && pc.serviceNameOK) { memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); if (conn->printACNames) { printf("AC-Ethernet-Address: %02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned) conn->peerEth[0], (unsigned) conn->peerEth[1], (unsigned) conn->peerEth[2], (unsigned) conn->peerEth[3], (unsigned) conn->peerEth[4], (unsigned) conn->peerEth[5]); continue; } conn->discoveryState = STATE_RECEIVED_PADO; break; } } } while (conn->discoveryState != STATE_RECEIVED_PADO); }
/* * Helper function performing the login procedure. */ static void loginHandleSocket(int socket) { // Try to receive the first packet from the client rfc response; int receive = receivePacket(socket, &response); if (receive == -1) { errnoPrint("receive"); return; } else if (receive == 0) { errorPrint("Remote host closed connection"); return; } // Check if we received a login request if (equalLiteral(response.main, "LRQ")) { // Check RFC version if (response.loginRequest.version != RFC_VERSION_NUMBER) { sendErrorMessage(socket, "Login Error: Wrong RFC version used"); infoPrint("Login attempt with wrong RFC version: %d", response.loginRequest.version); return; } // Store username string int length = ntohs(response.main.length) - 1; char s[length + 1]; s[length] = '\0'; memcpy(s, response.loginRequest.name, length); // Check Game Phase if (getGamePhase() != PHASE_PREPARATION) { sendErrorMessage(socket, "Login Error: Game has already started"); infoPrint("Login attempt while game has already started: \"%s\"", s); return; } // Detect empty name string if (length == 0) { sendErrorMessage(socket, "Login Error: A username is required"); infoPrint("Login attempt without a name"); return; } // Detect duplicate names for (int i = 0; i < MAX_PLAYERS; i++) { if (userGetPresent(i)) { if (strcmp(userGetName(i), s) == 0) { sendErrorMessage(socket, "Login error: Name already in use"); infoPrint("Login attempt with duplicate name: \"%s\"", s); return; } } } // Detect too many players int pos = userFirstFreeSlot(); if (pos == -1) { sendErrorMessage(socket, "Login Error: Server is full"); infoPrint("Login attempt while server is full: \"%s\"", s); return; } // Write new user data into "database" userSetPresent(pos, 1); userSetName(pos, s); userSetSocket(pos, socket); scoreMarkForUpdate(); // Start client thread for new user int thread = -1; for (int i = 0; i < (1 + MAX_PLAYERS); i++) { if (threadsFree[i] == -1) { thread = i; } } if (pthread_create(&threads[thread], NULL, clientThread, (void*)pos) != 0) { threadsFree[thread] = pos; errnoPrint("pthread_create"); return; } // Send LOK message response.main.type[0] = 'L'; response.main.type[1] = 'O'; response.main.type[2] = 'K'; response.main.length = htons(2); response.loginResponseOK.version = RFC_VERSION_NUMBER; response.loginResponseOK.clientID = (uint8_t)pos; if (send(socket, &response, RFC_LOK_SIZE, 0) == -1) { errnoPrint("send"); return; } } else { errorPrint("Unexpected response: %c%c%c", response.main.type[0], response.main.type[1], response.main.type[2]); return; } }
int main(void) { char buff[100]; channel = (void *)malloc(200); /*---Establezco los canales de comunicacion---*/ getDefaultChannel(channel); if ( connectToChannel(channel,CLIENT) < 0 ) { printf("Server not available\n"); return 0; } itoa(buff,GET_CHANNEL); sendPacket(buff,strlen(buff)+1, channel, CLIENT); receivePacket(buff,MAX_SIZE, channel, CLIENT); disconnectFromChannel(channel); stringToChannel(buff, channel); connectToChannel(channel,CLIENT); /*---Abro el pipe de sincronismo entre padre e hijo---*/ if( pipe(syncPipe) == -1 ){ printf("Error al crear el pipe de sincronismo en el client.\n"); return 0; } /*---Abro el pipe de pasaje de argumentos para seniales---*/ if( pipe(signalPipe) == -1 ){ printf("Error al crear el pipe de args para seniales.\n"); return 0; } /*---Seteo el semaforo---*/ int semkey = getpid(); semun x; x.val = 1; int flags = IPC_CREAT | IPC_EXCL; if ( ( semid = semget(semkey, 1, 0666 | flags )) == -1 ) { printf("Error al crear semaforo: %d\n", semkey); return -1; } if ( semctl(semid, 0, SETVAL, x) == -1 ) { printf("Error al configurar semaforo\n"); return -1; } /*---Configuracion de manejo de seniales---*/ /* SIGUSR1 -> SHELL_SIGNAL */ /* SIGUSR2 -> DRAFT_SIGNAL */ struct sigaction draftSigAct; draftSigAct.sa_handler = draftSignalHandler; sigemptyset(&(draftSigAct.sa_mask)); draftSigAct.sa_flags = SA_NODEFER; struct sigaction shellSigAct; shellSigAct.sa_handler = shellSignalHandler; sigemptyset(&(shellSigAct.sa_mask)); shellSigAct.sa_flags = SA_NODEFER; sigaction( SIGUSR1, &shellSigAct, NULL); sigaction( SIGUSR2, &draftSigAct, NULL); static struct sigaction act3; act3.sa_handler = catchSigPipe; sigfillset(&(act3.sa_mask)); sigaction(SIGPIPE, &act3, NULL); static struct sigaction act1; static struct sigaction act2; /*Convenimos a este proceso como programa de envio de datos*/ senderPid = getpid(); pid_t auxPid; switch( auxPid = fork() ) { case -1: printf("Error al configurar el cliente.\n"); break; case 0: receiverPid = getpid(); close(syncPipe[0]); close(signalPipe[0]); receive(); break; default: act1.sa_handler = shutDown; sigfillset(&(act1.sa_mask)); sigaction(SIGINT, &act1, NULL); act2.sa_handler = shutDown; sigfillset(&(act2.sa_mask)); sigaction(SIGTSTP, &act2, NULL); receiverPid = auxPid; close(signalPipe[1]); close(syncPipe[1]); raise(SIGUSR1);break; } return 0; }
/* Receive function * Takes the (maximum) length of message to be received and a pointer to the char array * to be returned * Returns the actual number of bytes received */ int UDPDataLink::receive(int bytes, char * message) { if (socketDataAvailable()) { //check for a timeout return receivePacket(bytes, message); } return -1; }
int rp_receivePacket(int sock, void *pkt, int *size) { return receivePacket(sock, static_cast<PPPoEPacket*>(pkt), size); }
/************************ Simulation Code *****************************/ void ReceiverThread::run () { EPacketState eState = eExpectStart; uint8_t character, idx=0, frameDetection=ON; running = true; while(running) { if(uart_data_available() > 0) { uart_read(&character, 1); switch(eState) { case eExpectStart: switch(character) { case FRAME: eState = eExpectAddress; break; } break; case eExpectAddress: switch(character) { case BATTERY_1: case BATTERY_2: case BATTERY_3: case BROADCAST: address = character; eState = eExpectCommand; break; case FRAME: eState = eExpectAddress; break; default: eState = eExpectStart; } break; case eExpectCommand: switch(character) { case REQ_DATA: case REQ_GROUP: case TRM_DATA: case TRM_GROUP: command = character; checksum = character; length = character & LENGTH_MASK; idx = 0; eState = eExpectData; break; case FRAME: eState = eExpectAddress; break; default: eState = eExpectStart; } break; case eExpectData: checksum ^= character; if( frameDetection && idx>0 && data[idx-1] == FRAME) { if(character == FRAME) { // FRAME character was doubled: // -> add one frame character to the data buffer. frameDetection = OFF; } else { // A single FRAME character detected: // -> Reset state machine to start condition. address = character; eState = eExpectCommand; break; } } else { frameDetection = ON; data[idx++] = character; } if(idx >= length) { frameDetection = ON; eState = eExpectChecksum; } break; case eExpectChecksum: if (frameDetection && character == FRAME) { frameDetection = OFF; } else { if(checksum==character) { receivePacket(); } eState = eExpectStart; } break; } } os_thread_sleep(10); } }
/********************************************************************** *%FUNCTION: waitForPADO *%ARGUMENTS: * conn -- PPPoEConnection structure * timeout -- how long to wait (in seconds) *%RETURNS: * Nothing *%DESCRIPTION: * Waits for a PADO packet and copies useful information ***********************************************************************/ static void waitForPADO(PPPoEConnection *conn, int timeout) { fd_set readable; int r; struct timeval tv; struct timeval expire_at; struct timeval now; PPPoEPacket packet; int len; struct PacketCriteria pc; pc.conn = conn; #ifdef PLUGIN conn->seenMaxPayload = 0; #endif if (gettimeofday(&expire_at, NULL) < 0) { fatalSys("gettimeofday (waitForPADO)"); } expire_at.tv_sec += timeout; do { #ifdef PLUGIN if (got_sigterm || got_sighup) return; #endif if (BPF_BUFFER_IS_EMPTY) { if (gettimeofday(&now, NULL) < 0) { fatalSys("gettimeofday (waitForPADO)"); } tv.tv_sec = expire_at.tv_sec - now.tv_sec; tv.tv_usec = expire_at.tv_usec - now.tv_usec; if (tv.tv_usec < 0) { tv.tv_usec += 1000000; if (tv.tv_sec) { tv.tv_sec--; } else { /* Timed out */ return; } } if (tv.tv_sec <= 0 && tv.tv_usec <= 0) { /* Timed out */ return; } FD_ZERO(&readable); FD_SET(conn->discoverySocket, &readable); while(1) { r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); if (r >= 0 || errno != EINTR) break; #ifdef PLUGIN if (got_sigterm || got_sighup) return; #endif } if (r < 0) { fatalSys("select (waitForPADO)"); } if (r == 0) { /* Timed out */ return; } } /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); /* Check length */ if (ntohs(packet.length) + HDR_SIZE > len) { syslog(LOG_ERR, "Bogus PPPoE length field (%u)", (unsigned int) ntohs(packet.length)); continue; } #ifdef USE_BPF /* If it's not a Discovery packet, loop again */ if (etherType(&packet) != Eth_PPPOE_Discovery) continue; #endif #ifdef DEBUGGING_ENABLED if (conn->debugFile) { dumpPacket(conn->debugFile, &packet, "RCVD"); fprintf(conn->debugFile, "\n"); fflush(conn->debugFile); } #endif /* If it's not for us, loop again */ if (!packetIsForMe(conn, &packet)) continue; if (packet.code == CODE_PADO) { if (BROADCAST(packet.ethHdr.h_source)) { printErr("Ignoring PADO packet from broadcast MAC address"); continue; } #ifdef PLUGIN if (conn->req_peer && memcmp(packet.ethHdr.h_source, conn->req_peer_mac, ETH_ALEN) != 0) { warn("Ignoring PADO packet from wrong MAC address"); continue; } #endif pc.gotError = 0; pc.seenACName = 0; pc.seenServiceName = 0; pc.acNameOK = (conn->acName) ? 0 : 1; pc.serviceNameOK = (conn->serviceName) ? 0 : 1; parsePacket(&packet, parsePADOTags, &pc); if (pc.gotError) { printErr("Error in PADO packet"); continue; } if (!pc.seenACName) { printErr("Ignoring PADO packet with no AC-Name tag"); continue; } if (!pc.seenServiceName) { printErr("Ignoring PADO packet with no Service-Name tag"); continue; } conn->numPADOs++; if (pc.acNameOK && pc.serviceNameOK) { memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); if (conn->printACNames) { printf("AC-Ethernet-Address: %02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned) conn->peerEth[0], (unsigned) conn->peerEth[1], (unsigned) conn->peerEth[2], (unsigned) conn->peerEth[3], (unsigned) conn->peerEth[4], (unsigned) conn->peerEth[5]); printf("--------------------------------------------------\n"); continue; } conn->discoveryState = STATE_RECEIVED_PADO; break; } } } while (conn->discoveryState != STATE_RECEIVED_PADO); }
void Framework::loop() { /* main loop variable */ bool done = false; /* used to collect events */ SDL_Event event; /* wait for events */ while (!done) { /* handle the events in the queue */ while (SDL_PollEvent(&event)) { switch(event.type) { case SDL_MOUSEMOTION: /* give away mouse movement with buttons pressed */ handleMouseMove(event.motion.xrel, event.motion.yrel, event.motion.state); break; case SDL_MOUSEBUTTONUP: /* handle mouse button release for serving */ if (event.button.button == SDL_BUTTON_LEFT) if (!paused) serveBall(); case SDL_KEYDOWN: /* handle key presses */ handleKeyPress(&event.key.keysym); break; case SDL_QUIT: /* handle quit requests */ done = true; break; case SDL_USEREVENT: switch (event.user.code) { case NET2_EXTERNAL: if (((TimerData*)event.user.data1)->timer == NULL) { /* this means our timer has gone inactive and we are pleased to stop our work! */ } else { ((TimerData*)event.user.data1)->receiver->action(((TimerData*)event.user.data1)->event); } break; case NET2_ERROREVENT: printf("Error: %s(%d)\n", NET2_GetEventError(&event), NET2_GetSocket(&event)); break; case NET2_UDPRECEIVEEVENT: UDPpacket *p = NULL; p = NET2_UDPRead(NET2_GetSocket(&event)); while (p != NULL) // if we get NULL we are done { Peer* peer = getCreatePeer(p->address.host); receivePacket(peer, (char*)p->data, p->len); NET2_UDPFreePacket(p); p = NET2_UDPRead(NET2_GetSocket(&event)); } break; } } } int tdiff = SDL_GetTicks() - lasttime; if (tdiff > timeunit) { frames++; xdiff += tdiff; // always greater 0 because we decided to let tdiff be greater than timeunit if ((xdiff >= 100)&&(xdiff >= timeunit * 20)) { output.updateFPS(frames * 1000.0 / xdiff); // There are 1000 ticks / second frames = 0; xdiff = 0; } lasttime += tdiff; // Game status code updateGame(tdiff); // Rendering code drawScene(); } } }
/********************************************************************** *%FUNCTION: waitForPADS *%ARGUMENTS: * conn -- PPPoE connection info * timeout -- how long to wait (in seconds) *%RETURNS: * Nothing *%DESCRIPTION: * Waits for a PADS packet and copies useful information ***********************************************************************/ void waitForPADS(PPPoEConnection *conn, int timeout) { fd_set readable; int r; struct timeval tv; PPPoEPacket packet; int len; do { if (BPF_BUFFER_IS_EMPTY) { tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&readable); FD_SET(conn->discoverySocket, &readable); while(1) { r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); if (r >= 0 || errno != EINTR) break; } if (r < 0) { fatalSys("select (waitForPADS)"); } if (r == 0) return; } /* Get the packet */ receivePacket(conn->discoverySocket, &packet, &len); /* Check length */ if (ntohs(packet.length) + HDR_SIZE > len) { syslog(LOG_ERR, "Bogus PPPoE length field (%u)", (unsigned int) ntohs(packet.length)); continue; } #ifdef USE_BPF /* If it's not a Discovery packet, loop again */ if (etherType(&packet) != Eth_PPPOE_Discovery) continue; #endif if (conn->debugFile) { dumpPacket(conn->debugFile, &packet, "RCVD"); fprintf(conn->debugFile, "\n"); fflush(conn->debugFile); } /* If it's not from the AC, it's not for me */ if (memcmp(packet.ethHdr.h_source, conn->peerEth, ETH_ALEN)) continue; /* If it's not for us, loop again */ if (!packetIsForMe(conn, &packet)) continue; /* Is it PADS? */ if (packet.code == CODE_PADS) { /* Parse for goodies */ parsePacket(&packet, parsePADSTags, conn); conn->discoveryState = STATE_SESSION; break; } } while (conn->discoveryState != STATE_SESSION); /* Don't bother with ntohs; we'll just end up converting it back... */ conn->session = packet.session; syslog(LOG_INFO, "PPP session is %d", (int) ntohs(conn->session)); /* RFC 2516 says session id MUST NOT be zero or 0xFFFF */ if (ntohs(conn->session) == 0 || ntohs(conn->session) == 0xFFFF) { syslog(LOG_ERR, "Access concentrator used a session value of %x -- the AC is violating RFC 2516", (unsigned int) ntohs(conn->session)); } }
static void waitForPADO(PPPoEConnection * conn, int timeout) { fd_set readable; int r = -1; struct timeval tv; PPPoEPacket packet; int len; struct PacketCriteria pc; pc.conn = conn; pc.acNameOK = (conn->acName) ? 0 : 1; pc.serviceNameOK = (conn->serviceName) ? 0 : 1; pc.seenACName = 0; pc.seenServiceName = 0; do { tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&readable); FD_SET(conn->discoverySocket, &readable); while (!got_sigterm) /* Modified by Kwest Wan 20080919 to terminate pppd immediately if PPPoE server don't reponse */ { d_dbg("[%d]: waitPADO select >>>>\n", getpid()); r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); d_dbg("[%d]: waitPADO select (%d) <<<<\n", getpid(), r); if (r >= 0 || errno != EINTR) break; } if (r < 0) { d_error("[%d]: select (waitForPADS)\n", getpid()); return; } if (r == 0) return; /* Get the packet */ d_dbg("[%d]: receivePacket >>>\n", getpid()); receivePacket(conn->discoverySocket, &packet, &len); d_dbg("[%d]: receivePacket <<<\n", getpid()); /* Check length */ if (ntohs(packet.length) + HDR_SIZE > len) { d_error("[%d]: Bogus PPPoE length field (%u)\n", getpid(), (unsigned int)ntohs(packet.length)); continue; } /* If it's not for us, loop again */ if (!packetIsForMe(conn, &packet)) { d_dbg("[%d]: packet is not for me!\n", getpid()); continue; } /* Is it PADS ? */ if (packet.code == CODE_PADO) { if (NOT_UNICAST(packet.ethHdr.h_source)) { d_info("[%d]: Ignoring PADO packet from non-unicast MAC address\n", getpid()); #ifndef LOGNUM #ifdef ELBOX_PROGS_GPL_SYSLOGD_AP syslog(ALOG_NOTICE|LOG_NOTICE, "[Notice]PPPoE: Ignore PADO packet from non-unicast MAC address. (%s)", linkname); #else syslog(ALOG_NOTICE|LOG_NOTICE, "PPPoE: Ignore PADO packet from non-unicast MAC address. (%s)", linkname); #endif #else syslog(ALOG_NOTICE|LOG_NOTICE, "NTC:029[%s]", linkname); #endif continue; } kpppoe_parsePacket(&packet, parsePADOTags, &pc); if (!pc.seenACName) { d_info("[%d]: Ignoring PADO packet with no AC-Name tag\n", getpid()); #ifndef LOGNUM #ifdef ELBOX_PROGS_GPL_SYSLOGD_AP syslog(ALOG_NOTICE|LOG_NOTICE, "[Notice]PPPoE: Ignore PADO packet with no AC-Name tag. (%s)", linkname); #else syslog(ALOG_NOTICE|LOG_NOTICE, "PPPoE: Ignore PADO packet with no AC-Name tag. (%s)", linkname); #endif #else syslog(ALOG_NOTICE|LOG_NOTICE, "NTC:030[%s]", linkname); #endif continue; } if (!pc.seenServiceName) { d_info("[%d]: Ignoring PADO packet with no Service-Name tag\n", getpid()); #ifndef LOGNUM #ifdef ELBOX_PROGS_GPL_SYSLOGD_AP syslog(ALOG_NOTICE|LOG_NOTICE, "[Notice]PPPoE: Ignore PADO packet with no Service-Name tag. (%s)", linkname); #else syslog(ALOG_NOTICE|LOG_NOTICE, "PPPoE: Ignore PADO packet with no Service-Name tag. (%s)", linkname); #endif #else syslog(ALOG_NOTICE|LOG_NOTICE, "NTC:031[%s]", linkname); #endif continue; } conn->numPADOs++; if (conn->printACNames) printf("------------------------------------------------------\n"); update_statusfile("PPPoE:PADO"); d_dbg("[%d]: acNameOK:%d, serviceNameOK:%d\n", getpid(), pc.acNameOK, pc.serviceNameOK); if (pc.acNameOK && pc.serviceNameOK) { memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); if (conn->printACNames) { printf("AC-Ethernet-Address: %02x:%02x:%02x:%02x:%02x:%02x\n", (unsigned)conn->peerEth[0], (unsigned)conn->peerEth[1], (unsigned)conn->peerEth[2], (unsigned)conn->peerEth[3], (unsigned)conn->peerEth[4], (unsigned)conn->peerEth[5]); continue; } conn->discoveryState = STATE_RECEIVED_PADO; #ifndef LOGNUM #ifdef ELBOX_PROGS_GPL_SYSLOGD_AP syslog(ALOG_NOTICE|LOG_NOTICE, "[Notice]PPPoE: Received PADO for %s, from: %02x:%02x:%02x:%02x:%02x:%02x", linkname, (unsigned)conn->peerEth[0], (unsigned)conn->peerEth[1], (unsigned)conn->peerEth[2], (unsigned)conn->peerEth[3], (unsigned)conn->peerEth[4], (unsigned)conn->peerEth[5]); #else syslog(ALOG_NOTICE|LOG_NOTICE, "PPPoE: Received PADO for %s, from: %02x:%02x:%02x:%02x:%02x:%02x", linkname, (unsigned)conn->peerEth[0], (unsigned)conn->peerEth[1], (unsigned)conn->peerEth[2], (unsigned)conn->peerEth[3], (unsigned)conn->peerEth[4], (unsigned)conn->peerEth[5]); #endif #else syslog(ALOG_NOTICE|LOG_NOTICE, "NTC:026[%s][%02x:%02x:%02x:%02x:%02x:%02x]", linkname, (unsigned)conn->peerEth[0], (unsigned)conn->peerEth[1], (unsigned)conn->peerEth[2], (unsigned)conn->peerEth[3], (unsigned)conn->peerEth[4], (unsigned)conn->peerEth[5]); #endif break; } } else { d_dbg("[%d]: this is not PADO!\n", getpid()); } } while (conn->discoveryState != STATE_RECEIVED_PADO); }
/********************************************************************** *%FUNCTION: relayGotSessionPacket *%ARGUMENTS: * iface -- interface on which packet is waiting *%RETURNS: * Nothing *%DESCRIPTION: * Receives and processes a session packet. ***********************************************************************/ void relayGotSessionPacket(PPPoEInterface const *iface) { PPPoEPacket packet; int size; SessionHash *sh; PPPoESession *ses; if (receivePacket(iface->sessionSock, &packet, &size) < 0) { return; } /* Ignore unknown code/version */ if (packet.ver != 1 || packet.type != 1) { return; } /* Must be a session packet */ if (packet.code != CODE_SESS) { syslog(LOG_ERR, "Session packet with code %d", (int) packet.code); return; } /* Ignore session packets whose destination address isn't ours */ if (memcmp(packet.ethHdr.h_dest, iface->mac, ETH_ALEN)) { return; } /* Validate length */ if (ntohs(packet.length) + HDR_SIZE > size) { syslog(LOG_ERR, "Bogus PPPoE length field (%u)", (unsigned int) ntohs(packet.length)); return; } /* Drop Ethernet frame padding */ if (size > ntohs(packet.length) + HDR_SIZE) { size = ntohs(packet.length) + HDR_SIZE; } /* We're in business! Find the hash */ sh = findSession(packet.ethHdr.h_source, packet.session); if (!sh) { /* Don't log this. Someone could be running the client and the relay on the same box. */ return; } /* Relay it */ ses = sh->ses; ses->epoch = Epoch; sh = sh->peer; packet.session = sh->sesNum; memcpy(packet.ethHdr.h_source, sh->interface->mac, ETH_ALEN); memcpy(packet.ethHdr.h_dest, sh->peerMac, ETH_ALEN); #if 0 printf( "Relaying %02x:%02x:%02x:%02x:%02x:%02x(%s:%d) to %02x:%02x:%02x:%02x:%02x:%02x(%s:%d)\n", sh->peer->peerMac[0], sh->peer->peerMac[1], sh->peer->peerMac[2], sh->peer->peerMac[3], sh->peer->peerMac[4], sh->peer->peerMac[5], sh->peer->interface->name, ntohs(sh->peer->sesNum), sh->peerMac[0], sh->peerMac[1], sh->peerMac[2], sh->peerMac[3], sh->peerMac[4], sh->peerMac[5], sh->interface->name, ntohs(sh->sesNum)); #endif sendPacket(NULL, sh->interface->sessionSock, &packet, size); }
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; }