浏览代码

Adds msb_message_t with basic builders, smb_packet_t. Adds a few defines to smb_defs.h

Julien 'Lta' BALLET 11 年之前
父节点
当前提交
7f85fa46f4
共有 7 个文件被更改,包括 149 次插入126 次删除
  1. 2 1
      Makefile
  2. 10 112
      dsm.c
  3. 36 10
      include/bdsm/smb_defs.h
  4. 20 0
      include/bdsm/smb_message.h
  5. 2 2
      src/netbios_ns.c
  6. 1 1
      src/netbios_session.c
  7. 78 0
      src/smb_message.c

+ 2 - 1
Makefile

@@ -1,7 +1,7 @@
 # Makefile for libdsm
 
 CFLAGS      = -g3 -I include -DBDSM_DEBUG=1 -D_BSD_SOURCE -std=c99
-LDFLAGS     = -levent
+LDFLAGS     = #-levent
 CC          = clang
 
 UTIL				= dsm
@@ -13,6 +13,7 @@ UTIL_SRC		= dsm.c 							    \
 							src/netbios_ns_entry.c	\
 							src/netbios_query.c     \
 							src/netbios_session.c		\
+							src/smb_message.c				\
 							src/context.c
 
 UTIL_OBJS		= $(UTIL_SRC:.c=.o)

+ 10 - 112
dsm.c

@@ -25,134 +25,32 @@ int main(int ac, char **av)
 {
   struct sockaddr_in  addr;
   bdsm_context_t      *ctx;
+  const char          *dialects[]= SMB_DIALECTS;
 
-  //printf("sizeof(smb_header_t) = %lu", sizeof(smb_header_t));
+  printf("sizeof(smb_header_t) = %lu", sizeof(smb_header_t));
 
   ctx = bdsm_context_new();
   assert(ctx);
   addr.sin_addr.s_addr = netbios_ns_resolve(ctx->ns, av[1], NETBIOS_FILESERVER);
   printf("%s's IP address is : %s\n", av[1], inet_ntoa(addr.sin_addr));
 
-  netbios_ns_discover(ctx->ns);
-
-  exit(0);
+  //netbios_ns_discover(ctx->ns);
+  //exit(0);
 
   netbios_session_t *session;
   session = netbios_session_new(addr.sin_addr.s_addr);
   if (netbios_session_connect(session, "Cerbere"))
     printf("A NetBIOS session with %s has been established\n", av[1]);
   else
+  {
     printf("Unable to establish a NetBIOS session with %s\n", av[1]);
-  netbios_session_destroy(session);
-  bdsm_context_destroy(ctx);
-  // struct sockaddr_in  addr;
-  // int                 sock;
-  // int                 sock_opt = 1;
-
-  // netbios_name_t      nb_name;
-  // char                test[64];
-  // int                 res;
-
-  // nb_name = netbios_name_encode("Cerbere", 0, NETBIOS_WORKSTATION);
-  // res = netbios_name_decode(nb_name, test, 0);
-
-  // printf("Encoded: %s\n", (char *)nb_name + 1);
-  // printf("Decoded: %s\n", (char *)test);
-
-  // if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
-  // {
-  //   printf("Unable to create socket: %s\n", strerror(errno));
-  //   exit(42);
-  // }
-
-  // if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (void *)&sock_opt, sizeof(sock_opt)) < 0)
-  // {
-  //   printf("Unable to set broadcast opt on socket: %s\n", strerror(errno));
-  //   close(sock);
-  //   exit(42);
-  // }
-
-  // sock_opt = 0;
-  // if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, (void *)&sock_opt, sizeof(sock_opt)) < 0)
-  // {
-  //   printf("Unable to set broadcast opt on socket: %s\n", strerror(errno));
-  //   close(sock);
-  //   exit(42);
-  // }
-
-  // addr.sin_family = AF_INET;
-  // //addr.sin_port = htons(NBT_UDP_PORT);
-  // addr.sin_port = htons(0);
-  // addr.sin_addr.s_addr = 0;
-
-  // if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
-  // {
-  //   printf("Unable to bind socket: %s\n", strerror(errno));
-  //   close(sock);
-  //   exit(42);
-  // }
-
-  // // Let's build a packet;
-  // nbt_ns_packet_t     *packet = malloc(512);
-  // unsigned int        payload_size = 34 + 4;
-  // nbt_encoded_name_t  encoded_name;
+    exit(21);
+  }
 
-  // nbt_encode_name(av[1], strlen(av[1]), encoded_name);
-  // printf("Requested encoded_name = %.32s\n", encoded_name);
 
-  // memset((void *)packet, 0, 512);
-  // packet->trn_id      = rand();
-  // packet->flags       = htons(0x0110);
-  // packet->qd_count    = htons(1);
-  // packet->payload[0]  = 0x20;
-  // memcpy(packet->payload + 1, encoded_name, 33);
-  // packet->payload[34] = 0x00;
-  // packet->payload[35] = 0x20;
-  // packet->payload[36] = 0x00;
-  // packet->payload[37] = 0x01;
 
+  netbios_session_destroy(session);
+  bdsm_context_destroy(ctx);
 
-
-  // struct sockaddr_in  bcast_addr;
-  // ssize_t             sent;
-
-  // inet_aton("255.255.255.255", &(bcast_addr.sin_addr));
-  // bcast_addr.sin_family = AF_INET;
-  // bcast_addr.sin_port   = htons(137);
-
-  // sent = sendto(sock, (void *)packet, sizeof(nbt_ns_packet_t) + payload_size, 0,
-  //               (struct sockaddr *)&bcast_addr, sizeof(struct sockaddr_in));
-
-  // if (sent < 0)
-  // {
-  //   perror("sendto");
-  //   close(sock);
-  //   exit(42);
-  // }
-  // else
-  // {
-  //   printf("Packet emitted ! (%lu bytes)\n", sizeof(nbt_ns_packet_t) + payload_size);
-  // }
-
-  // struct sockaddr_in  recv_addr;
-  // size_t              recv_addr_length;
-  // ssize_t             recv;
-  // char                buffer[512];
-
-  // recv = recvfrom(sock, (void *)buffer, 512, 0, 0, 0);
-
-  // if (recv < 0)
-  // {
-  //   perror("recvfrom");
-  //   close(sock);
-  //   exit(42);
-  // }
-
-  // for(size_t i = 0; i < recv; i++)
-  // {
-  //   printf("%X", buffer[i]);
-  // }
-  // printf("\n");
-
-  // return (0);
+  return (0);
 }

