summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLAN-TW <lantw44@gmail.com>2013-12-20 01:00:45 +0800
committerLAN-TW <lantw44@gmail.com>2013-12-20 08:09:01 +0800
commit63601d7bbeb4da13eb8e18cbcb4f00d260138003 (patch)
tree3080863b8724eba0bd0aafbbd170a034beaf3edc
parentb9643739bd841544d7dba24baf2ed9a5676d8f2b (diff)
downloadcn2013-63601d7bbeb4da13eb8e18cbcb4f00d260138003.tar.gz
cn2013-63601d7bbeb4da13eb8e18cbcb4f00d260138003.tar.zst
cn2013-63601d7bbeb4da13eb8e18cbcb4f00d260138003.zip
HW2: 準備 build system 與尚未測試的 TCP 封包結構
-rw-r--r--hw2/Makefile.am19
-rwxr-xr-xhw2/autogen.sh51
-rw-r--r--hw2/configure.ac53
-rw-r--r--hw2/ump-common.h55
-rw-r--r--hw2/ump-pkt.c50
-rw-r--r--hw2/ump-pkt.h67
6 files changed, 295 insertions, 0 deletions
diff --git a/hw2/Makefile.am b/hw2/Makefile.am
new file mode 100644
index 0000000..ccfb78f
--- /dev/null
+++ b/hw2/Makefile.am
@@ -0,0 +1,19 @@
+NULL =
+
+EXTRA_DIST = autogen.sh
+
+bin_PROGRAMS = ump-trans ump-agent
+noinst_LIBRARIES = libump.a
+
+libump_a_SOURCES = \
+ ump-common.h \
+ ump-pkt.c ump-pkt.h \
+ $(NULL)
+
+ump_trans_SOURCES = \
+ $(NULL)
+ump_trans_LDADD = $(top_builddir)/libump.a
+
+ump_agent_SOURCES = \
+ $(NULL)
+ump_agent_LDADD = $(top_builddir)/libump.a
diff --git a/hw2/autogen.sh b/hw2/autogen.sh
new file mode 100755
index 0000000..e359561
--- /dev/null
+++ b/hw2/autogen.sh
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+map_c_filename ()
+{
+ c_filename="`basename $1`"
+ case "$c_filename" in
+ "d1array.c") echo "basic-array.c" ;;
+ "d1arrstr.c") echo "basic-arrstr.c" ;;
+ "d2array.c") echo "basic-array2.c" ;;
+ "list.c") echo "basic-list.c" ;;
+ "toargv.c") echo "basic-argv.c" ;;
+ "qarg.c") echo "basic-qarg.c" ;;
+ *) echo "$c_filename" ;;
+ esac
+}
+
+map_h_filename ()
+{
+ h_filename="`basename $1`"
+ case "$h_filename" in
+ "l4darr.h") echo "basic-array.h" ;;
+ "l4bds.h") echo "basic-list.h" ;;
+ "l4arg.h") echo "basic-arg.h" ;;
+ *) echo "$h_filename" ;;
+ esac
+}
+
+generate_file ()
+{
+ file_src="$1"
+ case "$file_src" in
+ *.c) file_dest="`map_c_filename $file_src`" ;;
+ *.h) file_dest="`map_h_filename $file_src`" ;;
+ esac
+ [ -z "$file_dest" ] && return 1
+
+ echo "Generating $file_dest from $file_src"
+ sed -f "libbasic.sed" "$file_src" > "$file_dest"
+}
+
+autoreconf -iv
+[ -z "$1" ] && exit 0
+
+git clone "$1" "l4basic" -b l4basic-1.1
+
+for i in l4basic/l4darr/*.[ch] l4basic/l4bds/*.[ch] l4basic/l4arg/*.[ch]
+do
+ generate_file "$i" "."
+done
+
+rm -rf "l4basic"
diff --git a/hw2/configure.ac b/hw2/configure.ac
new file mode 100644
index 0000000..164e3d3
--- /dev/null
+++ b/hw2/configure.ac
@@ -0,0 +1,53 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_INIT([cn2013-hw2], [1])
+AC_CONFIG_SRCDIR([ump-pkt.h])
+AC_CONFIG_HEADERS([config.h])
+
+AM_INIT_AUTOMAKE([foreign])
+AM_SILENT_RULES([yes])
+
+AC_CANONICAL_HOST
+AC_CANONICAL_BUILD
+AH_TEMPLATE([_POSIX_C_SOURCE])
+AH_TEMPLATE([_XOPEN_SOURCE])
+AH_TEMPLATE([_BSD_SOURCE])
+AH_TEMPLATE([_WITH_GETLINE])
+AH_TEMPLATE([OS_IS_BSD])
+case "$host_os" in
+ *gnu*)
+ AC_DEFINE([_POSIX_C_SOURCE], [200809L])
+ AC_DEFINE([_XOPEN_SOURCE], [700])
+ AC_DEFINE([_BSD_SOURCE])
+ ;;
+ *bsd*)
+ AC_DEFINE([_WITH_GETLINE])
+ AC_DEFINE([OS_IS_BSD])
+ ;;
+esac
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_CC_C99
+AC_PROG_RANLIB
+
+# Checks for libraries.
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_CHECK_HEADER_STDBOOL
+AC_C_INLINE
+AC_C_VOLATILE
+AC_TYPE_SIZE_T
+AC_TYPE_UINT8_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_FUNC_REALLOC
+
+# Misc options.
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/hw2/ump-common.h b/hw2/ump-common.h
new file mode 100644
index 0000000..57f22d9
--- /dev/null
+++ b/hw2/ump-common.h
@@ -0,0 +1,55 @@
+#ifndef UMP_COMMON_H
+#define UMP_COMMON_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+static inline void ump_common_copy (
+ void* dest, const void* src, size_t len) {
+
+ uint8_t* dest_byte = dest;
+ const uint8_t* src_byte = src;
+ for (int i = 0; i < len; i++) {
+ dest_byte[i] = src_byte[i];
+ }
+}
+
+#define UMP_COMMON_MOVE_POINTER(x,offset) (((uint8_t*)(x)) + (offset))
+#define UMP_COMMON_UINT8_ONE ((uint8_t)(1))
+
+#define UMP_COMMON_DEFINE_GETTER(struct_type,func_ns,name,offset,type) \
+ static inline type func_ns ## _get_ ## name (struct_type* pkt) { \
+ type x; \
+ ump_common_copy (&x, UMP_COMMON_MOVE_POINTER (pkt, offset), \
+ sizeof (type) / sizeof (uint8_t)); \
+ return x; \
+ }
+#define UMP_COMMON_DEFINE_SETTER(struct_type,func_ns,name,offset,type) \
+ static inline void func_ns ## _set_ ## name (struct_type* pkt, type x) { \
+ memcpy (UMP_COMMON_MOVE_POINTER (pkt, offset), &x, \
+ sizeof (type) / sizeof (uint8_t)); \
+ }
+#define UMP_COMMON_DEFINE_BOTH(struct_type,func_ns,name,offset,type) \
+ UMP_COMMON_DEFINE_GETTER (struct_type,func_ns,name,offset,type) \
+ UMP_COMMON_DEFINE_SETTER (struct_type,func_ns,name,offset,type)
+
+#define UMP_COMMON_DEFINE_GETTER_FLAG(struct_type,func_ns,name,offset,bit) \
+ static inline uint8_t func_ns ## _get_ ## name (struct_type* pkt) { \
+ uint8_t* x = UMP_COMMON_MOVE_POINTER (pkt, offset); \
+ return *x & (UMP_COMMON_UINT8_ONE << bit); \
+ }
+#define UMP_COMMON_DEFINE_SETTER_FLAG(struct_type,func_ns,name,offset,bit) \
+ static inline void func_ns ## _set_ ## name (struct_type* pkt, uint8_t x) { \
+ uint8_t* d = UMP_COMMON_MOVE_POINTER (pkt, offset); \
+ if (x) { \
+ *d &= ~(UMP_COMMON_UINT8_ONE << bit); \
+ } else { \
+ *d |= (UMP_COMMON_UINT8_ONE << bit); \
+ } \
+ }
+#define UMP_COMMON_DEFINE_BOTH_FLAG(struct_type,func_ns,name,offset,bit) \
+ UMP_COMMON_DEFINE_GETTER_FLAG (struct_type,func_ns,name,offset,bit) \
+ UMP_COMMON_DEFINE_SETTER_FLAG (struct_type,func_ns,name,offset,bit)
+
+#endif /* UMP_COMMON_H */
diff --git a/hw2/ump-pkt.c b/hw2/ump-pkt.c
new file mode 100644
index 0000000..5b7deaa
--- /dev/null
+++ b/hw2/ump-pkt.c
@@ -0,0 +1,50 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "ump-pkt.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+
+void ump_pkt_init (UmpPkt* pkt) {
+ memset (pkt, 0, sizeof (UmpPkt));
+ ump_pkt_set_data_offset (pkt, 20);
+}
+
+void ump_pkt_set_app_data (UmpPkt* pkt, const uint8_t* data, size_t len) {
+ uint8_t* app_data = ump_pkt_get_app_data (pkt);
+ ump_common_copy (app_data, data, len);
+ pkt->app_data_len = len;
+}
+
+uint16_t ump_pkt_calc_checksum (UmpPkt* pkt) {
+ size_t pkt_len = ump_pkt_get_data_offset (pkt) + pkt->app_data_len;
+ uint8_t* pkt_data = UMP_COMMON_MOVE_POINTER (pkt, 0);
+ uint16_t checksum = 0;
+ for (int i = 0; i < pkt_len; i++) {
+ if (i != 16 && i != 17) {
+ uint32_t checksum_new = checksum + pkt_data[i];
+ if (checksum_new > checksum) {
+ checksum_new = checksum;
+ } else {
+ checksum_new = checksum + 1;
+ }
+ }
+ }
+ return checksum;
+}
+
+void ump_pkt_fill_checksum (UmpPkt* pkt) {
+ uint8_t checksum = ump_pkt_calc_checksum (pkt);
+ ump_pkt_set_checksum (pkt, checksum);
+}
+
+bool ump_pkt_verify_checksum (UmpPkt* pkt) {
+ uint8_t checksum = ump_pkt_calc_checksum (pkt);
+ if (~(checksum + ump_pkt_get_checksum (pkt))) {
+ return false;
+ } else {
+ return true;
+ }
+}
diff --git a/hw2/ump-pkt.h b/hw2/ump-pkt.h
new file mode 100644
index 0000000..33bd2c0
--- /dev/null
+++ b/hw2/ump-pkt.h
@@ -0,0 +1,67 @@
+#ifndef UMP_TCP_H
+#define UMP_TCP_H
+
+#include "ump-common.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define UMP_TCP_PKT_SIZE 1024
+
+typedef struct UmpPktStruct {
+ uint8_t data[UMP_TCP_PKT_SIZE];
+ size_t app_data_len;
+} UmpPkt;
+
+/* Accessor function for UmpPkt, prefixed with ump_pkt */
+
+UMP_COMMON_DEFINE_BOTH (UmpPkt, ump_pkt, src_port, 0, uint16_t);
+UMP_COMMON_DEFINE_BOTH (UmpPkt, ump_pkt, dest_port, 2, uint16_t);
+UMP_COMMON_DEFINE_BOTH (UmpPkt, ump_pkt, seq_num, 4, uint32_t);
+UMP_COMMON_DEFINE_BOTH (UmpPkt, ump_pkt, ack_num, 8, uint32_t);
+
+#define ump_pkt_get_hdr_len ump_pkt_get_data_offset
+static inline uint8_t ump_pkt_get_data_offset (UmpPkt* pkt) {
+ uint8_t* p = UMP_COMMON_MOVE_POINTER (pkt, 12);
+ uint8_t hdr_len = *p;
+ return (hdr_len >> 4) << 2;
+}
+#define ump_pkt_set_hdr_len ump_pkt_set_data_offset
+static inline void ump_pkt_set_data_offset (UmpPkt* pkt, uint8_t x) {
+ uint8_t* p = UMP_COMMON_MOVE_POINTER (pkt, 12);
+ uint8_t hdr_len = (*p) | ((x >> 2) << 4);
+ *p = hdr_len;
+}
+
+UMP_COMMON_DEFINE_BOTH_FLAG (UmpPkt, ump_pkt, flag_ns, 12, 1);
+UMP_COMMON_DEFINE_BOTH_FLAG (UmpPkt, ump_pkt, flag_cwr, 13, 7);
+UMP_COMMON_DEFINE_BOTH_FLAG (UmpPkt, ump_pkt, flag_ece, 13, 6);
+UMP_COMMON_DEFINE_BOTH_FLAG (UmpPkt, ump_pkt, flag_urg, 13, 5);
+UMP_COMMON_DEFINE_BOTH_FLAG (UmpPkt, ump_pkt, flag_ack, 13, 4);
+UMP_COMMON_DEFINE_BOTH_FLAG (UmpPkt, ump_pkt, flag_psh, 13, 3);
+UMP_COMMON_DEFINE_BOTH_FLAG (UmpPkt, ump_pkt, flag_rst, 13, 2);
+UMP_COMMON_DEFINE_BOTH_FLAG (UmpPkt, ump_pkt, flag_syn, 13, 1);
+UMP_COMMON_DEFINE_BOTH_FLAG (UmpPkt, ump_pkt, flag_fin, 13, 0);
+
+UMP_COMMON_DEFINE_BOTH (UmpPkt, ump_pkt, window_size, 14, uint16_t);
+UMP_COMMON_DEFINE_BOTH (UmpPkt, ump_pkt, checksum, 16, uint16_t);
+UMP_COMMON_DEFINE_BOTH (UmpPkt, ump_pkt, urgent_ptr, 18, uint16_t);
+
+static inline uint8_t* ump_pkt_get_app_data (UmpPkt* pkt) {
+ uint8_t off = ump_pkt_get_data_offset (pkt);
+ return UMP_COMMON_MOVE_POINTER (pkt, off);
+}
+static inline size_t ump_pkt_get_app_data_len (UmpPkt* pkt) {
+ return pkt->app_data_len;
+}
+
+/* Other convenient functions */
+
+void ump_pkt_init (UmpPkt* pkt);
+void ump_pkt_set_app_data (UmpPkt* pkt, const uint8_t* data, size_t len);
+uint16_t ump_pkt_calc_checksum (UmpPkt* pkt);
+void ump_pkt_fill_checksum (UmpPkt* pkt);
+bool ump_pkt_verify_checksum (UmpPkt* pkt);
+
+#endif /* UMP_TCP_H */