void send_ip_handler(char *packet, unsigned int size) { ip_optlen = ip_opt_build(ip_opt); if (!opt_fragment && (size+ip_optlen+20 > h_if_mtu)) { /* auto-activate fragmentation */ virtual_mtu = h_if_mtu-20; virtual_mtu = virtual_mtu - (virtual_mtu % 8); opt_fragment = TRUE; opt_mf = opt_df = FALSE; /* deactivate incompatible options */ if (opt_verbose || opt_debug) printf("auto-activate fragmentation, fragments size: %d\n", virtual_mtu); } if (!opt_fragment) { unsigned short fragment_flag = 0; if (opt_mf) fragment_flag |= MF; /* more fragments */ if (opt_df) fragment_flag |= DF; /* dont fragment */ send_ip((char*)&local.sin_addr, (char*)&remote.sin_addr, packet, size, fragment_flag, ip_frag_offset, ip_opt, ip_optlen); } else { unsigned int remainder = size; int frag_offset = 0; while(1) { if (remainder <= virtual_mtu) break; send_ip((char*)&local.sin_addr, (char*)&remote.sin_addr, packet+frag_offset, virtual_mtu, MF, frag_offset, ip_opt, ip_optlen); remainder-=virtual_mtu; frag_offset+=virtual_mtu; } send_ip((char*)&local.sin_addr, (char*)&remote.sin_addr, packet+frag_offset, remainder, NF, frag_offset, ip_opt, ip_optlen); } }
void send_tcp(tcp_pkt* pkt1,ip_pkt* pkt2) { unsigned short tmp; pkt2->buf.len = pkt1->buf.len+20; pkt2->pr = 0x06; pkt2->buf.ptr[0]=pkt1->p_s >> 8; pkt2->buf.ptr[1]=pkt1->p_s & 0xFF; pkt2->buf.ptr[2]=pkt1->p_d >> 8; pkt2->buf.ptr[3]=pkt1->p_d & 0xFF; pkt2->buf.ptr[4]=(pkt1->n_tr >> 24) & 0xFF; pkt2->buf.ptr[5]=(pkt1->n_tr >> 16) & 0xFF; pkt2->buf.ptr[6]=(pkt1->n_tr >> 8) & 0xFF; pkt2->buf.ptr[7]=(pkt1->n_tr) & 0xFF; pkt2->buf.ptr[8]=(pkt1->n_rcv >> 24) & 0xFF; pkt2->buf.ptr[9]=(pkt1->n_rcv >> 16) & 0xFF; pkt2->buf.ptr[10]=(pkt1->n_rcv >> 8) & 0xFF; pkt2->buf.ptr[11]=(pkt1->n_rcv) & 0xFF; pkt2->buf.ptr[12]=0x50; pkt2->buf.ptr[13]=pkt1->fl; pkt2->buf.ptr[14]=0x04; pkt2->buf.ptr[15]=0x00; pkt2->buf.ptr[16]=0x00;pkt2->buf.ptr[17]=0x00; pkt2->buf.ptr[18]=0x00;pkt2->buf.ptr[19]=0x00; for(tmp=0;tmp<pkt1->buf.len;tmp++) pkt2->buf.ptr[20+tmp]=pkt1->buf.ptr[tmp]; send_ip(pkt2); }
void update_arp_queue(struct sr_instance* sr, arp_hdr* arp_header, const char* interface) { router_state* rs = get_router_state(sr); node* n = rs->arp_queue; node* next = NULL; while (n) { next = n->next; arp_queue_entry* aqe = (arp_queue_entry*)n->data; /* Does this arp reply match an entry waiting for it? */ if (arp_header->arp_sip.s_addr == aqe->next_hop.s_addr) { /* send out the packets */ node* cur_packet_node = aqe->head; node* next_packet_node = NULL; while (cur_packet_node) { next_packet_node = cur_packet_node->next; arp_queue_packet_entry* aqpe = (arp_queue_packet_entry*)cur_packet_node->data; /* send_ip takes responsibility for the packet so we don't need to free it */ send_ip(sr, aqpe->packet, aqpe->len, &(aqe->next_hop), aqe->out_iface_name); node_remove(&(aqe->head), cur_packet_node); cur_packet_node = next_packet_node; } node_remove(&(rs->arp_queue), n); } n = next; } }
/* * NOT THREAD SAFE! Lock cache rd, queue wr * * */ void send_queued_packets(struct sr_instance* sr, struct in_addr* dest_ip, char* dest_mac) { node* n = get_router_state(sr)->arp_queue; node* next = NULL; while (n) { next = n->next; arp_queue_entry* aqe = (arp_queue_entry*)n->data; /* match the arp reply sip to our entry next hop ip */ if (dest_ip->s_addr == aqe->next_hop.s_addr) { node* cur_packet_node = aqe->head; node* next_packet_node = NULL; while (cur_packet_node) { next_packet_node = cur_packet_node->next; /* send the packet */ arp_queue_packet_entry* aqpe = (arp_queue_packet_entry*)cur_packet_node->data; send_ip(sr, aqpe->packet, aqpe->len, &(aqe->next_hop), aqe->out_iface_name); node_remove(&(aqe->head), cur_packet_node); cur_packet_node = next_packet_node; } /* free the arp queue entry for this destination ip, and patch the list */ node_remove(&(get_router_state(sr)->arp_queue), n); } n = next; } }
/** * DNS: Sends a standard DNS-query (read request package) to a DNS-server. * DNS-server respones with host IP or signals some error condition. * Responses from the server are handled by handle_dns function. * * @param fd socket descriptor * @param domain_name the domain name given as series of labels preceded * with length(label) and terminated with 0 * <br>(e.g. "\3,w,w,w,\4,h,o,s,t,\3,o,r,g,\0") * @see handle_dns */ static void dns_send_query(int fd, int8_t * domain_name, uint8_t ip_version) { int qry_len = strlen((char *) domain_name) + 5; int iphdr_len = (ip_version == 4) ? sizeof(struct iphdr) : sizeof(struct ip6hdr); ip6_addr_t server_ipv6; uint32_t packetsize = iphdr_len + sizeof(struct udphdr) + sizeof(struct dnshdr) + qry_len; memset(ether_packet, 0, packetsize); fill_dnshdr(ðer_packet[ iphdr_len + sizeof(struct udphdr)], domain_name, ip_version); fill_udphdr(ðer_packet[iphdr_len], sizeof(struct dnshdr) + sizeof(struct udphdr) + qry_len, UDPPORT_DNSC, UDPPORT_DNSS); if (ip_version == 4) { fill_iphdr(ether_packet, sizeof(struct dnshdr) + sizeof(struct udphdr) + iphdr_len + qry_len, IPTYPE_UDP, 0, dns_server_ip); } else { memcpy(server_ipv6.addr, dns_server_ipv6, 16); fill_ip6hdr(ether_packet, sizeof(struct dnshdr) + sizeof(struct udphdr) + qry_len, IPTYPE_UDP, get_ipv6_address(), &server_ipv6); } send_ip(fd, ether_packet, packetsize); }
void ping_echo(icmp_pkt* pkt1,ip_pkt* pkt2) { unsigned short tmp; for(tmp=0;tmp<4;tmp++) pkt2->ip_d[tmp] = pkt2->ip_s[tmp]; pkt2->pr = 0x01; pkt2->buf.ptr[0]=0x00; pkt2->buf.ptr[1]=0x00; pkt2->buf.ptr[2]=0x00; pkt2->buf.ptr[3]=0x00; pkt2->buf.ptr[4]=pkt1->id[0];pkt2->buf.ptr[5]=pkt1->id[1]; pkt2->buf.ptr[6]=pkt1->num[0];pkt2->buf.ptr[7]=pkt1->num[1]; for(tmp=0;tmp < pkt1->buf.len;tmp++) pkt2->buf.ptr[8+tmp]=pkt1->buf.ptr[tmp]; pkt2->buf.len= 8 + pkt1->buf.len; send_ip(pkt2); }
static void select_handler(ClickRecognizerRef crr, void *context) { s_current_field++; if (s_current_field > 3) { s_ip_set = true; persist_write_data(IP_PERSIST_KEY, s_ip, 4); send_ip(s_ip); click_down_handler = click_handler; click_up_handler = click_handler; click_select_handler = click_handler; window_set_click_config_provider(s_window, (ClickConfigProvider) config_provider); } update_ui(); }
long _IKED::packet_ike_xmit( IDB_PH1 * ph1, IDB_XCH * xch, PACKET_IKE & packet, bool retry ) { // // prepare for log output // char txtaddr_l[ LIBIKE_MAX_TEXTADDR ]; char txtaddr_r[ LIBIKE_MAX_TEXTADDR ]; text_addr( txtaddr_l, &ph1->tunnel->saddr_l, true ); text_addr( txtaddr_r, &ph1->tunnel->saddr_r, true ); char * encap_mode = encap_ike; if( ph1->tunnel->natt_version != IPSEC_NATT_NONE ) encap_mode = encap_nat; // // encapsulate ike packet into UDP/IP packet // PACKET_IP packet_ip; packet_ike_encap( packet, packet_ip, ph1->tunnel->saddr_l, ph1->tunnel->saddr_r, ph1->tunnel->natt_version ); // // log the result // log.bin( LLOG_DEBUG, LLOG_DECODE, packet_ip.buff(), packet_ip.size(), "-> : send %s packet %s -> %s", encap_mode, txtaddr_l, txtaddr_r ); // // send ike packet // ETH_HEADER header; long result = send_ip( packet_ip, &header ); if( result != LIBIKE_OK ) { ph1->status( XCH_STATUS_DEAD, XCH_FAILED_NETWORK, 0 ); xch->status( XCH_STATUS_DEAD, XCH_FAILED_NETWORK, 0 ); return LIBIKE_FAILED; } // // queue packet for resend // xch->resend_queue( packet_ip ); // // dump for encoded packets // if( dump_encrypt ) pcap_encrypt.dump( header, packet_ip ); return LIBIKE_OK; }
/** * TODO : take the pseudo header function out. NOTE : make sure it is generic * enough to be called by handshake funcs AND send data funcs. * TODO : 3rd shake might have data * TODO : RST */ void tcp_send_handshake(int gripnum, socket_t *socket){ tcphdr *header = NULL; switch(gripnum) { case 0: printf("\t TODO : RST NOT IMPLEMENTED YET\n"); case SYN_SENT://1'st shake header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, 0,0,1,0,0,0, WINSIZE); //half the max sequence number break; case SYN_RCVD://2'nd shake header = tcp_mastercrafter(socket->myport, socket->urport, (socket->myseq)++, socket->ackseq, 0,1,0,0,1, WINSIZE); break; case ESTABLISHED://3'rd shake header = tcp_mastercrafter(socket->myport, socket->urport, ++(socket->myseq), socket->ackseq, 0,0,0,0,1, WINSIZE); break; case FIN_WAIT_1:// from ESTABLISHED --> FIN_WAIT_1 state (FIN SEGMENT) header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 1,0,0,0,1,MAXSEQ); break; case CLOSE_WAIT: //regular ACK header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 0,0,0,0,1,MAXSEQ); break; case LAST_ACK: // moving from CLOSE_WAIT --> LAST_ACK (FIN SEGMENT) header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 1,0,0,0,1,MAXSEQ); break; case CLOSING: // moving from FIN_WAIT_1 --> CLOSING header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 1,0,0,0,1,MAXSEQ); break; case ACKNOWLEDGE: printf("RST, ACK\n"); header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 0,0,0,0,1,MAXSEQ); case RST: // RST packet header = tcp_mastercrafter(socket->myport, socket->urport, socket->myseq, socket->ackseq, 1,0,0,0,1,MAXSEQ); break; default: printf("\t WARNING : Unknown shake!\n"); return; } //0. make sure TCP header is not NULL if (header == NULL) { printf("\tWARNING : Could not make TCP header\n"); return; } struct pseudo_tcpp *tcp_packet = (uint16_t *)malloc(sizeof(struct pseudo_tcpp)); memset(tcp_packet, 0x0, sizeof(struct pseudo_tcpp)); //1. fill the pseudiheader part ((uint32_t *)tcp_packet)[0] = socket->myaddr; ((uint32_t *)tcp_packet)[1] = socket->uraddr; ((uint8_t *)tcp_packet)[9] = (uint8_t)TCP; ((uint16_t *)tcp_packet)[5] = ntohs((uint16_t)TCPHDRSIZE); //2. fill the header tcp_hton(header); memcpy(&tcp_packet->tcp, header, TCPHDRSIZE); //3. data (NONE) //TODO : 3rd handshake could have data. memset(tcp_packet->payload, 0, 1024); //4. checksum uint16_t checksum = tcp_checksum(tcp_packet, TCPHDRSIZE+12); //5. set the checksum in the TCP header header->check = checksum; if (header->check == 0) { printf("\t ERROR : something went wrong with checksum\n"); header->check = 0xffffff; } //6. TODO : error checking interface_t *nexthop = get_nexthop(socket->uraddr); //TODO : packet top pass to ip char *packet = (char *)malloc(TCPHDRSIZE+IPHDRSIZE); if (packet == NULL) { printf("\t ERROR : Malloc failed\n"); return; } //7. copy the TCP header to ip packet memset(packet, 0, TCPHDRSIZE+IPHDRSIZE); memcpy(packet, header, TCPHDRSIZE); //8. NO data, so you are done : pass to ip encapsulate_inip(socket->myaddr,socket->uraddr,(uint8_t)TCP,header, TCPHDRSIZE, &packet); //9. TCP/IP packet all set, sending time int ret = send_ip(nexthop, packet, TCPHDRSIZE+IPHDRSIZE); free(tcp_packet); free(packet); free(header); return; }
void handler_sigalarm(int signo) { send_ip(); alarm(2); }