diff options
author | LAN-TW <lantw44@gmail.com> | 2013-12-20 01:00:45 +0800 |
---|---|---|
committer | LAN-TW <lantw44@gmail.com> | 2013-12-20 08:09:01 +0800 |
commit | 63601d7bbeb4da13eb8e18cbcb4f00d260138003 (patch) | |
tree | 3080863b8724eba0bd0aafbbd170a034beaf3edc | |
parent | b9643739bd841544d7dba24baf2ed9a5676d8f2b (diff) | |
download | cn2013-63601d7bbeb4da13eb8e18cbcb4f00d260138003.tar.gz cn2013-63601d7bbeb4da13eb8e18cbcb4f00d260138003.tar.zst cn2013-63601d7bbeb4da13eb8e18cbcb4f00d260138003.zip |
HW2: 準備 build system 與尚未測試的 TCP 封包結構
-rw-r--r-- | hw2/Makefile.am | 19 | ||||
-rwxr-xr-x | hw2/autogen.sh | 51 | ||||
-rw-r--r-- | hw2/configure.ac | 53 | ||||
-rw-r--r-- | hw2/ump-common.h | 55 | ||||
-rw-r--r-- | hw2/ump-pkt.c | 50 | ||||
-rw-r--r-- | hw2/ump-pkt.h | 67 |
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 */ |