8 #include <sys/socket.h>
9 #include <netinet/in.h>
15 typedef struct blockdevice
{
21 static blockdevice
*dev
;
26 #define MAGIC 0x14983543
28 typedef struct message
{
39 #define CMD_READBLOCK 2
40 #define CMD_WRITEBLOCK 3
42 static int validate_message(message
*msg
, int len
)
44 if(len
< sizeof(message
))
47 // validate the message
48 if(ntohl(msg
->magic
) != MAGIC
)
50 if(ntohl(msg
->block_id
) != 0)
53 switch(ntohl(msg
->command
)) {
72 struct sockaddr_in from_addr
;
73 socklen_t slen
= sizeof(struct sockaddr
);
79 err
= recvfrom(sockfd
, buf
, sizeof(buf
), 0, (struct sockaddr
*)&from_addr
, &slen
);
81 printf("error reading from socket\n");
85 message
*msg
= (message
*)buf
;
87 if(!validate_message(msg
, err
))
90 // printf("got message, command %d\n", ntohl(msg->command));
91 reply_size
= sizeof(message
);
92 switch(ntohl(msg
->command
)) {
95 msg
->command
= htonl(~CMD_NULL
);
98 msg
->command
= htonl(~CMD_GETSIZE
);
99 printf("GETSIZE %d\n", htonl(dev
->size
));
100 *(int *)&msg
->data
[0] = htonl(dev
->size
);
104 msg
->command
= htonl(~CMD_READBLOCK
);
105 printf("R %d %d\n", ntohl(msg
->arg
), ntohl(msg
->arg2
));
106 if(ntohl(msg
->arg
) + ntohl(msg
->arg2
) <= dev
->size
) {
107 lseek(dev
->filefd
, ntohl(msg
->arg
), SEEK_SET
);
108 read(dev
->filefd
, &msg
->data
[0], ntohl(msg
->arg2
));
110 printf("CMD_READBLOCK: invalid offset %d and size %d\n", ntohl(msg
->arg
), ntohl(msg
->arg2
));
111 memset(&msg
->data
[0], 0, ntohl(msg
->arg2
));
113 reply_size
+= BLOCKSIZE
;
116 msg
->command
= htonl(~CMD_WRITEBLOCK
);
117 printf("W %d %d\n", ntohl(msg
->arg
), ntohl(msg
->arg2
));
118 if(ntohl(msg
->arg
) + ntohl(msg
->arg2
) <= dev
->size
) {
119 lseek(dev
->filefd
, ntohl(msg
->arg
), SEEK_SET
);
120 write(dev
->filefd
, &msg
->data
[0], ntohl(msg
->arg2
));
122 printf("CMD_WRITEBLOCK: invalid offset %d and size %d\n", ntohl(msg
->arg
), ntohl(msg
->arg2
));
130 err
= sendto(sockfd
, buf
, reply_size
, 0, (struct sockaddr
*)&from_addr
, slen
);
132 printf("error replying to message\n");
142 printf("usage: netblock <blockdev file>\n");
145 int main(int argc
, char *argv
[])
157 dev
= new blockdevice
;
159 // open the block device and figure out how big it is
160 dev
->filefd
= open(argv
[1], O_RDWR
|O_BINARY
);
161 if(dev
->filefd
< 0) {
162 printf("error opening file '%s'\n", argv
[1]);
167 err
= fstat(dev
->filefd
, &stat
);
169 printf("error statting file\n");
173 if(stat
.st_size
< 512) {
174 printf("file is too small to use as a block device\n");
178 dev
->size
= stat
.st_size
;
180 printf("opened file '%s', size %Ld\n", argv
[1], dev
->size
);
184 // open the server socket
185 struct sockaddr_in addr
;
186 addr
.sin_family
= AF_INET
;
187 addr
.sin_port
= htons(9999);
188 memset(&addr
.sin_addr
, 0, sizeof(addr
.sin_addr
));
190 sockfd
= socket(PF_INET
, SOCK_DGRAM
, 0);
192 printf("error creating socket\n");
196 err
= bind(sockfd
, (struct sockaddr
*)&addr
, sizeof(struct sockaddr
));
198 printf("error binding socket\n");