Archive

Posts Tagged ‘Notes’

C语言中的有符合与无符合类型

April 20th, 2009 No comments

这几天在解析ARP,ICMP 的时候, 要对数据进行移位,由于之前对unsigned 和 singned没有很好的认识,有些莫名奇怪的问题。

比如下面的代码:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define ARRAY_SIZE(arr)        (sizeof(arr) / sizeof((arr)[0]))

int main(void)
{
char mac[6] = {0×80, 0x1E, 0×37, 0x1A, 0x3D, 0x7F};

int i = 0;
for(i = 0; i<ARRAY_SIZE(mac); i++) {
printf(“0x%X “, mac[i]);
}
printf(“\n”);

write1(mac, 6);
return 0;
}

void write1(unsigned char *buf, uint16_t buf_size)
{
int i = 0;
uint16_t cur_word = 0;

for (i = 0; i < buf_size; i += 2) {
cur_word = (uint16_t)((buf[i] <<8 ) | buf[i+1]);
printf(“0x%04X buf[i] 0x%02X  buf[i+1] 0x%02X\n”, cur_word, buf[i], buf[i+1]);
}
}

border@ubuntu:~$ uname -a
Linux ubuntu 2.6.24-21-generic #1 SMP Tue Oct 21 23:43:45 UTC 2008 i686 GNU/Linux
border@ubuntu:~$ ./hello
0xFFFFFF80 0x1E 0×37 0x1A 0x3D 0x7F
0x801E buf[i] 0×80  buf[i+1] 0x1E
0x371A buf[i] 0×37  buf[i+1] 0x1A
0x3D7F buf[i] 0x3D  buf[i+1] 0x7F

怎么打印结果不同, 在主函数里面第一个打印出来的是 0xFFFFFF80, 但是在write1函数里面就是正常的0×80了,但是你有可能说
是0x%x 和 0x%02x 的问题,于是程序改为:

char mac[6] = {0x80, 0x1E, 0x37, 0x1A, 0x3D, 0x7F};
int i = 0;
for(i = 0; iprintf("0x%02X ", mac[i]);
}
printf("\n");

就算是改为 %02X,也是输出0xFFFFFF80,和%x的结果一样。

但是如果把char mac[6] 改为 unsigned char mac[6] 主函数就没有问题。

在write1函数里面,如果你把参数unsigned char *buf 改为char *buf, 当大于0x7F的时候,也会溢出,是因为C 里面如果没有定义
类型符合的话默认为singned.

singned的取之范围是-128-127(0×80-0x7F), 所以当大于0x7F的时候会溢出。

unsigned 的取值范围是0-255(0-0xFF).

如果你要进行高低段位移的话,以后要定义为unsigned.

疑问:  为什么%02X输出的也是8个字节,而不是两个字节?

Bian Jiang

http://www.wifihack.net

–EOF–

Categories: Tech.Notes Tags: , ,

Git-svn workflow

April 3rd, 2009 No comments

本文参考: http://notes.jimlindley.com/2008/3/25/git-svn-that-works-for-me
作者: Jim Lindley

The canonical git-svn workflow that I’ve seen goes like this:
标准的git-svn工作流程参考这里:

[code lang="C"]
git svn clone
git checkout -b
...hack...hack...

git commit -a
git checkout master
git merge #NOTE: no need for --squash anymore
git svn rebase
git svn dcommit -e # -e will let you enter a commit message for SVN

[/code]

I’ve had more luck with the following workflow, when integrating changes via SVN from other team members:
我从团队的其他成员学到了更好的工作流程:

[code lang="C"]
# initial setup
git svn clone

# 99% of daily workflow
git checkout -b
...hack...hack...
git commit -a

# switch back to master, then rebase against
# any revisions in the svn repo
git checkout master
git svn rebase

# now that master is current with svn,
# sync working branch to local master
git checkout # These two are the added steps
git rebase master # which help prevent conflicts

# final upstream commit after rebasing
git checkout master
git svn rebase # one last check for new svn check ins
git merge
git svn dcommit -e

[/code]

The extra rebase step seems to do a better job of integrating your patches into the tree. Merge should do the same thing, if I’m reading the man pages right, but splitting the steps is more idiot proof (me-proof) this way.

It also keeps the master local branch from getting messy dealing with conflicts. Instead conflict is kept in the side working branch.

上面虽然很罗嗦但是做的好处在于,我们把所有的工作和从svn代码的合并都放在本地的分支上进行。这样就能保证本地主干与svn服务器进行同步,并且在本地主干没有任何修改。

