int vnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct vnet_softc *sc = ifp->if_softc; struct ifaddr *ifa = (struct ifaddr *)data; struct ifreq *ifr = (struct ifreq *)data; int s, error = 0; s = splnet(); switch (cmd) { case SIOCSIFADDR: ifp->if_flags |= IFF_UP; if (ifa->ifa_addr->sa_family == AF_INET) arp_ifinit(&sc->sc_ac, ifa); /* FALLTHROUGH */ case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { if ((ifp->if_flags & IFF_RUNNING) == 0) vnet_init(ifp); } else { if (ifp->if_flags & IFF_RUNNING) vnet_stop(ifp); } break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); break; case SIOCADDMULTI: case SIOCDELMULTI: /* * XXX Removing all multicast addresses and adding * most of them back, is somewhat retarded. */ vnet_setmulti(sc, 0); error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); vnet_setmulti(sc, 1); if (error == ENETRESET) error = 0; break; default: error = ether_ioctl(ifp, &sc->sc_ac, cmd, data); } splx(s); return (error); }
long _IKED::init( long setlevel ) { // // initialize ike service interface // if( ikes.init() != IPCERR_OK ) { printf( "Another instance of iked was detected\n" ); return LIBIKE_FAILED; } // // ititialize openssl libcrypto // crypto_init(); // // open our log ( debug and echo ) // log.open( NULL, LLOG_DEBUG, logflags ); // // load our configuration // if( !conf_load( PATH_CONF ) ) return LIBIKE_FAILED; // // open our log ( config settings ) // if( setlevel ) level = setlevel; bool logging = log.open( path_log, level, logflags ); // // output our identity // log.txt( LLOG_NONE, "## : IKE Daemon, ver %d.%d.%d\n" "## : Copyright %i Shrew Soft Inc.\n" "## : This product linked %s\n", CLIENT_VER_MAJ, CLIENT_VER_MIN, CLIENT_VER_BLD, CLIENT_YEAR, SSLeay_version( SSLEAY_VERSION ) ); if( logflags & LOGFLAG_SYSTEM ) log.txt( LLOG_INFO, "ii : opened system log facility\n" ); else { if( !logging ) log.txt( LLOG_ERROR, "!! : failed to open %s\n", path_log ); else log.txt( LLOG_INFO, "ii : opened \'%s\'\n", path_log ); } // // open our packet dump interfaces // if( dump_decrypt ) { if( !pcap_decrypt.open( path_decrypt ) ) log.txt( LLOG_ERROR, "!! : failed to open %s\n", path_decrypt ); else log.txt( LLOG_INFO, "ii : opened \'%s\'\n", path_decrypt ); } if( dump_encrypt ) { if( !pcap_encrypt.open( path_encrypt ) ) log.txt( LLOG_ERROR, "!! : failed to open %s\n", path_encrypt ); else log.txt( LLOG_INFO, "ii : opened \'%s\'\n", path_encrypt ); } // // load our dhcp seed file // #ifdef UNIX bool dhcp_seed_loaded = false; FILE * fp = fopen( path_dhcp, "r" ); if( fp != NULL ) { unsigned int seed[ 6 ]; if( fscanf( fp, "%02x:%02x:%02x:%02x:%x:%02x", &seed[ 0 ], &seed[ 1 ], &seed[ 2 ], &seed[ 3 ], &seed[ 4 ], &seed[ 5 ] ) == 6 ) { dhcp_seed[ 0 ] = ( char ) seed[ 0 ]; dhcp_seed[ 1 ] = ( char ) seed[ 1 ]; dhcp_seed[ 2 ] = ( char ) seed[ 2 ]; dhcp_seed[ 3 ] = ( char ) seed[ 3 ]; dhcp_seed[ 4 ] = ( char ) seed[ 4 ]; dhcp_seed[ 5 ] = ( char ) seed[ 5 ]; dhcp_seed_loaded = true; } fclose( fp ); } if( dhcp_seed_loaded == false ) { FILE * fp = fopen( path_dhcp, "w" ); if( fp != NULL ) { rand_bytes( dhcp_seed, 6 ); unsigned int seed[ 6 ]; seed[ 0 ] = dhcp_seed[ 0 ]; seed[ 1 ] = dhcp_seed[ 1 ]; seed[ 2 ] = dhcp_seed[ 2 ]; seed[ 3 ] = dhcp_seed[ 3 ]; seed[ 4 ] = dhcp_seed[ 4 ]; seed[ 5 ] = dhcp_seed[ 5 ]; if( fprintf( fp, "%02x:%02x:%02x:%02x:%02x:%02x", seed[ 0 ], seed[ 1 ], seed[ 2 ], seed[ 3 ], seed[ 4 ], seed[ 5 ] ) != 18 ) dhcp_seed_loaded = true; else log.txt( LLOG_ERROR, "!! : failed to write dhcp seed to %s\n", path_dhcp ); fclose( fp ); } else log.txt( LLOG_ERROR, "!! : failed to create dhcp seed to %s\n", path_dhcp ); } #endif // // initialize our vnet interface // vnet_init(); // // initialize our socket interface // socket_init(); // // setup natt port on OSX systems // #ifdef __APPLE__ int natt_port = LIBIKE_NATT_PORT; sysctlbyname( "net.inet.ipsec.esp_port", NULL, NULL, &natt_port, sizeof( natt_port ) ); #endif // // default socket initialization // if( !sock_ike_open ) { IKE_SADDR saddr; memset( &saddr, 0, sizeof( saddr ) ); SET_SALEN( &saddr.saddr4, sizeof( sockaddr_in ) ); saddr.saddr4.sin_family = AF_INET; saddr.saddr4.sin_port = htons( LIBIKE_IKE_PORT ); if( socket_create( saddr, false ) != LIBIKE_OK ) { char txtaddr[ 16 ]; text_addr( txtaddr, &saddr, true ); log.txt( LLOG_ERROR, "!! : unable to open ike socket for %s\n", txtaddr ); return LIBIKE_FAILED; } } #ifdef OPT_NATT if( !sock_natt_open ) { IKE_SADDR saddr; memset( &saddr, 0, sizeof( saddr ) ); SET_SALEN( &saddr.saddr4, sizeof( sockaddr_in ) ); saddr.saddr4.sin_family = AF_INET; saddr.saddr4.sin_port = htons( LIBIKE_NATT_PORT ); if( socket_create( saddr, true ) != LIBIKE_OK ) { char txtaddr[ 16 ]; text_addr( txtaddr, &saddr, true ); log.txt( LLOG_ERROR, "!! : unable to open natt socket for %s\n", txtaddr ); return LIBIKE_FAILED; } } #endif return LIBIKE_OK; }
int main(int argc, char **argv) { char *tap_if = "tap5"; char *ex_host = NULL; char *ex_port = DEFAULT_PORT_STR; char *peer_host = NULL; char *peer_port = DEFAULT_PORT_STR; char *listen_port = DEFAULT_PORT_STR; char *enc_key = NULL; int opt; while ((opt = getopt(argc, argv, "vQ:i:e:E:r:R:l:h")) != -1) { switch (opt) { case 'v': debug++; break; case 'i': tap_if = optarg; DEBUG("tapif = %s", tap_if); break; case 'e': ex_host = optarg; DEBUG("ex_host = %s", ex_host); break; case 'E': ex_port = optarg; DEBUG("ex_port = %s", ex_port); break; case 'r': peer_host = optarg; DEBUG("peer_host = %s", peer_host); break; case 'R': peer_port = optarg; DEBUG("peer_port = %s", peer_port); break; case 'l': listen_port = optarg; DEBUG("listen_port = %s", listen_port); if (!strcmp(ex_port, DEFAULT_PORT_STR)) { ex_port = optarg; DEBUG("ex_port = %s", ex_port); } if (!strcmp(peer_port, DEFAULT_PORT_STR)) { peer_port = optarg; DEBUG("peer_port = %s", peer_port); } break; case 'Q': enc_key = optarg; DEBUG("enc_key = %s", enc_key); break; default: usage(argc?argv[0]:"L2O3"); break; } } if (!ex_host) { fprintf(stderr, "arguments: at least ex_host (-e <host>)" " must be specified\n"); usage(argc?argv[0]:"L2O3"); } /* Initializes vnet, dpg, and routing. * Spawns net listener and initial peer threads. * Listens for new peers. */ vnet_t vnet; dpg_t dpg; routing_t rd; pcon_t pc; int ret = vnet_init(&vnet, tap_if); if(ret < 0) { WARN("vnet_init failed"); } ret = dpg_init(&dpg, ex_host, ex_port); if(ret < 0) { DIE("dpg_init failed."); } struct ipv4_host ip_host = { .mac = vnet_get_mac(&vnet), .in = DPG_LADDR(&dpg) }; ret = rt_init(&rd); if(ret < 0) { DIE("rd_init failed."); } ret = rt_lhost_add(&rd, &ip_host); if (ret < 0) { DIE("rd_dhost_add failed."); } ret = pcon_init(&pc); if (ret < 0) { DIE("peer connection limiter init failed."); } /* vnet listener spawn */ ret = vnet_spawn_listener(&vnet, &rd, &dpg); if (ret < 0) { DIE("vnet spawn listener failed."); } /* inital dpeer spawn */ if (peer_host && peer_port) { DEBUG("creating initial peer with %s : %s", peer_host, peer_port); ret = dp_create_initial(&dpg, &rd, &vnet, &pc, peer_host, peer_port); if (ret < 0) { WARN("initial dp init failed."); } } int fd; struct addrinfo *ai; if (peer_listener_bind(NULL, listen_port, &fd, &ai)) { DIE("peer_listener_bind failed."); } return peer_listener(fd, &dpg, &rd, &vnet, &pc); }