/* * This function assumes it is being called from dev_queue_xmit() * and that skb is filled properly by that function. */ int ipsec_mast_start_xmit(struct sk_buff *skb , struct net_device *dev , IPsecSAref_t SAref) { struct ipsec_xmit_state ixs_mem; struct ipsec_xmit_state *ixs = &ixs_mem; enum ipsec_xmit_value stat = IPSEC_XMIT_OK; /* dev could be a mast device, but should be optional, I think... */ /* SAref is also optional, but one of the two must be present. */ /* I wonder if it could accept no device or saref and guess? */ /* ipsec_xmit_sanity_check_dev(ixs); */ ipsec_xmit_sanity_check_skb(ixs); ipsec_xmit_adjust_hard_header(ixs); stat = ipsec_xmit_encap_bundle(ixs); if(stat != IPSEC_XMIT_OK) { /* SA processing failed */ } ipsec_xmit_hard_header_restore(); }
int main(char *argv[], int argc) { int error; struct sockaddr_in saddr,daddr; struct sockaddr_in saddr2,daddr2; void *main_talloc = NULL; struct ipsec_sa *sa, *sa1; char auth1[]={0x87, 0x65, 0x87, 0x65, 0x87, 0x65, 0x87, 0x65, 0x87, 0x65, 0x87, 0x65, 0x87, 0x65, 0x87, 0x65}; char enc[] ={0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46, 0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f, 0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57, 0x58}; debug_xform = 1; init_kmalloc(); debug_tunnel=0xffffffff; debug_xmit=0xffffffff; sysctl_ipsec_debug_verbose = 1; prng_init(&ipsec_prng, seed, sizeof(seed)); ipsec_sadb_init(); ipsec_alg_init(); { sa1 = ipsec_sa_alloc(&error); assert(error == 0); ipsec_sa_intern(sa1); sa1->ips_seq = 1; sa1->ips_pid = 10; sa1->ips_said.spi = htonl(0x12345678); sa1->ips_said.proto = IPPROTO_IPIP; sa1->ips_said.dst.u.v4.sin_addr.s_addr = htonl(0xc001022D); sa1->ips_state = SADB_SASTATE_MATURE; daddr2.sin_addr.s_addr = htonl(0xc001022D); saddr2.sin_addr.s_addr = htonl(0xc0010217); sa1->ips_addr_s = (struct sockaddr *)&saddr2; sa1->ips_addr_d = (struct sockaddr *)&daddr2; } { sa = ipsec_sa_alloc(&error); assert(error == 0); ipsec_sa_intern(sa); sa->ips_said.spi = htonl(0x12345678); sa->ips_said.proto = IPPROTO_ESP; sa->ips_said.dst.u.v4.sin_addr.s_addr = htonl(0xc001022D); sa->ips_said.dst.u.v4.sin_family = AF_INET; sa->ips_seq = 1; sa->ips_pid = 10; sa->ips_inext = sa1; { /* make a copy so that ipsec_sa_init() can zero it out */ char *auth = talloc_size(main_talloc, AHMD596_KLEN); memcpy(auth, auth1, AHMD596_KLEN); sa->ips_authalg = AH_MD5; sa->ips_key_bits_a = AHMD596_KLEN * 8; sa->ips_key_a = auth; } sa->ips_encalg = ESP_3DES; sa->ips_key_bits_e = 192; sa->ips_iv_bits = 128; sa->ips_key_e_size = 0; sa->ips_key_e = talloc_memdup(main_talloc, enc, sa->ips_key_bits_e); sa->ips_state = SADB_SASTATE_MATURE; daddr.sin_addr.s_addr = htonl(0xc001022D); saddr.sin_addr.s_addr = htonl(0xc0010217); sa->ips_addr_s = (struct sockaddr *)&saddr; sa->ips_addr_d = (struct sockaddr *)&daddr; ipsec_sa_add(sa); assert(ipsec_sa_init(sa) == 0); ipsec_sa_put(sa); } { struct ipsec_xmit_state ixs_mem; struct ipsec_xmit_state *ixs = &ixs_mem; enum ipsec_xmit_value stat; struct net_device_stats stats; int iphlen; struct sk_buff *skb = skbFromArray(packet2, packet2_len); skb->nh.raw = skb_pull(skb, skb->mac_len); iphlen = (skb->nh.iph->ihl<<2); /* do not use skb_pull, since data should stay at IP header */ skb->h.raw = skb->nh.raw + iphlen; memset((caddr_t)ixs, 0, sizeof(*ixs)); memset(&stats, 0, sizeof(stats)); ixs->stats = &stats; ixs->oskb = NULL; ixs->saved_header = NULL; /* saved copy of the hard header */ ixs->route = NULL; memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips)); ixs->dev = NULL; ixs->skb = skb; ixs->physmtu = 1500; ixs->cur_mtu = 1500; ixs->outgoing_said.spi = htonl(0x12345678); ixs->outgoing_said.proto = IPPROTO_ESP; ixs->outgoing_said.dst.u.v4.sin_family = AF_INET; ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = htonl(0xc001022D); stat = ipsec_xmit_sanity_check_skb(ixs); assert(stat == IPSEC_XMIT_OK); #if 0 stat = ipsec_tunnel_strip_hard_header(ixs); assert(stat == IPSEC_XMIT_OK); stat = ipsec_tunnel_SAlookup(ixs); assert(stat == IPSEC_XMIT_OK); #endif stat = ipsec_xmit_encap_bundle(ixs); assert(stat == IPSEC_XMIT_OK); #if 0 stat = ipsec_tunnel_restore_hard_header(ixs); #endif ipsec_print_ip(ixs->iph); } return 0; }
/* * This function assumes it is being called from dev_queue_xmit() * and that skb is filled properly by that function. */ int ipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ipsec_xmit_state *ixs; IPsecSAref_t SAref; KLIPS_PRINT(debug_mast, "klips_debug:ipsec_mast_start_xmit: skb=%p\n", skb); if(skb == NULL) { printk("ipsec_mast_start_xmit: " "passed NULL\n"); return 0; } ixs = ipsec_xmit_state_new(dev); if(ixs == NULL) return NETDEV_TX_BUSY; ixs->dev = dev; ixs->skb = skb; SAref = 0; #ifdef NETDEV_25 #if defined(CONFIG_NETFILTER) if(skb->nfmark & IPSEC_NFMARK_IS_SAREF_BIT) { SAref = NFmark2IPsecSAref(skb->nfmark); KLIPS_PRINT(debug_mast, "klips_debug:ipsec_mast_start_xmit: " "getting SAref=%d from nfmark\n", SAref); } #endif #endif #ifdef CONFIG_INET_IPSEC_SAREF if(skb->sp && skb->sp->ref != IPSEC_SAREF_NULL) { SAref = skb->sp->ref; KLIPS_PRINT(debug_mast, "klips_debug:ipsec_mast_start_xmit: " "getting SAref=%d from sec_path\n", SAref); } #endif if (ipsec_xmit_sanity_check_skb(ixs) != IPSEC_XMIT_OK) { ipsec_xmit_cleanup(ixs); ipsec_xmit_state_delete(ixs); return 0; } ixs->ipsp = ipsec_sa_getbyref(SAref, IPSEC_REFOTHER); if(ixs->ipsp == NULL) { KLIPS_ERROR(debug_mast, "klips_debug:ipsec_mast_start_xmit: " "%s: no SA for saref=%d\n", dev->name, SAref); ipsec_xmit_cleanup(ixs); ipsec_xmit_state_delete(ixs); return 0; } /* make sure this packet can go out on this SA */ if (ipsec_mast_check_outbound_policy(ixs)) { ipsec_xmit_cleanup(ixs); ipsec_xmit_state_delete(ixs); return 0; } /* fill in outgoing_said using the ipsp we have */ ixs->outgoing_said = ixs->ipsp->ips_said; #ifdef NETDEV_25 #if defined(CONFIG_NETFILTER) /* prevent recursion through the saref route */ if(skb->nfmark & 0x80000000) { skb->nfmark = 0; } #endif #endif #if 0 /* TODO: do we have to also have to do this? */ if(skb->sp && skb->sp->ref != IPSEC_SAREF_NULL) { secpath_put(skb->sp); skb->sp = NULL; } #endif /* * we should be calculating the MTU by looking up a route * based upon the destination in the SA, and then cache * it into the SA, but we don't do that right now. */ ixs->cur_mtu = 1460; ixs->physmtu = 1460; ixs->mast_mode = 1; ixs->xsm_complete = ipsec_mast_xsm_complete; ixs->state = IPSEC_XSM_INIT2; /* we start later in the process */ ixs->prv = netdev_priv(ixs->dev); ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats); ipsec_xsm(ixs); return 0; }