更多有关git, git-svn,  git-reset 的文章:
1. git-svn workflow
2. An introduction to git-svn for Subversion/SVK users and deserters
3. Git reset in depth

2009.4.3
Bian Jiang
–EOF–

Categories: Tech.Notes Tags: , , ,

cmake常见问题

March 31st, 2009 No comments

CMake 是一个跨平台的自动化建构系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程,
可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。
文件 CMakeLists.txt 需要手工编写,也可以通过编写脚本进行半自动的生成。CMake 提供了比 autoconfig 更简洁的语法.

之前想用automake autoconf来管理项目,但是看了一天也没有搞明白是怎么回事。最后只好投奔cmake.

经过一天的努力终于把项目从Makefile移植到cmake. 在移植的过程中遇到了些问题,简单记录如下.

网上关于cmake的的资料比较少,官方网站上的资料也特别少,有好多看了还看不懂, 哎。

从网上找到一篇“Cmake Practice(cmake 实践)”国人Cjacker写的。可以从这不下载 http://www.scribd.com/doc/13774019/Cmake-Practicecmake-

1. 在cmake中通过EXEC_PROGRAM来调用命令行来取得一些参数. 比如你要想通过取得gtkmm一些头部文件和库的路径。
[code lang="C"]
pkg-config gtkmm --cflags --libs
[/code]

Use the EXEC_PROGRAM command and then use the CACHE option of the SET
command to save the output to a variable like GTK_PKG_FLAGS.  Then use
the SET command to add the value.  Something like this:

[code lang="C"]
IF(NOT GTK_PKG_FLAGS)
EXEC_PROGRAM(pkg-config ARGS --cflags --libs gtkmm
OUTPUT_VARIABLE GTK_PKG_FLAGS)
SET(GTK_PKG_FLAGS "${GTK_PKG_FLAGS}" CACHE STRING "GTK Flags")
ENDIF(NOT GTK_PKG_FLAGS)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GTK_PKG_FLAGS}")
[/code]

2. 通过execute_process来实现文件, 目录的拷贝
[code lang="C"]
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/path/to/www
${CMAKE_BINARY_DIR}/path/to/www)
[/code]

PS: EXECUTE_PROCESS 和 EXEC_PROGRAM 基本相同,  EXECUTE_PROCESS是用来替代EXEC_PROGRAM的。
参见:  http://www.cmake.org/pipermail/cmake/2006-February/008250.html

参考:  http://www.cmake.org/pipermail/cmake/2009-March/028299.html

3. 常用的几个内置变量

通过set语句可以自定义变量,然而,CMake还包含大量的内置变量,这些变量和自定义变量的用法没有区别,下面就列出一些常用的变量:

* CMAKE_C_COMPILER

指定C编译器,通常,CMake运行时能够自动检测C语言编译器。进行嵌入式系统开发时,通常需要设置此变量,指定交叉编译器。
* CMAKE_CXX_COMPILER

指定C++编译器
* CMAKE_C_FLAGS

指定编译C文件时编译选项,比如-g指定产生调试信息。也可以通过add_definitions命令添加编译选项。
* EXECUTABLE_OUTPUT_PATH

指定可执行文件存放的路径。
* LIBRARY_OUTPUT_PATH

指定库文件放置的路径

4. 常用的命令

除了内置变量,我们还可以通过命令来修改编译选项,现将一些常用的命令列出来:

* include_directories

指定头文件的搜索路径,相当于指定gcc编译器的-I参数
* link_directories

动态链接库或静态链接库的搜索路径,相当于指>定gcc的-L参数
* add_subdirectory

包含子目录,当工程包含多个子目录时,此命令有用
* add_definitions

添加编译参数,比如add_definitions(-DDEBUG)将在gcc命令行添加DEBUG宏定义
* add_executable

编译可执行程序
* target_link_libraries

指定链接库,相同于指定-l参数

* AUX_SOURCE_DIRECTORY 将指定目录中的源文件名称赋值给变量DIR_SRCS

AUX_SOURCE_DIRECTORY(. DIR_SECS)

把当前目录下面的所有源文件名称赋值给变量DIR_SRCS

Cmake Practice(cmake 实践)   http://www.scribd.com/full/13774019?access_key=key-hkil010h7nnglwgk8x5

