⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ip_masq_app.c

📁 GNU Hurd 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *		IP_MASQ_APP application masquerading module * * * 	$Id: ip_masq_app.c,v 1.16 1998/08/29 23:51:14 davem Exp $ * * Author:	Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar> * * *	This program is free software; you can redistribute it and/or *	modify it under the terms of the GNU General Public License *	as published by the Free Software Foundation; either version *	2 of the License, or (at your option) any later version. * * Fixes: *	JJC			: Implemented also input pkt hook *	Miquel van Smoorenburg	: Copy more stuff when resizing skb * * * FIXME: *	- ip_masq_skb_replace(): use same skb if space available. * */#include <linux/config.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/skbuff.h>#include <linux/in.h>#include <linux/ip.h>#include <linux/init.h>#include <net/protocol.h>#include <net/tcp.h>#include <net/udp.h>#include <asm/system.h>#include <linux/stat.h>#include <linux/proc_fs.h>#include <net/ip_masq.h>#define IP_MASQ_APP_TAB_SIZE  16 /* must be power of 2 */#define IP_MASQ_APP_HASH(proto, port) ((port^proto) & (IP_MASQ_APP_TAB_SIZE-1))#define IP_MASQ_APP_TYPE(proto, port) ( proto<<16 | port )#define IP_MASQ_APP_PORT(type)        ( type & 0xffff )#define IP_MASQ_APP_PROTO(type)       ( (type>>16) & 0x00ff )EXPORT_SYMBOL(register_ip_masq_app);EXPORT_SYMBOL(unregister_ip_masq_app);EXPORT_SYMBOL(ip_masq_skb_replace);/* * 	will hold masq app. hashed list heads */struct ip_masq_app *ip_masq_app_base[IP_MASQ_APP_TAB_SIZE];/* * 	ip_masq_app registration routine *	port: host byte order. */int register_ip_masq_app(struct ip_masq_app *mapp, unsigned short proto, __u16 port){        unsigned long flags;        unsigned hash;        if (!mapp) {                IP_MASQ_ERR("register_ip_masq_app(): NULL arg\n");                return -EINVAL;        }        mapp->type = IP_MASQ_APP_TYPE(proto, port);        mapp->n_attach = 0;        hash = IP_MASQ_APP_HASH(proto, port);        save_flags(flags);        cli();        mapp->next = ip_masq_app_base[hash];        ip_masq_app_base[hash] = mapp;        restore_flags(flags);        return 0;}/* * 	ip_masq_app unreg. routine. */int unregister_ip_masq_app(struct ip_masq_app *mapp){        struct ip_masq_app **mapp_p;        unsigned hash;        unsigned long flags;        if (!mapp) {                IP_MASQ_ERR("unregister_ip_masq_app(): NULL arg\n");                return -EINVAL;        }        /*         * only allow unregistration if it has no attachments         */        if (mapp->n_attach)  {                IP_MASQ_ERR("unregister_ip_masq_app(): has %d attachments. failed\n",                       mapp->n_attach);                return -EINVAL;        }        hash = IP_MASQ_APP_HASH(IP_MASQ_APP_PROTO(mapp->type), IP_MASQ_APP_PORT(mapp->type));        save_flags(flags);        cli();        for (mapp_p = &ip_masq_app_base[hash]; *mapp_p ; mapp_p = &(*mapp_p)->next)                if (mapp == (*mapp_p))  {                        *mapp_p = mapp->next;                        restore_flags(flags);                        return 0;                }        restore_flags(flags);        IP_MASQ_ERR("unregister_ip_masq_app(proto=%s,port=%u): not hashed!\n",               masq_proto_name(IP_MASQ_APP_PROTO(mapp->type)), IP_MASQ_APP_PORT(mapp->type));        return -EINVAL;}/* *	get ip_masq_app object by its proto and port (net byte order). */struct ip_masq_app * ip_masq_app_get(unsigned short proto, __u16 port){        struct ip_masq_app *mapp;        unsigned hash;        unsigned type;        port = ntohs(port);        type = IP_MASQ_APP_TYPE(proto,port);        hash = IP_MASQ_APP_HASH(proto,port);        for(mapp = ip_masq_app_base[hash]; mapp ; mapp = mapp->next) {                if (type == mapp->type) return mapp;        }        return NULL;}/* *	ip_masq_app object binding related funcs. *//* * 	change ip_masq_app object's number of bindings */static __inline__ int ip_masq_app_bind_chg(struct ip_masq_app *mapp, int delta){        unsigned long flags;        int n_at;        if (!mapp) return -1;        save_flags(flags);        cli();        n_at = mapp->n_attach + delta;        if (n_at < 0) {                restore_flags(flags);                IP_MASQ_ERR("ip_masq_app: tried to set n_attach < 0 for (proto=%s,port==%d) ip_masq_app object.\n",                       masq_proto_name(IP_MASQ_APP_PROTO(mapp->type)),                       IP_MASQ_APP_PORT(mapp->type));                return -1;        }        mapp->n_attach = n_at;        restore_flags(flags);        return 0;}/* *	Bind ip_masq to its ip_masq_app based on proto and dport ALREADY *	set in ip_masq struct. Also calls constructor. */struct ip_masq_app * ip_masq_bind_app(struct ip_masq *ms){        struct ip_masq_app * mapp;	if (ms->protocol != IPPROTO_TCP && ms->protocol != IPPROTO_UDP)		return NULL;        mapp = ip_masq_app_get(ms->protocol, ms->dport);#if 0000/* #ifdef CONFIG_IP_MASQUERADE_IPAUTOFW */	if (mapp == NULL)		mapp = ip_masq_app_get(ms->protocol, ms->sport);/* #endif */#endif        if (mapp != NULL) {                /*                 *	don't allow binding if already bound                 */                if (ms->app != NULL) {                        IP_MASQ_ERR("ip_masq_bind_app() called for already bound object.\n");                        return ms->app;                }                ms->app = mapp;                if (mapp->masq_init_1) mapp->masq_init_1(mapp, ms);                ip_masq_app_bind_chg(mapp, +1);        }        return mapp;}/* * 	Unbind ms from type object and call ms destructor (does not kfree()). */int ip_masq_unbind_app(struct ip_masq *ms){        struct ip_masq_app * mapp;        mapp = ms->app;	if (ms->protocol != IPPROTO_TCP && ms->protocol != IPPROTO_UDP)		return 0;        if (mapp != NULL) {                if (mapp->masq_done_1) mapp->masq_done_1(mapp, ms);                ms->app = NULL;                ip_masq_app_bind_chg(mapp, -1);        }        return (mapp != NULL);}/* *	Fixes th->seq based on ip_masq_seq info. */static __inline__ void masq_fix_seq(const struct ip_masq_seq *ms_seq, struct tcphdr *th){        __u32 seq;        seq = ntohl(th->seq);	/*	 * 	Adjust seq with delta-offset for all packets after         * 	the most recent resized pkt seq and with previous_delta offset         *	for all packets	before most recent resized pkt seq.	 */	if (ms_seq->delta || ms_seq->previous_delta) {		if(after(seq,ms_seq->init_seq) ) {			th->seq = htonl(seq + ms_seq->delta);			IP_MASQ_DEBUG(1, "masq_fix_seq() : added delta (%d) to seq\n",ms_seq->delta);		} else {			th->seq = htonl(seq + ms_seq->previous_delta);			IP_MASQ_DEBUG(1, "masq_fix_seq() : added previous_delta (%d) to seq\n",ms_seq->previous_delta);		}	}}/* *	Fixes th->ack_seq based on ip_masq_seq info. */static __inline__ void masq_fix_ack_seq(const struct ip_masq_seq *ms_seq, struct tcphdr *th){        __u32 ack_seq;        ack_seq=ntohl(th->ack_seq);        /*         * Adjust ack_seq with delta-offset for         * the packets AFTER most recent resized pkt has caused a shift         * for packets before most recent resized pkt, use previous_delta         */        if (ms_seq->delta || ms_seq->previous_delta) {                if(after(ack_seq,ms_seq->init_seq)) {                        th->ack_seq = htonl(ack_seq-ms_seq->delta);                        IP_MASQ_DEBUG(1, "masq_fix_ack_seq() : subtracted delta (%d) from ack_seq\n",ms_seq->delta);                } else {                        th->ack_seq = htonl(ack_seq-ms_seq->previous_delta);                        IP_MASQ_DEBUG(1, "masq_fix_ack_seq() : subtracted previous_delta (%d) from ack_seq\n",ms_seq->previous_delta);                }        }}/* *	Updates ip_masq_seq if pkt has been resized *	Assumes already checked proto==IPPROTO_TCP and diff!=0. */static __inline__ void masq_seq_update(struct ip_masq *ms, struct ip_masq_seq *ms_seq, unsigned mflag, __u32 seq, int diff){        /* if (diff == 0) return; */        if ( !(ms->flags & mflag) || after(seq, ms_seq->init_seq))        {                ms_seq->previous_delta=ms_seq->delta;                ms_seq->delta+=diff;                ms_seq->init_seq=seq;                ms->flags |= mflag;        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -