// Send string void ORCP::sendString(const char* str) { if(str) send_packet(CP_DUINO_IR, CP_DUINO_IT, CP_DUINO_BS, CP_DUINO_SENDSTRING, (uint8_t*)str, strlen(str)); }
/* * This function will send a file to a remote host. Expects a socket integer * and a string containing the full path to the local file name. File cannot * exceed MAXFILE definition. Takes a server boolean for some additional * checks. * */ void send_file(int skt, const char *filename, int server) { char errmsg[ERRMSGLEN], msg[MSGLEN]; int fsize = 0, segments = 0, cur_segment; FILE *infile; memset(errmsg, '\0', ERRMSGLEN); memset(msg, '\0', MSGLEN); /* file must exist */ if(!exist(filename)) { if(server) { send_packet(skt, "err:That file does not exist"); } error("The file does not exist!"); return; } /* file must be in valid size range, do not send endpoint sizes */ fsize = filesize(filename); if(fsize <= 0 || fsize >= MAXFILE) { if(server) { send_packet(skt, "err:File is too big"); } error("File is too big"); return; } segments = (int) ceil(fsize / MSGLEN); /* open file or die */ infile = fopen(filename, "r"); if(infile == NULL) { if(server) { send_packet(skt, "err:File could not be read"); } sprintf(errmsg, "File could not be read: %s", strerror(errno)); error(errmsg); return; } /* send cts to client */ if(server) { send_packet(skt, "cts"); sleep(1); } /* send number of segments and file size to the other size cmd:arg style */ sprintf(msg, "%d:%d", segments, fsize); /* do not expect a response, only data after this */ send_packet(skt, msg); /* now read in the file, MSGLEN at a time and send the chunk to the host */ for(cur_segment = 0; cur_segment <= segments; cur_segment++) { memset(msg, '\0', MSGLEN); fread(msg, MSGLEN, 1, infile); printf("\rFilesystem: Sending file %d / %d", cur_segment, segments); send_packet(skt, msg); } printf("\n"); fclose(infile); }
void do_server () { struct ae_recv *packet; int ret; int pktrecv = 0; int acksent = 0; int gotstop = 0; int printmismatch; int adjust; /* se up pktring and get DPF filter for proper UDP packets */ xio_net_wrap_init (&nwinfo, malloc(32 * 4096), (32 * 4096)); printf ("getting dpf: dstportno %x (%d), srcportno %x (%d)\n", dstportno, dstportno, -1, -1); ret = xio_net_wrap_getdpf_udp (&nwinfo, dstportno, -1); assert (ret != -1); /* wait for start packet */ while ((packet = xio_net_wrap_getPacket(&nwinfo)) == NULL) ; printf ("got packet: dstportno %02x %02x, srcportno %02x %02x\n", packet->r[0].data[36], packet->r[0].data[37], packet->r[0].data[34], packet->r[0].data[35]); /* set up proper variables, send ack packet and start timer */ process_start_packet ((struct start_pkt *) packet->r[0].data); setnetcardno (packet->r[0].data); xio_net_wrap_returnPacket (&nwinfo, packet); init_packets (); setup_startack_packet (outpkt); printf ("sending packet: netcardno %d, dstportno %02x %02x, srcportno %02x %02x\n", netcardno, outpkt->r[0].data[36], outpkt->r[0].data[37], outpkt->r[0].data[34], outpkt->r[0].data[35]); send_packet (netcardno, outpkt); /* get Packets, check their size, ack when appropriate */ printmismatch = 1; adjust = 0; while (pktrecv < pktcnt) { while ((packet = xio_net_wrap_getPacket(&nwinfo)) == NULL) ; if (is_stop_pkt (packet)) { gotstop = 1; break; } #ifndef DIRECT_XMIT if ((printmismatch) && (((struct pkt *)packet->r[0].data)->id != (pktrecv+adjust))) { //printf ("out of order packet: id %d, expected %d (adjust %d)\n", ((struct pkt *)packet->r[0].data)->id, pktrecv, adjust); //printmismatch = 0; adjust = ((struct pkt *)packet->r[0].data)->id - pktrecv; } #endif assert (packet->r[0].sz == max(64,(sizeof(struct pkt) + pktdata - 4))); xio_net_wrap_returnPacket (&nwinfo, packet); pktrecv++; if ((ackfreq) && ((pktrecv % ackfreq) == 0)) { setup_dataack_packet (outpkt); send_packet (netcardno, outpkt); acksent++; } } /* when stop packet received, get time */ /* print results */ printf ("packets received %d (acks %d) (gotstop %d)\n", pktrecv, acksent, gotstop); }
int main(int argc, char *argv[]) { /* Disable driver enable for RS485 ASAP */ //DDRC |= (1 << PC2); //PORTC &= ~(1 << PC2); /* init serial line debugging */ UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UCSR0B = (1 << RXCIE1) | (1 << RXEN1) | (1 << TXEN0); UCSR0C = (1<<UCSZ00) | (1<<UCSZ01); /* Initialize UART */ net_init(); DBG("READY!\r\n"); DBG("Initializing SPI...\r\n"); spi_init(); DBG("Initializing ENC28J60...\r\n"); init_enc28j60(); DBG("Initialized ENC28J60\r\n"); char obuf[64]; snprintf(obuf, sizeof(obuf), "enc28j60 rev 0x%x\n", read_control_register(REG_EREVID)); DBG(obuf); char buf[16] = "serial: X\n"; int cnt = 0; while (1) { if (eth_to_rs_cnt > 0 && eth_to_rs[eth_to_rs_cnt-1] == '$') { eth_to_rs[eth_to_rs_cnt-1] = '\0'; int dest = 0; int pktlen = 0; char minibuf[16]; minibuf[0] = eth_to_rs[1]; minibuf[1] = eth_to_rs[2]; minibuf[2] = '\0'; if (sscanf(minibuf, "%d", &dest) != 1) { DBG("Could not parse dest\r\n"); eth_to_rs_cnt = 0; continue; } minibuf[0] = eth_to_rs[3]; minibuf[1] = eth_to_rs[4]; if (sscanf(minibuf, "%d", &pktlen) != 1) { DBG("Could not parse len\r\n"); eth_to_rs_cnt = 0; continue; } if (pktlen != (eth_to_rs_cnt - 6)) { DBG("lens are not the same\r\n"); minibuf[2] = '\r'; minibuf[3] = '\n'; minibuf[4] = '\0'; DBG(minibuf); snprintf(minibuf, sizeof(minibuf), "e: %d\r\n", eth_to_rs_cnt-6); DBG(minibuf); snprintf(minibuf, sizeof(minibuf), "p: %d\r\n", pktlen); DBG(minibuf); eth_to_rs_cnt = 0; continue; } fmt_packet(lbuffer, dest, 0xFF, eth_to_rs + 5, pktlen); struct buspkt *packet = (struct buspkt*)lbuffer; send_packet(packet); syslog_send("sent packet", strlen("sent packet")); _delay_ms(25); sendit = 0; eth_to_rs_cnt = 0; } #if 0 network_process(); if (uip_recvlen > 0) { syslog_send("handling ethernet packet", strlen("handling ethernet packet")); DBG("Handling packet\r\n"); handle_icmpv6(); if (uip_recvbuf[20] == 0x11) { syslog_send("handling udp packet", strlen("handling udp packet")); /* UDP */ uint8_t *udp = uip_recvbuf + 14 + 40; uint8_t len = udp[5] - 8; /* TODO: sanity check */ uint8_t *recvpayload = udp + 8 /* udp */; fmt_packet(lbuffer, uip_recvbuf[53], 0xFF, recvpayload, len); struct buspkt *packet = (struct buspkt*)lbuffer; //syslog_send("sending packet", strlen("sending packet")); send_packet(packet); _delay_ms(25); cnt = 85; syslog_send("ethernet to rs485 done", strlen("ethernet to rs485 done")); } //syslog_send("received a packet", strlen("received a packet")); buf[14] = uip_recvlen; //syslog_send(uip_recvbuf, uip_recvlen); uip_recvlen = 0; } #endif _delay_ms(10); if (cnt++ == 100) { fmt_packet(lbuffer, 1, 0, "ping", 4); struct buspkt *packet = (struct buspkt*)lbuffer; syslog_send("ping sent", strlen("ping sent")); send_packet(packet); cnt = 0; snprintf(obuf, sizeof(obuf), "cnt = %d, rem = %d\r\n", eth_to_rs_cnt, eth_to_rs_rem); syslog_send(obuf, strlen(obuf)); } uint8_t status = bus_status(); if (status == BUS_STATUS_IDLE) continue; if (status == BUS_STATUS_MESSAGE) { /* get a copy of the current packet */ struct buspkt *packet = current_packet(); uint8_t *walk = packet; uint8_t *payload = (uint8_t*)packet; payload += sizeof(struct buspkt); /* check for ping replies */ if (packet->destination == 0x00 && memcmp(payload, "pong", strlen("pong")) == 0) { syslog_send("pong received", strlen("pong received")); /* TODO: store that this controller is reachable */ /* check if the controller has any waiting messages */ if (payload[4] > 0) { /* request the message */ fmt_packet(lbuffer, packet->source, 0, "send", 4); struct buspkt *reply = (struct buspkt*)lbuffer; //syslog_send("sending packet", strlen("sending packet")); _delay_ms(25); send_packet(reply); syslog_send("sendreq sent", strlen("sendreq sent")); //syslog_send(reply, reply->length_lo + sizeof(struct buspkt)); _delay_ms(25); cnt = 0; } } #if 0 /* copy packet->destination into the MAC and IPv6 address */ uip_buf[5] = packet->destination; /* MAC */ uip_buf[53] = packet->destination; /* IPv6 */ /* copy packet->source into the MAC and IPv6 address */ uip_buf[11] = packet->source; /* MAC */ uip_buf[37] = packet->source; /* IPv6 */ raw_send(payload, packet->length_lo); #endif char minibuf[16]; snprintf(minibuf, sizeof(minibuf), "^%02d%02d", 0, packet->length_lo); uart_puts(minibuf); uint8_t c; for (c = 0; c < sizeof(struct buspkt); c++) { while ( !( UCSR0A & (1<<UDRE0)) ); UDR0 = walk[c]; } for (c = 0; c < packet->length_lo; c++) { while ( !( UCSR0A & (1<<UDRE0)) ); UDR0 = payload[c]; } while ( !( UCSR0A & (1<<UDRE0)) ); UDR0 = '$'; /* discard the packet from serial buffer */ packet_done(); continue; } if (status == BUS_STATUS_WRONG_CRC) { syslog_send("broken", strlen("broken")); struct buspkt *packet = current_packet(); raw_send(packet, 16); skip_byte(); continue; } } }
int main(int argc, char **argv) { int32_t arg_id; int fd, clonefd = -1; int i, j, eoff, off, ret; FILE* onf; char msg[MAX_SEND]; int c; int mlen = 0; int udp = 0; int det = 0; char fname[MAX_FILENAME] = ""; char raddr[MAX_IP] = "127.0.0.1"; int rport = 12345; kfs_event_arg_t *kea; struct fsevent_clone_args fca; char buffer[FSEVENT_BUFSIZ]; struct passwd *p; struct group *g; mode_t va_mode; u_int32_t va_type; u_int32_t is_fse_arg_vnode = 0; char fileModeString[11 + 1]; int8_t event_list[] = { // action to take for each event FSE_REPORT, // FSE_CREATE_FILE, FSE_REPORT, // FSE_DELETE, FSE_REPORT, // FSE_STAT_CHANGED, FSE_REPORT, // FSE_RENAME, FSE_REPORT, // FSE_CONTENT_MODIFIED, FSE_REPORT, // FSE_EXCHANGE, FSE_REPORT, // FSE_FINDER_INFO_CHANGED, FSE_REPORT, // FSE_CREATE_DIR, FSE_REPORT, // FSE_CHOWN, FSE_REPORT, // FSE_XATTR_MODIFIED, FSE_REPORT, // FSE_XATTR_REMOVED, }; // Print usage if not root if (geteuid() != 0){ usage(); exit(1); } onf = stdout; opterr = 0; while ((c = getopt (argc, argv, "huf:s:p:")) != -1) switch (c){ case 'f': strncpy(fname,optarg,MAX_FILENAME - 1); onf = fopen(fname,"w"); if (onf == NULL){ fprintf(stderr, "Cannot open output file %s.\n\n",optarg); usage(); exit(1); } break; case 'u': udp = 1; break; case 's': strncpy(raddr,optarg,MAX_IP); break; case 'p': rport = atoi( optarg ); break; case 'h': case '?': if (optopt == 'f'){ fprintf(stderr, "Output filename required.\n"); usage(); exit(1); } usage(); exit(1); } setbuf(onf, NULL); //Set UDP Socket set_dest(raddr, rport); set_sock(); if ((fd = open(DEV_FSEVENTS, O_RDONLY)) < 0) { perror("open"); exit(1); } fca.event_list = (int8_t *)event_list; fca.num_events = sizeof(event_list)/sizeof(int8_t); fca.event_queue_depth = EVENT_QUEUE_SIZE; fca.fd = &clonefd; if ((ret = ioctl(fd, FSEVENTS_CLONE, (char *)&fca)) < 0) { perror("ioctl"); close(fd); exit(1); } close(fd); //YAML comments lines start with '#'. Use this for debug and status statements snprintf(msg, MAX_DATA,"#fsevents device cloned (fd %d)\n#fslogger ready\n",clonefd); if (udp){ send_packet(msg, strlen(msg)); } else { fprintf(onf,"%s",msg); // Since we use setbuf this might not be necessary. Let's do it anyway. fflush(onf); } if ((ret = ioctl(clonefd, FSEVENTS_WANT_EXTENDED_INFO, NULL)) < 0) { perror("ioctl"); close(clonefd); exit(1); } while (1) { // event processing loop if ((ret = read(clonefd, buffer, FSEVENT_BUFSIZ)) > 0){ snprintf(msg, MAX_DATA, "# => received %d bytes\n", ret); if (udp){ send_packet(msg, strlen(msg)); } else { fprintf(onf,"%s", msg); fflush(onf); } } off = 0; while (off < ret) { // process one or more events received // Start message over mlen = 0; struct kfs_event *kfse = (struct kfs_event *)((char *)buffer + off); off += sizeof(int32_t) + sizeof(pid_t); // type + pid //Use snprintf for formatting to permit concantenting the message together mlen += snprintf(msg + mlen, MAX_DATA, "---\n"); if (kfse->type == FSE_EVENTS_DROPPED) { // special event mlen += snprintf(msg + mlen, MAX_DATA, "Event:\n"); mlen += snprintf(msg + mlen, MAX_DATA, " %s: %s\n", "type", "EVENTS_DROPPED"); mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d\n", "pid", kfse->pid); // Special event with continue. So send data then restart loop if (udp){ send_packet(msg, strlen(msg)); } else { fprintf(onf,"%s", msg); fflush(onf); } off += sizeof(u_int16_t); // FSE_ARG_DONE: sizeof(type) continue; } int32_t atype = kfse->type & FSE_TYPE_MASK; uint32_t aflags = FSE_GET_FLAGS(kfse->type); if ((atype < FSE_MAX_EVENTS) && (atype >= -1)) { mlen += snprintf(msg + mlen, MAX_DATA, "Event:\n"); mlen += snprintf(msg + mlen, MAX_DATA, " %s: %s", "type", kfseNames[atype]); if (aflags & FSE_COMBINED_EVENTS) { mlen += snprintf(msg + mlen, MAX_DATA,"%s", ", combined events"); } if (aflags & FSE_CONTAINS_DROPPED_EVENTS) { mlen += snprintf(msg + mlen, MAX_DATA, "%s", ", contains dropped events"); } mlen += snprintf(msg + mlen,MAX_DATA, "%s","\n"); } else { // should never happen mlen += snprintf(msg + mlen, MAX_DATA, "# This may be a program bug (type = %d).\n", atype); // Special event with exit. So send data if (udp){ send_packet(msg, strlen(msg)); } else { fprintf(onf,"%s", msg); fflush(onf); } exit(1); } mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d\n", "pid", kfse->pid); mlen += snprintf(msg + mlen, MAX_DATA, " %s: %s\n", "pname", get_proc_name(kfse->pid)); mlen += snprintf(msg + mlen, MAX_DATA, "%s", "Details:\n"); kea = kfse->args; i = 0; //while ((off < ret) && (i <= FSE_MAX_ARGS)) { // process arguments while (off < ret) { i++; if (kea->type == FSE_ARG_DONE) { // no more arguments mlen += snprintf(msg + mlen, MAX_DATA, " %s:\n", "FSE_ARG_DONE"); // Added Length for FSE_ARG_DONE to be consistent with other values mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d\n", "len", 0); // Added Type for FSE_ARG_DONE to be consistent with other values mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d\n", "type", kea->type); //This should be the only time to send data for a YAML doc which is a full FSEVENT if (udp){ send_packet(msg, strlen(msg)); } else { fprintf(onf,"%s", msg); fflush(onf); } det = 0; off += sizeof(u_int16_t); break; } eoff = sizeof(kea->type) + sizeof(kea->len) + kea->len; off += eoff; arg_id = (kea->type > FSE_MAX_ARGS) ? 0 : kea->type; // Do no put detail marker on timestamp if (arg_id == 5){ mlen += snprintf(msg + mlen, MAX_DATA, " %s:\n", kfseArgNames[arg_id]); } else { mlen += snprintf(msg + mlen, MAX_DATA, " %s_%d:\n", kfseArgNames[arg_id],det); } mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d\n", "len", kea->len); switch (kea->type) { // handle based on argument type case FSE_ARG_VNODE: // a vnode (string) pointer is_fse_arg_vnode = 1; mlen += snprintf(msg + mlen, MAX_DATA, " %s: %s\n", "path", (char *)&(kea->data.vp)); break; case FSE_ARG_STRING: // a string pointer // Added double quotes to protect strings with ":"s // Actually, to handle "\" it needs to be a single quote mlen += snprintf(msg + mlen, MAX_DATA, " %s: \'%s\'\n", "string", (char *)&(kea->data.str)-4); break; case FSE_ARG_INT32: mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d\n", "int32", kea->data.int32); break; case FSE_ARG_RAW: // a void pointer mlen += snprintf(msg + mlen, MAX_DATA, " %s: ", "ptr"); for (j = 0; j < kea->len; j++) mlen += snprintf(msg + mlen, MAX_DATA, "%02x ", ((char *)kea->data.ptr)[j]); mlen += snprintf(msg + mlen, MAX_DATA, "%s", "\n"); break; case FSE_ARG_INO: // an inode number mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d\n", "ino", (int)kea->data.ino); break; case FSE_ARG_UID: // a user ID p = getpwuid(kea->data.uid); mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d (%s)\n", "uid", kea->data.uid, (p) ? p->pw_name : "?"); break; case FSE_ARG_DEV: // a file system ID or a device number if (is_fse_arg_vnode) { mlen += snprintf(msg + mlen, MAX_DATA, " %s: %#08x\n", "fsid", kea->data.dev); is_fse_arg_vnode = 0; } else { mlen += snprintf(msg + mlen, MAX_DATA, " %s: %#08x (major %u, minor %u)\n", "dev", kea->data.dev, major(kea->data.dev), minor(kea->data.dev)); } break; case FSE_ARG_MODE: // a combination of file mode and file type va_mode = (kea->data.mode & 0x0000ffff); va_type = (kea->data.mode & 0xfffff000); strmode(va_mode, fileModeString); va_type = iftovt_tab[(va_type & S_IFMT) >> 12]; mlen += snprintf(msg + mlen, MAX_DATA, " %s: %s (%#08x, vnode type %s)", "mode", fileModeString, kea->data.mode, (va_type < VTYPE_MAX) ? vtypeNames[va_type] : "?"); if (kea->data.mode & FSE_MODE_HLINK) { mlen += snprintf(msg + mlen, MAX_DATA, "%s", ", hard link"); } if (kea->data.mode & FSE_MODE_LAST_HLINK) { mlen += snprintf(msg + mlen, MAX_DATA, "%s", ", link count zero now"); } mlen += snprintf(msg + mlen, MAX_DATA, "%s", "\n"); break; case FSE_ARG_GID: // a group ID g = getgrgid(kea->data.gid); mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d (%s)\n", "gid", kea->data.gid, (g) ? g->gr_name : "?"); // This is usually the last value before everything repeats. Inc det det += 1; break; case FSE_ARG_INT64: // timestamp mlen += snprintf(msg + mlen, MAX_DATA, " %s: %llu\n", "tstamp", kea->data.timestamp); break; default: mlen += snprintf(msg + mlen, MAX_DATA, " %s = ?\n", "unknown"); break; } kea = (kfs_event_arg_t *)((char *)kea + eoff); // next } // for each argument } // for each event } // forever close(clonefd); // Only close output file if it is not stdout if (argc == 2) { fclose(onf); } exit(0); }
int startMyftpClient(struct sockaddr_in *servaddr, const char *filename) { int socketfd; if((socketfd= socket(AF_INET,SOCK_DGRAM,0))<0){ perror("Socket Error!"); exit(1); } /*set time out*/ struct timeval timeout = {3,0}; if(setsockopt(socketfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(struct timeval)) != 0){ perror("setsockopt for time out"); exit(1); } struct myFtphdr *packet_FRQ; int f_len = strlen(filename)+1; int FRQ_size = f_len+4; packet_FRQ =(struct myFtphdr *)malloc(FRQ_size); bzero(packet_FRQ,FRQ_size); packet_FRQ->mf_opcode = htons(FRQ); packet_FRQ->mf_cksum=htons(0); strcpy(packet_FRQ->mf_filename,filename); packet_FRQ->mf_cksum=in_cksum((unsigned short *)packet_FRQ,FRQ_size); if(sendto(socketfd,packet_FRQ,FRQ_size,0,(struct sockaddr *)servaddr,sizeof(struct sockaddr_in)) == -1){ exit(1); } FILE *fin; char recv_file[FNAMELEN]; sprintf(recv_file,"client_%s",filename); fin=fopen(recv_file,"wb"); //Function: Get file printf("file transmission start!!\n"); printf("get file : <%s> from IP:%s\n",filename,inet_ntoa(servaddr->sin_addr)); //data packet struct myFtphdr *data_packet; int data_packet_size = MFMAXDATA+6; data_packet = (struct myFtphdr *)malloc(data_packet_size); //ACK and ERROR packet struct myFtphdr *ACK_ERROR_packet; int ACK_ERROR_size = 6; ACK_ERROR_packet = (struct myFtphdr *)malloc(ACK_ERROR_size); int sockaddr_len = sizeof(struct sockaddr_in); int block = 0; int recv; while(1){ //MSG_WAITALL bzero(data_packet,data_packet_size); if((recv = recvfrom(socketfd,data_packet,data_packet_size,0,(struct sockaddr*)servaddr,&sockaddr_len))<0){ //check the FRQ is arrived or not if(block == 0){ //if block == 1,this means we have not received the data block 1 //so,the server may not receive FRQ or the block 1 has lost //FRQ can be regard as request for block 1 printf("time out!! send FRQ packet again\n"); if(sendto(socketfd,packet_FRQ,FRQ_size,0,(struct sockaddr *)servaddr,sizeof(struct sockaddr_in)) == -1){ exit(1); } continue; } //client has received block 1 printf("time out waiting data,request server to resend\n"); send_packet(socketfd,ACK_ERROR_packet,servaddr,block,ERROR,ACK_ERROR_size); } else if(in_cksum((unsigned short *)data_packet,data_packet_size)!=0){ //receive data has error bit printf("received data checksum error\n"); send_packet(socketfd,ACK_ERROR_packet,servaddr,block,ERROR,ACK_ERROR_size); } else if(ntohs(data_packet->mf_opcode) == DATA && ntohs(data_packet->mf_block) == block+1){ printf("receive data for block = %d\n",ntohs(data_packet->mf_block)); int write_bytes = recv-6; fwrite(data_packet->mf_data,1,write_bytes,fin); /*printf("write_bytes = %d\n",write_bytes);*/ if(write_bytes<MFMAXDATA){ printf("file transmission finish!!\n"); block = 0; send_packet(socketfd,ACK_ERROR_packet,servaddr,block,ACK,ACK_ERROR_size); fclose(fin); break; } else{ //send ACK block = ntohs(data_packet->mf_block); send_packet(socketfd,ACK_ERROR_packet,servaddr,block,ACK,ACK_ERROR_size); printf("send ack = %d\n",block); if(block == 65534){ block = 1; } } }else if(ntohs(data_packet->mf_opcode) == DATA && ntohs(data_packet->mf_block) != block+1){ //server dose not receive previous ack packet,send again int previous = ntohs(data_packet->mf_block); send_packet(socketfd,ACK_ERROR_packet,servaddr,previous,ACK,ACK_ERROR_size); } } return 0; }
/** * Handle the incoming content messages. Extracts the data, and * requests the next block in sequence if the received block was * not the final one. */ enum ccn_upcall_res incoming_content(struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { struct ccn_charbuf *name = NULL; struct ccn_charbuf *templ = NULL; const unsigned char *ccnb = NULL; size_t ccnb_size = 0; const unsigned char *data = NULL; size_t data_size = 0; size_t written; const unsigned char *ib = NULL; /* info->interest_ccnb */ struct ccn_indexbuf *ic = NULL; int res; struct mydata *md = selfp->data; if (kind == CCN_UPCALL_FINAL) { if (md != NULL) { selfp->data = NULL; free(md); md = NULL; } return(CCN_UPCALL_RESULT_OK); } if (kind == CCN_UPCALL_INTEREST_TIMED_OUT) { printf("le timeout!\n"); return(CCN_UPCALL_RESULT_REEXPRESS); } if (kind == CCN_UPCALL_CONTENT_UNVERIFIED) return(CCN_UPCALL_RESULT_VERIFY); if (kind != CCN_UPCALL_CONTENT) return(CCN_UPCALL_RESULT_ERR); if (md == NULL) selfp->data = md = calloc(1, sizeof(*md)); ccnb = info->content_ccnb; ccnb_size = info->pco->offset[CCN_PCO_E]; ib = info->interest_ccnb; ic = info->interest_comps; res = ccn_content_get_value(ccnb, ccnb_size, info->pco, &data, &data_size); if (res < 0) abort(); if (info->pco->type != CCN_CONTENT_DATA) { /* For us this is spam. For now, give up. */ fprintf(stderr, "*** spammed at block %d\n", (int)selfp->intdata); exit(1); } /* OK, we will accept this block. */ if (data_size == 0) *(md->done) = 1; else { written = fwrite(data, data_size, 1, stderr); if(data_size > 500) { printf("Pack: %lu\n size:%d\n", atoi(data), data_size); send_packet(data, data_size); } if (written != 1) exit(1); } // XXX The test below should get refactored into the library if (info->pco->offset[CCN_PCO_B_FinalBlockID] != info->pco->offset[CCN_PCO_E_FinalBlockID]) { const unsigned char *finalid = NULL; size_t finalid_size = 0; const unsigned char *nameid = NULL; size_t nameid_size = 0; struct ccn_indexbuf *cc = info->content_comps; ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb, info->pco->offset[CCN_PCO_B_FinalBlockID], info->pco->offset[CCN_PCO_E_FinalBlockID], &finalid, &finalid_size); if (cc->n < 2) abort(); ccn_ref_tagged_BLOB(CCN_DTAG_Component, ccnb, cc->buf[cc->n - 2], cc->buf[cc->n - 1], &nameid, &nameid_size); if (finalid_size == nameid_size && 0 == memcmp(finalid, nameid, nameid_size)) *(md->done) = 1; } if (*(md->done)) { ccn_set_run_timeout(info->h, 0); return(CCN_UPCALL_RESULT_OK); } /* Ask for the next fragment */ name = ccn_charbuf_create(); ccn_name_init(name); if (ic->n < 2) abort(); res = ccn_name_append_components(name, ib, ic->buf[0], ic->buf[ic->n - 2]); if (res < 0) abort(); ccn_name_append_numeric(name, CCN_MARKER_SEQNUM, ++(selfp->intdata)); templ = make_template(md, info); //printf("Expressing interest!\n"); //usleep(50); res = ccn_express_interest(info->h, name, selfp, templ); if (res < 0) abort(); ccn_charbuf_destroy(&templ); ccn_charbuf_destroy(&name); return(CCN_UPCALL_RESULT_OK); }
void handle_packet(apacket *p, atransport *t) { D("handle_packet() %c%c%c%c", ((char*) (&(p->msg.command)))[0], ((char*) (&(p->msg.command)))[1], ((char*) (&(p->msg.command)))[2], ((char*) (&(p->msg.command)))[3]); print_packet("recv", p); switch(p->msg.command){ case A_SYNC: if (p->msg.arg0){ send_packet(p, t); #if ADB_HOST send_connect(t); #endif } else { t->connection_state = kCsOffline; handle_offline(t); send_packet(p, t); } return; case A_CNXN: // CONNECT(version, maxdata, "system-id-string") handle_new_connection(t, p); break; case A_AUTH: if (p->msg.arg0 == ADB_AUTH_TOKEN) { t->connection_state = kCsUnauthorized; send_auth_response(p->data, p->msg.data_length, t); } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) { if (adb_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) { adb_auth_verified(t); t->failed_auth_attempts = 0; } else { if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000); send_auth_request(t); } } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) { adb_auth_confirm_key(p->data, p->msg.data_length, t); } break; case A_OPEN: /* OPEN(local-id, 0, "destination") */ if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) { char *name = (char*) p->data; name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0; asocket* s = create_local_service_socket(name, t); if (s == nullptr) { send_close(0, p->msg.arg0, t); } else { s->peer = create_remote_socket(p->msg.arg0, t); s->peer->peer = s; send_ready(s->id, s->peer->id, t); s->ready(s); } } break; case A_OKAY: /* READY(local-id, remote-id, "") */ if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) { asocket* s = find_local_socket(p->msg.arg1, 0); if (s) { if(s->peer == 0) { /* On first READY message, create the connection. */ s->peer = create_remote_socket(p->msg.arg0, t); s->peer->peer = s; s->ready(s); } else if (s->peer->id == p->msg.arg0) { /* Other READY messages must use the same local-id */ s->ready(s); } else { D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s", p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial); } } else { // When receiving A_OKAY from device for A_OPEN request, the host server may // have closed the local socket because of client disconnection. Then we need // to send A_CLSE back to device to close the service on device. send_close(p->msg.arg1, p->msg.arg0, t); } } break; case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */ if (t->online && p->msg.arg1 != 0) { asocket* s = find_local_socket(p->msg.arg1, p->msg.arg0); if (s) { /* According to protocol.txt, p->msg.arg0 might be 0 to indicate * a failed OPEN only. However, due to a bug in previous ADB * versions, CLOSE(0, remote-id, "") was also used for normal * CLOSE() operations. * * This is bad because it means a compromised adbd could * send packets to close connections between the host and * other devices. To avoid this, only allow this if the local * socket has a peer on the same transport. */ if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) { D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s", p->msg.arg1, t->serial, s->peer->transport->serial); } else { s->close(s); } } } break; case A_WRTE: /* WRITE(local-id, remote-id, <data>) */ if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) { asocket* s = find_local_socket(p->msg.arg1, p->msg.arg0); if (s) { unsigned rid = p->msg.arg0; p->len = p->msg.data_length; if (s->enqueue(s, p) == 0) { D("Enqueue the socket"); send_ready(s->id, rid, t); } return; } } break; default: printf("handle_packet: what is %08x?!\n", p->msg.command); } put_apacket(p); }
static int elp_start_xmit(struct sk_buff *skb, struct device *dev) { elp_device * adapter = (elp_device *) dev->priv; CHECK_NULL(dev); /* * not sure what this does, but the 3c509 driver does it, so... */ if (skb == NULL) { dev_tint(dev); return 0; } /* * Fill in the ethernet header * (for kernels prior to 1.1.4 only) */ #if (ELP_KERNEL_TYPE < 2) IS_SKB(skb); if (!skb->arp && dev->rebuild_header(SKB_DATA, dev)) { skb->dev = dev; IS_SKB(skb); arp_queue (skb); return 0; } #endif /* * if we ended up with a munged length, don't send it */ if (skb->len <= 0) return 0; if (elp_debug >= 3) printk("%s: request to send packet of length %d\n", dev->name, (int)skb->len); /* * if the transmitter is still busy, we have a transmit timeout... */ if (dev->tbusy) { int tickssofar = jiffies - dev->trans_start; if (tickssofar < 200) /* was 500, AJT */ return 1; printk("%s: transmit timed out, resetting adapter\n", dev->name); if ((INB(adapter->io_addr+PORT_STATUS)&STATUS_ACRF) != 0) printk("%s: hmmm...seemed to have missed an interrupt!\n", dev->name); adapter_reset(adapter); dev->trans_start = jiffies; dev->tbusy = 0; } /* * send the packet at skb->data for skb->len */ if (!send_packet(adapter, (unsigned char *)SKB_DATA, skb->len)) { printk("%s: send packet PCB failed\n", dev->name); return 1; } if (elp_debug >= 3) printk("%s: packet of length %d sent\n", dev->name, (int)skb->len); /* * start the transmit timeout */ dev->trans_start = jiffies; /* * the transmitter is now busy */ dev->tbusy = 1; /* * if we have been asked to free the buffer, do so */ #if (ELP_KERNEL_TYPE < 4) if (skb->free) { IS_SKB(skb); kfree_skb(skb, FREE_WRITE); } #else dev_kfree_skb(skb, FREE_WRITE); #endif return 0; }
static int accept(struct socket *sock, struct socket *new_sock, int flags) { struct sock *sk = sock->sk; struct sk_buff *buf; int res; lock_sock(sk); if (sock->state != SS_LISTENING) { res = -EINVAL; goto exit; } while (skb_queue_empty(&sk->sk_receive_queue)) { if (flags & O_NONBLOCK) { res = -EWOULDBLOCK; goto exit; } release_sock(sk); res = wait_event_interruptible(*sk_sleep(sk), (!skb_queue_empty(&sk->sk_receive_queue))); lock_sock(sk); if (res) goto exit; } buf = skb_peek(&sk->sk_receive_queue); res = tipc_create(sock_net(sock->sk), new_sock, 0, 0); if (!res) { struct sock *new_sk = new_sock->sk; struct tipc_sock *new_tsock = tipc_sk(new_sk); struct tipc_port *new_tport = new_tsock->p; u32 new_ref = new_tport->ref; struct tipc_msg *msg = buf_msg(buf); lock_sock(new_sk); /* * Reject any stray messages received by new socket * before the socket lock was taken (very, very unlikely) */ reject_rx_queue(new_sk); /* Connect new socket to it's peer */ new_tsock->peer_name.ref = msg_origport(msg); new_tsock->peer_name.node = msg_orignode(msg); tipc_connect2port(new_ref, &new_tsock->peer_name); new_sock->state = SS_CONNECTED; tipc_set_portimportance(new_ref, msg_importance(msg)); if (msg_named(msg)) { new_tport->conn_type = msg_nametype(msg); new_tport->conn_instance = msg_nameinst(msg); } /* * Respond to 'SYN-' by discarding it & returning 'ACK'-. * Respond to 'SYN+' by queuing it on new socket. */ if (!msg_data_sz(msg)) { struct msghdr m = {NULL,}; advance_rx_queue(sk); send_packet(NULL, new_sock, &m, 0); } else { __skb_dequeue(&sk->sk_receive_queue); __skb_queue_head(&new_sk->sk_receive_queue, buf); } release_sock(new_sk); } exit: release_sock(sk); return res; }
static int send_stream(struct kiocb *iocb, struct socket *sock, struct msghdr *m, size_t total_len) { struct sock *sk = sock->sk; struct tipc_port *tport = tipc_sk_port(sk); struct msghdr my_msg; struct iovec my_iov; struct iovec *curr_iov; int curr_iovlen; char __user *curr_start; u32 hdr_size; int curr_left; int bytes_to_send; int bytes_sent; int res; lock_sock(sk); /* Handle special cases where there is no connection */ if (unlikely(sock->state != SS_CONNECTED)) { if (sock->state == SS_UNCONNECTED) { res = send_packet(NULL, sock, m, total_len); goto exit; } else if (sock->state == SS_DISCONNECTING) { res = -EPIPE; goto exit; } else { res = -ENOTCONN; goto exit; } } if (unlikely(m->msg_name)) { res = -EISCONN; goto exit; } if ((total_len > (unsigned)INT_MAX) || (m->msg_iovlen > (unsigned)INT_MAX)) { res = -EMSGSIZE; goto exit; } /* * Send each iovec entry using one or more messages * * Note: This algorithm is good for the most likely case * (i.e. one large iovec entry), but could be improved to pass sets * of small iovec entries into send_packet(). */ curr_iov = m->msg_iov; curr_iovlen = m->msg_iovlen; my_msg.msg_iov = &my_iov; my_msg.msg_iovlen = 1; my_msg.msg_flags = m->msg_flags; my_msg.msg_name = NULL; bytes_sent = 0; hdr_size = msg_hdr_sz(&tport->phdr); while (curr_iovlen--) { curr_start = curr_iov->iov_base; curr_left = curr_iov->iov_len; while (curr_left) { bytes_to_send = tport->max_pkt - hdr_size; if (bytes_to_send > TIPC_MAX_USER_MSG_SIZE) bytes_to_send = TIPC_MAX_USER_MSG_SIZE; if (curr_left < bytes_to_send) bytes_to_send = curr_left; my_iov.iov_base = curr_start; my_iov.iov_len = bytes_to_send; res = send_packet(NULL, sock, &my_msg, bytes_to_send); if (res < 0) { if (bytes_sent) res = bytes_sent; goto exit; } curr_left -= bytes_to_send; curr_start += bytes_to_send; bytes_sent += bytes_to_send; } curr_iov++; } res = bytes_sent; exit: release_sock(sk); return res; }
int main() { struct termios boardSettings; struct termios oldBoardSettings; int board; int sent; printf("INPUT TERMINAL\n\n"); printf("Trying to connect to the board..."); board = open_board(&oldBoardSettings, &boardSettings); if( board < 0 ) { printf("Error: connection to board failed."); return 1; } char ctty = 0; char cboard = 0; printf("Connection successful!\n\n"); while(1) { printf("user> "); packet_t p; p.header = 0x0; p.command = 0x0; ctty = getchar_tty(); switch(ctty) { case '1': printf("pc> turn on led1.\n"); p.header = SET_LED; p.command = LED1; break; case '2': p.header = SET_LED; p.command = LED2; break; case '3': p.header = SET_LED; p.command = LED3; break; case '4': p.header = SET_LED; p.command = LED4; break; case 'q': break; default: ctty = 0; printf("pc> Command not recognized.\n"); }; if(ctty == 'q') break; if(ctty) send_packet(board, p); sleep(1); //give time to board to write output while( (cboard = getchar_board(board)) ) printf("%c", cboard); } printf("\nEnd of communication.\n"); close_board(board, &oldBoardSettings); return 0; }
int sendACK(struct dhcpMessage *oldpacket, u_int32_t yiaddr) { struct dhcpMessage packet; struct option_set *curr; struct dhcpOfferedAddr *offerlist; char *lease_time, *vendorid, *userclsid; char length = 0; u_int32_t lease_time_align = cur_iface->lease; struct in_addr addr; //brcm begin char VIinfo[VENDOR_IDENTIFYING_INFO_LEN]; char *req; int saveVIoptionNeeded = 0; //brcm end init_packet(&packet, oldpacket, DHCPACK); packet.yiaddr = yiaddr; if ((lease_time = (char *)get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > cur_iface->lease) lease_time_align = cur_iface->lease; else if (lease_time_align < server_config.min_lease) lease_time_align = cur_iface->lease; } //<< jojopo : wifi leasetime 300 seconds , 2015/12/25 if(isHostFromWireless(packet.chaddr)) lease_time_align = 300; //>> jojopo : end add_simple_option(packet.options, DHCP_LEASE_TIME, lease_time_align); curr = cur_iface->options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); //brcm begin /* if DHCPRequest from client has device identity, send back gateway identity, and save the device identify */ if ((req = (char *)get_option(oldpacket, DHCP_VENDOR_IDENTIFYING))) { if (createVIoption(VENDOR_IDENTIFYING_FOR_GATEWAY, VIinfo) != -1) { add_option_string(packet.options, (unsigned char *)VIinfo); } saveVIoptionNeeded = 1; } //brcm end addr.s_addr = packet.yiaddr; LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(addr)); if (send_packet(&packet, 0) < 0) return -1; add_lease(packet.chaddr, packet.yiaddr, lease_time_align); offerlist = find_lease_by_chaddr(packet.chaddr); if (saveVIoptionNeeded) { saveVIoption(req,offerlist); } vendorid = (char *)get_option(oldpacket, DHCP_VENDOR); userclsid = (char *)get_option(oldpacket, DHCP_USER_CLASS_ID); memset(offerlist->classid, 0, sizeof(offerlist->classid)); memset(offerlist->vendorid, 0, sizeof(offerlist->vendorid)); if( vendorid != NULL){ length = *(vendorid - 1); memcpy(offerlist->vendorid, vendorid, (size_t)length); offerlist->vendorid[(int)length] = '\0'; } if( userclsid != NULL){ length = *(userclsid - 1); memcpy(offerlist->classid, userclsid, (size_t)length); offerlist->classid[(int)length] = '\0'; } return 0; }
/* send a DHCP OFFER to a DHCP DISCOVER */ int sendOffer(struct dhcpMessage *oldpacket) { struct dhcpMessage packet; struct dhcpOfferedAddr *lease = NULL; u_int32_t req_align, lease_time_align = cur_iface->lease; char *req, *lease_time; struct option_set *curr; struct in_addr addr; //For static IP lease uint32_t static_lease_ip; //brcm begin char VIinfo[VENDOR_IDENTIFYING_INFO_LEN]; //brcm end init_packet(&packet, oldpacket, DHCPOFFER); //For static IP lease static_lease_ip = getIpByMac(cur_iface->static_leases, oldpacket->chaddr); if(!static_lease_ip) { /* the client is in our lease/offered table */ if ((lease = find_lease_by_chaddr(oldpacket->chaddr))) { if (!lease_expired(lease)) lease_time_align = lease->expires - time(0); packet.yiaddr = lease->yiaddr; /* Or the client has a requested ip */ } else if ((req = (char *)get_option(oldpacket, DHCP_REQUESTED_IP)) && /* Don't look here (ugly hackish thing to do) */ memcpy(&req_align, req, 4) && /* and the ip is in the lease range */ ntohl(req_align) >= ntohl(cur_iface->start) && ntohl(req_align) <= ntohl(cur_iface->end) && /* and its not already taken/offered */ ((!(lease = find_lease_by_yiaddr(req_align)) || /* or its taken, but expired */ lease_expired(lease)))) { packet.yiaddr = req_align; /* otherwise, find a free IP */ } else { packet.yiaddr = find_address(0); /* try for an expired lease */ if (!packet.yiaddr) packet.yiaddr = find_address(1); } if(!packet.yiaddr) { LOG(LOG_WARNING, "no IP addresses to give -- " "OFFER abandoned"); return -1; } if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) { LOG(LOG_WARNING, "lease pool is full -- " "OFFER abandoned"); return -1; } if ((lease_time = (char *)get_option(oldpacket, DHCP_LEASE_TIME))) { memcpy(&lease_time_align, lease_time, 4); lease_time_align = ntohl(lease_time_align); if (lease_time_align > cur_iface->lease) lease_time_align = cur_iface->lease; } /* Make sure we aren't just using the lease time from the * previous offer */ if (lease_time_align < server_config.min_lease) lease_time_align = cur_iface->lease; //<< jojopo : wifi leasetime 300 seconds , 2015/12/25 if(isHostFromWireless(packet.chaddr)) lease_time_align = 300; //>> jojopo : end } else { /* It is a static lease... use it */ packet.yiaddr = static_lease_ip; } add_simple_option(packet.options, DHCP_LEASE_TIME, lease_time_align); curr = cur_iface->options; while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) add_option_string(packet.options, curr->data); curr = curr->next; } add_bootp_options(&packet); //brcm begin /* if DHCPDISCOVER from client has device identity, send back gateway identity */ if ((req = (char *)get_option(oldpacket, DHCP_VENDOR_IDENTIFYING))) { if (createVIoption(VENDOR_IDENTIFYING_FOR_GATEWAY, VIinfo) != -1) add_option_string(packet.options, (unsigned char *)VIinfo); } //brcm end addr.s_addr = packet.yiaddr; LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(addr)); return send_packet(&packet, 0); }
/* Loop for downloading file, parameters: int sock - socket to be used int type - type of the instance (server or client) Returns pointer to first filedata block, stops the loops when receiving error */ int download_mode_loop(clientnode *cl) { int n = 0, packet_len = 0, rv = 0; int returnval = 1; struct timeval to; packet *pck = NULL; data_packet *d_pck = NULL; error_packet *e_pck = NULL; fd_set s_set; FD_ZERO(&s_set); while((cl->state == RUN) || (cl->state == WAIT)) { /* Set timeout values */ to.tv_sec = TIMEOUT_SEC; to.tv_usec = cl->timeout; FD_SET(cl->socket,&s_set); /* Check if there is something in socket */ rv = select(cl->socket+1,&s_set,NULL,NULL,&to); if(rv < 0) { pck = encode_error_packet(ERROR_NOT_DEFINED); send_packet(cl->socket,pck); perror("Error in select()"); cl->state = STOP; returnval = -1; } /* If got something */ else if(rv > 0) { if(FD_ISSET(cl->socket,&s_set)) /* Used socket has something */ { /* Read packet and backup length */ pck = read_packet(cl->socket); packet_len = pck->length; /* Reset timeout */ cl->timeout = TIMEOUT_USEC; /* If packet is less than 4 bytes or greater than 516 bytes (MAX_MSG) discard it */ if((packet_len < 4) || (packet_len > MAX_MSG)) { pck = encode_error_packet(ERROR_ILLEGAL_OPERATION); error_minor("Invalid packet size, discarding"); send_packet(cl->socket,pck); } /* Otherwise check the packet */ else { if((d_pck = decode_data_packet(pck)) == NULL) { pck = encode_error_packet(ERROR_NOT_DEFINED); send_packet(cl->socket,pck); perror("Error decoding packet"); cl->state = STOP; returnval = -1; break; } /* If it is a DATA packet */ if(ntohs(d_pck->opcode) == OPCODE_DATA) { //printf("GOT: %d (%d bytes)\n",ntohs(d_pck->blockno),packet_len); /* Check blocknumber that it is the same as waited block*/ if(ntohs(d_pck->blockno) == cl->lastpacket) { if(packet_len == 4) { cl->state = STOP; returnval = 1; break; /* If data packet with 0 data -> last packet */ } /* Add data packet to fileblock list */ cl->data = add_data_packet(cl->data,d_pck,packet_len); if(write_block_to_file(cl) == -1) { pck = encode_error_packet(ERROR_ACCESS_VIOLATION); send_packet(cl->socket,pck); cl->state = STOP; } /* Create ack packet for this packet and send it */ pck = encode_ack_packet(ntohs(d_pck->blockno)); n = send_packet(cl->socket,pck); //printf("Sent ACK: %d\n",ntohs(d_pck->blockno)); /* Increase the block counter */ cl->lastpacket += 1; /* If got less data than max 512 bytes -> last packet */ if(packet_len != MAX_MSG) { cl->state = STOP; returnval = 1; break; } else cl->state = RUN; } } /* If it is an error packet, decode it, print message and stop */ else if(ntohs(d_pck->opcode) == OPCODE_ERROR) { e_pck = decode_error_packet(pck); printf("Error: %s\n",e_pck->content); cl->state = STOP; returnval = -1; break; } /* Otherwise a errorous packet */ else { printf("Erroreus packet"); pck = encode_error_packet(ERROR_ILLEGAL_OPERATION); send_packet(cl->socket,pck); cl->state = STOP; returnval = -1; break; } } } } /* If timeout happened, send re-ack if not waiting for first block */ else { /* client cannot send ack with block number 0 */ if(cl->lastpacket != 1) { pck = encode_ack_packet(cl->lastpacket-1); n = send_packet(cl->socket,pck); } cl->state = WAIT; cl->timeout += TIMEOUT_ADD; /* If max reached */ if(cl->timeout == TIMEOUT_MAX) { printf("Timeout happened.\n"); cl->state = STOP; returnval = -1; } } } free(pck); free(d_pck); return returnval; }
/*---------------------------------------------------------------------------*/ static void qsend_list(mac_callback_t sent, void *ptr, struct rdc_buf_list *buf_list) { struct rdc_buf_list *curr; struct rdc_buf_list *next; int ret; int is_receiver_awake; if(buf_list == NULL) { return; } /* Do not send during reception of a burst */ if(we_are_receiving_burst) { /* Prepare the packetbuf for callback */ queuebuf_to_packetbuf(buf_list->buf); /* Return COLLISION so the MAC may try again later */ mac_call_sent_callback(sent, ptr, MAC_TX_COLLISION, 1); return; } /* Create and secure frames in advance */ curr = buf_list; do { next = list_item_next(curr); queuebuf_to_packetbuf(curr->buf); if(!packetbuf_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED)) { /* create and secure this frame */ if(next != NULL) { packetbuf_set_attr(PACKETBUF_ATTR_PENDING, 1); } packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); if(NETSTACK_FRAMER.create_and_secure() < 0) { PRINTF("contikimac: framer failed\n"); mac_call_sent_callback(sent, ptr, MAC_TX_ERR_FATAL, 1); return; } packetbuf_set_attr(PACKETBUF_ATTR_IS_CREATED_AND_SECURED, 1); queuebuf_update_from_packetbuf(curr->buf); } curr = next; } while(next != NULL); /* The receiver needs to be awoken before we send */ is_receiver_awake = 0; curr = buf_list; do { /* A loop sending a burst of packets from buf_list */ next = list_item_next(curr); /* Prepare the packetbuf */ queuebuf_to_packetbuf(curr->buf); /* Send the current packet */ ret = send_packet(sent, ptr, curr, is_receiver_awake); if(ret != MAC_TX_DEFERRED) { mac_call_sent_callback(sent, ptr, ret, 1); } if(ret == MAC_TX_OK) { if(next != NULL) { /* We're in a burst, no need to wake the receiver up again */ is_receiver_awake = 1; curr = next; } } else { /* The transmission failed, we stop the burst */ next = NULL; } } while((next != NULL) && packetbuf_attr(PACKETBUF_ATTR_PENDING)); }
/* Loop for uploading a file for client, parameters: int sock - socket used for sending filedata *files - pointer to first fileblock Returns 0 if successful, stops the loop if an error message is received */ int upload_mode_loop(clientnode *cl) { int n = 0, rv = 0, returnval = 1, last_round = 0; struct timeval to; packet *pck = NULL; ack_packet *a_pck = NULL; error_packet *e_pck = NULL; fd_set s_set; FD_ZERO(&s_set); /* Start uploading */ while(cl->state == RUN || cl->state == WAIT) { /* Timeout values */ to.tv_sec = TIMEOUT_SEC; to.tv_usec = cl->timeout; FD_SET(cl->socket,&s_set); /* Create data packet and send it, quit if sent less than package size */ pck = encode_data_packet(cl->data); if((n = send_packet(cl->socket,pck)) < pck->length) printf("Sent less than package size!"); //printf("SENT: %d (%d bytes)\n",cl->data->block_id, cl->data->length); /* Check socket */ rv = select(cl->socket+1,&s_set,NULL,NULL,&to); if(rv < 0) { pck = encode_error_packet(ERROR_NOT_DEFINED); send_packet(cl->socket,pck); error("Error in select()"); } /* If got something */ else if (rv > 0) { if(FD_ISSET(cl->socket,&s_set)) { /* Read packet */ pck = read_packet(cl->socket); /* Reset timeout */ cl->timeout = TIMEOUT_USEC; /* Check length */ if(pck->length == 4) { /* Decode ack packet */ a_pck = decode_ack_packet(pck); if(ntohs(a_pck->opcode) == OPCODE_ACK) { /* check that the blocknumbers match */ if(ntohs(a_pck->blockno) == cl->data->block_id) { //printf("ACK: %d for packet: %d\n",ntohs(a_pck->blockno),cl->data->block_id); if(last_round == 1) { returnval = 1; cl->state = STOP; break; } n = read_file_to_block(cl); /* EOF */ if(n == 0) { cl->state = RUN; last_round = 1; returnval = 1; } /* Data */ else if(n != -1) { /* If last block */ if(n < TFTP_BLOCK) last_round = 1; cl->state = RUN; returnval = 1; } /* Error */ else { pck = encode_error_packet(ERROR_ACCESS_VIOLATION); send_packet(cl->socket,pck); cl->state = STOP; returnval = -1; } } } /* If it is an error packet with empty message */ /* This is highly unlikely scenario */ else if(ntohs(a_pck->opcode) == OPCODE_ERROR) { e_pck = decode_error_packet(pck); printf("Error code %d\n",ntohs(e_pck->errcode)); return -1; } /* Otherwise got something illegal, send error message */ else { pck = encode_error_packet(ERROR_ILLEGAL_OPERATION); send_packet(cl->socket,pck); printf("Erroreus packet\n"); return -1; } } /* If the message is some other TFTP message */ else if((pck->length > 4) && (pck->length <= MAX_MSG)) { e_pck = decode_error_packet(pck); /* Check if it is an error message and print the message */ if(ntohs(e_pck->opcode) == OPCODE_ERROR) { e_pck = decode_error_packet(pck); printf("Error: %s\n",e_pck->content); return -1; } /* Otherwise got something illegal, send error message */ else { pck = encode_error_packet(ERROR_ILLEGAL_OPERATION); send_packet(cl->socket,pck); printf("Erroreus packet\n"); return -1; } } /* Otherwise got something illegal, send error message */ else { pck = encode_error_packet(ERROR_ILLEGAL_OPERATION); send_packet(cl->socket,pck); printf("Erroreus packet\n"); return -1; } } } /* Timeout */ else { cl->state = WAIT; cl->timeout += TIMEOUT_ADD; /* If max reached */ if(cl->timeout == TIMEOUT_MAX) { printf("Timeout happened.\n"); cl->state = STOP; returnval = -1; } } } return returnval; }
void inmate_main(void) { enum { ROLE_UNDEFINED, ROLE_CONTROLLER, ROLE_TARGET } role; unsigned long min = -1, max = 0, rtt; struct eth_header *rx_packet; unsigned long long start; bool first_round = true; unsigned int n; u32 eerd, val; u8 mac[6]; u64 bar; int bdf; printk_uart_base = UART_BASE; bdf = pci_find_device(PCI_ID_ANY, PCI_ID_ANY, 0); if (bdf < 0) { printk("No device found!\n"); return; } printk("Found %04x:%04x at %02x:%02x.%x\n", pci_read_config(bdf, PCI_CFG_VENDOR_ID, 2), pci_read_config(bdf, PCI_CFG_DEVICE_ID, 2), bdf >> 8, (bdf >> 3) & 0x1f, bdf & 0x3); bar = pci_read_config(bdf, PCI_CFG_BAR, 4); if ((bar & 0x6) == 0x4) bar |= (u64)pci_read_config(bdf, PCI_CFG_BAR + 4, 4) << 32; mmiobar = (void *)(bar & ~0xfUL); map_range(mmiobar, 128 * 1024, MAP_UNCACHED); printk("MMIO register BAR at %p\n", mmiobar); pci_write_config(bdf, PCI_CFG_COMMAND, PCI_CMD_MEM | PCI_CMD_MASTER, 2); mmio_write32(mmiobar + E1000_REG_CTRL, E1000_CTRL_RST); delay_us(20000); val = mmio_read32(mmiobar + E1000_REG_CTRL); val &= ~(E1000_CTRL_LRST | E1000_CTRL_FRCSPD); val |= E1000_CTRL_ASDE | E1000_CTRL_SLU; mmio_write32(mmiobar + E1000_REG_CTRL, val); printk("Reset done, waiting for link..."); while (!(mmio_read32(mmiobar + E1000_REG_STATUS) & E1000_STATUS_LU)) cpu_relax(); printk(" ok\n"); if (mmio_read32(mmiobar + E1000_REG_RAH) & E1000_RAH_AV) { *(u32 *)mac = mmio_read32(mmiobar + E1000_REG_RAL); *(u16 *)&mac[4] = mmio_read32(mmiobar + E1000_REG_RAH); } else { for (n = 0; n < 3; n++) { mmio_write32(mmiobar + E1000_REG_EERD, E1000_EERD_START | (n << E1000_EERD_ADDR_SHIFT)); do { eerd = mmio_read32(mmiobar + E1000_REG_EERD); cpu_relax(); } while (!(eerd & E1000_EERD_DONE)); mac[n * 2] = (u8)(eerd >> E1000_EERD_DATA_SHIFT); mac[n * 2 + 1] = (u8)(eerd >> (E1000_EERD_DATA_SHIFT + 8)); } } printk("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); mmio_write32(mmiobar + E1000_REG_RAL, *(u32 *)mac); mmio_write32(mmiobar + E1000_REG_RAH, *(u16 *)&mac[4] | E1000_RAH_AV); for (n = 0; n < RX_DESCRIPTORS; n++) rx_ring[n].addr = (unsigned long)&buffer[n * RX_BUFFER_SIZE]; mmio_write32(mmiobar + E1000_REG_RDBAL, (unsigned long)&rx_ring); mmio_write32(mmiobar + E1000_REG_RDBAH, 0); mmio_write32(mmiobar + E1000_REG_RDLEN, sizeof(rx_ring)); mmio_write32(mmiobar + E1000_REG_RDH, 0); mmio_write32(mmiobar + E1000_REG_RDT, RX_DESCRIPTORS - 1); val = mmio_read32(mmiobar + E1000_REG_RCTL); val |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_BSIZE_2048 | E1000_RCTL_SECRC; mmio_write32(mmiobar + E1000_REG_RCTL, val); mmio_write32(mmiobar + E1000_REG_TDBAL, (unsigned long)&tx_ring); mmio_write32(mmiobar + E1000_REG_TDBAH, 0); mmio_write32(mmiobar + E1000_REG_TDLEN, sizeof(tx_ring)); mmio_write32(mmiobar + E1000_REG_TDH, 0); mmio_write32(mmiobar + E1000_REG_TDT, 0); val = mmio_read32(mmiobar + E1000_REG_TCTL); val |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_CT_DEF | E1000_TCTL_COLD_DEF; mmio_write32(mmiobar + E1000_REG_TCTL, val); mmio_write32(mmiobar + E1000_REG_TIPG, E1000_TIPG_IPGT_DEF | E1000_TIPG_IPGR1_DEF | E1000_TIPG_IPGR2_DEF); role = ROLE_UNDEFINED; memcpy(tx_packet.src, mac, sizeof(tx_packet.src)); memset(tx_packet.dst, 0xff, sizeof(tx_packet.dst)); tx_packet.type = FRAME_TYPE_ANNOUNCE; send_packet(&tx_packet, sizeof(tx_packet)); start = pm_timer_read(); while (pm_timer_read() - start < NS_PER_MSEC && role == ROLE_UNDEFINED) { rx_packet = packet_received(); if (!rx_packet) continue; if (rx_packet->type == FRAME_TYPE_TARGET_ROLE) { role = ROLE_TARGET; memcpy(tx_packet.dst, rx_packet->src, sizeof(tx_packet.dst)); } packet_reception_done(); } if (role == ROLE_UNDEFINED) { role = ROLE_CONTROLLER; printk("Waiting for peer\n"); while (1) { rx_packet = packet_received(); if (!rx_packet) continue; if (rx_packet->type == FRAME_TYPE_ANNOUNCE) { memcpy(tx_packet.dst, rx_packet->src, sizeof(tx_packet.dst)); packet_reception_done(); tx_packet.type = FRAME_TYPE_TARGET_ROLE; send_packet(&tx_packet, sizeof(tx_packet)); break; } else { packet_reception_done(); } } } mmio_write32(mmiobar + E1000_REG_RCTL, mmio_read32(mmiobar + E1000_REG_RCTL) & ~E1000_RCTL_BAM); if (role == ROLE_CONTROLLER) { printk("Running as controller\n"); tx_packet.type = FRAME_TYPE_PING; while (1) { start = pm_timer_read(); send_packet(&tx_packet, sizeof(tx_packet)); do rx_packet = packet_received(); while (!rx_packet || rx_packet->type != FRAME_TYPE_PONG); packet_reception_done(); if (!first_round) { rtt = pm_timer_read() - start; if (rtt < min) min = rtt; if (rtt > max) max = rtt; printk("Received pong, RTT: %6ld ns, " "min: %6ld ns, max: %6ld ns\n", rtt, min, max); } first_round = false; delay_us(100000); } } else { printk("Running as target\n"); tx_packet.type = FRAME_TYPE_PONG; while (1) { rx_packet = packet_received(); if (!rx_packet || rx_packet->type != FRAME_TYPE_PING) continue; packet_reception_done(); send_packet(&tx_packet, sizeof(tx_packet)); } } }
size_t send_message (interface_t *iface, dhcp_t *dhcp, unsigned long xid, char type, options_t *options) { dhcpmessage_t message; unsigned char *m = (unsigned char *) &message; unsigned char *p = (unsigned char *) &message.options; unsigned char *n_params = NULL; unsigned long l; struct in_addr from; struct in_addr to; if (!iface || !options || !dhcp) return -1; if (type == DHCP_RELEASE || type == DHCP_INFORM || (type == DHCP_REQUEST && iface->previous_address.s_addr == dhcp->address.s_addr)) from.s_addr = dhcp->address.s_addr; else from.s_addr = 0; if (type == DHCP_RELEASE) to.s_addr = dhcp->serveraddress.s_addr; else to.s_addr = 0; memset (&message, 0, sizeof (dhcpmessage_t)); message.op = DHCP_BOOTREQUEST; message.hwtype = ARPHRD_ETHER; message.hwlen = ETHER_ADDR_LEN; long up = uptime() - iface->start_uptime; if (up < 0 || up > UINT16_MAX) message.secs = htons (UINT16_MAX); else message.secs = htons (up); message.xid = xid; memcpy (&message.hwaddr, &iface->ethernet_address, ETHER_ADDR_LEN); message.cookie = htonl (MAGIC_COOKIE); /* This logic should be improved so that we don't need to set the 0 flag as it's done in the above memset statement */ if (type == DHCP_REQUEST && dhcp->address.s_addr == iface->previous_address.s_addr && iface->previous_address.s_addr != 0) message.flags = 0; else message.flags = htons (BROADCAST_FLAG); if (iface->previous_address.s_addr != 0 && (type == DHCP_INFORM || type == DHCP_RELEASE || (type == DHCP_REQUEST && iface->previous_address.s_addr == dhcp->address.s_addr))) message.ciaddr = iface->previous_address.s_addr; *p++ = DHCP_MESSAGETYPE; *p++ = 1; *p++ = type; if (type == DHCP_REQUEST) { *p++ = DHCP_MAXMESSAGESIZE; *p++ = 2; uint16_t sz = htons (sizeof (dhcpmessage_t)); memcpy (p, &sz, 2); p += 2; } #define PUTADDR(_type, _val) \ { \ *p++ = _type; \ *p++ = 4; \ memcpy (p, &_val.s_addr, 4); \ p += 4; \ } if (dhcp->address.s_addr != 0 && iface->previous_address.s_addr == 0 && type != DHCP_RELEASE) PUTADDR (DHCP_ADDRESS, dhcp->address); if (dhcp->serveraddress.s_addr != 0 && dhcp->address.s_addr !=0 && (iface->previous_address.s_addr == 0 || type == DHCP_RELEASE)) PUTADDR (DHCP_SERVERIDENTIFIER, dhcp->serveraddress); #undef PUTADDR if (type == DHCP_REQUEST || type == DHCP_DISCOVER) { if (options->leasetime != 0) { *p++ = DHCP_LEASETIME; *p++ = 4; uint32_t ul = htonl (options->leasetime); memcpy (p, &ul, 4); p += 4; } } if (type == DHCP_DISCOVER || type == DHCP_INFORM || type == DHCP_REQUEST) { *p++ = DHCP_PARAMETERREQUESTLIST; n_params = p; *p++ = 0; /* If we don't request one item, then we get defaults back which we don't want */ if (type == DHCP_DISCOVER) { *p++ = DHCP_DNSSERVER; } else { *p++ = DHCP_RENEWALTIME; *p++ = DHCP_REBINDTIME; *p++ = DHCP_NETMASK; *p++ = DHCP_BROADCAST; *p++ = DHCP_CSR; /* RFC 3442 states classless static routes should be before routers * and static routes as classless static routes override them both */ *p++ = DHCP_ROUTERS; *p++ = DHCP_STATICROUTE; *p++ = DHCP_HOSTNAME; *p++ = DHCP_DNSSEARCH; *p++ = DHCP_DNSDOMAIN; *p++ = DHCP_DNSSERVER; *p++ = DHCP_NISDOMAIN; *p++ = DHCP_NISSERVER; *p++ = DHCP_NTPSERVER; /* These parameters were requested by dhcpcd-2.0 and earlier but we never did anything with them */ /* *p++ = DHCP_DEFAULTIPTTL; *p++ = DHCP_MASKDISCOVERY; *p++ = DHCP_ROUTERDISCOVERY; */ } *n_params = p - n_params - 1; } if (type == DHCP_REQUEST) { if (options->hostname) { if (options->fqdn == FQDN_DISABLE) { *p++ = DHCP_HOSTNAME; *p++ = l = strlen (options->hostname); memcpy (p, options->hostname, l); p += l; } else { /* Draft IETF DHC-FQDN option (81) */ *p++ = DHCP_FQDN; *p++ = (l = strlen (options->hostname)) + 3; /* Flags: 0000NEOS * S: 1 => Client requests Server to update A RR in DNS as well as PTR * O: 1 => Server indicates to client that DNS has been updated * E: 1 => Name data is DNS format * N: 1 => Client requests Server to not update DNS */ *p++ = options->fqdn & 0x9; *p++ = 0; /* rcode1, response from DNS server for PTR RR */ *p++ = 0; /* rcode2, response from DNS server for A RR if S=1 */ memcpy (p, options->hostname, l); p += l; } } } if (type != DHCP_DECLINE && type != DHCP_RELEASE) { if (options->userclass) { *p++ = DHCP_USERCLASS; *p++ = options->userclass_len; memcpy (p, &options->userclass, options->userclass_len); p += options->userclass_len; } *p++ = DHCP_CLASSID; *p++ = l = strlen (options->classid); memcpy (p, options->classid, l); p += l; } *p++ = DHCP_CLIENTID; if (options->clientid[0]) { l = strlen (options->clientid); *p++ = l + 1; *p++ = 0; /* string */ memcpy (p, options, l); p += l; } else { *p++ = ETHER_ADDR_LEN + 1; *p++ = ARPHRD_ETHER; memcpy (p, &iface->ethernet_address, ETHER_ADDR_LEN); p += ETHER_ADDR_LEN; } *p++ = DHCP_END; unsigned int message_length = p - m; struct udp_dhcp_packet packet; memset (&packet, 0, sizeof (struct udp_dhcp_packet)); make_dhcp_packet (&packet, (unsigned char *) &message, message_length, from, to); logger (LOG_DEBUG, "Sending %s with xid %d", dhcp_message[(int) type], xid); return send_packet (iface, ETHERTYPE_IP, (unsigned char *) &packet, message_length + sizeof (struct ip) + sizeof (struct udphdr)); }
/** * GET function * Performs the receiving half of a request */ void get(SOCKET s, SOCKADDR_IN sa, char * username, char* filename, int client_num, int server_num, FILE* logfile){ char buffer[FRAME_SIZE]; int count, offset, recv, filesize, size; char tracebuf[128]; FILE* recv_file = fopen(filename, "wb"); if(recv_safe(s, sa, buffer, FRAME_SIZE, 101) == 101){ // Receives the filesize negotiation packet memcpy(&filesize, buffer + (3 * sizeof(char)), sizeof(int)); cout << "Got filesize " << filesize << " starting transfer..." << endl; sprintf(tracebuf, "Filesize %d", filesize); write_log(logfile, username, tracebuf); offset = recv = count = 0; int expected_size = WINDOW_SIZE + 1; int recv_count, nak; int next = 0; int packet_id; // Receive the file while(1){ nak = -1; recv_count = 0; next = offset; while(count < filesize && recv_count < WINDOW_SIZE){ if(filesize - count >= (FRAME_SIZE)) size = (FRAME_SIZE / sizeof(char)); // Read the full buffer else size = ((filesize - count) / sizeof(char)); // Read a subset of the buffer if((packet_id = recv_packet(s,sa,buffer,FRAME_SIZE,offset)) == offset){ // Receive the packet from the peer count += FRAME_SIZE; fwrite(buffer,sizeof(char),size,recv_file); // Write to the output file sprintf(tracebuf, "Recv %d (%d of %d)", offset, count, filesize); write_log(logfile, username, tracebuf); offset = (offset + 1) % expected_size; recv_count++; }else if(packet_id < 0){ nak = offset; break; }else if(packet_id == 101){ fclose(recv_file); return get(s, sa, username, filename, client_num, server_num, logfile); } } while(recv_count > 0 || nak >= 0){ memset(buffer,0,FRAME_SIZE); if(next != nak) strncpy(buffer, "ACK", 3); // Send ACK else strncpy(buffer, "NAK", 3); // Send NAK send_packet(s,sa,buffer,FRAME_SIZE,next); // Send acknowledgement recv_count--; if(next == nak){ offset = nak; sprintf(tracebuf, "Sent NAK for %d", nak); write_log(logfile, username, tracebuf); break; } // As soon as we send a NAK we can break next = (next + 1) % expected_size; } if(count >= filesize) break; } strncpy(buffer, "ALL", 3); send_packet(s, sa, buffer, FRAME_SIZE, next); cout << "Transfer completed! " << count << " bytes received" << endl; fclose(recv_file); }else{ fclose(recv_file); return get(s, sa, username, filename, client_num, server_num, logfile); } }
int CNetManager::send_msg( message_stream& body_ms ) { send_packet(&body_ms); return 0; }
/** * PUT function * Performs the sending half of a request */ void put(SOCKET s, SOCKADDR_IN sa, char * username, char* filename, int client_num, int server_num, FILE* logfile){ char window[FRAME_SIZE * WINDOW_SIZE]; // data retention window char buffer[FRAME_SIZE]; // send buffer int filesize; int size = 0, sent = 0; // Trace variables char tracebuf[128]; FILE* send_file; if((send_file = fopen(filename, "rb")) != NULL){ // open the file // Determines the file size fseek(send_file, 0L, SEEK_END); filesize = ftell(send_file); fseek(send_file, 0L, SEEK_SET); sprintf(tracebuf, "Filesize %d", filesize); write_log(logfile, username, tracebuf); strncpy(buffer, "SIZ", 3); memcpy(buffer + (3 * sizeof(char)), &filesize, sizeof(int)); // Add the size of the element to the buffer if(send_safe(s,sa,buffer,FRAME_SIZE,101) == 101){ cout << "Sent filesize, starting transfer..." << endl; memset(buffer, 0, sizeof(buffer)); int count = 0; int offset = 0; int frames_outstanding = 0; int next = 0; bool resend = false; int packet_id; int pid_max = WINDOW_SIZE + 1; // Start sending the file while (1){ // If the acks mismatch with the current send offset, has to be a resend if(next != offset && frames_outstanding > 0) resend = true; // Send as many frames as available for the given window size while((!feof(send_file) && frames_outstanding < WINDOW_SIZE) || resend){ if(next == offset) resend = false; if(!resend){ if(feof(send_file)) break; fread(buffer,1,FRAME_SIZE,send_file); // Read the next block of data memcpy(window + (offset * FRAME_SIZE), buffer, FRAME_SIZE); // Store the data in the local window send_packet(s,sa,buffer,FRAME_SIZE,offset); // Send the packet to peer offset = (offset + 1) % pid_max; // Update the offset frames_outstanding++; }else{ // Resend by copying the data from the window memcpy(buffer, window + (next * FRAME_SIZE), FRAME_SIZE); send_packet(s,sa,buffer,FRAME_SIZE,next); sprintf(tracebuf, "Resending packet %d", next); write_log(logfile, username, tracebuf); next = (next + 1) % pid_max; } } // Receive ACKs before continuing sending while(frames_outstanding > 0){ if((packet_id = recv_packet(s,sa,buffer,FRAME_SIZE,next)) < 0){ if(count < filesize) resend = true; //else frames_outstanding --; break; } // Receive acknowledgment from the client if(!strncmp(buffer,"NAK", 3)){ if(packet_id >= 0) next = packet_id; // Set the next packet id to send break; }else if(!strncmp(buffer,"ALL", 3)){ frames_outstanding = 0; break; } count += FRAME_SIZE; // Increment the counter sprintf(tracebuf, "Sent %d bytes", count); write_log(logfile, username, tracebuf); memset(buffer, 0, sizeof(buffer)); // Zero the buffer next = (next + 1) % pid_max; // Update the next frame tracker frames_outstanding --; // Another frame has been acked } if(feof(send_file) && frames_outstanding == 0) break; // Break when done reading the file and all frames are acked } cout << "File transfer completed" << endl; fclose(send_file); }else{ fclose(send_file); return put(s,sa,username,filename, client_num, server_num, logfile); } } }
/* Loop for downloading file, parameters: int sock - socket to be used int type - type of the instance (server or client) Returns pointer to first filedata block */ filedata *download_mode_loop(int sock, int type) { int n = 0, packet_len = 0, cur_block = 1, rv = 0; struct timeval to; packet *pck = NULL; data_packet *d_pck = NULL; filedata *files = NULL; FD_ZERO(&s_set); while(1) { /* Set timeout values */ to.tv_sec = TIMEOUT_SEC; to.tv_usec = TIMEOUT_USEC; FD_SET(sock,&s_set); /* Check if there is something in socket */ rv = select(sock+1,&s_set,NULL,NULL,&to); if(rv < 0) error("Error in select()"); /* If got something */ else if(rv > 0) { if(FD_ISSET(sock,&s_set)) /* Used socket has something */ { /* Read packet and backup length */ pck = read_packet(sock); packet_len = pck->length; /* If packet is less than 4 bytes or greater than 516 bytes (MAX_MSG) discard it */ if((packet_len < 4) || (packet_len > MAX_MSG)) error_minor("Invalid packet size, discarding"); /* Otherwise check the packet */ else { if((d_pck = decode_data_packet(pck)) == NULL) error("Error decoding packet"); /* If it is a DATA packet */ if(ntohs(d_pck->opcode) == OPCODE_DATA) { /* Check blocknumber that it is the same as waited block*/ if(ntohs(d_pck->blockno) == cur_block) { if(packet_len == 4) break; /* If data packet with 0 data -> last packet */ //printf("Got DATA: %d\n",ntohs(d_pck->blockno)); /* Add data packet to fileblock list */ files = add_data_packet(files,d_pck,packet_len); /* Create ack packet for this packet and send it */ pck = encode_ack_packet(ntohs(d_pck->blockno)); n = send_packet(sock,pck); //printf("Sent ACK: %d\n",ntohs(d_pck->blockno)); /* Increase the block counter */ cur_block = ntohs(d_pck->blockno) + 1; /* If got less data than max 512 bytes -> last packet */ if(packet_len != MAX_MSG) break; } } /* Otherwise a errorous packet */ else printf("Erroreus packet"); } } } /* If timeout happened, send re-ack if not waiting for first block */ else { /* If client, cannot send ack with block number 0 */ if((type != TYPE_CLIENT) && (cur_block != 1)) { pck = encode_ack_packet(cur_block-1); n = send_packet(sock,pck); //printf("TIMEOUT ACK: %d\n",cur_block-1); } } } free(pck); free(d_pck); return files; }
int send_ack(libgdbr_t* g) { g->send_buff[0] = '+'; g->send_len = 1; send_packet (g); return 0; }
/* * This will receive a file from a remote host. Expects a socket integer and * a filename. The file will be basename'd and saved into /tmp. * */ void receive_file(int skt, const char *filename, int server) { char msg[MSGLEN], cmd[CMDLEN], arg[MSGLEN], lname[MSGLEN], errmsg[ERRMSGLEN]; char *basefname; FILE *outfile; int fsize = 0, segments = 0, cur_segment = 0; /* get the local file name in /tmp */ memset(lname, '\0', MSGLEN); memset(errmsg, '\0', ERRMSGLEN); strcpy(msg, filename); basefname = basename(msg); sprintf(lname, "/tmp/%s", basefname); /* if file exists, send err to remote, otherwise send cts and await size */ if(exist(lname)) { debug("Filesystem", "Not receiving file since it already exists"); if(server) { send_packet(skt, "err:File already exists"); } return; } /* open file for writing */ outfile = fopen(lname, "w"); if(outfile == NULL) { sprintf(errmsg, "Could not open file for writing: %s", strerror(errno)); debug("Filesystem", errmsg); if(server) { send_packet(skt, "err:File could not be written"); } return; } /* ready to receive file */ if(server) { memset(msg, '\0', MSGLEN); strcpy(msg, "cts"); send_message(skt, msg); } else { receive_packet(skt, msg); } split_command(msg, cmd, arg); segments = atoi(cmd); fsize = atoi(arg); sprintf(errmsg, "Going to receive %d bytes in %d segments", fsize, segments); debug("Filesystem", errmsg); /* loop through segments packet count and get the file */ for(cur_segment = 0; cur_segment <= segments; cur_segment++) { printf("\rFilesystem: Receiving File: %d / %d", cur_segment, segments); memset(msg, '\0', MSGLEN); receive_packet(skt, msg); if(cur_segment == segments) { /* write remaining bytes */ fwrite(msg, (fsize - (segments * MSGLEN)), 1, outfile); } else { /* write complete segment */ fwrite(msg, MSGLEN, 1, outfile); } } printf("\n"); fclose(outfile); }
/* database description packet handling */ int send_db_description(struct nbr *nbr) { struct in6_addr dst; struct db_dscrp_hdr dd_hdr; struct lsa_entry *le, *nle; struct ibuf *buf; int ret = 0; u_int8_t bits = 0; if ((buf = ibuf_open(nbr->iface->mtu - sizeof(struct ip))) == NULL) fatal("send_db_description"); /* OSPF header */ if (gen_ospf_hdr(buf, nbr->iface, PACKET_TYPE_DD)) goto fail; /* reserve space for database description header */ if (ibuf_reserve(buf, sizeof(dd_hdr)) == NULL) goto fail; switch (nbr->state) { case NBR_STA_DOWN: case NBR_STA_ATTEMPT: case NBR_STA_INIT: case NBR_STA_2_WAY: case NBR_STA_SNAP: log_debug("send_db_description: cannot send packet in state %s," " neighbor ID %s", nbr_state_name(nbr->state), inet_ntoa(nbr->id)); ret = -1; goto done; case NBR_STA_XSTRT: bits |= OSPF_DBD_MS | OSPF_DBD_M | OSPF_DBD_I; nbr->dd_more = 1; break; case NBR_STA_XCHNG: if (nbr->dd_master) bits |= OSPF_DBD_MS; else bits &= ~OSPF_DBD_MS; if (TAILQ_EMPTY(&nbr->db_sum_list)) { bits &= ~OSPF_DBD_M; nbr->dd_more = 0; } else { bits |= OSPF_DBD_M; nbr->dd_more = 1; } bits &= ~OSPF_DBD_I; /* build LSA list */ for (le = TAILQ_FIRST(&nbr->db_sum_list); le != NULL && buf->wpos + sizeof(struct lsa_hdr) < buf->max; le = nle) { nbr->dd_end = nle = TAILQ_NEXT(le, entry); if (ibuf_add(buf, le->le_lsa, sizeof(struct lsa_hdr))) goto fail; } break; case NBR_STA_LOAD: case NBR_STA_FULL: if (nbr->dd_master) bits |= OSPF_DBD_MS; else bits &= ~OSPF_DBD_MS; bits &= ~OSPF_DBD_M; bits &= ~OSPF_DBD_I; nbr->dd_more = 0; break; default: fatalx("send_db_description: unknown neighbor state"); } bzero(&dd_hdr, sizeof(dd_hdr)); switch (nbr->iface->type) { case IF_TYPE_POINTOPOINT: inet_pton(AF_INET6, AllSPFRouters, &dst); dd_hdr.iface_mtu = htons(nbr->iface->mtu); break; case IF_TYPE_BROADCAST: dst = nbr->addr; dd_hdr.iface_mtu = htons(nbr->iface->mtu); break; case IF_TYPE_NBMA: case IF_TYPE_POINTOMULTIPOINT: /* XXX not supported */ break; case IF_TYPE_VIRTUALLINK: dst = nbr->iface->dst; dd_hdr.iface_mtu = 0; break; default: fatalx("send_db_description: unknown interface type"); } dd_hdr.opts = htonl(area_ospf_options(area_find(oeconf, nbr->iface->area_id))); dd_hdr.bits = bits; dd_hdr.dd_seq_num = htonl(nbr->dd_seq_num); memcpy(ibuf_seek(buf, sizeof(struct ospf_hdr), sizeof(dd_hdr)), &dd_hdr, sizeof(dd_hdr)); /* calculate checksum */ if (upd_ospf_hdr(buf, nbr->iface)) goto fail; /* transmit packet */ ret = send_packet(nbr->iface, buf->buf, buf->wpos, &dst); done: ibuf_free(buf); return (ret); fail: log_warn("send_db_description"); ibuf_free(buf); return (-1); }
int main(int argc, char **argv){ extern char *optarg; char *endptr; /* Used by strtoul() */ fd_set sset, rset; struct timeval timeout; int r, sel; time_t curtime, start, lastecho=0; static struct option longopts[] = { {"interface", required_argument, 0, 'i'}, {"link-src-addr", required_argument, 0, 'S'}, {"link-dst-addr", required_argument, 0, 'D'}, {"src-address", required_argument, 0, 's'}, {"dst-address", required_argument, 0, 'd'}, {"hop-limit", required_argument, 0, 'A'}, {"dst-opt-hdr", required_argument, 0, 'u'}, {"dst-opt-u-hdr", required_argument, 0, 'U'}, {"hbh-opt-hdr", required_argument, 0, 'H'}, {"frag-hdr", required_argument, 0, 'y'}, {"ipv6-length", required_argument, 0, 'q'}, {"jumbo-length", required_argument, 0, 'Q'}, {"payload-size", required_argument, 0, 'P'}, {"loop", no_argument, 0, 'l'}, {"sleep", required_argument, 0, 'z'}, {"listen", no_argument, 0, 'L'}, {"verbose", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'} }; char shortopts[]= "i:s:d:A:u:U:H:y:S:D:q:Q:P:lz:Lvh"; char option; if(argc<=1){ usage(); exit(EXIT_FAILURE); } hoplimit=64+random()%180; init_iface_data(&idata); while((r=getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) { option= r; switch(option) { case 'i': /* Interface */ strncpy(idata.iface, optarg, IFACE_LENGTH-1); idata.iface[IFACE_LENGTH-1]=0; idata.ifindex= if_nametoindex(idata.iface); idata.iface_f=TRUE; break; case 's': /* IPv6 Source Address */ if(idata.srcaddr_f){ puts("Error: Multiple '-s' options have been specified"); exit(EXIT_FAILURE); } if((charptr = strtok_r(optarg, "/", &lasts)) == NULL){ puts("Error in Source Address"); exit(EXIT_FAILURE); } if ( inet_pton(AF_INET6, charptr, &(idata.srcaddr)) <= 0){ puts("inet_pton(): Source Address not valid"); exit(EXIT_FAILURE); } idata.srcaddr_f = 1; if((charptr = strtok_r(NULL, " ", &lasts)) != NULL){ idata.srcpreflen = atoi(charptr); if(idata.srcpreflen>128){ puts("Prefix length error in IPv6 Source Address"); exit(EXIT_FAILURE); } sanitize_ipv6_prefix(&(idata.srcaddr), idata.srcpreflen); idata.srcprefix_f=1; } break; case 'd': /* IPv6 Destination Address */ if( inet_pton(AF_INET6, optarg, &(idata.dstaddr)) <= 0){ puts("inet_pton(): address not valid"); exit(EXIT_FAILURE); } idata.dstaddr_f = 1; break; case 'A': /* Hop Limit */ hoplimit= atoi(optarg); hoplimit_f=1; break; case 'u': /* Destinations Options Header */ if(ndstopthdr >= MAX_DST_OPT_HDR){ puts("Too many Destination Options Headers"); exit(EXIT_FAILURE); } hdrlen= atoi(optarg); if(hdrlen < 8){ puts("Bad length in Destination Options Header"); exit(EXIT_FAILURE); } hdrlen = ((hdrlen+7)/8) * 8; dstopthdrlen[ndstopthdr]= hdrlen; if( (dstopthdr[ndstopthdr]= malloc(hdrlen)) == NULL){ puts("Not enough memory for Destination Options Header"); exit(EXIT_FAILURE); } ptrhdr= dstopthdr[ndstopthdr] + 2; ptrhdrend= dstopthdr[ndstopthdr] + hdrlen; while( ptrhdr < ptrhdrend){ if( (ptrhdrend-ptrhdr)>257) pad= 257; else pad= ptrhdrend-ptrhdr; if(!insert_pad_opt(ptrhdr, ptrhdrend, pad)){ puts("Destination Options Header Too Big"); exit(EXIT_FAILURE); } ptrhdr= ptrhdr + pad; } *(dstopthdr[ndstopthdr]+1)= (hdrlen/8)-1; ndstopthdr++; dstopthdr_f=1; break; case 'U': /* Destination Options Header (Unfragmentable Part) */ if(ndstoptuhdr >= MAX_DST_OPT_U_HDR){ puts("Too many Destination Options Headers (Unfragmentable Part)"); exit(EXIT_FAILURE); } hdrlen= atoi(optarg); if(hdrlen < 8){ puts("Bad length in Destination Options Header (Unfragmentable Part)"); exit(EXIT_FAILURE); } hdrlen = ((hdrlen+7)/8) * 8; dstoptuhdrlen[ndstoptuhdr]= hdrlen; if( (dstoptuhdr[ndstoptuhdr]= malloc(hdrlen)) == NULL){ puts("Not enough memory for Destination Options Header (Unfragmentable Part)"); exit(EXIT_FAILURE); } ptrhdr= dstoptuhdr[ndstoptuhdr]+2; ptrhdrend= dstoptuhdr[ndstoptuhdr] + hdrlen; while( ptrhdr < ptrhdrend){ if( (ptrhdrend-ptrhdr)>257) pad= 257; else pad= ptrhdrend-ptrhdr; if(!insert_pad_opt(ptrhdr, ptrhdrend, pad)){ puts("Destination Options Header (Unfragmentable Part) Too Big"); exit(EXIT_FAILURE); } ptrhdr = ptrhdr + pad; } *(dstoptuhdr[ndstoptuhdr]+1)= (hdrlen/8) - 1; ndstoptuhdr++; dstoptuhdr_f=1; break; case 'H': /* Hop-by-Hop Options Header */ if(nhbhopthdr >= MAX_HBH_OPT_HDR){ puts("Too many Hop-by-Hop Options Headers"); exit(EXIT_FAILURE); } hdrlen= atoi(optarg); if(hdrlen <= 8){ puts("Bad length in Hop-by-Hop Options Header"); exit(EXIT_FAILURE); } hdrlen = ((hdrlen+7)/8) * 8; hbhopthdrlen[nhbhopthdr]= hdrlen; if( (hbhopthdr[nhbhopthdr]= malloc(hdrlen)) == NULL){ puts("Not enough memory for Hop-by-Hop Options Header"); exit(EXIT_FAILURE); } ptrhdr= hbhopthdr[nhbhopthdr] + 2; ptrhdrend= hbhopthdr[nhbhopthdr] + hdrlen; while( ptrhdr < ptrhdrend){ if( (ptrhdrend-ptrhdr)>257) pad= 257; else pad= ptrhdrend-ptrhdr; if(!insert_pad_opt(ptrhdr, ptrhdrend, pad)){ puts("Hop-by-Hop Options Header Too Big"); exit(EXIT_FAILURE); } ptrhdr = ptrhdr + pad; } *(hbhopthdr[nhbhopthdr]+1)= (hdrlen/8) - 1; nhbhopthdr++; hbhopthdr_f=1; break; case 'y': /* Fragment header */ nfrags= atoi(optarg); if(nfrags < 8){ puts("Error in Fragmentation option: Fragment Size must be at least 8 bytes"); exit(EXIT_FAILURE); } nfrags = (nfrags +7) & 0xfff8; fragh_f= 1; break; case 'S': /* Source Ethernet address */ if(ether_pton(optarg, &(idata.hsrcaddr), sizeof(idata.hsrcaddr)) == 0){ puts("Error in Source link-layer address."); exit(EXIT_FAILURE); } idata.hsrcaddr_f = 1; break; case 'D': /* Destination Ethernet Address */ if(ether_pton(optarg, &(idata.hdstaddr), sizeof(idata.hdstaddr)) == 0){ puts("Error in Source link-layer address."); exit(EXIT_FAILURE); } idata.hdstaddr_f = 1; break; case 'P': /* Payload Size*/ icmp6psize= atoi(optarg); icmp6psize= (icmp6psize<<2) >> 2; /* The Redirected Header has a granularity of 8 bytes */ icmp6psize_f= 1; break; case 'q': /* IPv6 Payload Length */ if((ul_res = strtoul(optarg, &endptr, 0)) == ULONG_MAX){ perror("Error in 'TCP Sequence NUmber' parameter"); exit(EXIT_FAILURE); } if(endptr != optarg){ ip6length = ul_res; ip6length_f=1; } break; case 'Q': /* Jumbo Payload Length */ if((ul_res = strtoul(optarg, &endptr, 0)) == ULONG_MAX){ perror("Error in 'TCP Sequence NUmber' parameter"); exit(EXIT_FAILURE); } if(endptr != optarg){ jplength = ul_res; jplength_f=1; } break; case 'l': /* "Loop mode */ loop_f = 1; break; case 'z': /* Sleep option */ nsleep=atoi(optarg); if(nsleep==0){ puts("Invalid number of seconds in '-z' option"); exit(EXIT_FAILURE); } sleep_f=1; break; case 'L': /* "Listen mode */ listen_f = 1; break; case 'v': /* Be verbose */ idata.verbose_f++; break; case 'h': /* Help */ print_help(); exit(EXIT_FAILURE); break; default: usage(); exit(EXIT_FAILURE); break; } /* switch */ } /* while(getopt) */ if(geteuid()) { puts("jumbo6 needs root privileges to run."); exit(EXIT_FAILURE); } if(!idata.iface_f){ if(idata.dstaddr_f && IN6_IS_ADDR_LINKLOCAL(&(idata.dstaddr))){ puts("Must specify a network interface for link-local destinations"); exit(EXIT_FAILURE); } else if(idata.listen_f){ puts("Must specify a network interface when employing the 'listenging' mode"); exit(EXIT_FAILURE); } } if(listen_f && loop_f){ puts("'Error: listen' mode and 'loop' mode are incompatible"); exit(EXIT_FAILURE); } if(!idata.dstaddr_f && !listen_f){ /* Must specify IPv6 Destination Address if listening mode not used */ puts("IPv6 Destination Address not specified (and listening mode not selected)"); exit(EXIT_FAILURE); } if(load_dst_and_pcap(&idata, LOAD_SRC_NXT_HOP) == FAILURE){ puts("Error while learning Souce Address and Next Hop"); exit(EXIT_FAILURE); } release_privileges(); srandom(time(NULL)); if((idata.ip6_local_flag && idata.ip6_global_flag) && !idata.srcaddr_f) localaddr_f=1; if(!idata.ether_flag){ randomize_ether_addr(&idata.ether); idata.ether_flag=1; } if(!idata.ip6_local_flag){ ether_to_ipv6_linklocal(&idata.ether, &idata.ip6_local); } if(!sleep_f) nsleep=QUERY_TIMEOUT; if( !fragh_f && dstoptuhdr_f){ puts("Dst. Options Header (Unfragmentable Part) set, but Fragmentation not specified"); exit(EXIT_FAILURE); } if(idata.verbose_f){ print_attack_info(&idata); } /* Set filter for receiving Neighbor Solicitations, ICMPv6 Echo Responses, and ICMPv6 Parameter Problem */ if(pcap_compile(idata.pfd, &pcap_filter, PCAP_ICMPV6_NS_FILTER, PCAP_OPT, PCAP_NETMASK_UNKNOWN) == -1){ printf("pcap_compile(): %s", pcap_geterr(idata.pfd)); exit(EXIT_FAILURE); } if(pcap_setfilter(idata.pfd, &pcap_filter) == -1){ printf("pcap_setfilter(): %s", pcap_geterr(idata.pfd)); exit(EXIT_FAILURE); } pcap_freecode(&pcap_filter); /* Set initial contents of the attack packet */ init_packet_data(&idata); /* Fire a packet if a IPv6 Destination Address was specified */ if(idata.dstaddr_f){ FD_ZERO(&sset); FD_SET(idata.fd, &sset); start= time(NULL); while(1){ curtime=time(NULL); if(!loop_f && (curtime - start) >= QUERY_TIMEOUT){ break; } if((curtime - lastecho) >= nsleep){ lastecho=curtime; puts("Sending ICMPv6 Echo Request....\n"); if(send_packet(&idata, NULL, NULL) == -1){ puts("Error sending packet"); exit(EXIT_FAILURE); } } rset= sset; timeout.tv_usec=0; timeout.tv_sec= nsleep; if((sel=select(idata.fd+1, &rset, NULL, NULL, &timeout)) == -1){ if(errno == EINTR){ continue; } else{ puts("Error in select()"); exit(EXIT_FAILURE); } } if(sel == 0) continue; /* Read a packet (Echo Reply, Neighbor Solicitation, or ICMPv6 Error */ if((r=pcap_next_ex(idata.pfd, &pkthdr, &pktdata)) == -1){ printf("pcap_next_ex(): %s", pcap_geterr(idata.pfd)); exit(EXIT_FAILURE); } else if(r == 0){ continue; /* Should never happen */ } pkt_ether = (struct ether_header *) pktdata; pkt_ipv6 = (struct ip6_hdr *)((char *) pkt_ether + ETHER_HDR_LEN); pkt_icmp6 = (struct icmp6_hdr *) ((char *) pkt_ipv6 + sizeof(struct ip6_hdr)); pkt_ns= (struct nd_neighbor_solicit *) pkt_icmp6; pkt_end = (unsigned char *) pktdata + pkthdr->caplen; if( (pkt_end - pktdata) < (ETHER_HDR_LEN + MIN_IPV6_HLEN)) continue; if(pkt_ipv6->ip6_nxt == IPPROTO_ICMPV6){ if(pkt_icmp6->icmp6_type == ND_NEIGHBOR_SOLICIT){ if( (pkt_end - (unsigned char *) pkt_ns) < sizeof(struct nd_neighbor_solicit)) continue; /* If the addresses that we're using are not actually configured on the local system (i.e., they are "spoofed", we must check whether it is a Neighbor Solicitation for one of our addresses, and respond with a Neighbor Advertisement. Otherwise, the kernel will take care of that. */ if(!localaddr_f && is_eq_in6_addr(&(pkt_ns->nd_ns_target), &idata.srcaddr)){ if(send_neighbor_advert(&idata, idata.pfd, pktdata) == -1){ puts("Error sending Neighbor Advertisement"); exit(EXIT_FAILURE); } } } else if( (pkt_icmp6->icmp6_type == ICMP6_ECHO_REPLY) || (pkt_icmp6->icmp6_type == ICMP6_PARAM_PROB)){ if( (pkt_end - (unsigned char *) pkt_icmp6) < sizeof(struct icmp6_hdr)) continue; /* Do a preliminar validation check on the ICMPv6 packet (packet size, Source Address, and Destination Address). */ if(!valid_icmp6_response(&idata, pkthdr, pktdata)){ continue; } switch(pkt_icmp6->icmp6_type){ case ICMP6_ECHO_REPLY: print_icmp6_echo(&idata, pkthdr, pktdata); break; case ICMP6_PARAM_PROB: print_icmp6_error(&idata, pkthdr, pktdata); break; } } } } exit(EXIT_SUCCESS); } if(!idata.dstaddr_f){ puts("Error: Nothing to send! (Destination Address left unspecified)"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
void handle_packet(apacket *p, atransport *t) { asocket *s; D("handle_packet() %d\n", p->msg.command); print_packet("recv", p); switch(p->msg.command) { case A_SYNC: if(p->msg.arg0) { send_packet(p, t); if(HOST) send_connect(t); } else { t->connection_state = CS_OFFLINE; handle_offline(t); send_packet(p, t); } return; case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */ /* XXX verify version, etc */ if(t->connection_state != CS_OFFLINE) { t->connection_state = CS_OFFLINE; handle_offline(t); } parse_banner((char*) p->data, t); handle_online(); if(!HOST) send_connect(t); break; case A_OPEN: /* OPEN(local-id, 0, "destination") */ if(t->connection_state != CS_OFFLINE) { char *name = (char*) p->data; name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0; s = create_local_service_socket(name); if(s == 0) { send_close(0, p->msg.arg0, t); } else { s->peer = create_remote_socket(p->msg.arg0, t); s->peer->peer = s; send_ready(s->id, s->peer->id, t); s->ready(s); } } break; case A_OKAY: /* READY(local-id, remote-id, "") */ if(t->connection_state != CS_OFFLINE) { if((s = find_local_socket(p->msg.arg1))) { if(s->peer == 0) { s->peer = create_remote_socket(p->msg.arg0, t); s->peer->peer = s; } s->ready(s); } } break; case A_CLSE: /* CLOSE(local-id, remote-id, "") */ if(t->connection_state != CS_OFFLINE) { if((s = find_local_socket(p->msg.arg1))) { s->close(s); } } break; case A_WRTE: if(t->connection_state != CS_OFFLINE) { if((s = find_local_socket(p->msg.arg1))) { unsigned rid = p->msg.arg0; p->len = p->msg.data_length; if(s->enqueue(s, p) == 0) { D("Enqueue the socket\n"); send_ready(s->id, rid, t); } return; } } break; default: printf("handle_packet: what is %08x?!\n", p->msg.command); } put_apacket(p); }
/* * Send the server hello done message. */ static int ICACHE_FLASH_ATTR send_server_hello_done(SSL *ssl) { return send_packet(ssl, PT_HANDSHAKE_PROTOCOL, g_hello_done, sizeof(g_hello_done)); }
int TAP_ESC::init() { int ret; ASSERT(!_initialized); /* Respect boot time requierd by the ESC FW */ hrt_abstime uptime_us = hrt_absolute_time(); if (uptime_us < MAX_BOOT_TIME_MS * 1000) { usleep((MAX_BOOT_TIME_MS * 1000) - uptime_us); } /* Issue Basic Config */ EscPacket packet = {0xfe, sizeof(ConfigInfoBasicRequest), ESCBUS_MSG_ID_CONFIG_BASIC}; ConfigInfoBasicRequest &config = packet.d.reqConfigInfoBasic; memset(&config, 0, sizeof(ConfigInfoBasicRequest)); config.maxChannelInUse = _channels_count; /* Asign the id's to the ESCs to match the mux */ for (uint8_t phy_chan_index = 0; phy_chan_index < _channels_count; phy_chan_index++) { config.channelMapTable[phy_chan_index] = device_mux_map[phy_chan_index] & ESC_CHANNEL_MAP_CHANNEL; config.channelMapTable[phy_chan_index] |= (device_dir_map[phy_chan_index] << 4) & ESC_CHANNEL_MAP_RUNNING_DIRECTION; } config.maxChannelValue = RPMMAX; config.minChannelValue = RPMMIN; ret = send_packet(packet, 0); if (ret < 0) { return ret; } /* Verify All ESC got the config */ for (uint8_t cid = 0; cid < _channels_count; cid++) { /* Send the InfoRequest querying CONFIG_BASIC */ EscPacket packet_info = {0xfe, sizeof(InfoRequest), ESCBUS_MSG_ID_REQUEST_INFO}; InfoRequest &info_req = packet_info.d.reqInfo; info_req.channelID = cid; info_req.requestInfoType = REQEST_INFO_BASIC; ret = send_packet(packet_info, cid); if (ret < 0) { return ret; } /* Get a response */ int retries = 10; bool valid = false; while (retries--) { read_data_from_uart(); if (parse_tap_esc_feedback(&uartbuf, &_packet)) { valid = (_packet.msg_id == ESCBUS_MSG_ID_CONFIG_INFO_BASIC && _packet.d.rspConfigInfoBasic.channelID == cid && 0 == memcmp(&_packet.d.rspConfigInfoBasic.resp, &config, sizeof(ConfigInfoBasicRequest))); break; } else { /* Give it time to come in */ usleep(1000); } } if (!valid) { return -EIO; } } /* To Unlock the ESC from the Power up state we need to issue 10 * ESCBUS_MSG_ID_RUN request with all the values 0; */ EscPacket unlock_packet = {0xfe, _channels_count, ESCBUS_MSG_ID_RUN}; unlock_packet.len *= sizeof(unlock_packet.d.reqRun.rpm_flags[0]); memset(unlock_packet.d.bytes, 0, sizeof(packet.d.bytes)); int unlock_times = 10; while (unlock_times--) { send_packet(unlock_packet, -1); /* Min Packet to Packet time is 1 Ms so use 2 */ usleep(1000 * 2); } /* do regular cdev init */ ret = CDev::init(); return ret; }