Links:
1. http://www.cmake.org/pipermail/cmake/2005-January/006051.html
2.  CMake Useful Variables http://www.vtk.org/Wiki/CMake_Useful_Variables
3.  http://www.cmake.org/pipermail/cmake/2009-March/028299.html
4.  http://www.scribd.com/doc/13774019/Cmake-Practicecmake-

Categories: Tech.Notes Tags: , , , ,

对位运算

March 12th, 2009 No comments

近来在做驱动方面的开发, 结果发现对位操作反应比较迟钝, 就从网上搜了些有关位操作的说明复习一下.
[sourcecode language='c']
if (set) {
/* shift 位设置为1 */
val |= (1 << shift);
}
else{
/* shift 位清零 */
val &= ~(1 << shift);
}

[/sourcecode]
Set a bit (where n is the bit number, and 0 is the least significant bit):
[sourcecode language='c']
unsigned char a |= (1 << n);
[/sourcecode]
Clear a bit:
[sourcecode language='c']
unsigned char b &= ~(1 << n);
[/sourcecode]
Toggle a bit: n位的值取反
[sourcecode language='c']
unsigned char c ^= (1 << n);
[/sourcecode]
Test a bit:
[sourcecode language='c']
unsigned char e = d & (1 << n); //d has the byte value.
[/sourcecode]
还有一个对奇偶性进行判断
[sourcecode language='c']
a&1 = 0 // 偶数
a&1 = 1 // 奇数
[/sourcecode]
参考:
1.  http://en.wikipedia.org/wiki/Bit_manipulation

2. 这里面将的比较全也比较详细, 有兴趣的可以看看 http://graphics.stanford.edu/~seander/bithacks.html


Bian Jiang
Blog:  http://www.wifihack.net/

Categories: Tech.Notes Tags: , ,

snmp学习笔记之三--开发netsnmp Agent

November 27th, 2008 No comments

1.mib 库文件 BVCOM-SYSTEMUPTIME-MIB.txt:

BVCOM-SYSTEMUPTIME-MIB DEFINITIONS ::= BEGIN

IMPORTS
    TimeTicks   FROM SNMPv2-SMI
    enterprises      FROM SNMPv2-SMI
    OBJECT-TYPE, Integer32, MODULE-IDENTITY      FROM SNMPv2-SMI;

bvcom    OBJECT IDENTIFIER ::= { enterprises 26814 }

ipq6800    OBJECT IDENTIFIER ::= { bvcom 6800 }

bvcomAgentModules   OBJECT IDENTIFIER ::= { ipq6800 1 }

bvcomAgentModuleObject OBJECT-TYPE
    SYNTAX      Integer32
    MAX-ACCESS  read-write
    STATUS      current
    DESCRIPTION
    "This is an object that simply supports a writable integer
     when compiled into the agent.  See
     http://www.net-snmp.org/tutorial-5/toolkit/XXX for further
     implementation details."
    DEFVAL { 1 }
    ::= { bvcomAgentModules 1 }

bvcomAgentSubagentObject OBJECT-TYPE
    SYNTAX      Integer32
    MAX-ACCESS  read-write
    STATUS      current
    DESCRIPTION
    "This is an object that simply supports a writable integer
     when attached to the agent.  The object should be accessible
     when the agentx subagent containing this object is attached.
     See http://www.net-snmp.org/tutorial-5/toolkit/XXX for
     further implementation details."
    DEFVAL { 2 }
    ::= { bvcomAgentModules 2 }

bvcomAgentPluginObject OBJECT-TYPE
    SYNTAX      Integer32
    MAX-ACCESS  read-write
    STATUS      current
    DESCRIPTION
    "This is an object that simply supports a writable integer
     when attached to the agent.  This object should be accessible
     when the dynamic plugin has been loaded into the agent.  See
     http://www.net-snmp.org/tutorial-5/toolkit/XXX for further
     implementation details."
    DEFVAL { 3 }
    ::= { bvcomAgentModules 3 }

END
PS: 如果找不到mib库可以在/etc/profile文件中增加SNMPCONFPATH环境变量
export SNMPCONFPATH=/usr/local/share/snmp/
export MIBS=ALL

2.复制mib库文件到/usr/local/share/snmp/mibs/:

sudo cp BVCOM-SYSTEMUPTIME-MIB.txt /usr/local/share/snmp/mibs/

3.加载mib库:

cat /usr/local/share/snmp/snmp.conf
mibs +BVCOM-SYSTEMUPTIME-MIB

4.检查mib是否正常加载:

