Esempio n. 1
0
File: in_dhcp.c Progetto: Prajna/xnu
static int
dhcp_get_offer(struct dhcp_context * context, int wait_ticks)
{
    int				error = 0;
    int	 			gather_count = 0;
    const struct in_addr * 	ip;
    int				last_rating = 0;
    int				len;
    int				n;
    int 			rating;
    struct dhcp *		reply;
    struct in_addr		server_id;
    struct socket * 		timer_arg;

    timer_arg = context->so;
    reply = dhcp_context_reply(context);
    timeout((timeout_fcn_t)dhcp_timeout, &timer_arg, wait_ticks);
    while (1) {
	error = receive_packet(context->so, context->reply,
			       sizeof(context->reply), &n);
	if (error == 0) {
	    dhcpol_t		options;

	    dprintf(("\ndhcp: received packet length %d\n", n));
	    if (n < (int)sizeof(struct dhcp)) {
		dprintf(("dhcp: packet is too short %d < %d\n",
			 n, (int)sizeof(struct dhcp)));
		continue;
	    }
	    if (ntohl(reply->dp_xid) != context->xid
		|| reply->dp_yiaddr.s_addr == 0
		|| reply->dp_yiaddr.s_addr == INADDR_BROADCAST
		|| bcmp(reply->dp_chaddr,
			link_address(context->dl_p), 
			link_address_length(context->dl_p)) != 0) {
		/* not for us */
		continue;
	    }
	    (void)dhcpol_parse_packet(&options, reply, n);
	    if (get_dhcp_msgtype(&options) != dhcp_msgtype_offer_e) {
		/* not an offer */
		goto next_packet;
	    }
	    ip = (const struct in_addr *)
		dhcpol_find(&options, 
			    dhcptag_server_identifier_e, &len, NULL);
	    if (ip == NULL || len < (int)sizeof(*ip)) {
		/* missing/invalid server identifier */
		goto next_packet;
	    }
	    printf("dhcp: received OFFER: server " IP_FORMAT
		   " IP address "  IP_FORMAT "\n",
		   IP_LIST(ip), IP_LIST(&reply->dp_yiaddr));
	    server_id = *ip;
	    rating = rate_packet(&options);
	    if (rating > last_rating) {
		context->iaddr = reply->dp_yiaddr;
		ip = (const struct in_addr *)
		    dhcpol_find(&options, 
				dhcptag_subnet_mask_e, &len, NULL);
		if (ip != NULL && len >= (int)sizeof(*ip)) {
		    context->netmask = *ip;
		}
		ip = (const struct in_addr *)
		    dhcpol_find(&options, dhcptag_router_e, &len, NULL);
		if (ip != NULL && len >= (int)sizeof(*ip)) {
		    context->router = *ip;
		}
		context->server_id = server_id;
	    }
	    if (rating >= GOOD_RATING) {
		dhcpol_free(&options);
		/* packet is good enough */
		untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg);
		break;
	    }
	    if (gather_count == 0) {
		untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg);
		timer_arg = context->so;
		timeout((timeout_fcn_t)dhcp_timeout, &timer_arg, 
			hz * GATHER_TIME_SECS);
	    }
	    gather_count = 1;
	next_packet:
	    dhcpol_free(&options);
	}
	else if ((error != EWOULDBLOCK)) {
	    untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg);
	    break;
	}
	else if (timer_arg == NULL) { /* timed out */
	    if (gather_count != 0) {
		dprintf(("dhcp: gathering time has expired\n"));
		error = 0;
	    }
	    break;
	}
	else {
	    socket_lock(context->so, 1);
	    error = sbwait(&context->so->so_rcv);
	    socket_unlock(context->so, 1);
	}
    }
    return (error);
}
Esempio n. 2
0
/* Returns the length of the file received, or 0 on error: */
int ymodem_receive(char *buf, unsigned int length)
{
  unsigned char packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD];
  int packet_length, i, file_done, session_done, crc_tries, crc_nak, use_crc;
  unsigned int packets_received, errors, timeout, first_try = 1;
  char file_name[FILE_NAME_LENGTH], file_size[FILE_SIZE_LENGTH], *file_ptr;
  char *buf_ptr;
  unsigned long size = 0;
#ifdef CONFIG_MD5
  unsigned int sum[MD5_SUM_WORDS];
#endif

  if(crc16_init() < 0){
    putstr("Unable to generate CRC16 lookup table\r\n");
    return 0;
  }

  putstr("ready for YMODEM transfer...\r\n");

  /* Give the user time to frantically type in the file name: */
  timeout = INITIAL_TIMEOUT;

  for(session_done = 0, errors = 0; ; ){

    crc_tries = crc_nak = use_crc = 1;

    if(!first_try)
      putc(CRC);

    first_try = 0;

    for(packets_received = 0, file_done = 0, buf_ptr = buf; ; ){

      switch(receive_packet(packet_data, &packet_length, use_crc, timeout)){
      case 0:
	
	errors = 0;

	switch(packet_length){
	case -1:  /* abort */
	  
	  putc(ACK);
	  
	  return 0;
	  
	case 0:   /* end of transmission */
	  
	  putc(ACK);
	  
	  /* Should add some sort of sanity check on the number of
	   * packets received and the advertised file length.
	   */

	  file_done = 1;
	  
	  break;
	  
	default:  /* normal packet */
	  
	  if((packet_data[PACKET_SEQNO_INDEX] & 0xff) !=
	     (packets_received & 0xff)){

	    putc(NAK);
	    
	  } else {
	    
	    if(packets_received == 0){
	      
	      /* The spec suggests that the whole data section should
	       * be zeroed, but I don't think all senders do this. If
	       * we have a NULL filename and the first few digits of
	       * the file length are zero, we'll call it empty.
	       */
	      for(i = PACKET_HEADER; i < PACKET_HEADER + 4; ++i)
		if(packet_data[i] != 0)
		  break;

	      if(i < PACKET_HEADER + 4){  /* filename packet has data */

		for(file_ptr = packet_data + PACKET_HEADER, i = 0;
		    *file_ptr && i < FILE_NAME_LENGTH;)
		  file_name[i++] = *file_ptr++;
		
		file_name[i++] = '\0';
		
		for(++file_ptr, i = 0;
		    *file_ptr != ' ' && i < FILE_SIZE_LENGTH;)
		  file_size[i++] = *file_ptr++;
		
		file_size[i++] = '\0';

		size = strtoul(file_size, NULL, 0);
		
		if(size > length){
		  
		  putc(CAN);
		  putc(CAN);

		  delay_seconds(3);

		  putstr("Receive buffer too small (");
		  putHexInt32(length);
		  putLabeledWord(") to accept file size ", size);

		  return 0;

		}
		
		putc(ACK);
		putc(crc_nak ? CRC : NAK);

		crc_nak = 0;

	      } else {  /* filename packet is empty; end session */

		putc(ACK);

		file_done = 1;
		session_done = 1;

		break;

	      }
	      
	    } else {
	      
	      /* This shouldn't happen, but we check anyway in case the
	       * sender lied in its filename packet:
	       */
	      if((buf_ptr + packet_length) - buf > length){

		putc(CAN);
		putc(CAN);

		delay_seconds(3);

		putLabeledWord("Sender exceeded size of receive buffer: ",
			       length);

		return 0;

	      }

	      memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
	      
	      buf_ptr += packet_length;
	      
	      putc(ACK);

	    }
	    
	    ++packets_received;
	    
	  }  /* sequence number ok */
	  
	}
	
	break;
	
      default:

	if(++errors >= 
	   ((packets_received == 0 ? MAX_CRC_TRIES : 0) + MAX_ERRORS)){

	  putc(CAN);
	  putc(CAN);

	  delay_seconds(1);

	  putstr("Too many errors during receive; giving up.\r\n");

	  return 0;

	}

	if(packets_received == 0){

	  if(crc_tries < MAX_CRC_TRIES) {
	    ++crc_tries;
	    timeout = CRC_TIMEOUT;
	  } else {
	    crc_nak = use_crc = 0;
	    timeout = NAK_TIMEOUT;
	  }

	}

	putc(crc_nak ? CRC : NAK);

      }
      
      if(file_done)
	break;

    }  /* receive packets */

    if(session_done)
      break;

  }  /* receive files */

