1 /* 2 * Copyright 2008-2016, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Adrien Destugues, pulkomandy@pulkomandy.tk 7 */ 8 9 10 #include <debug.h> 11 #include <driver_settings.h> 12 #include <netinet/in.h> 13 #include <sys/socket.h> 14 15 16 #define NETCONSOLE_PORT 6666 17 18 19 static int gSocket; 20 21 22 static int 23 createSocket() 24 { 25 gSocket = socket(AF_INET, SOCK_DGRAM, 0); 26 if (gSocket < 0) 27 return B_ERROR; 28 29 // bind socket 30 sockaddr_in fSocketAddress; 31 fSocketAddress.sin_family = AF_INET; 32 fSocketAddress.sin_port = 0; 33 fSocketAddress.sin_addr.s_addr = INADDR_ANY; 34 fSocketAddress.sin_len = sizeof(sockaddr_in); 35 if (bind(gSocket, (sockaddr*)&fSocketAddress, sizeof(fSocketAddress)) < 0) { 36 return B_ERROR; 37 } 38 39 // set SO_BROADCAST on socket 40 int soBroadcastValue = 1; 41 if (setsockopt(gSocket, SOL_SOCKET, SO_BROADCAST, &soBroadcastValue, 42 sizeof(soBroadcastValue)) < 0) { 43 return B_ERROR; 44 } 45 46 return B_OK; 47 } 48 49 50 // FIXME this can't work this way, because debugger_puts is called with 51 // interrupts disabled and can't send to the network directly. Must be reworked 52 // to use a buffer, and do the network access from another thread. A similar 53 // solution is implemented to get syslog data to the syslog_daemon. 54 static int 55 debugger_puts(const char* message, int32 length) 56 { 57 if (gSocket < 0) 58 createSocket(); 59 60 if (gSocket >= 0) { 61 // init server address to broadcast 62 sockaddr_in fServerAddress; 63 fServerAddress.sin_family = AF_INET; 64 fServerAddress.sin_port = htons(NETCONSOLE_PORT); 65 fServerAddress.sin_addr.s_addr = htonl(INADDR_BROADCAST); 66 fServerAddress.sin_len = sizeof(sockaddr_in); 67 68 return sendto(gSocket, message, length, 0, 69 (sockaddr*)&fServerAddress, sizeof(fServerAddress)); 70 } 71 72 return 0; 73 } 74 75 76 static status_t 77 std_ops(int32 op, ...) 78 { 79 void* handle; 80 bool load = false; 81 82 switch (op) { 83 case B_MODULE_INIT: 84 gSocket = -1; 85 return B_OK; 86 #if 0 87 handle = load_driver_settings("kernel"); 88 if (handle) { 89 load = get_driver_boolean_parameter(handle, 90 "netconsole_debug_output", load, true); 91 unload_driver_settings(handle); 92 } 93 if (load) 94 gSocket = -1; 95 return load ? B_OK : B_ERROR; 96 #endif 97 case B_MODULE_UNINIT: 98 if (gSocket >= 0) 99 close(gSocket); 100 return B_OK; 101 } 102 return B_BAD_VALUE; 103 } 104 105 106 static struct debugger_module_info sModuleInfo = { 107 { 108 "debugger/netconsole/v1", 109 0, 110 &std_ops 111 }, 112 NULL, 113 NULL, 114 debugger_puts, 115 NULL 116 }; 117 118 module_info* modules[] = { 119 (module_info*)&sModuleInfo, 120 NULL 121 }; 122 123