Exemplo n.º 1
0
// 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));
}
Exemplo n.º 2
0
/*
 * 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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
        }
    }
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
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);
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
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);
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
0
/*---------------------------------------------------------------------------*/
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));
}
Exemplo n.º 17
0
/*	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;
}
Exemplo n.º 18
0
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));
		}
	}
}
Exemplo n.º 19
0
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));
}
Exemplo n.º 20
0
/**
 * 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);
    }
}
Exemplo n.º 21
0
int CNetManager::send_msg( message_stream& body_ms )
{
    send_packet(&body_ms);
    return 0;
}
Exemplo n.º 22
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);
        }
    }

}
Exemplo n.º 23
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
*/
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;
}
Exemplo n.º 24
0
int send_ack(libgdbr_t* g) {
	g->send_buff[0] = '+';
	g->send_len = 1;
	send_packet (g);
	return 0;
}
Exemplo n.º 25
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);
}
Exemplo n.º 26
0
/* 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);
}
Exemplo n.º 27
0
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);
}
Exemplo n.º 28
0
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);
}
Exemplo n.º 29
0
/*
 * 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));
}
Exemplo n.º 30
0
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;
}