1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "Error.h"
18
19 #include "../MessageDefinition.h"
20
21 #include <libnl++/printer.h>
22
23 #include <map>
24
25 namespace android::nl::protocols::base {
26
27 using DataType = AttributeDefinition::DataType;
28
29 // clang-format off
Error(int protocol)30 Error::Error(int protocol) : MessageDefinition<nlmsgerr>("nlmsg", {
31 {NLMSG_ERROR, {"ERROR", MessageGenre::Ack}},
32 }, {
33 {NLMSGERR_ATTR_MSG, {"MSG", DataType::String}},
34 {NLMSGERR_ATTR_OFFS, {"OFFS", DataType::Uint}},
35 {NLMSGERR_ATTR_COOKIE, {"COOKIE", DataType::Raw}},
36 }), mProtocol(protocol) {}
37 // clang-format on
38
39 std::map<int, std::string> errnoNames{
40 {EPERM, "EPERM"}, // Operation not permitted
41 {ENOENT, "ENOENT"}, // No such file or directory
42 {ESRCH, "ESRCH"}, // No such process
43 {EINTR, "EINTR"}, // Interrupted system call
44 {EIO, "EIO"}, // I/O error
45 {ENXIO, "ENXIO"}, // No such device or address
46 {E2BIG, "E2BIG"}, // Argument list too long
47 {ENOEXEC, "ENOEXEC"}, // Exec format error
48 {EBADF, "EBADF"}, // Bad file number
49 {ECHILD, "ECHILD"}, // No child processes
50 {EAGAIN, "EAGAIN"}, // Try again
51 {ENOMEM, "ENOMEM"}, // Out of memory
52 {EACCES, "EACCES"}, // Permission denied
53 {EFAULT, "EFAULT"}, // Bad address
54 {ENOTBLK, "ENOTBLK"}, // Block device required
55 {EBUSY, "EBUSY"}, // Device or resource busy
56 {EEXIST, "EEXIST"}, // File exists
57 {EXDEV, "EXDEV"}, // Cross-device link
58 {ENODEV, "ENODEV"}, // No such device
59 {ENOTDIR, "ENOTDIR"}, // Not a directory
60 {EISDIR, "EISDIR"}, // Is a directory
61 {EINVAL, "EINVAL"}, // Invalid argument
62 {ENFILE, "ENFILE"}, // File table overflow
63 {EMFILE, "EMFILE"}, // Too many open files
64 {ENOTTY, "ENOTTY"}, // Not a typewriter
65 {ETXTBSY, "ETXTBSY"}, // Text file busy
66 {EFBIG, "EFBIG"}, // File too large
67 {ENOSPC, "ENOSPC"}, // No space left on device
68 {ESPIPE, "ESPIPE"}, // Illegal seek
69 {EROFS, "EROFS"}, // Read-only file system
70 {EMLINK, "EMLINK"}, // Too many links
71 {EPIPE, "EPIPE"}, // Broken pipe
72 {EDOM, "EDOM"}, // Math argument out of domain of func
73 {ERANGE, "ERANGE"}, // Math result not representable
74 {EDEADLK, "EDEADLK"}, // Resource deadlock would occur
75 {ENAMETOOLONG, "ENAMETOOLONG"}, // File name too long
76 {ENOLCK, "ENOLCK"}, // No record locks available
77 {ENOSYS, "ENOSYS"}, // Invalid system call number
78 {ENOTEMPTY, "ENOTEMPTY"}, // Directory not empty
79 {ELOOP, "ELOOP"}, // Too many symbolic links encountered
80 {ENOMSG, "ENOMSG"}, // No message of desired type
81 {EIDRM, "EIDRM"}, // Identifier removed
82 {ECHRNG, "ECHRNG"}, // Channel number out of range
83 {EL2NSYNC, "EL2NSYNC"}, // Level 2 not synchronized
84 {EL3HLT, "EL3HLT"}, // Level 3 halted
85 {EL3RST, "EL3RST"}, // Level 3 reset
86 {ELNRNG, "ELNRNG"}, // Link number out of range
87 {EUNATCH, "EUNATCH"}, // Protocol driver not attached
88 {ENOCSI, "ENOCSI"}, // No CSI structure available
89 {EL2HLT, "EL2HLT"}, // Level 2 halted
90 {EBADE, "EBADE"}, // Invalid exchange
91 {EBADR, "EBADR"}, // Invalid request descriptor
92 {EXFULL, "EXFULL"}, // Exchange full
93 {ENOANO, "ENOANO"}, // No anode
94 {EBADRQC, "EBADRQC"}, // Invalid request code
95 {EBADSLT, "EBADSLT"}, // Invalid slot
96 {EBFONT, "EBFONT"}, // Bad font file format
97 {ENOSTR, "ENOSTR"}, // Device not a stream
98 {ENODATA, "ENODATA"}, // No data available
99 {ETIME, "ETIME"}, // Timer expired
100 {ENOSR, "ENOSR"}, // Out of streams resources
101 {ENONET, "ENONET"}, // Machine is not on the network
102 {ENOPKG, "ENOPKG"}, // Package not installed
103 {EREMOTE, "EREMOTE"}, // Object is remote
104 {ENOLINK, "ENOLINK"}, // Link has been severed
105 {EADV, "EADV"}, // Advertise error
106 {ESRMNT, "ESRMNT"}, // Srmount error
107 {ECOMM, "ECOMM"}, // Communication error on send
108 {EPROTO, "EPROTO"}, // Protocol error
109 {EMULTIHOP, "EMULTIHOP"}, // Multihop attempted
110 {EDOTDOT, "EDOTDOT"}, // RFS specific error
111 {EBADMSG, "EBADMSG"}, // Not a data message
112 {EOVERFLOW, "EOVERFLOW"}, // Value too large for defined data type
113 {ENOTUNIQ, "ENOTUNIQ"}, // Name not unique on network
114 {EBADFD, "EBADFD"}, // File descriptor in bad state
115 {EREMCHG, "EREMCHG"}, // Remote address changed
116 {ELIBACC, "ELIBACC"}, // Can not access a needed shared library
117 {ELIBBAD, "ELIBBAD"}, // Accessing a corrupted shared library
118 {ELIBSCN, "ELIBSCN"}, // .lib section in a.out corrupted
119 {ELIBMAX, "ELIBMAX"}, // Attempting to link in too many shared libraries
120 {ELIBEXEC, "ELIBEXEC"}, // Cannot exec a shared library directly
121 {EILSEQ, "EILSEQ"}, // Illegal byte sequence
122 {ERESTART, "ERESTART"}, // Interrupted system call should be restarted
123 {ESTRPIPE, "ESTRPIPE"}, // Streams pipe error
124 {EUSERS, "EUSERS"}, // Too many users
125 {ENOTSOCK, "ENOTSOCK"}, // Socket operation on non-socket
126 {EDESTADDRREQ, "EDESTADDRREQ"}, // Destination address required
127 {EMSGSIZE, "EMSGSIZE"}, // Message too long
128 {EPROTOTYPE, "EPROTOTYPE"}, // Protocol wrong type for socket
129 {ENOPROTOOPT, "ENOPROTOOPT"}, // Protocol not available
130 {EPROTONOSUPPORT, "EPROTONOSUPPORT"}, // Protocol not supported
131 {ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT"}, // Socket type not supported
132 {EOPNOTSUPP, "EOPNOTSUPP"}, // Operation not supported on transport endpoint
133 {EPFNOSUPPORT, "EPFNOSUPPORT"}, // Protocol family not supported
134 {EAFNOSUPPORT, "EAFNOSUPPORT"}, // Address family not supported by protocol
135 {EADDRINUSE, "EADDRINUSE"}, // Address already in use
136 {EADDRNOTAVAIL, "EADDRNOTAVAIL"}, // Cannot assign requested address
137 {ENETDOWN, "ENETDOWN"}, // Network is down
138 {ENETUNREACH, "ENETUNREACH"}, // Network is unreachable
139 {ENETRESET, "ENETRESET"}, // Network dropped connection because of reset
140 {ECONNABORTED, "ECONNABORTED"}, // Software caused connection abort
141 {ECONNRESET, "ECONNRESET"}, // Connection reset by peer
142 {ENOBUFS, "ENOBUFS"}, // No buffer space available
143 {EISCONN, "EISCONN"}, // Transport endpoint is already connected
144 {ENOTCONN, "ENOTCONN"}, // Transport endpoint is not connected
145 {ESHUTDOWN, "ESHUTDOWN"}, // Cannot send after transport endpoint shutdown
146 {ETOOMANYREFS, "ETOOMANYREFS"}, // Too many references: cannot splice
147 {ETIMEDOUT, "ETIMEDOUT"}, // Connection timed out
148 {ECONNREFUSED, "ECONNREFUSED"}, // Connection refused
149 {EHOSTDOWN, "EHOSTDOWN"}, // Host is down
150 {EHOSTUNREACH, "EHOSTUNREACH"}, // No route to host
151 {EALREADY, "EALREADY"}, // Operation already in progress
152 {EINPROGRESS, "EINPROGRESS"}, // Operation now in progress
153 {ESTALE, "ESTALE"}, // Stale file handle
154 {EUCLEAN, "EUCLEAN"}, // Structure needs cleaning
155 {ENOTNAM, "ENOTNAM"}, // Not a XENIX named type file
156 {ENAVAIL, "ENAVAIL"}, // No XENIX semaphores available
157 {EISNAM, "EISNAM"}, // Is a named type file
158 {EREMOTEIO, "EREMOTEIO"}, // Remote I/O error
159 {EDQUOT, "EDQUOT"}, // Quota exceeded
160 {ENOMEDIUM, "ENOMEDIUM"}, // No medium found
161 {EMEDIUMTYPE, "EMEDIUMTYPE"}, // Wrong medium type
162 {ECANCELED, "ECANCELED"}, // Operation Canceled
163 {ENOKEY, "ENOKEY"}, // Required key not available
164 {EKEYEXPIRED, "EKEYEXPIRED"}, // Key has expired
165 {EKEYREVOKED, "EKEYREVOKED"}, // Key has been revoked
166 {EKEYREJECTED, "EKEYREJECTED"}, // Key was rejected by service
167 {EOWNERDEAD, "EOWNERDEAD"}, // Owner died
168 {ENOTRECOVERABLE, "ENOTRECOVERABLE"}, // State not recoverable
169 {ERFKILL, "ERFKILL"}, // Operation not possible due to RF-kill
170 {EHWPOISON, "EHWPOISON"}, // Memory page has hardware error
171
172 // Duplicates: EWOULDBLOCK (Operation would block), EDEADLOCK
173 };
174
toStream(std::stringstream & ss,const nlmsgerr & data) const175 void Error::toStream(std::stringstream& ss, const nlmsgerr& data) const {
176 ss << "nlmsgerr{";
177 if (data.error == 0) {
178 ss << "ACK";
179 } else {
180 ss << "error=";
181 const auto nameIt = errnoNames.find(-data.error);
182 if (nameIt == errnoNames.end()) {
183 ss << data.error;
184 } else {
185 ss << nameIt->second;
186 }
187 }
188 ss << ", msg=" << toString({&data.msg, sizeof(data.msg)}, mProtocol, false) << "}";
189 }
190
191 } // namespace android::nl::protocols::base
192