1/*
2 * $Id: ddp.c,v 1.3 2002-01-17 06:13:02 srittau Exp $
3 */
4
5#ifdef HAVE_CONFIG_H
6#include "config.h"
7#endif /* HAVE_CONFIG_H */
8
9#include <sys/types.h>
10#include <sys/stream.h>
11#include <sys/cmn_err.h>
12#include <sys/socket.h>
13#include <sys/errno.h>
14#include <sys/tihdr.h>
15#include <sys/ddi.h>
16#include <sys/ethernet.h>
17#include <net/if.h>
18
19#ifdef STDC_HEADERS
20#include <strings.h>
21#else
22#include <string.h>
23#endif
24
25#include <netatalk/endian.h>
26#include <netatalk/ddp.h>
27#include <netatalk/at.h>
28
29#include "if.h"
30#include "sock.h"
31
32    int
33ddp_rput( struct atif_data *aid, mblk_t *m )
34{
35    struct atif_data	*daid;
36    struct ddpehdr	*deh;
37    struct sockaddr_at	sat;
38    struct sock_data	*sd;
39
40    if ( m->b_wptr - m->b_rptr < sizeof( struct ddpehdr )) {
41	cmn_err( CE_NOTE, "ddp_rput short packet\n" );
42	freemsg( m );
43	return( EINVAL );
44    }
45
46    deh = (struct ddpehdr *)m->b_rptr;
47
48    sat.sat_addr.s_net = deh->deh_dnet;
49    sat.sat_addr.s_node = deh->deh_dnode;
50    sat.sat_port = deh->deh_dport;
51
52    if (( daid = if_dest( aid, &sat )) != NULL ) {
53	if (( sd = sock_dest( daid, &sat )) != NULL ) {
54	    if ( sd->sd_state != TS_IDLE ) {
55		freemsg( m );
56		return( EHOSTDOWN );
57	    }
58	    bzero( (caddr_t)&sat, sizeof( struct sockaddr_at ));
59	    sat.sat_family = AF_APPLETALK;
60	    sat.sat_addr.s_net = deh->deh_snet;
61	    sat.sat_addr.s_node = deh->deh_snode;
62	    sat.sat_port = deh->deh_sport;
63	    adjmsg( m, sizeof( struct ddpehdr ));
64	    t_unitdata_ind( WR( sd->sd_q ), m, &sat );
65	} else {
66	    /* toss it */
67	    freemsg( m );
68	    return( EHOSTDOWN );
69	}
70    } else {
71	/* route it */
72	freemsg( m );
73	return( ENETUNREACH );
74    }
75    return( 0 );
76}
77