• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.5/libatalk/nbp/
1/*
2 * $Id: nbp_rgstr.c,v 1.6 2009-10-14 02:24:05 didg Exp $
3 *
4 * Copyright (c) 1990,1993 Regents of The University of Michigan.
5 * All Rights Reserved. See COPYRIGHT.
6 */
7
8#ifdef HAVE_CONFIG_H
9#include "config.h"
10#endif /* HAVE_CONFIG_H */
11
12#include <string.h>
13#include <errno.h>
14#include <signal.h>
15
16#include <sys/types.h>
17#include <sys/param.h>
18#include <sys/socket.h>
19#include <sys/time.h>
20
21#include <netatalk/at.h>
22#include <netatalk/endian.h>
23#include <atalk/nbp.h>
24#include <atalk/ddp.h>
25#include <atalk/netddp.h>
26
27#ifdef HAVE_NETDB_H
28#include <netdb.h>
29#endif /* HAVE_NETDB_H */
30#include  "nbp_conf.h"
31
32/* FIXME/SOCKLEN_T: socklen_t is a unix98 feature. */
33#ifndef SOCKLEN_T
34#define SOCKLEN_T unsigned int
35#endif /* ! SOCKLEN_T */
36
37int nbp_rgstr( struct sockaddr_at *sat, const char *obj, const char *type, const char *zone)
38{
39    struct sockaddr_at	to;
40    struct nbpnve	nn;
41    struct nbphdr	nh;
42    struct nbptuple	nt;
43    struct timeval	timeout;
44    fd_set		readfd;
45    struct servent	*se;
46    char		*data;
47    int			s, cc;
48    SOCKLEN_T		namelen;
49
50    if ( nbp_lookup( obj, type, zone, &nn, 1, &sat->sat_addr ) > 0 ) {
51        errno = EADDRINUSE;
52	return( -1 );
53    }
54
55    memset(&to, 0, sizeof(to));
56    if ((s = netddp_open(&to, NULL)) < 0)
57        return -1;
58
59    data = nbp_send;
60    *data++ = DDPTYPE_NBP;
61    nh.nh_op = NBPOP_RGSTR;
62    nh.nh_cnt = 1;
63    nh.nh_id = ++nbp_id;
64    memcpy( data, &nh, SZ_NBPHDR );
65    data += SZ_NBPHDR;
66
67    memset(&nt, 0, sizeof(nt));
68    nt.nt_net = sat->sat_addr.s_net;
69    nt.nt_node = sat->sat_addr.s_node;
70    nt.nt_port = sat->sat_port;
71    memcpy( data, &nt, SZ_NBPTUPLE);
72    data += SZ_NBPTUPLE;
73
74    if ( obj ) {
75	if (( cc = strlen( obj )) > NBPSTRLEN ) return( -1 );
76	*data++ = cc;
77	memcpy( data, obj, cc );
78	data += cc;
79    } else {
80	*data++ = 0;
81    }
82
83    if ( type ) {
84	if (( cc = strlen( type )) > NBPSTRLEN ) return( -1 );
85	*data++ = cc;
86	memcpy( data, type, cc );
87	data += cc;
88    } else {
89	*data++ = 0;
90    }
91
92    if ( zone ) {
93	if (( cc = strlen( zone )) > NBPSTRLEN ) return( -1 );
94	*data++ = cc;
95	memcpy( data, zone, cc );
96	data += cc;
97    } else {
98	*data++ = 1;
99	*data++ = '*'; /* default zone */
100    }
101
102
103    if ( nbp_port == 0 ) {
104	if (( se = getservbyname( "nbp", "ddp" )) == NULL ) {
105	    nbp_port = 2;
106	} else {
107	    nbp_port = ntohs( se->s_port );
108	}
109    }
110    to.sat_port = nbp_port;
111
112    if ( netddp_sendto( s, nbp_send, data - nbp_send, 0,
113			(struct sockaddr *)&to,
114			sizeof( struct sockaddr_at )) < 0 ) {
115        goto register_err;
116    }
117
118    FD_ZERO( &readfd );
119    FD_SET( s, &readfd );
120    timeout.tv_sec = 2;
121    timeout.tv_usec = 0;
122    if (( cc = select( s + 1, &readfd, NULL, NULL, &timeout )) < 0 ) {
123        goto register_err;
124    }
125    if ( cc == 0 ) {
126	errno = ETIMEDOUT;
127	goto register_err;
128    }
129
130    namelen = sizeof( struct sockaddr_at );
131    if (( cc = netddp_recvfrom( s, nbp_recv, sizeof( nbp_recv ), 0,
132			(struct sockaddr *)&to, &namelen )) < 0 ) {
133        goto register_err;
134    }
135
136    netddp_close( s );
137
138    data = nbp_recv;
139    if ( *data++ != DDPTYPE_NBP ) {
140	return( -1 );
141    }
142    memcpy( &nh, data, SZ_NBPHDR );
143    if ( nh.nh_op != NBPOP_OK ) {
144        return -1;
145    }
146    return( 0 );
147
148register_err:
149    netddp_close(s);
150    return -1;
151}
152