struct timer_hook *timerhook_create(struct module *moduleToHook) { struct timer_hook *hook; BUG_ON(!moduleToHook); hook = (struct timer_hook *)kmalloc(sizeof(struct timer_hook), GFP_KERNEL); if (!hook) return NULL; spin_lock_init(&hook->lock); hook->module = moduleToHook; if (atomic_inc_return(&timer_hook_installed) == 1) { register_tracepoint_wrapper(timer_expire_entry, hook_timer_entry, hook); register_tracepoint_wrapper(timer_expire_exit, hook_timer_exit, hook); } return hook; }
struct netpoll_wrapper *netpoll_wrapper_create(const char *pDeviceName, int localPort, const char *pOptionalLocalIp) { struct net_device *pDevice; struct netpoll_wrapper *pResult; int localIp; int err; if (!pDeviceName || !localPort) { printk(KERN_ERR "kgdboe: cannot create a netpoll wrapper without a device name\n"); return NULL; } pDevice = dev_get_by_name(&init_net, pDeviceName); if (!pDevice) { printk(KERN_ERR "kgdboe: Cannot find network device by name: %s\n", pDeviceName); return NULL; } if (pOptionalLocalIp) { localIp = in_aton(pOptionalLocalIp); if (!localIp) { printk(KERN_ERR "kgdboe: Invalid local IP: %s\n", pOptionalLocalIp); return NULL; } } else { if (!pDevice->ip_ptr) { printk(KERN_ERR "kgdboe: %s does not have an in_device associated. Cannot get default IP address.\n", pDeviceName); return NULL; } if (!pDevice->ip_ptr->ifa_list) { printk(KERN_ERR "kgdboe: %s does not have a in_ifaddr struct associated. Cannot get default IP address.\n", pDeviceName); return NULL; } localIp = pDevice->ip_ptr->ifa_list->ifa_local; } pResult = (struct netpoll_wrapper *)kmalloc(sizeof(struct netpoll_wrapper), GFP_KERNEL); if (!pResult) { printk(KERN_ERR "kgdboe: cannot allocate memory for netpoll wrapper\n"); return NULL; } memset(pResult, 0, sizeof(*pResult)); #ifdef NETPOLL_POLL_DEV_USABLE pResult->netpoll_poll_dev = (void(*)(struct net_device *))kallsyms_lookup_name("netpoll_poll_dev"); if (!pResult->netpoll_poll_dev) { printk(KERN_ERR "kgdboe: Cannot find netpoll_poll_dev(). Aborting.\n"); netpoll_wrapper_free(pResult); return NULL; } #else pResult->zap_completion_queue = (void(*)(void))kallsyms_lookup_name("zap_completion_queue"); if (!pResult->zap_completion_queue) { printk(KERN_ERR "kgdboe: Cannot find zap_completion_queue(). Aborting.\n"); netpoll_wrapper_free(pResult); return NULL; } #endif rtnl_lock(); err = netdev_rx_handler_register(pDevice, netpoll_wrapper_rx_handler, pResult); rtnl_unlock(); if (err < 0) { printk(KERN_ERR "kgdboe: Failed to register rx handler for %s, code %d\n", pDeviceName, err); netpoll_wrapper_free(pResult); return NULL; } register_tracepoint_wrapper(netif_receive_skb, hook_receive_skb, pResult); pResult->tracepoint_registered = true; pResult->pDeviceWithHandler = pDevice; strncpy(pResult->netpoll_obj.dev_name, pDeviceName, sizeof(pResult->netpoll_obj.dev_name)); pResult->netpoll_obj.name = "kgdboe"; pResult->netpoll_obj.local_port = localPort; memset(pResult->netpoll_obj.remote_mac, 0xFF, sizeof(pResult->netpoll_obj.remote_mac)); err = netpoll_setup(&pResult->netpoll_obj); if (err < 0) { printk(KERN_ERR "kgdboe: Failed to setup netpoll for %s, code %d\n", pDeviceName, err); netpoll_wrapper_free(pResult); return NULL; } pResult->netpoll_initialized = true; return pResult; }