#ifdef CONFIG_MD5
  /* Give sender time to exit so that the subsequent MD5 display will be
   * visible on the user's terminal:
   */
  delay_seconds(1);

  md5_sum(buf, size, sum);
  md5_display(sum);
  putstr("  ");
  putstr(file_name);
  putstr("\r\n");
#endif
  
  return size;

}
Esempio n. 3
0
void cc110x_rx_handler(void *args)
{
    uint8_t res = 0;

    /* Possible packet received, RX -> IDLE (0.1 us) */
    cc110x_statistic.packets_in++;

    res = receive_packet((uint8_t *)&(cc110x_rx_buffer[rx_buffer_next].packet),
            sizeof(cc110x_packet_t));

    if (res) {
        /* If we are sending a burst, don't accept packets.
         * Only ACKs are processed (for stopping the burst).
         * Same if state machine is in TX lock. */
        if (radio_state == RADIO_SEND_BURST) {
            cc110x_statistic.packets_in_while_tx++;
            return;
        }

        cc110x_rx_buffer[rx_buffer_next].rssi = rflags._RSSI;
        cc110x_rx_buffer[rx_buffer_next].lqi = rflags._LQI;
        cc110x_strobe(CC1100_SFRX);     /* ...for flushing the RX FIFO */

        /* Valid packet. After a wake-up, the radio should be in IDLE.
         * So put CC110x to RX for WOR_TIMEOUT (have to manually put
         * the radio back to sleep/WOR). */
        cc110x_write_reg(CC1100_MCSM2, 0x07);   /* Configure RX_TIME (until end of packet) */
        cc110x_strobe(CC1100_SRX);
        hwtimer_wait(IDLE_TO_RX_TIME);
        radio_state = RADIO_RX;

#ifdef MODULE_TRANSCEIVER
        /* notify transceiver thread if any */
        if (transceiver_pid != KERNEL_PID_UNDEF) {
            msg_t m;
            m.type = (uint16_t) RCV_PKT_CC1100;
            m.content.value = rx_buffer_next;
            msg_send_int(&m, transceiver_pid);
        }
#endif

#ifdef MODULE_NETDEV_BASE
        if (cc110x_recv_cb != NULL) {
            cc110x_packet_t p = cc110x_rx_buffer[rx_buffer_next].packet;
            cc110x_recv_cb(&cc110x_dev, &p.phy_src, sizeof(uint8_t), &p.address,
                    sizeof(uint8_t), p.data, p.length - CC1100_HEADER_LENGTH);
        }
#endif

        /* shift to next buffer element */
        if (++rx_buffer_next == RX_BUF_SIZE) {
            rx_buffer_next = 0;
        }

        return;
    }
    else {
        /* CRC false or RX buffer full -> clear RX FIFO in both cases */
        cc110x_strobe(CC1100_SIDLE);    /* Switch to IDLE (should already be)... */
        cc110x_strobe(CC1100_SFRX);     /* ...for flushing the RX FIFO */

        /* If currently sending, exit here (don't go to RX/WOR) */
        if (radio_state == RADIO_SEND_BURST) {
            cc110x_statistic.packets_in_while_tx++;
            return;
        }

        /* No valid packet, so go back to RX/WOR as soon as possible */
        cc110x_switch_to_rx();
    }
}
Esempio n. 4
0
File: in_dhcp.c Progetto: Prajna/xnu
static int
dhcp_get_ack(struct dhcp_context * context, int wait_ticks)
{
    int				error = 0;
    const struct in_addr * 	ip;
    int				len;
    int				n;
    struct dhcp *		reply;
    struct in_addr		server_id;
    struct socket * 		timer_arg;

    timer_arg = context->so;
    reply = dhcp_context_reply(context);
    timeout((timeout_fcn_t)dhcp_timeout, &timer_arg, wait_ticks);
    while (1) {
	error = receive_packet(context->so, context->reply,
			       sizeof(context->reply), &n);
	if (error == 0) {
	    dhcp_msgtype_t	msg;
	    dhcpol_t		options;

	    dprintf(("\ndhcp: received packet length %d\n", n));
	    if (n < (int)sizeof(struct dhcp)) {
		dprintf(("dhcp: packet is too short %d < %d\n",
			 n, (int)sizeof(struct dhcp)));
		continue;
	    }
	    if (ntohl(reply->dp_xid) != context->xid
		|| bcmp(reply->dp_chaddr, link_address(context->dl_p), 
			link_address_length(context->dl_p)) != 0) {
		/* not for us */
		continue;
	    }
	    (void)dhcpol_parse_packet(&options, reply, n);
	    server_id.s_addr = 0;
	    ip = (const struct in_addr *)
		dhcpol_find(&options, 
			    dhcptag_server_identifier_e, &len, NULL);
	    if (ip != NULL && len >= (int)sizeof(*ip)) {
		server_id = *ip;
	    }
	    msg = get_dhcp_msgtype(&options);
	    if (msg == dhcp_msgtype_nak_e
		&& server_id.s_addr == context->server_id.s_addr) {
		/* server NAK'd us, start over */
		dhcpol_free(&options);
		error = EPROTO;
		untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg);
		break;
	    }
	    if (msg != dhcp_msgtype_ack_e
		|| reply->dp_yiaddr.s_addr == 0
		|| reply->dp_yiaddr.s_addr == INADDR_BROADCAST) {
		/* ignore the packet */
		goto next_packet;
	    }
	    printf("dhcp: received ACK: server " IP_FORMAT
		   " IP address "  IP_FORMAT "\n",
		   IP_LIST(&server_id), IP_LIST(&reply->dp_yiaddr));
	    context->iaddr = reply->dp_yiaddr;
	    ip = (const struct in_addr *)
		dhcpol_find(&options, 
			    dhcptag_subnet_mask_e, &len, NULL);
	    if (ip != NULL && len >= (int)sizeof(*ip)) {
		context->netmask = *ip;
	    }
	    ip = (const struct in_addr *)
		dhcpol_find(&options, dhcptag_router_e, &len, NULL);
	    if (ip != NULL && len >= (int)sizeof(*ip)) {
		context->router = *ip;
	    }
	    dhcpol_free(&options);
	    untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg);
	    break;

	next_packet:
	    dhcpol_free(&options);
	}
	else if ((error != EWOULDBLOCK)) {
	    /* if some other error occurred, we're done */
	    untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg);
	    break;
	}
	else if (timer_arg == NULL) { 
	    /* timed out */
	    break;
	}
	else {
	    /* wait for a wait to arrive, or a timeout to occur */
	    socket_lock(context->so, 1);
	    error = sbwait(&context->so->so_rcv);
	    socket_unlock(context->so, 1);
	}
    }
    return (error);
}
Esempio n. 5
0
static irqreturn_t elp_interrupt(int irq, void *dev_id)
{
	int len;
	int dlen;
	int icount = 0;
	struct net_device *dev = dev_id;
	elp_device *adapter = netdev_priv(dev);
	unsigned long timeout;

	spin_lock(&adapter->lock);

	do {
		/*
		 * has a DMA transfer finished?
		 */
		if (inb_status(dev->base_addr) & DONE) {
			if (!adapter->dmaing)
				pr_warning("%s: phantom DMA completed\n", dev->name);

			if (elp_debug >= 3)
				pr_debug("%s: %s DMA complete, status %02x\n", dev->name,
					adapter->current_dma.direction ? "tx" : "rx",
					inb_status(dev->base_addr));

			outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
			if (adapter->current_dma.direction) {
				dev_kfree_skb_irq(adapter->current_dma.skb);
			} else {
				struct sk_buff *skb = adapter->current_dma.skb;
				if (skb) {
					if (adapter->current_dma.target) {
				  	/* have already done the skb_put() */
				  	memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length);
					}
					skb->protocol = eth_type_trans(skb,dev);
					dev->stats.rx_bytes += skb->len;
					netif_rx(skb);
				}
			}
			adapter->dmaing = 0;
			if (adapter->rx_backlog.in != adapter->rx_backlog.out) {
				int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
				adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
				if (elp_debug >= 2)
					pr_debug("%s: receiving backlogged packet (%d)\n", dev->name, t);
				receive_packet(dev, t);
			} else {
				adapter->busy = 0;
			}
		} else {
			/* has one timed out? */
			check_3c505_dma(dev);
		}

		/*
		 * receive a PCB from the adapter
		 */
		timeout = jiffies + 3*HZ/100;
		while ((inb_status(dev->base_addr) & ACRF) != 0 && time_before(jiffies, timeout)) {
			if (receive_pcb(dev, &adapter->irx_pcb)) {
				switch (adapter->irx_pcb.command)
				{
				case 0:
					break;
					/*
					 * received a packet - this must be handled fast
					 */
				case 0xff:
				case CMD_RECEIVE_PACKET_COMPLETE:
					/* if the device isn't open, don't pass packets up the stack */
					if (!netif_running(dev))
						break;
					len = adapter->irx_pcb.data.rcv_resp.pkt_len;
					dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
					if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
						pr_err("%s: interrupt - packet not received correctly\n", dev->name);
					} else {
						if (elp_debug >= 3) {
							pr_debug("%s: interrupt - packet received of length %i (%i)\n",
								dev->name, len, dlen);
						}
						if (adapter->irx_pcb.command == 0xff) {
							if (elp_debug >= 2)
								pr_debug("%s: adding packet to backlog (len = %d)\n",
									dev->name, dlen);
							adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
							adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
						} else {
							receive_packet(dev, dlen);
						}
						if (elp_debug >= 3)
							pr_debug("%s: packet received\n", dev->name);
					}
					break;

					/*
					 * 82586 configured correctly
					 */
				case CMD_CONFIGURE_82586_RESPONSE:
					adapter->got[CMD_CONFIGURE_82586] = 1;
					if (elp_debug >= 3)
						pr_debug("%s: interrupt - configure response received\n", dev->name);
					break;

					/*
					 * Adapter memory configuration
					 */
				case CMD_CONFIGURE_ADAPTER_RESPONSE:
					adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
					if (elp_debug >= 3)
						pr_debug("%s: Adapter memory configuration %s.\n", dev->name,
						       adapter->irx_pcb.data.failed ? "failed" : "succeeded");
					break;

					/*
					 * Multicast list loading
					 */
				case CMD_LOAD_MULTICAST_RESPONSE:
					adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
					if (elp_debug >= 3)
						pr_debug("%s: Multicast address list loading %s.\n", dev->name,
						       adapter->irx_pcb.data.failed ? "failed" : "succeeded");
					break;

					/*
					 * Station address setting
					 */
				case CMD_SET_ADDRESS_RESPONSE:
					adapter->got[CMD_SET_STATION_ADDRESS] = 1;
					if (elp_debug >= 3)
						pr_debug("%s: Ethernet address setting %s.\n", dev->name,
						       adapter->irx_pcb.data.failed ? "failed" : "succeeded");
					break;


					/*
					 * received board statistics
					 */
				case CMD_NETWORK_STATISTICS_RESPONSE:
					dev->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv;
					dev->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit;
					dev->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC;
					dev->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align;
					dev->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun;
					dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
					adapter->got[CMD_NETWORK_STATISTICS] = 1;
					if (elp_debug >= 3)
						pr_debug("%s: interrupt - statistics response received\n", dev->name);
					break;

					/*
					 * sent a packet
					 */
				case CMD_TRANSMIT_PACKET_COMPLETE:
					if (elp_debug >= 3)
						pr_debug("%s: interrupt - packet sent\n", dev->name);
					if (!netif_running(dev))
						break;
					switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
					case 0xffff:
						dev->stats.tx_aborted_errors++;
						pr_info("%s: transmit timed out, network cable problem?\n", dev->name);
						break;
					case 0xfffe:
						dev->stats.tx_fifo_errors++;
						pr_info("%s: transmit timed out, FIFO underrun\n", dev->name);
						break;
					}
					netif_wake_queue(dev);
					break;

					/*
					 * some unknown PCB
					 */
				default:
					pr_debug("%s: unknown PCB received - %2.2x\n",
						dev->name, adapter->irx_pcb.command);
					break;
				}
			} else {
				pr_warning("%s: failed to read PCB on interrupt\n", dev->name);
				adapter_reset(dev);
			}
		}

	} while (icount++ < 5 && (inb_status(dev->base_addr) & (ACRF | DONE)));

	prime_rx(dev);

	/*
	 * indicate no longer in interrupt routine
	 */
	spin_unlock(&adapter->lock);
	return IRQ_HANDLED;
}
Esempio n. 6
0
int dhcp_init_ifc(const char *ifname)
{
    dhcp_msg discover_msg;
    dhcp_msg request_msg;
    dhcp_msg reply;
    dhcp_msg *msg;
    dhcp_info info;
    int s, r, size;
    int valid_reply;
    uint32_t xid;
    unsigned char hwaddr[6];
    struct pollfd pfd;
    unsigned int state;
    unsigned int timeout;
    int if_index;

    xid = (uint32_t) get_msecs();

    if (ifc_get_hwaddr(ifname, hwaddr)) {
        return fatal("cannot obtain interface address");
    }
    if (ifc_get_ifindex(ifname, &if_index)) {
        return fatal("cannot obtain interface index");
    }

    s = open_raw_socket(ifname, hwaddr, if_index);

    timeout = TIMEOUT_INITIAL;
    state = STATE_SELECTING;
    info.type = 0;
    goto transmit;

    for (;;) {
        pfd.fd = s;
        pfd.events = POLLIN;
        pfd.revents = 0;
        r = poll(&pfd, 1, timeout);

        if (r == 0) {
#if VERBOSE
            printerr("TIMEOUT\n");
#endif
            if (timeout >= TIMEOUT_MAX) {
                printerr("timed out\n");
                if ( info.type == DHCPOFFER ) {
                    printerr("no acknowledgement from DHCP server\nconfiguring %s with offered parameters\n", ifname);
                    return dhcp_configure(ifname, &info);
                }
                errno = ETIME;
                close(s);
                return -1;
            }
            timeout = timeout * 2;

        transmit:
            size = 0;
            msg = NULL;
            switch(state) {
            case STATE_SELECTING:
                msg = &discover_msg;
                size = init_dhcp_discover_msg(msg, hwaddr, xid);
                break;
            case STATE_REQUESTING:
                msg = &request_msg;
                size = init_dhcp_request_msg(msg, hwaddr, xid, info.ipaddr, info.serveraddr);
                break;
            default:
                r = 0;
            }
            if (size != 0) {
                r = send_message(s, if_index, msg, size);
                if (r < 0) {
                    printerr("error sending dhcp msg: %s\n", strerror(errno));
                }
            }
            continue;
        }

        if (r < 0) {
            if ((errno == EAGAIN) || (errno == EINTR)) {
                continue;
            }
            return fatal("poll failed");
        }

        errno = 0;
        r = receive_packet(s, &reply);
        if (r < 0) {
            if (errno != 0) {
                ALOGD("receive_packet failed (%d): %s", r, strerror(errno));
                if (errno == ENETDOWN || errno == ENXIO) {
                    return -1;
                }
            }
            continue;
        }

#if VERBOSE > 1
        dump_dhcp_msg(&reply, r);
#endif
        decode_dhcp_msg(&reply, r, &info);

        if (state == STATE_SELECTING) {
            valid_reply = is_valid_reply(&discover_msg, &reply, r);
        } else {
            valid_reply = is_valid_reply(&request_msg, &reply, r);
        }
        if (!valid_reply) {
            printerr("invalid reply\n");
            continue;
        }

        if (verbose) dump_dhcp_info(&info);

        switch(state) {
        case STATE_SELECTING:
            if (info.type == DHCPOFFER) {
                state = STATE_REQUESTING;
                timeout = TIMEOUT_INITIAL;
                xid++;
                goto transmit;
            }
            break;
        case STATE_REQUESTING:
            if (info.type == DHCPACK) {
                printerr("configuring %s\n", ifname);
                close(s);
                return dhcp_configure(ifname, &info);
            } else if (info.type == DHCPNAK) {
                printerr("configuration request denied\n");
                close(s);
                return -1;
            } else {
                printerr("ignoring %s message in state %d\n",
                         dhcp_type_to_name(info.type), state);
            }
            break;
        }
    }
    close(s);
    return 0;
}
Esempio n. 7
0
void cc110x_rx_handler(void)
{
    uint8_t res = 0;

    /* Possible packet received, RX -> IDLE (0.1 us) */
    rflags.CAA      = 0;
    rflags.MAN_WOR  = 0;
    cc110x_statistic.packets_in++;

    res = receive_packet((uint8_t *)&(cc110x_rx_buffer[rx_buffer_next].packet), sizeof(cc110x_packet_t));

    if (res) {
        /* If we are sending a burst, don't accept packets.
         * Only ACKs are processed (for stopping the burst).
         * Same if state machine is in TX lock. */
        if (radio_state == RADIO_SEND_BURST || rflags.TX) {
            cc110x_statistic.packets_in_while_tx++;
            return;
        }

        cc110x_rx_buffer[rx_buffer_next].rssi = rflags._RSSI;
        cc110x_rx_buffer[rx_buffer_next].lqi = rflags._LQI;
        cc110x_strobe(CC1100_SFRX);		/* ...for flushing the RX FIFO */

        /* Valid packet. After a wake-up, the radio should be in IDLE.
         * So put CC1100 to RX for WOR_TIMEOUT (have to manually put
         * the radio back to sleep/WOR). */
        //cc110x_spi_write_reg(CC1100_MCSM0, 0x08);	/* Turn off FS-Autocal */
        cc110x_write_reg(CC1100_MCSM2, 0x07);	/* Configure RX_TIME (until end of packet) */
        cc110x_strobe(CC1100_SRX);
        hwtimer_wait(IDLE_TO_RX_TIME);
        radio_state = RADIO_RX;

#ifdef DBG_IGNORE

        if (is_ignored(cc110x_rx_buffer[rx_buffer_next].packet.phy_src)) {
            LED_RED_TOGGLE;
            return;
        }

#endif

        /* notify transceiver thread if any */
        if (transceiver_pid) {
            msg_t m;
            m.type = (uint16_t) RCV_PKT_CC1100;
            m.content.value = rx_buffer_next;
            msg_send_int(&m, transceiver_pid);
        }

        /* shift to next buffer element */
        if (++rx_buffer_next == RX_BUF_SIZE) {
            rx_buffer_next = 0;
        }

        return;
    }
    else {
        /* No ACK received so TOF is unpredictable */
        rflags.TOF = 0;

        /* CRC false or RX buffer full -> clear RX FIFO in both cases */
        cc110x_strobe(CC1100_SIDLE);	/* Switch to IDLE (should already be)... */
        cc110x_strobe(CC1100_SFRX);		/* ...for flushing the RX FIFO */

        /* If packet interrupted this nodes send call,
         * don't change anything after this point. */
        if (radio_state == RADIO_AIR_FREE_WAITING) {
            cc110x_strobe(CC1100_SRX);
            hwtimer_wait(IDLE_TO_RX_TIME);
            return;
        }

        /* If currently sending, exit here (don't go to RX/WOR) */
        if (radio_state == RADIO_SEND_BURST) {
            cc110x_statistic.packets_in_while_tx++;
            return;
        }

        /* No valid packet, so go back to RX/WOR as soon as possible */
        cc110x_switch_to_rx();
    }
}
Esempio n. 8
0
/*
 * Send a file via the TFTP data session.
 */
