int forward_receive_packet(int nic_index, int index) { struct sk_zcopy * zkb = get_zkb_by_index(index); if((zkb == NULL) || (index == 0)) { E("%s: zkb is null or index %d error.\n", __func__, index); return -1; } if((zkb->magic != FROMKERNEL) || zkb->usage != 1) { E("%s must use a packet that from get_one_packet !\n", __func__); E("zkb->index %d, magic, %x, usage %d.\n", zkb->index, zkb->magic, zkb->usage); return -1; } update_zkb_count(); zkb->nic_index = nic_index; if(__send_packet(zkb->queue_index, index)) { zkb->usage = 0; return -1; } return 0; }
static void icmp_send_reply( ip_header * reqip, icmp_header * reqping, u16 len ) { u08 iface; memset( &out, 0, sizeof(out) ); if (!arp_make_eth_header( &out.eth, reqip->src_addr, &iface )) return; __ip_make_response( &out.ip, reqip, len ); out.icmp.type = 0; out.icmp.code = 0; out.icmp.sequence = reqping->sequence; out.icmp.id = reqping->id; memcpy( &out.crap, reqping + 1, len - sizeof( ip_header ) - sizeof( icmp_header ) ); out.icmp.checksum = ~__htons(__checksum( &out.icmp, len - sizeof( ip_header ) )); __send_packet( iface, &out, len + sizeof( eth_header ) ); }
int send_packet(int nic_index, int index, int size) { struct sk_zcopy * zkb = NULL; struct shared_hash_table * wh = whash.ht; zkb = get_zkb_by_index(index); if((zkb == NULL) || (index == 0)) { E("%s: zkb is null or index %d error.\n", __func__, index); return -1; } if((size > 1514) || (wh == NULL)) { E("%s: data packet len %d error.\n", __func__, size); E("No enable send packet function,\n"); return -1; } if((zkb->next != (void*)0x19810828) || (zkb->magic != FROMUSER)) { D("you got wrong packet index %u or packet come from kernel %x !\n",\ index, zkb->magic); return -1; } //just one queue is enough ? zkb->nic_index = nic_index; zkb->queue_index = index % wh->hash_count; zkb->len = size < ETH_ZLEN ? ETH_ZLEN : size; zkb->next = zkb->prev; if(__send_packet(zkb->queue_index, index)) { free_zkb_to_pool(zkb); return -1; } return 0; }
void udp_send( udp_sock sock, u32 to_ip, u16 to_port, u08 const * data, u16 len ) { udp_conn * conn = &udp_conns[sock]; u08 iface; if (!conn->handler) { log_printf( "udp: not_sock in send\n" ); return; } memset( &out, 0, sizeof( out ) ); if ( !arp_make_eth_header( &out.eth, to_ip, &iface ) ) return; out.eth.src = get_macaddr(); out.eth.ethertype = __htons( ethertype_ipv4 ); __ip_make_header( &out.ip, IPPROTO_UDP, 0, len + sizeof( ip_header ) + sizeof( udp_header ), to_ip ); out.udp.src_port = __htons(conn->port); out.udp.dest_port = __htons(to_port); out.udp.length = __htons( len + sizeof( udp_header ) ); if ( len ) memcpy( out.crap, data, len ); out.udp.checksum = ~__htons(__checksum_ex( __pseudoheader_checksum( &out.ip ), &out.udp, len + sizeof( udp_header ) )); __send_packet( iface, (u08 const *) &out, sizeof( eth_header ) + sizeof( ip_header ) + sizeof( udp_header ) + len ); }