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; }
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); }
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; }
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; }