void
tftp_send(int peer, uint16_t *block, struct tftp_stats *ts)
{
	struct tftphdr *rp;
	int size, n_data, n_ack, try;
	uint16_t oldblock;
	char sendbuffer[MAXPKTSIZE];
	char recvbuffer[MAXPKTSIZE];

	rp = (struct tftphdr *)recvbuffer;
	*block = 1;
	ts->amount = 0;
	do {
		if (debug&DEBUG_SIMPLE)
			tftp_log(LOG_DEBUG, "Sending block %d", *block);

		size = read_file(sendbuffer, segsize);
		if (size < 0) {
			tftp_log(LOG_ERR, "read_file returned %d", size);
			send_error(peer, errno + 100);
			goto abort;
		}

		for (try = 0; ; try++) {
			n_data = send_data(peer, *block, sendbuffer, size);
			if (n_data > 0) {
				if (try == maxtimeouts) {
					tftp_log(LOG_ERR,
					    "Cannot send DATA packet #%d, "
					    "giving up", *block);
					return;
				}
				tftp_log(LOG_ERR,
				    "Cannot send DATA packet #%d, trying again",
				    *block);
				continue;
			}

			n_ack = receive_packet(peer, recvbuffer,
			    MAXPKTSIZE, NULL, timeoutpacket);
			if (n_ack < 0) {
				if (n_ack == RP_TIMEOUT) {
					if (try == maxtimeouts) {
						tftp_log(LOG_ERR,
						    "Timeout #%d send ACK %d "
						    "giving up", try, *block);
						return;
					}
					tftp_log(LOG_WARNING,
					    "Timeout #%d on ACK %d",
					    try, *block);
					continue;
				}

				/* Either read failure or ERROR packet */
				if (debug&DEBUG_SIMPLE)
					tftp_log(LOG_ERR, "Aborting: %s",
					    rp_strerror(n_ack));
				goto abort;
			}
			if (rp->th_opcode == ACK) {
				ts->blocks++;
				if (rp->th_block == *block) {
					ts->amount += size;
					break;
				}

				/* Re-synchronize with the other side */
				(void) synchnet(peer);
				if (rp->th_block == (*block - 1)) {
					ts->retries++;
					continue;
				}
			}

		}
		oldblock = *block;
		(*block)++;
		if (oldblock > *block) {
			if (options[OPT_ROLLOVER].o_request == NULL) {
				/*
				 * "rollover" option not specified in
				 * tftp client.  Default to rolling block
				 * counter to 0.
				 */
				*block = 0;
			} else {
				*block = atoi(options[OPT_ROLLOVER].o_request);
			}

			ts->rollovers++;
		}
		gettimeofday(&(ts->tstop), NULL);
	} while (size == segsize);
abort:
	return;
}

