patch-1.3.36 linux/net/appletalk/ddp.c
Next file: linux/net/ax25/af_ax25.c
Previous file: linux/net/appletalk/aarp.c
Back to the patch index
Back to the overall index
- Lines: 476
- Date:
Tue Oct 17 13:42:36 1995
- Orig file:
v1.3.35/linux/net/appletalk/ddp.c
- Orig date:
Wed Sep 13 12:45:34 1995
diff -u --recursive --new-file v1.3.35/linux/net/appletalk/ddp.c linux/net/appletalk/ddp.c
@@ -14,6 +14,9 @@
* Wesley Craig : Fix probing to listen to a
* passed node id.
* Alan Cox : Added send/recvmsg support
+ * Alan Cox : Moved at. to protinfo in
+ * socket.
+ * Alan Cox : Added firewall hooks.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -54,6 +57,7 @@
#include <linux/atalk.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#include <linux/firewall.h>
#ifdef CONFIG_ATALK
@@ -126,23 +130,27 @@
{
atalk_socket *s;
- for( s = atalk_socket_list; s != NULL; s = s->next ) {
- if ( to->sat_port != s->at.src_port ) {
- continue;
- }
+ for( s = atalk_socket_list; s != NULL; s = s->next )
+ {
+ if ( to->sat_port != s->protinfo.af_at.src_port )
+ {
+ continue;
+ }
- if ( to->sat_addr.s_net == 0 &&
+ if ( to->sat_addr.s_net == 0 &&
to->sat_addr.s_node == ATADDR_BCAST &&
- s->at.src_net == atif->address.s_net ) {
- break;
- }
+ s->protinfo.af_at.src_net == atif->address.s_net )
+ {
+ break;
+ }
- if ( to->sat_addr.s_net == s->at.src_net &&
- to->sat_addr.s_node == s->at.src_node ) {
- break;
- }
+ if ( to->sat_addr.s_net == s->protinfo.af_at.src_net &&
+ to->sat_addr.s_node == s->protinfo.af_at.src_node )
+ {
+ break;
+ }
- /* XXXX.0 */
+ /* XXXX.0 */
}
return( s );
}
@@ -155,17 +163,21 @@
{
atalk_socket *s;
- for ( s = atalk_socket_list; s != NULL; s = s->next ) {
- if ( s->at.src_net != sat->sat_addr.s_net ) {
- continue;
- }
- if ( s->at.src_node != sat->sat_addr.s_node ) {
- continue;
- }
- if ( s->at.src_port != sat->sat_port ) {
- continue;
- }
- break;
+ for ( s = atalk_socket_list; s != NULL; s = s->next )
+ {
+ if ( s->protinfo.af_at.src_net != sat->sat_addr.s_net )
+ {
+ continue;
+ }
+ if ( s->protinfo.af_at.src_node != sat->sat_addr.s_node )
+ {
+ continue;
+ }
+ if ( s->protinfo.af_at.src_port != sat->sat_port )
+ {
+ continue;
+ }
+ break;
}
return( s );
}
@@ -214,7 +226,10 @@
}
-/* Called from proc fs */
+/*
+ * Called from proc fs
+ */
+
int atalk_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
{
atalk_socket *s;
@@ -223,19 +238,17 @@
off_t begin=0;
/*
- * Fill this in to print out the appletalk info you want
+ * Output the appletalk data for the /proc virtual fs.
*/
- /* Theory.. Keep printing in the same place until we pass offset */
-
len += sprintf (buffer,"Type local_addr remote_addr tx_queue rx_queue st uid\n");
for (s = atalk_socket_list; s != NULL; s = s->next)
{
len += sprintf (buffer+len,"%02X ", s->type);
len += sprintf (buffer+len,"%04X:%02X:%02X ",
- s->at.src_net,s->at.src_node,s->at.src_port);
+ s->protinfo.af_at.src_net,s->protinfo.af_at.src_node,s->protinfo.af_at.src_port);
len += sprintf (buffer+len,"%04X:%02X:%02X ",
- s->at.dest_net,s->at.dest_node,s->at.dest_port);
+ s->protinfo.af_at.dest_net,s->protinfo.af_at.dest_node,s->protinfo.af_at.dest_port);
len += sprintf (buffer+len,"%08lX:%08lX ", s->wmem_alloc, s->rmem_alloc);
len += sprintf (buffer+len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid);
@@ -432,13 +445,12 @@
static struct atalk_iface *atalk_find_anynet(int node, struct device *dev)
{
struct atalk_iface *iface;
- for(iface=atalk_iface_list;iface!=NULL;iface=iface->next) {
- if ( iface->dev != dev || ( iface->status & ATIF_PROBE )) {
+ for(iface=atalk_iface_list;iface!=NULL;iface=iface->next)
+ {
+ if ( iface->dev != dev || ( iface->status & ATIF_PROBE ))
continue;
- }
- if ( node == ATADDR_BCAST || iface->address.s_node == node ) {
+ if ( node == ATADDR_BCAST || iface->address.s_node == node )
return iface;
- }
}
return NULL;
}
@@ -549,29 +561,30 @@
if(r->rt_flags != rt->flags)
continue;
- if(ta->sat_addr.s_net == rt->target.s_net) {
- if(!(rt->flags&RTF_HOST))
- break;
- if(ta->sat_addr.s_node == rt->target.s_node)
- break;
+ if(ta->sat_addr.s_net == rt->target.s_net)
+ {
+ if(!(rt->flags&RTF_HOST))
+ break;
+ if(ta->sat_addr.s_node == rt->target.s_node)
+ break;
}
}
- if ( devhint == NULL ) {
- for ( riface = NULL, iface = atalk_iface_list; iface;
- iface = iface->next ) {
- if ( riface == NULL && ntohs( ga->sat_addr.s_net ) >=
- ntohs( iface->nets.nr_firstnet ) &&
- ntohs( ga->sat_addr.s_net ) <=
- ntohs( iface->nets.nr_lastnet ))
- riface = iface;
- if ( ga->sat_addr.s_net == iface->address.s_net &&
- ga->sat_addr.s_node == iface->address.s_node )
- riface = iface;
- }
- if ( riface == NULL )
- return -ENETUNREACH;
- devhint = riface->dev;
+ if ( devhint == NULL )
+ {
+ for ( riface = NULL, iface = atalk_iface_list; iface; iface = iface->next )
+ {
+ if ( riface == NULL && ntohs( ga->sat_addr.s_net ) >= ntohs( iface->nets.nr_firstnet ) &&
+ ntohs( ga->sat_addr.s_net ) <= ntohs( iface->nets.nr_lastnet ))
+ {
+ riface = iface;
+ }
+ if ( ga->sat_addr.s_net == iface->address.s_net && ga->sat_addr.s_node == iface->address.s_node )
+ riface = iface;
+ }
+ if ( riface == NULL )
+ return -ENETUNREACH;
+ devhint = riface->dev;
}
if(rt==NULL)
@@ -606,10 +619,12 @@
struct atalk_route **r = &atalk_router_list;
struct atalk_route *tmp;
- while ((tmp = *r) != NULL) {
+ while ((tmp = *r) != NULL)
+ {
if (tmp->target.s_net == addr->s_net &&
(!(tmp->flags&RTF_GATEWAY) ||
- tmp->target.s_node == addr->s_node )) {
+ tmp->target.s_node == addr->s_node ))
+ {
*r = tmp->next;
kfree_s(tmp, sizeof(struct atalk_route));
return 0;
@@ -629,8 +644,10 @@
struct atalk_route **r = &atalk_router_list;
struct atalk_route *tmp;
- while ((tmp = *r) != NULL) {
- if (tmp->dev == dev) {
+ while ((tmp = *r) != NULL)
+ {
+ if (tmp->dev == dev)
+ {
*r = tmp->next;
kfree_s(tmp, sizeof(struct atalk_route));
}
@@ -751,11 +768,14 @@
/*
* Routerless initial state.
*/
- if(nr->nr_firstnet==htons(0) && nr->nr_lastnet==htons(0xFFFE)) {
+ if(nr->nr_firstnet==htons(0) && nr->nr_lastnet==htons(0xFFFE))
+ {
sa->sat_addr.s_net=atif->address.s_net;
atrtr_create(&rtdef, dev);
atrtr_set_default(dev);
- } else {
+ }
+ else
+ {
limit=ntohs(nr->nr_lastnet);
if(limit-ntohs(nr->nr_firstnet) > 256)
{
@@ -1093,13 +1113,13 @@
sk->type=sock->type;
sk->debug=0;
- sk->at.src_net=0;
- sk->at.src_node=0;
- sk->at.src_port=0;
-
- sk->at.dest_net=0;
- sk->at.dest_node=0;
- sk->at.dest_port=0;
+ sk->protinfo.af_at.src_net=0;
+ sk->protinfo.af_at.src_node=0;
+ sk->protinfo.af_at.src_port=0;
+
+ sk->protinfo.af_at.dest_net=0;
+ sk->protinfo.af_at.dest_node=0;
+ sk->protinfo.af_at.dest_port=0;
sk->mtu=DDP_MAXSZ;
@@ -1151,10 +1171,11 @@
static int atalk_pick_port(struct sockaddr_at *sat)
{
- for ( sat->sat_port = ATPORT_RESERVED; sat->sat_port < ATPORT_LAST;
- sat->sat_port++ )
- if ( atalk_find_socket( sat ) == NULL )
- return sat->sat_port;
+ for ( sat->sat_port = ATPORT_RESERVED; sat->sat_port < ATPORT_LAST; sat->sat_port++ )
+ {
+ if ( atalk_find_socket( sat ) == NULL )
+ return sat->sat_port;
+ }
return -EBUSY;
}
@@ -1165,13 +1186,13 @@
int n;
if ( ap == NULL || ap->s_net == htons( ATADDR_ANYNET ))
- return -EADDRNOTAVAIL;
- sk->at.src_net = sat.sat_addr.s_net = ap->s_net;
- sk->at.src_node = sat.sat_addr.s_node = ap->s_node;
+ return -EADDRNOTAVAIL;
+ sk->protinfo.af_at.src_net = sat.sat_addr.s_net = ap->s_net;
+ sk->protinfo.af_at.src_node = sat.sat_addr.s_node = ap->s_node;
if (( n = atalk_pick_port( &sat )) < 0 )
- return( n );
- sk->at.src_port=n;
+ return( n );
+ sk->protinfo.af_at.src_port=n;
atalk_insert_socket(sk);
sk->zapped=0;
return 0;
@@ -1202,16 +1223,15 @@
struct at_addr *ap=atalk_find_primary();
if(ap==NULL)
return -EADDRNOTAVAIL;
- sk->at.src_net=addr->sat_addr.s_net=ap->s_net;
- sk->at.src_node=addr->sat_addr.s_node=ap->s_node;
+ sk->protinfo.af_at.src_net=addr->sat_addr.s_net=ap->s_net;
+ sk->protinfo.af_at.src_node=addr->sat_addr.s_node=ap->s_node;
}
else
{
- if ( atalk_find_interface( addr->sat_addr.s_net,
- addr->sat_addr.s_node ) == NULL )
- return -EADDRNOTAVAIL;
- sk->at.src_net=addr->sat_addr.s_net;
- sk->at.src_node=addr->sat_addr.s_node;
+ if ( atalk_find_interface( addr->sat_addr.s_net, addr->sat_addr.s_node ) == NULL )
+ return -EADDRNOTAVAIL;
+ sk->protinfo.af_at.src_net=addr->sat_addr.s_net;
+ sk->protinfo.af_at.src_node=addr->sat_addr.s_node;
}
if(addr->sat_port == ATADDR_ANYPORT)
@@ -1219,10 +1239,10 @@
int n = atalk_pick_port(addr);
if(n < 0)
return n;
- sk->at.src_port=addr->sat_port=n;
+ sk->protinfo.af_at.src_port=addr->sat_port=n;
}
else
- sk->at.src_port=addr->sat_port;
+ sk->protinfo.af_at.src_port=addr->sat_port;
if(atalk_find_socket(addr)!=NULL)
return -EADDRINUSE;
@@ -1264,9 +1284,9 @@
if(atrtr_get_dev(&addr->sat_addr)==NULL)
return -ENETUNREACH;
- sk->at.dest_port=addr->sat_port;
- sk->at.dest_net=addr->sat_addr.s_net;
- sk->at.dest_node=addr->sat_addr.s_node;
+ sk->protinfo.af_at.dest_port=addr->sat_port;
+ sk->protinfo.af_at.dest_net=addr->sat_addr.s_net;
+ sk->protinfo.af_at.dest_node=addr->sat_addr.s_node;
sock->state = SS_CONNECTED;
sk->state=TCP_ESTABLISHED;
return(0);
@@ -1316,15 +1336,15 @@
{
if(sk->state!=TCP_ESTABLISHED)
return -ENOTCONN;
- sat.sat_addr.s_net=sk->at.dest_net;
- sat.sat_addr.s_node=sk->at.dest_node;
- sat.sat_port=sk->at.dest_port;
+ sat.sat_addr.s_net=sk->protinfo.af_at.dest_net;
+ sat.sat_addr.s_node=sk->protinfo.af_at.dest_node;
+ sat.sat_port=sk->protinfo.af_at.dest_port;
}
else
{
- sat.sat_addr.s_net=sk->at.src_net;
- sat.sat_addr.s_node=sk->at.src_node;
- sat.sat_port=sk->at.src_port;
+ sat.sat_addr.s_net=sk->protinfo.af_at.src_net;
+ sat.sat_addr.s_node=sk->protinfo.af_at.src_node;
+ sat.sat_port=sk->protinfo.af_at.src_port;
}
sat.sat_family = AF_APPLETALK;
memcpy(uaddr,&sat,sizeof(sat));
@@ -1372,7 +1392,7 @@
/*
* Size check to see if ddp->deh_len was crap
* (Otherwise we'll detonate most spectacularly
- * in the middle of recvfrom()).
+ * in the middle of recvmsg()).
*/
if(skb->len<sizeof(*ddp))
@@ -1392,6 +1412,16 @@
kfree_skb(skb,FREE_READ);
return(0);
}
+
+#ifdef CONFIG_FIREWALL
+
+ if(call_in_firewall(AF_APPLETALK, skb, ddp)!=FW_ACCEPT)
+ {
+ kfree_skb(skb, FREE_READ);
+ return 0;
+ }
+
+#endif
/* Check the packet is aimed at us */
@@ -1413,7 +1443,18 @@
kfree_skb(skb, FREE_READ);
return(0);
}
-
+
+#ifdef CONFIG_FIREWALL
+ /*
+ * Check firewall allows this routing
+ */
+
+ if(call_fw_firewall(AF_APPLETALK, skb, ddp)!=FW_ACCEPT)
+ {
+ kfree_skb(skb, FREE_READ);
+ return(0);
+ }
+#endif
ta.s_net=ddp->deh_dnet;
ta.s_node=ddp->deh_dnode;
@@ -1511,9 +1552,9 @@
return -ENOTCONN;
usat=&local_satalk;
usat->sat_family=AF_APPLETALK;
- usat->sat_port=sk->at.dest_port;
- usat->sat_addr.s_node=sk->at.dest_node;
- usat->sat_addr.s_net=sk->at.dest_net;
+ usat->sat_port=sk->protinfo.af_at.dest_port;
+ usat->sat_addr.s_node=sk->protinfo.af_at.dest_node;
+ usat->sat_addr.s_net=sk->protinfo.af_at.dest_net;
}
/* Build a packet */
@@ -1534,7 +1575,7 @@
{
struct at_addr at_hint;
at_hint.s_node=0;
- at_hint.s_net=sk->at.src_net;
+ at_hint.s_net=sk->protinfo.af_at.src_net;
rt=atrtr_find(&at_hint);
if(rt==NULL)
return -ENETUNREACH;
@@ -1573,11 +1614,11 @@
*((__u16 *)ddp)=ntohs(*((__u16 *)ddp));
ddp->deh_dnet=usat->sat_addr.s_net;
- ddp->deh_snet=sk->at.src_net;
+ ddp->deh_snet=sk->protinfo.af_at.src_net;
ddp->deh_dnode=usat->sat_addr.s_node;
- ddp->deh_snode=sk->at.src_node;
+ ddp->deh_snode=sk->protinfo.af_at.src_node;
ddp->deh_dport=usat->sat_port;
- ddp->deh_sport=sk->at.src_port;
+ ddp->deh_sport=sk->protinfo.af_at.src_port;
if(sk->debug)
printk("SK %p: Copy user data (%d bytes).\n", sk, len);
@@ -1588,6 +1629,16 @@
ddp->deh_sum=0;
else
ddp->deh_sum=atalk_checksum(ddp, len+sizeof(*ddp));
+
+#ifdef CONFIG_FIREWALL
+
+ if(call_out_firewall(AF_APPLETALK, skb, ddp)!=FW_ACCEPT)
+ {
+ kfree_skb(skb, FREE_WRITE);
+ return -EPERM;
+ }
+
+#endif
/*
* Loopback broadcast packets to non gateway targets (ie routes
@@ -1921,6 +1972,6 @@
atalk_if_get_info
});
- printk("Appletalk BETA 0.13 for Linux NET3.031\n");
+ printk("Appletalk 0.14 for Linux NET3.032\n");
}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this