+ 36 - 10
include/bdsm/smb_defs.h

@@ -8,6 +8,24 @@
 
 #include <stdint.h>
 
+#define SMB_MAGIC               { 0xff, 0x53, 0x4d, 0x42 } // aka "\xffSMB"
+
+#define SMB_DIALECTS {          \
+  "\2PC NETWORK PROGRAM 1.0",   \
+  "\2NT LM 0.12",               \
+  NULL                          \
+}
+
+#define SMB_CMD_CLOSE           0x04
+#define SMB_CMD_TRANS2          0x32
+#define SMD_CMD_TREE_DISCONNECT 0x71
+#define SMB_CMD_NEGOTIATE       0x72
+#define SMB_CMD_SETUP           0x73 // Session Setup AndX
+#define SMB_CMD_TREE_CONNECT    0x75 // Tree Connect AndX
+#define SMB_CMD_ECHO            0x2b
+#define SMB_CMD_READ            0x2e // Read AndX
+#define SMB_CMD_CREATE          0xa2 // NT Create AndX
+
 typedef struct
 {
   uint8_t         wct; // zero
@@ -18,7 +36,8 @@ typedef struct
 
 typedef struct
 {
-
+  uint8_t         wct; // +-17 :)
+  uint8_t         payload[];
 } __attribute__((packed))   smb_negotiate_resp_t;
 
 typedef struct
@@ -43,16 +62,23 @@ typedef struct
   uint16_t        reserved;     // More usuned bit (we have so much BW :)
   uint16_t        tree_id;      // SMB's file descriptor or service id ?
   uint16_t        pid;          // Process ID.
-  uint16_t        uid;          // Process ID.
+  uint16_t        uid;          // User ID.
   uint16_t        mux_id;       // Multiplex ID. Increment it sometimes.
-  //uint8_t         payload[];    // The yummy data inside. Remember to eat 5 fruits/day
-  union {
-    smb_negotiate_req_t     negotiate_req;
-    smb_negotiate_resp_t    negotiate_resp;
-    smb_session_req_t       session_req;
-    smb_session_resp_t      session_resp;
-  }               msg;
-} __attribute__((packed))   smb_header_t;
+} __attribute__((packed))       smb_header_t;
+
+typedef struct
+{
+  smb_header_t    header;       // A packet header full of gorgeous goodness.
+  uint8_t         payload[];    // Ze yummy data inside. Eat 5 fruits/day !
+} __attribute__((packed))       smb_packet_t;
+
+// This is used with convenience functions to build packets.
+typedef struct
+{
+  size_t          payload_size; // Size of the allocated payload
+  size_t          cursor;       // Write cursor in the payload
+  smb_packet_t    *packet;      // Yummy yummy, Fruity fruity !
+}                               smb_message_t;
 
 
 #endif

+ 20 - 0
include/bdsm/smb_message.h

@@ -0,0 +1,20 @@
+// This file is part of libdsm
+// Author: Julien 'Lta' BALLET <contact@lta.io>
+// Copyright VideoLabs 2014
+// License: MIT License
+
+#ifndef __BDSM_SMB_PACKET_H_
+#define __BDSM_SMB_PACKET_H_
+
+// The actual packet data format definition is here
+#include "bdsm/smb_defs.h"
+
+smb_message_t   *smb_message_new(uint8_t cmd, size_t payload_size);
+void            smb_message_destroy(smb_message_t *msg);
+int             smb_message_append(smb_message_t *msg, const void *data,
+                                   size_t data_size);
+int             smb_message_put8(smb_message_t *msg, uint8_t data);
+int             smb_message_put16(smb_message_t *msg, uint16_t data);
+int             smb_message_put32(smb_message_t *msg, uint32_t data);
+int             smb_message_put64(smb_message_t *msg, uint32_t data);
+#endif

+ 2 - 2
src/netbios_ns.c

@@ -186,8 +186,8 @@ uint32_t      netbios_ns_resolve(netbios_ns_t *ns, const char *name, char type)
   free(encoded_name);
 
   // Now wait for a reply and pray
-  timeout.tv_sec = 1;
-  timeout.tv_usec = 500;
+  timeout.tv_sec = 2;
+  timeout.tv_usec = 420;
   recv = netbios_ns_recv(ns->socket, (void *)recv_buffer, 512, &timeout, 0, 0);
 
   if (recv <= 0)

+ 1 - 1
src/netbios_session.c

@@ -80,7 +80,7 @@ int               netbios_session_connect(netbios_session_t *s, char *name)
   encoded_name = netbios_name_encode(name, 0, NETBIOS_FILESERVER);
   netbios_session_packet_append(s, encoded_name, strlen(encoded_name) + 1);
   free(encoded_name);
-  encoded_name = netbios_name_encode("LIBDSM", 0, NETBIOS_FILESERVER);
+  encoded_name = netbios_name_encode("LIBDSM", 0, NETBIOS_WORKSTATION);
   netbios_session_packet_append(s, encoded_name, strlen(encoded_name) + 1);
   free(encoded_name);
 

+ 78 - 0
src/smb_message.c

@@ -0,0 +1,78 @@
+// This file is part of libdsm
+// Author: Julien 'Lta' BALLET <contact@lta.io>
+// Copyright VideoLabs 2014
+// License: MIT License
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "bdsm/smb_message.h"
+
+smb_message_t   *smb_message_new(uint8_t cmd, size_t payload_size)
+{
+  const char    magic[4] = SMB_MAGIC;
+  smb_message_t *msg;
+
+  msg = (smb_message_t *)malloc(sizeof(smb_message_t));
+  assert(msg != NULL);
+  memset((void *)msg, 0, sizeof(smb_message_t));
+
+  msg->packet = (smb_packet_t *)malloc(sizeof(smb_message_t) + payload_size);
+  assert(msg != NULL);
+  memset((void *)msg->packet, 0, sizeof(smb_message_t) + payload_size);
+
+  msg->payload_size = payload_size;
+  msg->cursor = 0;
+
+  for (unsigned i = 0; i < 4; i++)
+    msg->packet->header.magic[i] = magic[i];
+  msg->packet->header.command  = cmd;
+
+  return (msg);
+}
+
+void            smb_message_destroy(smb_message_t *msg)
+{
+  if (msg != NULL)
+  {
+    if (msg->packet != NULL)
+      free(msg->packet);
+    free(msg);
+  }
+}
+
+int             smb_message_append(smb_message_t *msg, const void *data,
+                                   size_t data_size)
+{
+  assert(msg != NULL && data != NULL);
+
+  if (data_size > msg->payload_size - msg->cursor)
+    return (0);
+
+  memcpy(msg->packet->payload + msg->cursor, data, data_size);
+  msg->cursor += data_size;
+
+  return (1);
+}
+
+int             smb_message_put8(smb_message_t *msg, uint8_t data)
+{
+  return(smb_message_append(msg, (void *)&data, 1));
+}
+
+int             smb_message_put16(smb_message_t *msg, uint16_t data)
+{
+    return(smb_message_append(msg, (void *)&data, 2));
+}
+
+int             smb_message_put32(smb_message_t *msg, uint32_t data)
+{
+    return(smb_message_append(msg, (void *)&data, 4));
+}
+
+int             smb_message_put64(smb_message_t *msg, uint32_t data)
+{
+    return(smb_message_append(msg, (void *)&data, 8));
+}