/*
 * Receive a file via the TFTP data session.
 *
 * - It could be that the first block has already arrived while
 *   trying to figure out if we were receiving options or not. In
 *   that case it is passed to this function.
 */
void
tftp_receive(int peer, uint16_t *block, struct tftp_stats *ts,
    struct tftphdr *firstblock, size_t fb_size)
{
	struct tftphdr *rp;
	uint16_t oldblock;
	int n_data, n_ack, writesize, i, retry;
	char recvbuffer[MAXPKTSIZE];

	ts->amount = 0;

	if (firstblock != NULL) {
		writesize = write_file(firstblock->th_data, fb_size);
		ts->amount += writesize;
		for (i = 0; ; i++) {
			n_ack = send_ack(peer, *block);
			if (n_ack > 0) {
				if (i == maxtimeouts) {
					tftp_log(LOG_ERR,
					    "Cannot send ACK packet #%d, "
					    "giving up", *block);
					return;
				}
				tftp_log(LOG_ERR,
				    "Cannot send ACK packet #%d, trying again",
				    *block);
				continue;
			}

			break;
		}

		if (fb_size != segsize) {
			gettimeofday(&(ts->tstop), NULL);
			return;
		}
	}

	rp = (struct tftphdr *)recvbuffer;
	do {
		oldblock = *block;
		(*block)++;
		if (oldblock > *block) {
			if (options[OPT_ROLLOVER].o_request == NULL) {
				/*
				 * "rollover" option not specified in
				 * tftp client.  Default to rolling block
				 * counter to 0.
				 */
				*block = 0;
			} else {
				*block = atoi(options[OPT_ROLLOVER].o_request);
			}

			ts->rollovers++;
		}

		for (retry = 0; ; retry++) {
			if (debug&DEBUG_SIMPLE)
				tftp_log(LOG_DEBUG,
				    "Receiving DATA block %d", *block);

			n_data = receive_packet(peer, recvbuffer,
			    MAXPKTSIZE, NULL, timeoutpacket);
			if (n_data < 0) {
				if (retry == maxtimeouts) {
					tftp_log(LOG_ERR,
					    "Timeout #%d on DATA block %d, "
					    "giving up", retry, *block);
					return;
				}
				if (n_data == RP_TIMEOUT) {
					tftp_log(LOG_WARNING,
					    "Timeout #%d on DATA block %d",
					    retry, *block);
					send_ack(peer, oldblock);
					continue;
				}

				/* Either read failure or ERROR packet */
				if (debug&DEBUG_SIMPLE)
					tftp_log(LOG_DEBUG, "Aborting: %s",
					    rp_strerror(n_data));
				goto abort;
			}
			if (rp->th_opcode == DATA) {
				ts->blocks++;

				if (rp->th_block == *block)
					break;

				tftp_log(LOG_WARNING,
				    "Expected DATA block %d, got block %d",
				    *block, rp->th_block);

				/* Re-synchronize with the other side */
				(void) synchnet(peer);
				if (rp->th_block == (*block-1)) {
					tftp_log(LOG_INFO, "Trying to sync");
					*block = oldblock;
					ts->retries++;
					goto send_ack;	/* rexmit */
				}

			} else {
				tftp_log(LOG_WARNING,
				    "Expected DATA block, got %s block",
				    packettype(rp->th_opcode));
			}
		}

		if (n_data > 0) {
			writesize = write_file(rp->th_data, n_data);
			ts->amount += writesize;
			if (writesize <= 0) {
				tftp_log(LOG_ERR,
				    "write_file returned %d", writesize);
				if (writesize < 0)
					send_error(peer, errno + 100);
				else
					send_error(peer, ENOSPACE);
				goto abort;
			}
		}

send_ack:
		for (i = 0; ; i++) {
			n_ack = send_ack(peer, *block);
			if (n_ack > 0) {

				if (i == maxtimeouts) {
					tftp_log(LOG_ERR,
					    "Cannot send ACK packet #%d, "
					    "giving up", *block);
					return;
				}

				tftp_log(LOG_ERR,
				    "Cannot send ACK packet #%d, trying again",
				    *block);
				continue;
			}

			break;
		}
		gettimeofday(&(ts->tstop), NULL);
	} while (n_data == segsize);