border@debian:/work/border/snmp/example-demon$ snmptranslate -IR -Tp bvcom
+--bvcom(26814)
   |
   +--ipq6800(6800)
      |
      +--bvcomAgentModules(1)
         |
         +-- -RW- Integer32 bvcomAgentModuleObject(1)
         +-- -RW- Integer32 bvcomAgentSubagentObject(2)
         +-- -RW- Integer32 bvcomAgentPluginObject(3)

5.查看mib2c支持的模板:

border@debian:/work/border/snmp/example-demon$ ls /usr/local/share/snmp/
mib2c.access_functions.conf    mib2c.create-dataset.conf  mib2c.scalar.conf
mib2c.array-user.conf          mib2c-data                 mib2c.table_data.conf
mib2c.check_values.conf        mib2c.genhtml.conf         mibs
mib2c.check_values_local.conf  mib2c.int_watch.conf       snmp.conf
mib2c.column_defines.conf      mib2c.iterate_access.conf  snmp.conf~
mib2c.column_enums.conf        mib2c.iterate.conf         snmpconf-data
mib2c.column_storage.conf      mib2c.mfd.conf             snmpd.conf
mib2c.conf                     mib2c.notify.conf          snmp_perl.pl
mib2c.container.conf           mib2c.old-api.conf         snmp_perl_trapd.pl

6.通过模板生成.c 和 .h 文件:

border@debian:/work/border/snmp/example-demon$ mib2c -c mib2c.int_watch.conf bvcomAgentModules
writing to -
*** Warning: only generating code for nodes of MIB type INTEGER
writing to bvcomAgentModules.h
writing to bvcomAgentModules.c
running indent on bvcomAgentModules.c
running indent on bvcomAgentModules.h

7.通过 snmp_agent_api 编写守护程序 example-demon.c:

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <signal.h>
#include "bvcomAgentModules.h"

static int keep_running;

RETSIGTYPE
stop_server(int a) {
    keep_running = 0;
}

int
main (int argc, char **argv) {

    int agentx_subagent=0; /* change this if you want to be a SNMP master agent */
    int background = 0; /* change this if you want to run in the background */
    int syslog = 0; /* change this if you want to use syslog */

    /* print log errors to syslog or stderr */

    if (syslog)
        snmp_enable_calllog();
    else
        snmp_enable_stderrlog();

    /* we're an agentx subagent? */
    if (agentx_subagent) {
        /* make us a agentx client. */
        netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
    }

    /* run in background, if requested */
    if (background && netsnmp_daemonize(1, !syslog))
        exit(1);

    /* Initialize tcpip, if necessary */
    SOCK_STARTUP;

    /* Initialize the agent library */
    init_agent("example-demon"); // 配置文件名

    /* Initialize our mib code here */
    printf("Before init bvcomAgentModules \n");

    init_bvcomAgentModules(); // 加载节点信息

    printf("End init bvcomAgentModules \n");

    /* initialize vacm/usm access control  */
    if (!agentx_subagent) {
        void  init_vacm_vars();
        void  init_usmUser();
    }

    /* Example-demon will be used to read example-demon.conf files. */
    init_snmp("example-demon");

    /* If we're going to be a snmp master agent, initial the ports */
    if (!agentx_subagent)
        init_master_agent();  /* open the port to listen on (defaults to udp:161) */

    printf("---------------------\n");
    /* In case we recevie a request to stop (kill -TERM or kill -INT) */
    keep_running = 1;
    signal(SIGTERM, stop_server);

    signal(SIGINT, stop_server);

    snmp_log(LOG_INFO,"example-demon is up and running.\n");

    /* your main loop here... */
    while(keep_running) {
        /* if you use select(), see snmp_select_info() in snmp_api(3) */
        /*     --- OR ---  */
        agent_check_and_process(1); /* 0 == don't block */

    }

    /* at shutdown time */
    snmp_shutdown("example-demon");
    SOCK_CLEANUP;
    return 0;
}

8.Makefile:

CC=gcc

OBJS2=example-demon.o bvcomAgentModules.o
TARGETS=example-demon

CFLAGS=-I. `net-snmp-config --cflags`
BUILDLIBS=`net-snmp-config --libs`
BUILDAGENTLIBS=`net-snmp-config --agent-libs`

# shared library flags (assumes gcc)
DLFLAGS=-fPIC -shared

all: $(TARGETS)

example-demon: $(OBJS2)
    $(CC) -o example-demon $(OBJS2)  $(BUILDAGENTLIBS)

