void send_arp(struct arp *arp_pkt) { struct rte_mbuf *mbuf = NULL; struct arp *arp_hdr = NULL; struct ether_hdr *eth = NULL; int i; mbuf = get_mbuf(); assert(mbuf != NULL); arp_hdr = (struct arp *)rte_pktmbuf_prepend (mbuf, sizeof(struct arp)); eth = (struct ether_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct ether_hdr)); logger(ARP, NORMAL, "Sending arp packet\n"); memcpy(arp_hdr, arp_pkt, sizeof(struct arp)); if(arp_pkt->opcode == ntohs(ARP_REQ)) { logger(ARP, ALL, "Sending arp request"); eth->ether_type = htons(ETHER_TYPE_ARP); for(i=0; i<6; i++) { eth->d_addr.addr_bytes[i] = 0xff; } memcpy(ð->s_addr.addr_bytes[0], arp_pkt->src_hw_add, sizeof(arp_pkt->hw_len)); } if(arp_pkt->opcode == ntohs(ARP_REPLY)) { logger(ARP, ALL, "Sending arp reply"); eth->ether_type = htons(ETHER_TYPE_ARP); for(i=0; i<6; i++) { eth->d_addr.addr_bytes[i] = 0xff; // should not be a brodcast ideally. fix it. } // memcpy(ð->d_addr.addr_bytes[0], arp_pkt->src_hw_add, sizeof(arp_pkt->hw_len)); memcpy(ð->s_addr.addr_bytes[0], arp_pkt->src_hw_add, sizeof(arp_pkt->hw_len)); } send_packet_out(mbuf, 0); }
int send_arp_request(unsigned char *src_pr_add, unsigned char *dst_pr_add) { int i; struct rte_mbuf *new_mbuf = get_mbuf(); struct arp *arp_reply = (struct arp *)rte_pktmbuf_prepend (new_mbuf, sizeof(struct arp)); char mac[6]; // http://www.tcpipguide.com/free/t_ARPMessageFormat.htm arp_reply->hw_type = htons(HW_TYPE_ETHERNET); arp_reply->pr_type = htons(SW_TYPE_IPV4); arp_reply->hw_len = HW_LEN_ETHER; arp_reply->pr_len = PR_LEN_IPV4; arp_reply->opcode = htons(1); unsigned char dest_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; uint32_t ip_add = GetIntAddFromChar(src_pr_add, 1); struct Interface *temp = NULL; temp = InterfaceList; while(temp && ip_add != GetIntAddFromChar(temp->IP, 1)) { temp = temp->Next; } if(temp == NULL) { logger(ARP, NORMAL, "Arp request failed, address not hosted\n"); return 0; } logger(ARP, NORMAL, "IP found in interface list\n"); int status = GetInterfaceMac(temp->InterfaceNumber, mac); memcpy(arp_reply->src_hw_add, mac, HW_LEN_ETHER); memcpy(arp_reply->dst_hw_add, dest_mac, HW_LEN_ETHER); memcpy(arp_reply->src_pr_add, src_pr_add, PR_LEN_IPV4); memcpy(arp_reply->dst_pr_add, dst_pr_add, PR_LEN_IPV4); send_arp(arp_reply); }
// remove this api. not used now void sendfin(struct tcb *ptcb) { struct rte_mbuf *mbuf = get_mbuf(); uint8_t tcp_len = 20 ; tcp_len = (tcp_len + 3) / 4; // len is in multiple of 4 bytes; 20 will be 5 tcp_len = tcp_len << 4; // len has upper 4 bits position in tcp header. logger(LOG_TCP, NORMAL, "sending tcp packet\n"); struct tcp_hdr *ptcphdr = (struct tcp_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_hdr)); // printf("head room2 = %d\n", rte_pktmbuf_headroom(mbuf)); if(ptcphdr == NULL) { // printf("tcp header is null\n"); } ptcphdr->src_port = htons(ptcb->dport); ptcphdr->dst_port = htons(ptcb->sport); ptcphdr->sent_seq = htonl(ptcb->next_seq); ptcb->next_seq ++; // for fin ptcphdr->recv_ack = htonl(ptcb->ack); ptcphdr->data_off = tcp_len; ptcphdr->tcp_flags = ptcb->tcp_flags | TCP_FLAG_FIN; ptcphdr->rx_win = 12000; // ptcphdr->cksum = 0x0001; ptcphdr->tcp_urp = 0; //mbuf->ol_flags |= PKT_TX_IP_CKSUM; // someday will calclate checkum here only. // printf(" null\n"); // fflush(stdout); ip_out(ptcb, mbuf, ptcphdr, 0); }
int socket_send(int ser_id, char *message, int len) { struct tcb *ptcb = NULL; struct rte_mbuf *mbuf = get_mbuf(); ptcb = get_tcb_by_identifier(ser_id); sendtcpdata(ptcb, mbuf, message, len); // sendtcppacket(ptcb, mbuf, message, len); // ptcb->send_data(message, len); }
void sendtcpdata(struct tcb *ptcb, unsigned char *data, int len) { printf("Sending tcp data\n"); static int counter_id = -1; if(counter_id == -1) { counter_id = create_counter("tcp_sent"); } counter_inc(counter_id, len); //uint8_t tcp_len = 0x50 + add_mss_option(mbuf, 1300);// + add_winscale_option(mbuf, 7); struct rte_mbuf *mbuf = get_mbuf(); // remove mbuf from parameters. uint8_t data_len = add_tcp_data(mbuf, data, len); uint8_t option_len = 0;//add_winscale_option(mbuf, 7) + add_mss_option(mbuf, 1300) + add_timestamp_option(mbuf, 203032, 0); uint8_t tcp_len = 20 + option_len; uint8_t pad = (tcp_len%4) ? 4 - (tcp_len % 4): 0; tcp_len += pad; logger(LOG_TCP, NORMAL, "padding option %d for tcb %u\n", pad, ptcb->identifier); char *nop = rte_pktmbuf_prepend (mbuf, pad); // always pad the option to make total size multiple of 4. memset(nop, 0, pad); tcp_len = (tcp_len + 3) / 4; // len is in multiple of 4 bytes; 20 will be 5 tcp_len = tcp_len << 4; // len has upper 4 bits position in tcp header. logger(LOG_TCP, NORMAL, "sending tcp data of len %d total %d for tcb %u\n", data_len, tcp_len, ptcb->identifier); struct tcp_hdr *ptcphdr = (struct tcp_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_hdr)); // printf("head room2 = %d\n", rte_pktmbuf_headroom(mbuf)); if(ptcphdr == NULL) { // printf("tcp header is null\n"); } ptcphdr->src_port = htons(ptcb->dport); ptcphdr->dst_port = htons(ptcb->sport); ptcphdr->sent_seq = htonl(ptcb->next_seq); ptcb->next_seq += data_len; if(((ptcb->tcp_flags & TCP_FLAG_SYN) == TCP_FLAG_SYN) || ((ptcb->tcp_flags & TCP_FLAG_FIN) == TCP_FLAG_FIN)) { logger(LOG_TCP, NORMAL, "Increasing seq number by one for flag syn or fin for tcb %u\n", ptcb->identifier); ptcb->next_seq += 1; } logger(LOG_TCP, LOG_LEVEL_NORMAL, "Next seq number is %u flags %u for tcb %u\n", ptcb->next_seq, ptcb->tcp_flags, ptcb->identifier); ptcphdr->recv_ack = htonl(ptcb->ack); ptcphdr->data_off = tcp_len; ptcphdr->tcp_flags = ptcb->tcp_flags; ptcphdr->rx_win = 12000; ptcphdr->cksum = 0x0000; ptcphdr->tcp_urp = 0; ptcb->tcp_flags = 0; //reset the flags as we have sent them in packet now. //mbuf->ol_flags |= PKT_TX_IP_CKSUM; // someday will calclate checkum here only. // printf(" null\n"); // fflush(stdout); logger(LOG_TCP, NORMAL, "[SENDING TCP PACKET] sending tcp packet seq %u ack %u and datalen %u for tcb %u\n", ntohl(ptcphdr->sent_seq), ntohl(ptcphdr->recv_ack), data_len, ptcb->identifier); // push the mbuf in send_window unacknowledged data and increase the refrence count of this segment also start the rto timer for this tcb. PushDataToSendWindow(ptcb, mbuf, ntohl(ptcphdr->sent_seq), ptcb->next_seq, data_len); ip_out(ptcb, mbuf, ptcphdr, data_len); }
void send_reset(struct ipv4_hdr *ip_hdr, struct tcp_hdr *t_hdr) { printf("sending reset\n"); logger(LOG_TCP, LOG_LEVEL_CRITICAL, "sending reset\n"); struct rte_mbuf *mbuf = get_mbuf(); //printf("head room = %d\n", rte_pktmbuf_headroom(mbuf)); // rte_pktmbuf_adj(mbuf, sizeof(struct tcp_hdr) + sizeof(struct ipv4_hdr) + sizeof(struct ether_hdr)); struct tcp_hdr *ptcphdr = (struct tcp_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct tcp_hdr)); //printf("head room2 = %d\n", rte_pktmbuf_headroom(mbuf)); if(ptcphdr == NULL) { //printf("tcp header is null\n"); } uint8_t tcp_len = 20 ; tcp_len = (tcp_len + 3) / 4; // len is in multiple of 4 bytes; 20 will be 5 tcp_len = tcp_len << 4; // len has upper 4 bits position in tcp header. // printf("head room2 = %d\n", rte_pktmbuf_headroom(mbuf)); if(ptcphdr == NULL) { // printf("tcp header is null\n"); } ptcphdr->data_off = tcp_len; ptcphdr->src_port = t_hdr->dst_port; ptcphdr->dst_port = t_hdr->src_port; ptcphdr->sent_seq = t_hdr->recv_ack; ptcphdr->recv_ack = 0; ptcphdr->tcp_flags = TCP_FLAG_RST; ptcphdr->rx_win = 12000; ptcphdr->tcp_urp = 0; // struct ipv4_hdr *hdr = (struct ipv4_hdr *)rte_pktmbuf_prepend (mbuf, sizeof(struct ipv4_hdr)); //printf("head room4 = %d\n", rte_pktmbuf_headroom(mbuf)); //printf("ip header is null\n"); // fflush(stdout); struct tcb ptcb; ptcb.identifier = 0; // dummy ptcb.ipv4_dst = ip_hdr->dst_addr; // fix it future , why we have htonl only for src ptcb.ipv4_src = htonl(ip_hdr->src_addr); fflush(stdout); ip_out(&ptcb, mbuf, ptcphdr, 0); }
void sendack(struct tcb *ptcb) { struct rte_mbuf *mbuf = get_mbuf(); sendtcpack(ptcb, mbuf, NULL, 0); }