	/* Don't do late packet management for the client implementation */
	if (acting_as_client)
		return;

	for (i = 0; ; i++) {
		n_data = receive_packet(peer, (char *)rp, pktsize,
		    NULL, timeoutpacket);
		if (n_data <= 0)
			break;
		if (n_data > 0 &&
		    rp->th_opcode == DATA &&	/* and got a data block */
		    *block == rp->th_block)	/* then my last ack was lost */
			send_ack(peer, *block);	/* resend final ack */
	}

abort:
	return;
}
Esempio n. 9
0
/****************************************************************************
  do a netbios name query to find someones IP
  returns an array of IP addresses or NULL if none
  *count will be set to the number of addresses returned
  ****************************************************************************/
struct in_addr *
name_query (int fd, const char *name, int name_type, BOOL bcast, BOOL recurse,
            struct in_addr to_ip, int *count, void (*fn) (struct packet_struct *))
{
    BOOL found = False;
    int i, retries = 3;
    int retry_time = bcast ? 250 : 2000;
    struct timeval tval;
    struct packet_struct p;
    struct packet_struct *p2;
    struct nmb_packet *nmb = &p.packet.nmb;
    static int name_trn_id = 0;
    struct in_addr *ip_list = NULL;

    memset ((char *) &p, '\0', sizeof (p));
    (*count) = 0;

