#include #include #include #include #define SERVER_PORT 5555 static struct socket *udpsocket=NULL; static DECLARE_COMPLETION( threadcomplete ); static int com_thread_pid; static int com_thread( void *data ) { struct sockaddr_in client; struct sockaddr *address; unsigned char buffer[100]; int len; struct msghdr msg; struct iovec iov; mm_segment_t oldfs; daemonize( "udpserver" ); allow_signal( SIGTERM ); if( udpsocket->sk==NULL ) return 0; msg.msg_name = &client; msg.msg_namelen = sizeof( struct sockaddr_in ); msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; while( !signal_pending(current) ) { iov.iov_base = buffer; iov.iov_len = sizeof(buffer); oldfs = get_fs(); set_fs( KERNEL_DS ); len = sock_recvmsg( udpsocket, &msg, sizeof(buffer), 0 ); set_fs( oldfs ); if( len>0 ) { address = (struct sockaddr *)&client; printk(KERN_INFO "msg \"%s\" from %u.%u.%u.%u\n", buffer, (unsigned char)address->sa_data[2], (unsigned char)address->sa_data[3], (unsigned char)address->sa_data[4], (unsigned char)address->sa_data[5] ); } } complete( &threadcomplete ); return 0; } static int __init server_init( void ) { struct sockaddr_in server; int servererror; if( sock_create( PF_INET,SOCK_DGRAM,IPPROTO_UDP,&udpsocket)<0 ) { printk( KERN_ERR "server: Error creating udpsocket.\n" ); return -EIO; } server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons( (unsigned short)SERVER_PORT ); servererror = udpsocket->ops->bind( udpsocket, (struct sockaddr *) &server, sizeof( server ) ); if( servererror ) { sock_release( udpsocket ); return -EIO; } com_thread_pid=kernel_thread(com_thread,NULL, CLONE_KERNEL ); if( com_thread_pid < 0 ) { sock_release( udpsocket ); return -EIO; } return 0; } static void __exit server_exit( void ) { if( com_thread_pid ) { kill_proc( com_thread_pid, SIGTERM, 0 ); wait_for_completion( &threadcomplete ); } if( udpsocket ) sock_release( udpsocket ); } module_init( server_init ); module_exit( server_exit ); MODULE_LICENSE("GPL");