Example #1
0
/*
 The following code does:
     * receive address (2 bytes), add them to CRC
     * transmit anything from this address onwards until
       0x8F is reached
     * send the 2 crc bytes.

     This is all very straightforward, except that the CRC calculation
 for the first byte to transmit is delayed somewhat:
 the time between recv_byte_in() and xmit_byte() is only a bit wide,
 which may not be enough time to add a CRC byte.
 */
void do_read_pio(void)
{
	u_short crc = 0;
	u_short adr;
	u_char bcrc = 1;
	u_char b;
	
	recv_byte();
	crc = crc16(crc,0xF0);
	b = recv_byte_in();			// address low byte
	recv_byte();
	crc = crc16(crc, b);
	adr = b;
	b = recv_byte_in();			// address high byte
	adr |= b<<8;

	/* note: bcrc is only true for the first byte to transmit */
#define XMIT(val) do { \
	xmit_byte(val); \
	if(bcrc) { crc = crc16(crc, b); bcrc = 0; } \
	crc = crc16(crc,val); \
} while(0)

	while(adr < 0x88) { XMIT(0); adr++; }
	switch(adr) {
	case 0x88: XMIT(pio_logic);
	case 0x89: XMIT(pio_output_latch);
	case 0x8A: XMIT(pio_activity_latch);
	case 0x8B: XMIT(cond_search_mask);
	case 0x8C: XMIT(cond_polarity_mask);
	case 0x8D: XMIT(control_status);
	case 0x8E: XMIT(0xFF);
	case 0x8F: XMIT(0xFF);
		crc = ~crc;
		xmit_byte(crc);
		xmit_byte(crc >> 8);
	default:
		while(1)
			XMIT(0xFF);
	}
}
Example #2
0
int NSCLASS dsr_ack_req_send(struct in_addr neigh_addr, unsigned short id)
{
	struct dsr_pkt *dp;
	struct dsr_ack_req_opt *ack_req;
	int len = DSR_OPT_HDR_LEN + DSR_ACK_REQ_HDR_LEN;
	char *buf;

	dp = dsr_pkt_alloc(NULL);

	dp->dst = neigh_addr;
	dp->nxt_hop = neigh_addr;
	dp->src = my_addr();

	buf = dsr_pkt_alloc_opts(dp, len);

	if (!buf)
		goto out_err;

	dp->nh.iph = dsr_build_ip(dp, dp->src, dp->dst, IP_HDR_LEN,
				  IP_HDR_LEN + len, IPPROTO_DSR, 1);

	if (!dp->nh.iph) {
		LOG_DBG("Could not create IP header\n");
		goto out_err;
	}

	dp->dh.opth = dsr_opt_hdr_add(buf, len, DSR_NO_NEXT_HDR_TYPE);

	if (!dp->dh.opth) {
		LOG_DBG("Could not create DSR opt header\n");
		goto out_err;
	}

	buf += DSR_OPT_HDR_LEN;
	len -= DSR_OPT_HDR_LEN;

	ack_req = dsr_ack_req_opt_create(buf, len, id);

	if (!ack_req) {
		LOG_DBG("Could not create ACK REQ opt\n");
		goto out_err;
	}

	LOG_DBG("Sending ACK REQ for %s id=%u\n", print_ip(neigh_addr), id);

	XMIT(dp);

	return 1;

      out_err:
	dsr_pkt_free(dp);
	return -1;
}
Example #3
0
void NSCLASS dsr_start_xmit(struct dsr_pkt *dp)
{
	int res;

	if (!dp) {
		DEBUG("Could not allocate DSR packet\n");
		return;
	}

	dp->srt = dsr_rtc_find(dp->src, dp->dst);

	if (dp->srt) {

		if (dsr_srt_add(dp) < 0) {
			DEBUG("Could not add source route\n");
			goto out;
		}
		/* Send packet */

		XMIT(dp);

		return;

	} else {
		res = send_buf_enqueue_packet(dp, &dsr_dev_xmit);
		if (res < 0) {
			DEBUG("Queueing failed!\n");
			goto out;
		}
		res = dsr_rreq_route_discovery(dp->dst);

		if (res < 0)
			DEBUG("RREQ Transmission failed...");

		return;
	}
      out:
	dsr_pkt_free(dp);
}
Example #4
0
int NSCLASS dsr_ack_send(struct in_addr dst, unsigned short id)
{
	struct dsr_pkt *dp;
	struct dsr_ack_opt *ack_opt;
	int len;
	char *buf;

	/* srt = dsr_rtc_find(my_addr(), dst); */

/* 	if (!srt) { */
/* 		LOG_DBG("No source route to %s\n", print_ip(dst.s_addr)); */
/* 		return -1; */
/* 	} */

	len = DSR_OPT_HDR_LEN + /* DSR_SRT_OPT_LEN(srt) +  */ DSR_ACK_HDR_LEN;

	dp = dsr_pkt_alloc(NULL);

	dp->dst = dst;
	/* dp->srt = srt; */
	dp->nxt_hop = dst;	//dsr_srt_next_hop(dp->srt, 0);
	dp->src = my_addr();

	buf = dsr_pkt_alloc_opts(dp, len);

	if (!buf)
		goto out_err;

	dp->nh.iph = dsr_build_ip(dp, dp->src, dp->dst, IP_HDR_LEN,
				  IP_HDR_LEN + len, IPPROTO_DSR, IPDEFTTL);

	if (!dp->nh.iph) {
		LOG_DBG("Could not create IP header\n");
		goto out_err;
	}

	dp->dh.opth = dsr_opt_hdr_add(buf, len, DSR_NO_NEXT_HDR_TYPE);

	if (!dp->dh.opth) {
		LOG_DBG("Could not create DSR opt header\n");
		goto out_err;
	}

	buf += DSR_OPT_HDR_LEN;
	len -= DSR_OPT_HDR_LEN;

	/* dp->srt_opt = dsr_srt_opt_add(buf, len, dp->srt); */

/* 	if (!dp->srt_opt) { */
/* 		LOG_DBG("Could not create Source Route option header\n"); */
/* 		goto out_err; */
/* 	} */

/* 	buf += DSR_SRT_OPT_LEN(dp->srt); */
/* 	len -= DSR_SRT_OPT_LEN(dp->srt); */

	ack_opt = dsr_ack_opt_add(buf, len, dp->src, dp->dst, id);

	if (!ack_opt) {
		LOG_DBG("Could not create DSR ACK opt header\n");
		goto out_err;
	}

	LOG_DBG("Sending ACK to %s id=%u\n", print_ip(dst), id);

	dp->flags |= PKT_XMIT_JITTER;

	XMIT(dp);

	return 1;

      out_err:
	dsr_pkt_free(dp);
	return -1;
}
Example #5
0
int NSCLASS dsr_recv(struct dsr_pkt *dp)
{
	int i = 0, action;
	int mask = DSR_PKT_NONE;

	/* Process DSR Options */
	action = dsr_opt_recv(dp);

	/* Add mac address of previous hop to the neighbor table */

	if (dp->flags & PKT_PROMISC_RECV) {
		dsr_pkt_free(dp);
		return 0;
	}
	for (i = 0; i < DSR_PKT_ACTION_LAST; i++) {
	
		switch (action & mask) {
		case DSR_PKT_NONE:
			break;
		case DSR_PKT_DROP:
		case DSR_PKT_ERROR:
			DEBUG("DSR_PKT_DROP or DSR_PKT_ERROR\n");
			dsr_pkt_free(dp);
			return 0;
		case DSR_PKT_SEND_ACK:
			/* Moved to dsr-ack.c */
			break;
		case DSR_PKT_SRT_REMOVE:
			//DEBUG("Remove source route\n");
			// Hmm, we remove the DSR options when we deliver a
			//packet
			//dsr_opt_remove(dp);
			break;
		case DSR_PKT_FORWARD:

			if (dp->nh.iph->ttl < 1)
			{
				DEBUG("ttl=0, dropping!\n");
				dsr_pkt_free(dp);
				return 0;
			} else {
				DEBUG("Forwarding %s %s nh %s\n",
				      print_ip(dp->src),
				      print_ip(dp->dst), print_ip(dp->nxt_hop));
				XMIT(dp);
				return 0;
			}
			break;
		case DSR_PKT_FORWARD_RREQ:
			XMIT(dp);
			return 0;
		case DSR_PKT_SEND_RREP:
			/* In dsr-rrep.c */
			break;
		case DSR_PKT_SEND_ICMP:
			DEBUG("Send ICMP\n");
			break;
		case DSR_PKT_SEND_BUFFERED:
			if (dp->rrep_opt) {
				struct in_addr rrep_srt_dst;
				int i;
				
				for (i = 0; i < dp->num_rrep_opts; i++) {
					rrep_srt_dst.s_addr = dp->rrep_opt[i]->addrs[DSR_RREP_ADDRS_LEN(dp->rrep_opt[i]) / sizeof(struct in_addr)];
					
					send_buf_set_verdict(SEND_BUF_SEND, rrep_srt_dst);
				}
			}
				break;
		case DSR_PKT_DELIVER:
			DEBUG("Deliver to DSR device\n");
			DELIVER(dp);
			return 0;
		case 0:
			break;
		default:
			DEBUG("Unknown pkt action\n");
		}
		mask = (mask << 1);
	}

	dsr_pkt_free(dp);

	return 0;
}