靈修分享:亞略巴古的演講

亞略巴古的演說是使徒行傳一篇非常著名的講道。基督徒往往用這段經文來說明上帝的屬性,同時也會參考這段經文作為和外邦人互動的一個參考方式。最近因為團契查經查到這一段,重新思想後看到了以前沒有考慮過的面向,在這邊記錄一下。

徒17:16-34保羅在雅典等候他們的時候,看見滿城都是偶像,就心裏着急;於是在會堂裏與猶太人和虔敬的人,並每日在市上所遇見的人,辯論。還有伊壁鳩魯和斯多亞兩門的學士,與他爭論。有的說:「這胡言亂語的要說甚麼?」有的說:「他似乎是傳說外邦鬼神的。」這話是因保羅傳講耶穌與復活的道。他們就把他帶到亞略‧巴古,說:「你所講的這新道,我們也可以知道嗎?因為你有些奇怪的事傳到我們耳中,我們願意知道這些事是甚麼意思。」(雅典人和住在那裏的客人都不顧別的事,只將新聞說說聽聽。)
保羅站在亞略‧巴古當中,說:「眾位雅典人哪,我看你們凡事很敬畏鬼神。我遊行的時候,觀看你們所敬拜的,遇見一座壇,上面寫着『未識之神』。你們所不認識而敬拜的,我現在告訴你們。創造宇宙和其中萬物的神,既是天地的主,就不住人手所造的殿,也不用人手服事,好像缺少甚麼;自己倒將生命、氣息、萬物,賜給萬人。他從一本本:有古卷是血脈造出萬族的人,住在全地上,並且預先定準他們的年限和所住的疆界,要叫他們尋求神,或者可以揣摩而得,其實他離我們各人不遠;我們生活、動作、存留,都在乎他。就如你們作詩的,有人說:『我們也是他所生的。』我們既是神所生的,就不當以為神的神性像人用手藝、心思所雕刻的金、銀、石。世人蒙昧無知的時候,神並不監察,如今卻吩咐各處的人都要悔改。因為他已經定了日子,要藉着他所設立的人按公義審判天下,並且叫他從死裏復活,給萬人作可信的憑據。」
眾人聽見從死裏復活的話,就有譏誚他的;又有人說:「我們再聽你講這個吧!」於是保羅從他們當中出去了。 但有幾個人貼近他,信了主,其中有亞略‧巴古的官丟尼修,並一個婦人,名叫大馬哩,還有別人一同信從。

對基督徒來說,保羅這篇講道講的真好,不但講出了上帝的超越性(像是不住人手所造的殿、也不是金銀石的彫刻),也帶出了耶穌基督復活的大能。但最近我才注意到眾人的反應:「眾人聽見從死裏復活的話,就有譏誚他的;又有人說:「我們再聽你講這個吧!」」不曉得你看到這一段有什麼感想?可能我是玻璃心吧,如果我是保羅,我大概會非常非常的難過,看起來似乎沒有人理會這個福音、這篇講道。這篇被基督…

Netfilter 的 Hook 方式初探

Netfilier,Linux 核心裡面的封包處理子系統。這篇文章唯一時心血來潮,看了一小段 code 以後所作的整理。

kernel: 2.6.23.14

下圖是 Linux 核心的網路封包處理流程:



讓我們到 ip_rcv 這隻函式來看一下,ip_rcv 是處理 IP 封包的主要進入函式。

net/ipv4/ip_input.c:

/*
* Main IP Receive routine.
*/
int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
{
....struct iphdr *iph;
....u32 len;

..../* When the interface is in promisc. mode, drop all the crap
....* that it receives, do not try to analyse it.
....*/
....if (skb->pkt_type == PACKET_OTHERHOST)
........goto drop;

....IP_INC_STATS_BH(IPSTATS_MIB_INRECEIVES);

....if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
........IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS);
........goto out;
....}

....if (!pskb_may_pull(skb, sizeof(struct iphdr)))
........goto inhdr_error;

....iph = ip_hdr(skb);

..../*
....* RFC1122: 3.1.2.2 MUST silently discard any IP frame that fails the checksum.
....*
....* Is the datagram acceptable?
....*
....* 1. Length at least the size of an ip header
....* 2. Version of 4
....* 3. Checksums correctly. [Speed optimisation for later, skip loopback checksums]
....* 4. Doesn't have a bogus length
....*/
....if (iph->ihl <>version != 4)
........goto inhdr_error;

....if (!pskb_may_pull(skb, iph->ihl*4))
........goto inhdr_error;

