2 * Copyright (c) 2000 Jakob Stoklund Olesen <stoklund@taxidriver.dk>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/usr.sbin/ppp/atm.c,v 1.9.2.1 2002/09/01 02:12:22 brian Exp $
27 * $DragonFly: src/usr.sbin/ppp/atm.c,v 1.2 2003/06/17 04:30:00 dillon Exp $
30 #include <sys/types.h>
31 #include <sys/socket.h>
33 #include <netnatm/natm.h>
51 #include "throughput.h"
57 #include "descriptor.h"
62 /* String identifying PPPoA */
64 #define PPPOA_LEN (sizeof(PPPOA) - 1)
67 struct device dev
; /* What struct physical knows about */
70 #define device2atm(d) ((d)->type == ATM_DEVICE ? (struct atmdevice *)d : NULL)
75 return sizeof(struct atmdevice
);
79 atm_Sendto(struct physical
*p
, const void *v
, size_t n
)
81 ssize_t ret
= write(p
->fd
, v
, n
);
83 log_Printf(LogDEBUG
, "atm_Sendto(%ld): %s\n", (long)n
, strerror(errno
));
90 atm_Recvfrom(struct physical
*p
, void *v
, size_t n
)
92 ssize_t ret
= read(p
->fd
, (char*)v
, n
);
94 log_Printf(LogDEBUG
, "atm_Recvfrom(%ld): %s\n", (long)n
, strerror(errno
));
101 atm_Free(struct physical
*p
)
103 struct atmdevice
*dev
= device2atm(p
->handler
);
109 atm_device2iov(struct device
*d
, struct iovec
*iov
, int *niov
,
110 int maxiov
, int *auxfd
, int *nauxfd
)
112 int sz
= physical_MaxDeviceSize();
114 iov
[*niov
].iov_base
= realloc(d
, sz
);
115 if (iov
[*niov
].iov_base
== NULL
) {
116 log_Printf(LogALERT
, "Failed to allocate memory: %d\n", sz
);
117 AbortProgram(EX_OSERR
);
119 iov
[*niov
].iov_len
= sz
;
123 static const struct device baseatmdevice
= {
127 { CD_NOTREQUIRED
, 0 },
145 atm_iov2device(int type
, struct physical
*p
, struct iovec
*iov
, int *niov
,
146 int maxiov
, int *auxfd
, int *nauxfd
)
148 if (type
== ATM_DEVICE
) {
149 struct atmdevice
*dev
= (struct atmdevice
*)iov
[(*niov
)++].iov_base
;
151 dev
= realloc(dev
, sizeof *dev
); /* Reduce to the correct size */
153 log_Printf(LogALERT
, "Failed to allocate memory: %d\n",
155 AbortProgram(EX_OSERR
);
158 /* Refresh function pointers etc */
159 memcpy(&dev
->dev
, &baseatmdevice
, sizeof dev
->dev
);
161 physical_SetupStack(p
, dev
->dev
.name
, PHYSICAL_FORCE_SYNCNOACF
);
168 static struct atmdevice
*
169 atm_CreateDevice(struct physical
*p
, const char *iface
, unsigned vpi
,
172 struct atmdevice
*dev
;
173 struct sockaddr_natm sock
;
175 if ((dev
= calloc(1, sizeof *dev
)) == NULL
) {
176 log_Printf(LogWARN
, "%s: Cannot allocate an atm device: %s\n",
177 p
->link
.name
, strerror(errno
));
181 sock
.snatm_len
= sizeof sock
;
182 sock
.snatm_family
= AF_NATM
;
183 strncpy(sock
.snatm_if
, iface
, IFNAMSIZ
);
184 sock
.snatm_vpi
= vpi
;
185 sock
.snatm_vci
= vci
;
187 log_Printf(LogPHASE
, "%s: Connecting to %s:%u.%u\n", p
->link
.name
,
190 p
->fd
= socket(PF_NATM
, SOCK_DGRAM
, PROTO_NATMAAL5
);
192 log_Printf(LogDEBUG
, "%s: Opened atm socket %s\n", p
->link
.name
,
194 if (connect(p
->fd
, (struct sockaddr
*)&sock
, sizeof sock
) == 0)
197 log_Printf(LogWARN
, "%s: connect: %s\n", p
->name
.full
, strerror(errno
));
199 log_Printf(LogWARN
, "%s: socket: %s\n", p
->name
.full
, strerror(errno
));
209 atm_Create(struct physical
*p
)
211 struct atmdevice
*dev
;
214 if (p
->fd
< 0 && !strncasecmp(p
->name
.full
, PPPOA
, PPPOA_LEN
)
215 && p
->name
.full
[PPPOA_LEN
] == ':') {
219 if (sscanf(p
->name
.full
+ PPPOA_LEN
+ 1, "%25[A-Za-z0-9]:%u.%u", iface
,
221 log_Printf(LogWARN
, "Malformed ATM device name \'%s\', "
222 "PPPoA:if:vpi.vci expected\n", p
->name
.full
);
226 dev
= atm_CreateDevice(p
, iface
, vpi
, vci
);
230 memcpy(&dev
->dev
, &baseatmdevice
, sizeof dev
->dev
);
231 physical_SetupStack(p
, dev
->dev
.name
, PHYSICAL_FORCE_SYNCNOACF
);
232 if (p
->cfg
.cd
.necessity
!= CD_DEFAULT
)
233 log_Printf(LogWARN
, "Carrier settings ignored\n");