Esempio n. 1
0
struct dsr_opt *dsr_opt_find_opt(struct dsr_pkt *dp, int type)
{
	int dsr_len, l;
	struct dsr_opt *dopt;

	dsr_len = dsr_pkt_opts_len(dp);

	l = DSR_OPT_HDR_LEN;
	dopt = DSR_GET_OPT(dp->dh.opth);

	while (l < dsr_len && (dsr_len - l) > 2) {
		if (type == dopt->type)
			return dopt;

		l += dopt->length + 2;
		dopt = DSR_GET_NEXT_OPT(dopt);
	}
	return NULL;
}
Esempio n. 2
0
struct dsr_ack_req_opt *NSCLASS
dsr_ack_req_opt_add(struct dsr_pkt *dp, unsigned short id)
{
	char *buf = NULL;
	int prot = 0, tot_len = 0, ttl = IPDEFTTL;

	if (!dp)
		return NULL;

	/* If we are forwarding a packet and there is already an ACK REQ option,
	 * we just overwrite the old one. */
	if (dp->ack_req_opt) {
		buf = (char *)dp->ack_req_opt;
		goto end;
	}
#ifdef NS2
	if (dp->p) {
		hdr_cmn *cmh = HDR_CMN(dp->p);
		prot = cmh->ptype();
	} else
		prot = DSR_NO_NEXT_HDR_TYPE;

	ttl = dp->nh.iph->ttl();
#else
	if (dp->nh.raw) {
		tot_len = ntohs(dp->nh.iph->tot_len);
		prot = dp->nh.iph->protocol;
		ttl = dp->nh.iph->ttl;
	}
#endif
	if (!dsr_pkt_opts_len(dp)) {

		buf =
		    dsr_pkt_alloc_opts(dp,
				       DSR_OPT_HDR_LEN + DSR_ACK_REQ_HDR_LEN);
		LOG_DBG("Allocating options for ACK REQ\n");
		if (!buf)
			return NULL;

		dsr_build_ip(dp, dp->src, dp->dst, IP_HDR_LEN,
			     tot_len + DSR_OPT_HDR_LEN + DSR_ACK_REQ_HDR_LEN,
			     IPPROTO_DSR, ttl);

		dp->dh.opth =
		    dsr_opt_hdr_add(buf, DSR_OPT_HDR_LEN + DSR_ACK_REQ_HDR_LEN,
				    prot);

		if (!dp->dh.opth) {
			return NULL;
		}

		buf += DSR_OPT_HDR_LEN;

	} else {
		buf = dsr_pkt_alloc_opts_expand(dp, DSR_ACK_REQ_HDR_LEN);

		LOG_DBG("Expanding options for ACK REQ p_len=%d\n",
		      ntohs(dp->dh.opth->p_len));
		if (!buf)
			return NULL;

		dsr_build_ip(dp, dp->src, dp->dst, IP_HDR_LEN,
			     tot_len + DSR_ACK_REQ_HDR_LEN, IPPROTO_DSR, ttl);

		dp->dh.opth =
		    dsr_opt_hdr_add(dp->dh.raw,
				    DSR_OPT_HDR_LEN +
				    ntohs(dp->dh.opth->p_len) +
				    DSR_ACK_REQ_HDR_LEN, dp->dh.opth->nh);
	}
	LOG_DBG("Added ACK REQ option id=%u\n", id, ntohs(dp->dh.opth->p_len));
      end:
	return dsr_ack_req_opt_create(buf, DSR_ACK_REQ_HDR_LEN, id);
}
Esempio n. 3
0
int dsr_opt_parse(struct dsr_pkt *dp)
{
	int dsr_len, l, n = 0;
	struct dsr_opt *dopt;

	if (!dp)
		return -1;

	dsr_len = dsr_pkt_opts_len(dp);

	l = DSR_OPT_HDR_LEN;
	dopt = DSR_GET_OPT(dp->dh.opth); //skip dsr option header
	
	dp->num_rrep_opts = dp->num_rerr_opts = dp->num_rreq_opts = dp->num_ack_opts = 0;
	
	dp->srt_opt = NULL;
	dp->ack_req_opt = NULL;

	while (l < dsr_len && (dsr_len - l) > 2) {
		switch (dopt->type) {
		case DSR_OPT_PADN:
			break;
		case DSR_OPT_RREQ:
			if (dp->num_rreq_opts == 0)
				dp->rreq_opt = (struct dsr_rreq_opt *)dopt;
#ifndef NS2
			else
				DEBUG("ERROR: More than one RREQ option!!\n");
#endif
			break;
		case DSR_OPT_RREP:
			if (dp->num_rrep_opts < MAX_RREP_OPTS)
				dp->rrep_opt[dp->num_rrep_opts++] = (struct dsr_rrep_opt *)dopt;
#ifndef NS2
			else
				DEBUG("Maximum RREP opts in one packet reached\n");
#endif
			break;
		case DSR_OPT_RERR:
			if (dp->num_rerr_opts < MAX_RERR_OPTS)
				dp->rerr_opt[dp->num_rerr_opts++] = (struct dsr_rerr_opt *)dopt;
#ifndef NS2
			else
				DEBUG("Maximum RERR opts in one packet reached\n");
#endif
			break;
		case DSR_OPT_PREV_HOP:
			break;
		case DSR_OPT_ACK:
			if (dp->num_ack_opts < MAX_ACK_OPTS)
				dp->ack_opt[dp->num_ack_opts++] = (struct dsr_ack_opt *)dopt;
#ifndef NS2
			else
				DEBUG("Maximum ACK opts in one packet reached\n");
#endif
			break;
		case DSR_OPT_SRT:
			if (!dp->srt_opt)
				dp->srt_opt = (struct dsr_srt_opt *)dopt;
#ifndef NS2
			else
				DEBUG("More than one source route in packet\n");
#endif
			break;
		case DSR_OPT_TIMEOUT:
			break;
		case DSR_OPT_FLOWID:
			break;
		case DSR_OPT_ACK_REQ:
			if (!dp->ack_req_opt)
				dp->ack_req_opt = (struct dsr_ack_req_opt *)dopt;
#ifndef NS2
			else
				DEBUG("More than one ACK REQ in packet\n");
#endif
			break;
		case DSR_OPT_PAD1:
			l++;
			dopt++;
			continue;
#ifndef NS2
		default:
			DEBUG("Unknown DSR option type=%d\n", dopt->type);
#endif
		}
		l += dopt->length + 2;
		dopt = DSR_GET_NEXT_OPT(dopt);
		n++;
	}
	
	return n;
}
Esempio n. 4
0
int NSCLASS dsr_opt_recv(struct dsr_pkt *dp)
{
	int dsr_len, l;
	int action = 0;
	struct dsr_opt *dopt;
	struct in_addr myaddr;

	if (!dp)
		return DSR_PKT_ERROR;

	myaddr = my_addr();

	/* Packet for us ? */
	if (dp->dst.s_addr == myaddr.s_addr && dp->payload_len != 0)
		action |= DSR_PKT_DELIVER;
	dsr_len = dsr_pkt_opts_len(dp);

	l = DSR_OPT_HDR_LEN;
	dopt = DSR_GET_OPT(dp->dh.opth);

	//DEBUG("Parsing DSR packet l=%d dsr_len=%d\n", l, dsr_len);
	
	while (l < dsr_len && (dsr_len - l) > 2) {
		//DEBUG("dsr_len=%d l=%d\n", dsr_len, l);
		switch (dopt->type) {
		case DSR_OPT_PADN:
			break;
		case DSR_OPT_RREQ:
			if (dp->flags & PKT_PROMISC_RECV)
				break;
			
			action |= dsr_rreq_opt_recv(dp, (struct dsr_rreq_opt *)dopt);
			break;
		case DSR_OPT_RREP:
			/* We should probably allow promisuously
			 * receiving RREPs */
			if (dp->flags & PKT_PROMISC_RECV)
				break;
			
			action |= dsr_rrep_opt_recv(dp, (struct dsr_rrep_opt *)dopt);		       
			break;
		case DSR_OPT_RERR:
			if (dp->flags & PKT_PROMISC_RECV)
				break;
			if (dp->num_rerr_opts < MAX_RERR_OPTS) {
				action |=
				    dsr_rerr_opt_recv(dp, (struct dsr_rerr_opt *)dopt);
			}

			break;
		case DSR_OPT_PREV_HOP:
			break;
		case DSR_OPT_ACK:
			if (dp->flags & PKT_PROMISC_RECV)
				break;

			if (dp->num_ack_opts < MAX_ACK_OPTS) {
				dp->ack_opt[dp->num_ack_opts++] =
				    (struct dsr_ack_opt *)dopt;
				action |=
				    dsr_ack_opt_recv((struct dsr_ack_opt *)
						     dopt);
			}
			break;
		case DSR_OPT_SRT:
			action |= dsr_srt_opt_recv(dp, (struct dsr_srt_opt *)dopt);
			break;
		case DSR_OPT_TIMEOUT:
			break;
		case DSR_OPT_FLOWID:
			break;
		case DSR_OPT_ACK_REQ:
			action |=
			    dsr_ack_req_opt_recv(dp, (struct dsr_ack_req_opt *)
						 dopt);
			break;
		case DSR_OPT_PAD1:
			l++;
			dopt++;
			continue;
		default:
			DEBUG("Unknown DSR option type=%d\n", dopt->type);
		}
		l += dopt->length + 2;
		dopt = DSR_GET_NEXT_OPT(dopt);
	}
	return action;
}
Esempio n. 5
0
struct sk_buff *dsr_skb_create(struct dsr_pkt *dp, struct net_device *dev)
{
	struct sk_buff *skb;
	char *buf;
	int ip_len;
	int tot_len;
	int dsr_opts_len = dsr_pkt_opts_len(dp);