....iph = ip_hdr(skb);

....if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
........goto inhdr_error;

....len = ntohs(iph->tot_len);
....if (skb->len <>ihl*4))
........goto inhdr_error;

..../* Our transport medium may have padded the buffer out. Now we know it
....* is IP we can trim to the true length of the frame.
....* Note this now means skb->len holds ntohs(iph->tot_len).
....*/
....if (pskb_trim_rcsum(skb, len)) {
........IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS);
........goto drop;
....}

..../* Remove any debris in the socket control block */
....memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));

....return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish);

....inhdr_error:
....IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
....drop:
....kfree_skb(skb);
....out:
....return NET_RX_DROP;
}

當然根本不用貼這麼多程式碼啦,因為大部分都在作 Error Check 的動作(不過就是讓自己順便看一下囉)
比較重要的是紅色的部份,那隻 NF_HOOK 的 Macro。
NF 就是 netfilter 的縮寫,在這裡我們可以清楚看到在 Linux 核心裡面是使用 Hook 的技術來加上攔截點的功能。

那我們來看看那隻 Macro 囉~

include/linux/netfilter.h

#ifdef CONFIG_NETFILTER

#define
NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN)

#else
/* !CONFIG_NETFILTER */

#define
NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)

#endif


在這裡我們可以看到兩個定義,一個是有啟用 netfilter Option的,另一個則是沒有。我們要觀察的當然是有啟用的囉。在這裡附帶一提,okfn 是 function pointer,以上面的例子來說,就是 ip_rcv_finish,這樣就會繼續核心的封包處理流程。

繼續追蹤下去:

include/linux/netfilter.h

#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
({int __ret; \
if ((__ret=nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, thresh, 1)) == 1)\
__ret = (okfn)(skb); \
__ret;})

static inline int nf_hook_thresh(..int pf, unsigned int hook,
....................................................struct sk_buff **pskb,
....................................................struct net_device *indev,
....................................................struct net_device *outdev,
....................................................int (*okfn)(struct sk_buff *), int thresh,
....................................................int cond)
{
....if (!cond)
........return 1;
....
....#ifndef CONFIG_NETFILTER_DEBUG
....if (list_empty(&nf_hooks[pf][hook]))
........return 1;
....#endif

....return nf_hook_slow(pf, hook, pskb, indev, outdev, okfn, thresh);
}

從這裡可以看得出來,如果 nf_hook_thresh 回傳值是 1 的話,核心會進行原本的流程,不然則會交由 nf_hook_slow 來處理。Let's go~

net/netfilter/core.c:

/* Returns 1 if okfn() needs to be executed by the caller,
* -EPERM for NF_DROP, 0 otherwise. */
int nf_hook_slow( int pf, unsigned int hook, struct sk_buff **pskb,
............................struct net_device *indev,
............................struct net_device *outdev,
............................int (*okfn)(struct sk_buff *),
............................int hook_thresh)
{
....struct list_head *elem;
....unsigned int verdict;
....int ret = 0;

..../* We may already have this, but read-locks nest anyway */
....rcu_read_lock();

....elem = &nf_hooks[pf][hook];

next_hook:

....verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev,
....outdev, &elem, okfn, hook_thresh);
....if (verdict == NF_ACCEPT || verdict == NF_STOP) {
........ret = 1;
........goto unlock;
....} else if (verdict == NF_DROP) {
........kfree_skb(*pskb);
........ret = -EPERM;
....} else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) {
........NFDEBUG("nf_hook: Verdict = QUEUE.\n");
........if (!nf_queue(*pskb, elem, pf, hook, indev, outdev, okfn,
............verdict >> NF_VERDICT_BITS))
............goto next_hook;
....}
unlock:
....rcu_read_unlock();
....return ret;
}

那就先停在這裡吧~下次在繼續追蹤~

PS:
如果要了解 tresh 和 cond,請參考下面的文章:
http://blog.chinaunix.net/u/12313/showart_185315.html

留言

  1. 你好,可不可以请教一下,你的流程图使用什么software做的啊?谢谢!!

    回覆刪除
  2. 其實這張圖是在網路上找到的,並不是我畫得唷

    (我個人流程圖都是用 Dia 畫)

    回覆刪除

張貼留言

這個網誌中的熱門文章

如何將Linux打造成OpenFlow Switch:Openvswitch

我弟家的新居感恩禮拜分享:善頌善禱

如何利用 Wireshark 來監聽 IEEE 802.11 的管理封包