    if (!name_trn_id)
        name_trn_id = ((unsigned) time (NULL) % (unsigned) 0x7FFF) +
            ((unsigned) getpid () % (unsigned) 100);
    name_trn_id = (name_trn_id + 1) % (unsigned) 0x7FFF;

    nmb->header.name_trn_id = name_trn_id;
    nmb->header.opcode = 0;
    nmb->header.response = False;
    nmb->header.nm_flags.bcast = bcast;
    nmb->header.nm_flags.recursion_available = False;
    nmb->header.nm_flags.recursion_desired = recurse;
    nmb->header.nm_flags.trunc = False;
    nmb->header.nm_flags.authoritative = False;
    nmb->header.rcode = 0;
    nmb->header.qdcount = 1;
    nmb->header.ancount = 0;
    nmb->header.nscount = 0;
    nmb->header.arcount = 0;

    make_nmb_name (&nmb->question.question_name, name, name_type);

    nmb->question.question_type = 0x20;
    nmb->question.question_class = 0x1;

    p.ip = to_ip;
    p.port = NMB_PORT;
    p.fd = fd;
    p.timestamp = time (NULL);
    p.packet_type = NMB_PACKET;

    GetTimeOfDay (&tval);

    if (!send_packet (&p))
        return NULL;

    retries--;

    while (1)
    {
        struct timeval tval2;
        GetTimeOfDay (&tval2);
        if (TvalDiff (&tval, &tval2) > retry_time)
        {
            if (!retries)
                break;
            if (!found && !send_packet (&p))
                return NULL;
            GetTimeOfDay (&tval);
            retries--;
        }

        if ((p2 = receive_packet (fd, NMB_PACKET, 90)))
        {
            struct nmb_packet *nmb2 = &p2->packet.nmb;
            debug_nmb_packet (p2);

            if (nmb->header.name_trn_id != nmb2->header.name_trn_id || !nmb2->header.response)
            {
                /* 
                 * Its not for us - maybe deal with it later 
                 * (put it on the queue?).
                 */
                if (fn)
                    fn (p2);
                else
                    free_packet (p2);
                continue;
            }

            if (nmb2->header.opcode != 0 ||
                nmb2->header.nm_flags.bcast || nmb2->header.rcode || !nmb2->header.ancount)
            {
                /* 
                 * XXXX what do we do with this? Could be a redirect, but
                 * we'll discard it for the moment.
                 */
                free_packet (p2);
                continue;
            }

            ip_list = (struct in_addr *) Realloc (ip_list, sizeof (ip_list[0]) *
                                                  ((*count) + nmb2->answers->rdlength / 6));
            if (ip_list)
            {
                DEBUG (fn ? 3 : 2, ("Got a positive name query response from %s ( ",
                                    inet_ntoa (p2->ip)));
                for (i = 0; i < nmb2->answers->rdlength / 6; i++)
                {
                    putip ((char *) &ip_list[(*count)], &nmb2->answers->rdata[2 + i * 6]);
                    DEBUG (fn ? 3 : 2, ("%s ", inet_ntoa (ip_list[(*count)])));
                    (*count)++;
                }
                DEBUG (fn ? 3 : 2, (")\n"));
            }

            found = True;
            retries = 0;
            free_packet (p2);
            if (fn)
                break;

            /*
             * If we're doing a unicast lookup we only
             * expect one reply. Don't wait the full 2
             * seconds if we got one. JRA.
             */
            if (!bcast && found)
                break;
        }
    }

    return ip_list;
}
Esempio n. 10
0
/*
 * RRQ - send a file to the client
 */