	ip_len = dp->nh.iph->ihl << 2;

	tot_len = ip_len + dsr_opts_len + dp->payload_len;

	DEBUG("ip_len=%d dsr_opts_len=%d payload_len=%d tot_len=%d\n",
	      ip_len, dsr_opts_len, dp->payload_len, tot_len);
#ifdef KERNEL26
	skb = alloc_skb(tot_len + LL_RESERVED_SPACE(dev), GFP_ATOMIC);
#else
	skb = alloc_skb(dev->hard_header_len + 15 + tot_len, GFP_ATOMIC);
#endif
	if (!skb) {
		DEBUG("alloc_skb failed\n");
		return NULL;
	}

	SKB_SET_MAC_HDR(skb, 0);

	/* We align to 16 bytes, for ethernet: 2 bytes + 14 bytes
	 * header. This will move the skb->data pointer forward. */
#ifdef KERNEL26
	skb_reserve(skb, LL_RESERVED_SPACE(dev));
#else
	skb_reserve(skb, (dev->hard_header_len + 15) & ~15);
#endif
	SKB_SET_NETWORK_HDR(skb, 0);
	       
	skb->dev = dev;
	skb->protocol = htons(ETH_P_IP);

	/* Copy in all the headers in the right order */
	buf = skb_put(skb, tot_len);

	memcpy(buf, dp->nh.raw, ip_len);

	/* For some reason the checksum has to be recalculated here, at least
	 * when there is a record route IP option */
	ip_send_check((struct iphdr *)buf);

	buf += ip_len;

	/* Add DSR header if it exists */
	if (dsr_opts_len) {
		memcpy(buf, dp->dh.raw, dsr_opts_len);
		buf += dsr_opts_len;
	}

	/* Add payload */
	if (dp->payload_len && dp->payload)
		memcpy(buf, dp->payload, dp->payload_len);

	return skb;
}