1 /* This header file is shared by client & server. They really have
2 * something to share...
5 /* Client/server protocol is as follows:
7 Send 64-bit cliserv_magic
8 Send 64-bit size of exported device
9 Send 128 bytes of zeros (reserved for future use)
15 #include <netinet/tcp.h>
16 #include <netinet/in.h>
19 #if SIZEOF_UNSIGNED_SHORT_INT==4
20 typedef unsigned short u32
;
21 #elif SIZEOF_UNSIGNED_INT==4
22 typedef unsigned int u32
;
23 #elif SIZEOF_UNSIGNED_LONG_INT==4
24 typedef unsigned long u32
;
26 #error I need at least some 32-bit type
29 #if SIZEOF_UNSIGNED_INT==8
30 typedef unsigned int u64
;
31 #elif SIZEOF_UNSIGNED_LONG_INT==8
32 typedef unsigned long u64
;
33 #elif SIZEOF_UNSIGNED_LONG_LONG_INT==8
34 typedef unsigned long long u64
;
36 #error I need at least some 64-bit type
43 #ifndef HAVE_FDATASYNC
44 #define fdatasync(arg) fsync(arg)
48 /* /usr/include/features.h (included from /usr/include/sys/types.h)
49 defines this when _GNU_SOURCE is defined
51 #ifndef _LARGEFILE_SOURCE
52 #define _LARGEFILE_SOURCE
54 #define _FILE_OFFSET_BITS 64
57 u64 cliserv_magic
= 0x00420281861253LL
;
58 u64 opts_magic
= 0x49484156454F5054LL
;
59 u64 rep_magic
= 0x3e889045565a9LL
;
60 #define INIT_PASSWD "NBDMAGIC"
62 #define INFO(a) do { } while(0)
64 void setmysockopt(int sock
) {
67 if (setsockopt(sock
, SOL_SOCKET
, SO_SNDBUF
, &size
, sizeof(int)) < 0)
68 INFO("(no sockopt/1: %m)");
72 if (setsockopt(sock
, IPPROTO_TCP
, TCP_NODELAY
, &size
, sizeof(int)) < 0)
73 INFO("(no sockopt/2: %m)");
77 if (setsockopt(sock
, IPPROTO_TCP
, TCP_MAXSEG
, &size
, sizeof(int)) < 0)
78 INFO("(no sockopt/3: %m)");
82 #ifndef G_GNUC_NORETURN
83 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
84 #define G_GNUC_NORETURN __attribute__((__noreturn__))
85 #define G_GNUC_UNUSED __attribute__((unused))
87 #define G_GNUC_NORETURN
92 void err_nonfatal(const char *s
) {
95 strncpy(s1
, s
, sizeof(s1
));
96 if ((s2
= strstr(s
, "%m"))) {
97 strcpy(s1
+ (s2
- s
), strerror(errno
));
99 strcpy(s1
+ strlen(s1
), s2
);
102 /* Solaris doesn't have %h in syslog */
103 else if ((s2
= strstr(s
, "%h"))) {
104 strcpy(s1
+ (s2
- s
), hstrerror(h_errno
));
106 strcpy(s1
+ strlen(s1
), s2
);
110 s1
[sizeof(s1
)-1] = '\0';
112 syslog(LOG_ERR
, "%s", s1
);
113 syslog(LOG_ERR
, "Exiting.");
115 fprintf(stderr
, "Error: %s\nExiting.\n", s1
);
118 void err(const char *s
) G_GNUC_NORETURN
;
120 void err(const char *s
) {
127 openlog(MY_NAME
, LOG_PID
, LOG_DAEMON
);
129 setvbuf(stdout
, NULL
, _IONBF
, 0);
130 setvbuf(stderr
, NULL
, _IONBF
, 0);
133 #ifdef WORDS_BIGENDIAN
139 u32 lo
= a
& 0xffffffff;
143 return ((u64
) lo
) << 32U | hi
;
146 #define htonll ntohll
148 #define NBD_DEFAULT_PORT "10809" /* Port on which named exports are
151 /* Options that the client can select to the server */
152 #define NBD_OPT_EXPORT_NAME (1) /** Client wants to select a named export (is followed by name of export) */
153 #define NBD_OPT_ABORT (2) /** Client wishes to abort negotiation */
154 #define NBD_OPT_LIST (3) /** Client request list of supported exports (not followed by data) */
156 /* Replies the server can send during negotiation */
157 #define NBD_REP_ACK (1) /** ACK a request. Data: option number to be acked */
158 #define NBD_REP_SERVER (2) /** Reply to NBD_OPT_LIST (one of these per server; must be followed by NBD_REP_ACK to signal the end of the list */
159 #define NBD_REP_FLAG_ERROR (1 << 31) /** If the high bit is set, the reply is an error */
160 #define NBD_REP_ERR_UNSUP (1 | NBD_REP_FLAG_ERROR) /** Client requested an option not understood by this version of the server */
161 #define NBD_REP_ERR_POLICY (2 | NBD_REP_FLAG_ERROR) /** Client requested an option not allowed by server configuration. (e.g., the option was disabled) */
162 #define NBD_REP_ERR_INVALID (3 | NBD_REP_FLAG_ERROR) /** Client issued an invalid request */
163 #define NBD_REP_ERR_PLATFORM (4 | NBD_REP_FLAG_ERROR) /** Option not supported on this platform */
166 #define NBD_FLAG_FIXED_NEWSTYLE (1 << 0) /* new-style export that actually supports extending */
167 /* Flags from client to server. Only one such option currently. */
168 #define NBD_FLAG_C_FIXED_NEWSTYLE NBD_FLAG_FIXED_NEWSTYLE