void
tftp_rrq(int peer, char *recvbuffer, ssize_t size)
{
    char *cp;
    int has_options = 0, ecode;
    char *filename, *mode;
    char	fnbuf[PATH_MAX];

    cp = parse_header(peer, recvbuffer, size, &filename, &mode);
    size -= (cp - recvbuffer) + 1;

    strcpy(fnbuf, filename);
    reduce_path(fnbuf);
    filename = fnbuf;

    if (size > 0) {
        if (options_rfc_enabled)
            has_options = !parse_options(peer, cp, size);
        else
            tftp_log(LOG_INFO, "Options found but not enabled");
    }

    ecode = validate_access(peer, &filename, RRQ);
    if (ecode == 0) {
        if (has_options) {
            int n;
            char lrecvbuffer[MAXPKTSIZE];
            struct tftphdr *rp = (struct tftphdr *)lrecvbuffer;

            send_oack(peer);
            n = receive_packet(peer, lrecvbuffer, MAXPKTSIZE,
                               NULL, timeoutpacket);
            if (n < 0) {
                if (debug&DEBUG_SIMPLE)
                    tftp_log(LOG_DEBUG, "Aborting: %s",
                             rp_strerror(n));
                return;
            }
            if (rp->th_opcode != ACK) {
                if (debug&DEBUG_SIMPLE)
                    tftp_log(LOG_DEBUG,
                             "Expected ACK, got %s on OACK",
                             packettype(rp->th_opcode));
                return;
            }
        }
    }

    if (logging)
        tftp_log(LOG_INFO, "%s: read request for %s: %s", peername,
                 filename, errtomsg(ecode));

    if (ecode) {
        /*
         * Avoid storms of naks to a RRQ broadcast for a relative
         * bootfile pathname from a diskless Sun.
         */
        if (suppress_naks && *filename != '/' && ecode == ENOTFOUND)
            exit(0);
        send_error(peer, ecode);
        exit(1);
    }
    tftp_xmitfile(peer, mode);
}
Esempio n. 11
0
void *background_process(void *ptr)
{

    extern int landebug;
    extern struct tm *time_ptr;

    static int i, t;
    static char prmessage[256];
    static int lantimesync = 0;
    static int fldigi_rpc_cnt = 0;

    int n;

    char debugbuffer[160];
    FILE *fp;

    i = 1;

    while (i) {

	while (stop_backgrnd_process == 1) {
	    sleep(1);
	}


	usleep(10000);

	if (packetinterface != 0) {
	    receive_packet();

	}

	if (trxmode == DIGIMODE && digikeyer != NO_KEYER)
	    rx_rtty();

	/*
	 * calling Fldigi XMLRPC method, which reads the Fldigi's carrier
	 * this function helps to show the correct freq of the RIG: reads
	 * the carrier value from Fldigi, and stores in a variable; then
	 * it readable by fldigi_get_carrier()
	 * only need at every 2nd cycle
	 * see fldigixmlrpc.[ch]
	 */
	if (trxmode == DIGIMODE && (digikeyer == GMFSK || digikeyer == FLDIGI)
		&& trx_control == 1) {
	    if (fldigi_rpc_cnt == 0) {
		fldigi_xmlrpc_get_carrier();
	    }
	    fldigi_rpc_cnt = 1 - fldigi_rpc_cnt;
	}

	if (stop_backgrnd_process == 0) {
	    write_keyer();
	    cw_simulator();
	}

	if (lan_active == 1) {
	    if (lan_message[0] == '\0') {

		if (lan_recv() < 0) {
		    recv_error++;
		} else {
		    lan_message[strlen(lan_message) - 1] = '\0';

		}
	    }

	    if (landebug == 1) {
		if ((fp = fopen("debuglog", "a")) == NULL) {
		    fprintf(stdout,
			    "store_qso.c: Error opening debug file.\n");

		}
		else {
		    get_time();
		    strftime(debugbuffer, 80, "%H:%M:%S-", time_ptr);
		    if (strlen(lan_message) > 2) {
			strcat(debugbuffer, lan_message);
			strcat(debugbuffer, "\n");
			fputs(debugbuffer, fp);
		    }

		    fclose(fp);
		}
	    }
	    if ((*lan_message != '\0') && (lan_message[0] == thisnode)) {
		mvprintw(24, 0,
		   "Warning: NODE ID CONFLICT ?! You should use another ID! ");
		refreshp();
		sleep(5);
	    }

	    if ((*lan_message != '\0')
		&& (lan_message[0] != thisnode)
		&& (stop_backgrnd_process != 1)) {

		switch (lan_message[1]) {

		case LOGENTRY:

		    log_to_disk(true);
		    break;

		case QTCRENTRY:

		    store_recv_qtc(lan_message+2);
		    break;

		case QTCSENTRY:

		    store_sent_qtc(lan_message+2);
		    break;

		case QTCFLAG:

		    parse_qtc_flagline(lan_message+2);
		    break;

		case CLUSTERMSG:
		    strncpy(prmessage, lan_message + 2, 80);
		    if (strstr(prmessage, call) != NULL)	// alert for cluster messages
		    {
			mvprintw(24, 0,
				 "                                                                           ");
			mvprintw(24, 0, "%s", prmessage);
			refreshp();
		    }

		    addtext(prmessage);
		    break;
		case TLFSPOT:
		    strncpy(prmessage, lan_message + 2, 80);
		    lanspotflg = 1;
		    addtext(prmessage);
		    lanspotflg = 0;
		    break;
		case TLFMSG:
		    for (t = 0; t < 4; t++)
			strcpy(talkarray[t], talkarray[t + 1]);

		    talkarray[4][0] = lan_message[0];
		    talkarray[4][1] = ':';
		    talkarray[4][2] = '\0';
		    strncat(talkarray[4], lan_message + 2, 60);
		    mvprintw(24, 0,
			     "                                                                           ");
		    mvprintw(24, 0, " MSG from %s", talkarray[4]);
		    refreshp();
		    break;
		case FREQMSG:
		    if ((lan_message[0] >= 'A')
			&& (lan_message[0] <= 'A' + MAXNODES)) {
			node_frequencies[lan_message[0] - 'A'] =
			    atof(lan_message + 2);
			break;
		    }
		case INCQSONUM:

		    n = atoi(lan_message + 2);

		    if (highqsonr < n)
			highqsonr = n;

		    if ((qsonum <= n) && (n > 0)) {
			qsonum = highqsonr + 1;
			qsonr_to_str();
		    }
		    lan_message[0] = '\0';

		case TIMESYNC:
		    if ((lan_message[0] >= 'A')
			&& (lan_message[0] <= 'A' + MAXNODES)) {
			lantime = atoi(lan_message + 2);

			if (lantimesync == 1)
			    timecorr =
				((4 * timecorr) + lantime -
				 (time(0) + (timeoffset * 3600L))) / 5;
			else {
			    timecorr =
				lantime - (time(0) + (timeoffset * 3600L));
			    lantimesync = 1;
			}

			break;
		    }
		}

		lan_message[0] = '\0';
		lan_message[1] = '\0';

	    }

	}

	gettxinfo();		/* get freq info from TRX */

    }

    return (NULL);
}
Esempio n. 12
0
void LLPacketBuffer::init (S32 hSocket)
{
	mSize = receive_packet(hSocket, mData);
	mHost = ::get_sender();
}
Esempio n. 13
0
static void 
rx_packet_handler( int fd, int events )
{
	char discardbuf[PACKET_BUF_SIZE];
	rx_qentry_t *pkg;
	char *buf;
	int i, size;
	mac_enet_t *is;
	struct iovec iov;
	
	for( is=&enetif[0], i=0; i<numifs && IFACE.fd != fd ; i++, is++ )
		;
	if( i >= numifs ) {
		printm("rx_packet_handler: bad fd\n");
		return;
	}

	if( !(events & POLLIN) )
		printm("rx_packet_handler called with events %08X\n", events);

	for( ;; ) {
		if( is->free_head )
			buf = (char *) is->free_head->packet;
		else {
			static int warned=0;
			if( ++warned < 10 )
				printm("WARNING: Ethernet packet dropped\n");
			buf = discardbuf;
		}

		/* read packet from device */
		iov.iov_base = buf;
		iov.iov_len = PACKET_BUF_SIZE;
		if( (size=receive_packet(&IFACE, &iov, 1)) < 0 ) {
			if( errno == EAGAIN )
				break;
			else
				perrorm("packet read");
		}
		
		if( size < 14 + IFACE.packet_pad || !is->started || !is->free_head )
			continue;

		if( !(buf[0+IFACE.packet_pad] & ETH_ADDR_MULTICAST) && memcmp( &IFACE.c_macaddr, buf+IFACE.packet_pad, 6) ) {
			// printm("Dropping packet with wrong HW-addr\n");
			continue;
		}
		/* Queue packet */

		// printm("Got packet size %d\n", size );
		pkg = is->free_head;
		is->free_head = is->free_head->next;

		/* Truncate packets containing more than 1514 bytes */
		if( size > IFACE.packet_pad + MAX_PACKET_SIZE )
			size = IFACE.packet_pad + MAX_PACKET_SIZE;

		pkg->p_size = size;
		queue_rx_packet( is, pkg );
	}
}
Esempio n. 14
0
int main(void)
{
    
  usi_enable();
  spiX_initslave(SPIMODE);
  sei();
  

  //Initialize slave
  slave_init();
  
  //Let settings catch up
  _delay_ms(100);
  
  //An initial packet, not sure what it's for, but the other code had it
  prepare_packet("", 0);
  spiX_put(0);
  
  unsigned char input;
  do{
    
    //Wait for SS
    while(!slave_selected());
    
    //Wait for pending transfers
    spiX_wait();
    
    //Read first character from master
    input = spiX_get();
    
    //Is the master telling us to receive?
      //If so, interpret the input and prepare a response packet
    if(input == RECEIVE_CHAR)
    {
      //Retrieve the rest of the packet from master
      receive_packet();
      
      //Check integrity
      if(!check_integrity())
      {
          prep_err();
          continue;
      }
        
      //Lowercase are read operations
      if(incoming_packet[1] > 96 && incoming_packet[1] < 127)
      {
        prep_response(incoming_packet[1]);
      }
      else
      {
        do_action(incoming_packet[1]);
      }
    }
    //Is the master telling us that it's ready to receive?
    else if(input == SEND_CHAR)
    {
      //Send the prepared packet
      send_packet();
    }
    if(waiting_measure){
       slave_run_measure();
       waiting_measure = 0;
    }
    if(waiting_write){
       slave_apply();
       waiting_write = 0;
    }
    
  } while(1);      // Loop forever...
}
Esempio n. 15
0
File: hw3.c Progetto: azyth/security
// executive entrypoint
int main(int argc, char** argv) {

	// variable declarations here
	int counter;
	pcap_t* handle;
	char errbuf[PCAP_ERRBUF_SIZE];	// contains verbose info about pcap failures
	struct pcap_pkthdr* info;
	const unsigned char* pkt;

	unsigned short proto;
	struct ethhdr* eth_hdr;
	struct iphdr* ip_header;
	struct tcphdr* tcp_hdr;

	// parse the command line
	if (argc < 2 || strcmp(argv[1], "-r") != 0 || argc < 3) {
		printf("usage: %s -r file_1 file_2 ... file_n\n", argv[0]);
		return 1;
	}

	hashtable_t* flowtable = create_table(65536, FLOW);
	hashtable_t* srctable = create_table(65536, SRC);
	
	// filenames are found in argv[2] to argv[argc-1]
	for (counter = 2; counter < argc; ++counter) {
		// open file for processing
		if ((handle = pcap_open_offline(argv[counter], errbuf)) == NULL) {
			printf("error loading [%s]. reason: [%s]\n", argv[counter], errbuf);
			return 1;
		}
		while (pcap_next_ex(handle, &info, &pkt) == 1) {
			//make sure packet can possibly be tcp
			if (info->len < sizeof(struct ethhdr*) + sizeof(struct iphdr*) + sizeof(struct tcphdr*)) { break; }            		
			
			//PARSE ETHERNET HEADER
			eth_hdr = (struct ethhdr*) pkt; // coerce cast
            proto = ntohs(eth_hdr->h_proto);
			if (proto != ETH_P_IP) { continue; }

			//PARSE IP HEADER
			ip_header = (struct iphdr*) (pkt+sizeof(struct ethhdr));
			if (ip_header->protocol != 6) { continue; }

			//PARSE TCP HEADER
			tcp_hdr = (struct tcphdr*) (pkt+sizeof(struct ethhdr)+sizeof(struct iphdr));

			//make the packet struct to send to hashtable		
			enum packet_type type = OTR;
			if (tcp_hdr->syn == 1 && 
				tcp_hdr->ack == 1) 						{ type = SYN_ACK; }

			else if (tcp_hdr->rst == 1 &&
					 tcp_hdr->ack ==1)					{ type = RST_ACK; }

			else if (tcp_hdr->rst == 1)					{ type = RST; }


			else if (tcp_hdr->fin == 1 && 
					 tcp_hdr->urg == 1 && 
					 tcp_hdr->psh == 1) 				{ type = XMAS; }

			else if (tcp_hdr->syn == 1 &&
					 tcp_hdr->ack == 0) 				{ type = SYN; }

			else if (tcp_hdr->fin == 1 &&
					 tcp_hdr->ack == 0) 				{ type = FIN; }
			
			else if (tcp_hdr->fin == 1 &&
					 tcp_hdr->ack == 1) 				{ type = FIN_ACK; }				

			else if (tcp_hdr->ack == 1 &&
					 tcp_hdr->syn == 0 &&
					 tcp_hdr->fin == 0 &&
					 tcp_hdr->rst == 0) 				{ type = ACK; }

			else if (tcp_hdr->fin == 0 &&
					tcp_hdr->syn == 0 &&
					tcp_hdr->rst == 0 && 
					tcp_hdr->psh == 0 &&
					tcp_hdr->ack == 0 &&
					tcp_hdr->urg == 0 &&
					tcp_hdr->ece == 0 &&
					tcp_hdr->cwr == 0)					{ type = NUL; }


			packet_t pkt = {  .type = type, 
							.four_tuple[0] = ip_header->saddr, 
							.four_tuple[1] = tcp_hdr->source, 
							.four_tuple[2] = ip_header->daddr,
							.four_tuple[3] = tcp_hdr->dest, 
							.timestamp = info->ts 
						};
			packet_t* p = &pkt;			

			receive_packet(p, flowtable, srctable);
		}
		print_portscanners(srctable);
		pcap_close(handle);
	}
	free_table(flowtable);
	free_table(srctable);
	return 0;
}