clean:
    rm $(OBJS2) $(OBJS2) $(TARGETS)

9.example-demon.conf:

###############################################################################
# Access Control
###############################################################################

#       sec.name  source          community
com2sec local     localhost       public
com2sec mynetwork 192.168.0.0/24      public

####
# Second, map the security names into group names:

#                 sec.model  sec.name
group MyRWGroup    v1         local
group MyRWGroup    v2c        local
group MyRWGroup    usm        local
group MyROGroup v1         mynetwork
group MyROGroup v2c        mynetwork
group MyROGroup usm        mynetwork

####
# Third, create a view for us to let the groups have rights to:

#           incl/excl subtree                          mask
view all    included  .1                               80

####
# Finally, grant the 2 groups access to the 1 view with different
# write permissions:

#              context sec.model sec.level match  read   write  notif
access MyROGroup ""      any       noauth    exact  all    none   none
access MyRWGroup ""      any       noauth    exact  all    all    none

agentaddress 161

10.运行example-demon 时要用超级管理员运行,不然会出错:

sudo ./example-demon

a.没有用超级管理员时,报的错误:

border@debian:/work/border/snmp/example-demon$ ./example-demon
netsnmp_assert !"registration != duplicate" failed agent_registry.c:535 netsnmp_subtree_load()
netsnmp_assert !"registration != duplicate" failed agent_registry.c:535 netsnmp_subtree_load()
netsnmp_assert !"registration != duplicate" failed agent_registry.c:535 netsnmp_subtree_load()
Before init bvcomAgentModules
End init bvcomAgentModules
Error opening specified endpoint "161"
---------------------
example-demon is up and running.
read_config_store open failure on /var/net-snmp/example-demon.conf
read_config_store open failure on /var/net-snmp/example-demon.conf
read_config_store open failure on /var/net-snmp/example-demon.conf

b.如果 报Error opening specified endpoint “”错,说明example-demon.conf配置文件没有agentaddress 161

11.拷贝配置文件到 ~/.snmp/目录下:

cp example-demon.conf /home/border/.snmp/

12.sudo ./example-demon:

border@debian:~$ snmpwalk -v1 -c public localhost bvcom
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentModuleObject.0 = INTEGER: 68001
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentSubagentObject.0 = INTEGER: 68002
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentPluginObject.0 = INTEGER: 68003
End of MIB

验证:

border@debian:~$ snmpget -v1 -c public localhost bvcomAgentModuleObject.0
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentModuleObject.0 = INTEGER: 68001

border@debian:~$ snmpgetnext -v1 -c public localhost bvcomAgentModuleObject.0
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentSubagentObject.0 = INTEGER: 68002

13.支持snmpv3 在配置文件中增加:

rwuser border
rwuser border1
createUser border MD5 "bvcombjbj" DES
createUser border1 SHA "bvcombjbj" AES
(最后一行也可以这样写:createUser border1 SHA "bvcombjbj" AES128)

通过如下命令验证:

a.验证MD5:

snmpwalk -v3 -l authPriv -u border -A bvcombjbj -X bvcombjbj localhost bvcom
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentModuleObject.0 = INTEGER: 68001
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentSubagentObject.0 = INTEGER: 68002
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentPluginObject.0 = INTEGER: 68003

b.验证SHA:

snmpwalk -v3 -l authPriv -u border1 -a SHA -x AES -A bvcombjbj -X bvcombjbj localhost bvcom
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentModuleObject.0 = INTEGER: 68001
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentSubagentObject.0 = INTEGER: 68002
BVCOM-SYSTEMUPTIME-MIB::bvcomAgentPluginObject.0 = INTEGER: 68003

如果你采用的是AES128,就需要把-x AES改为-x AES128:

snmpwalk -v3 -l authPriv -u border1 -a SHA -x AES128 -A bvcombjbj -X bvcombjbj localhost bvcom
参考:
  1. 用NET-SNMP软件包开发简单客户端代理 http://b0rder.com/wiki/NetSnmp/NetSnmpSimpleAgentMib
  2. snmpd.examples 配置信息相关 http://www.net-snmp.org/docs/man/snmpd.examples.html
  3. snmp_agent_api http://www.net-snmp.org/docs/man/snmp_agent_api.html
  4. Tutorial http://www.nwsmith.net/HintsTips/net-snmp-tutorial.htm
  5. http://www.net-snmp.org/wiki/index.php/TUT:SNMPv3_Options

–EOF–

Categories: Tech.Notes Tags: , , ,