📄 ipsec_tunnel.c
字号:
dev->header_cache_bind = NULL;#endif /* DETACH_AND_DOWN */#endif /* !NET_21 */ prv->header_cache_update = NULL;#ifdef DETACH_AND_DOWN dev->header_cache_update = NULL;#endif /* DETACH_AND_DOWN */#ifdef NET_21/* prv->neigh_setup = NULL; */#ifdef DETACH_AND_DOWN dev->neigh_setup = NULL;#endif /* DETACH_AND_DOWN */#endif /* NET_21 */ dev->hard_header_len = 0;#ifdef DETACH_AND_DOWN dev->mtu = 0;#endif /* DETACH_AND_DOWN */ prv->mtu = 0; for (i=0; i<MAX_ADDR_LEN; i++) { dev->dev_addr[i] = 0; } dev->addr_len = 0;#ifdef PHYSDEV_TYPE dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */#endif /* PHYSDEV_TYPE */ return 0;}/* * We call the clear routine to detach all ipsec tunnels from other devices. */DEBUG_NO_STATIC intipsec_tunnel_clear(void){ int i; struct net_device *ipsecdev = NULL, *prvdev; struct ipsecpriv *prv; char name[9]; int ret; KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_clear: .\n"); for(i = 0; i < IPSEC_NUM_IF; i++) { ipsecdev = ipsecdevices[i]; if(ipsecdev != NULL) { if((prv = (struct ipsecpriv *)(ipsecdev->priv))) { prvdev = (struct net_device *)(prv->dev); if(prvdev) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_clear: " "physical device for device %s is %s\n", name, prvdev->name); if((ret = ipsec_tunnel_detach(ipsecdev))) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_clear: " "error %d detatching device %s from device %s.\n", ret, name, prvdev->name); return ret; } } } } } return 0;}DEBUG_NO_STATIC intipsec_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd){ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data; struct ipsecpriv *prv = dev->priv; struct net_device *them; /* physical device */#ifdef CONFIG_IP_ALIAS char *colon; char realphysname[IFNAMSIZ];#endif /* CONFIG_IP_ALIAS */ if(dev == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "device not supplied.\n"); return -ENODEV; } KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "tncfg service call #%d for dev=%s\n", cmd, dev->name ? dev->name : "NULL"); switch (cmd) { /* attach a virtual ipsec? device to a physical device */ case IPSEC_SET_DEV: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "calling ipsec_tunnel_attatch...\n");#ifdef CONFIG_IP_ALIAS /* If this is an IP alias interface, get its real physical name */ strncpy(realphysname, cf->cf_name, IFNAMSIZ); realphysname[IFNAMSIZ-1] = 0; colon = strchr(realphysname, ':'); if (colon) *colon = 0; them = ipsec_dev_get(realphysname);#else /* CONFIG_IP_ALIAS */ them = ipsec_dev_get(cf->cf_name);#endif /* CONFIG_IP_ALIAS */ if (them == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "physical device %s requested is null\n", cf->cf_name); return -ENXIO; } #if 0 if (them->flags & IFF_UP) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "physical device %s requested is not up.\n", cf->cf_name); ipsec_dev_put(them); return -ENXIO; }#endif if (prv && prv->dev) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "virtual device is already connected to %s.\n", prv->dev->name ? prv->dev->name : "NULL"); ipsec_dev_put(them); return -EBUSY; } return ipsec_tunnel_attach(dev, them); case IPSEC_DEL_DEV: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "calling ipsec_tunnel_detatch.\n"); if (! prv->dev) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "physical device not connected.\n"); return -ENODEV; } return ipsec_tunnel_detach(dev); case IPSEC_CLR_DEV: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "calling ipsec_tunnel_clear.\n"); return ipsec_tunnel_clear(); default: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_ioctl: " "unknown command %d.\n", cmd); return -EOPNOTSUPP; }}intipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr){ struct net_device *dev = ptr; struct net_device *ipsec_dev; struct ipsecpriv *priv; int i; if (dev == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "dev=NULL for event type %ld.\n", event); return(NOTIFY_DONE); } /* check for loopback devices */ if (dev && (dev->flags & IFF_LOOPBACK)) { return(NOTIFY_DONE); } switch (event) { case NETDEV_DOWN: /* look very carefully at the scope of these compiler directives before changing anything... -- RGB */#ifdef NET_21 case NETDEV_UNREGISTER: switch (event) { case NETDEV_DOWN:#endif /* NET_21 */ KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_DOWN dev=%s flags=%x\n", dev->name, dev->flags); if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) { printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n", dev->name); }#ifdef NET_21 break; case NETDEV_UNREGISTER: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_UNREGISTER dev=%s flags=%x\n", dev->name, dev->flags); break; }#endif /* NET_21 */ /* find the attached physical device and detach it. */ for(i = 0; i < IPSEC_NUM_IF; i++) { ipsec_dev = ipsecdevices[i]; if(ipsec_dev) { priv = (struct ipsecpriv *)(ipsec_dev->priv); if(priv) { ; if(((struct net_device *)(priv->dev)) == dev) { /* dev_close(ipsec_dev); */ /* return */ ipsec_tunnel_detach(ipsec_dev); KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "device '%s' has been detached.\n", ipsec_dev->name); break; } } else { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "device '%s' has no private data space!\n", ipsec_dev->name); } } } break; case NETDEV_UP: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_UP dev=%s\n", dev->name); break;#ifdef NET_21 case NETDEV_REBOOT: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_REBOOT dev=%s\n", dev->name); break; case NETDEV_CHANGE: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_CHANGE dev=%s flags=%x\n", dev->name, dev->flags); break; case NETDEV_REGISTER: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_REGISTER dev=%s\n", dev->name); break; case NETDEV_CHANGEMTU: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_CHANGEMTU dev=%s to mtu=%d\n", dev->name, dev->mtu); break; case NETDEV_CHANGEADDR: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_CHANGEADDR dev=%s\n", dev->name); break; case NETDEV_GOING_DOWN: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_GOING_DOWN dev=%s\n", dev->name); break; case NETDEV_CHANGENAME: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "NETDEV_CHANGENAME dev=%s\n", dev->name); break;#endif /* NET_21 */ default: KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_device_event: " "event type %ld unrecognised for dev=%s\n", event, dev->name); break; } return NOTIFY_DONE;}/* * Called when an ipsec tunnel device is initialized. * The ipsec tunnel device structure is passed to us. */ intipsec_tunnel_init(struct net_device *dev){ int i; KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_tunnel_init: " "allocating %lu bytes initialising device: %s\n", (unsigned long) sizeof(struct ipsecpriv), dev->name ? dev->name : "NULL"); /* Add our tunnel functions to the device */ dev->open = ipsec_tunnel_open; dev->stop = ipsec_tunnel_close; dev->hard_start_xmit = ipsec_tunnel_start_xmit; dev->get_stats = ipsec_tunnel_get_stats; dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL); if (dev->priv == NULL) return -ENOMEM; memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv)); for(i = 0; i < sizeof(zeroes); i++) { ((__u8*)(zeroes))[i] = 0; } #ifndef NET_21 /* Initialize the tunnel device structure */ for (i = 0; i < DEV_NUMBUFFS; i++) skb_queue_head_init(&dev->buffs[i]);#endif /* !NET_21 */ dev->set_multicast_list = NULL; dev->do_ioctl = ipsec_tunnel_ioctl; dev->hard_header = NULL; dev->rebuild_header = NULL; dev->set_mac_address = NULL;#ifndef NET_21 dev->header_cache_bind = NULL;#endif /* !NET_21 */ dev->header_cache_update= NULL;#ifdef NET_21/* prv->neigh_setup = NULL; */ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;#endif /* NET_21 */ dev->hard_header_len = 0; dev->mtu = 0; dev->addr_len = 0; dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */ dev->tx_queue_len = 10; /* Small queue */ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */ /* New-style flags. */ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;#if 0#ifdef NET_21 dev_init_buffers(dev);#else /* NET_21 */ dev->family = AF_INET; dev->pa_addr = 0; dev->pa_brdaddr = 0; dev->pa_mask = 0; dev->pa_alen = 4;#endif /* NET_21 */#endif /* We're done. Have I forgotten anything? */ return 0;}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//* Module specific interface (but it links with the rest of IPSEC) *//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */intipsec_tunnel_probe(struct net_device *dev){ ipsec_tunnel_init(dev); return 0;}struct net_device *ipsecdevices[IPSEC_NUM_IF];int ipsec_tunnel_init_devices(void){ int i; char name[IFNAMSIZ]; struct net_device *dev_ipsec; KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_init_devices: " "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n", IPSEC_NUM_IF, (unsigned long) (sizeof(struct net_device) + IFNAMSIZ), IFNAMSIZ); for(i = 0; i < IPSEC_NUM_IF; i++) { sprintf(name, IPSEC_DEV_FORMAT, i); dev_ipsec = (struct net_device*)kmalloc(sizeof(struct net_device), GFP_KERNEL); if (dev_ipsec == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_init_devices: " "failed to allocate memory for device %s, quitting device init.\n", name); return -ENOMEM; } memset((caddr_t)dev_ipsec, 0, sizeof(struct net_device));#ifdef NETDEV_23 strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));#else /* NETDEV_23 */ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL); if (dev_ipsec->name == NULL) { KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_init_devices: " "failed to allocate memory for device %s name, quitting device init.\n", name); return -ENOMEM; } memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ); strncpy(dev_ipsec->name, name, IFNAMSIZ);#endif /* NETDEV_23 */ dev_ipsec->next = NULL; dev_ipsec->init = &ipsec_tunnel_probe; KLIPS_PRINT(debug_tunnel & DB_TN_INIT, "klips_debug:ipsec_tunnel_init_devices: " "registering device %s\n", dev_ipsec->name); /* reference and hold the device reference */ dev_hold(dev_ipsec);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -