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
29 #include <sys/types.h>
30 #include <sys/socket.h>
32 #include <netnatm/natm.h>
50 #include "throughput.h"
56 #include "descriptor.h"
61 /* String identifying PPPoA */
63 #define PPPOA_LEN (sizeof(PPPOA) - 1)
66 struct device dev
; /* What struct physical knows about */
69 #define device2atm(d) ((d)->type == ATM_DEVICE ? (struct atmdevice *)d : NULL)
74 return sizeof(struct atmdevice
);
78 atm_Sendto(struct physical
*p
, const void *v
, size_t n
)
80 ssize_t ret
= write(p
->fd
, v
, n
);
82 log_Printf(LogDEBUG
, "atm_Sendto(%ld): %s\n", (long)n
, strerror(errno
));
89 atm_Recvfrom(struct physical
*p
, void *v
, size_t n
)
91 ssize_t ret
= read(p
->fd
, (char*)v
, n
);
93 log_Printf(LogDEBUG
, "atm_Recvfrom(%ld): %s\n", (long)n
, strerror(errno
));
100 atm_Free(struct physical
*p
)
102 struct atmdevice
*dev
= device2atm(p
->handler
);
108 atm_device2iov(struct device
*d
, struct iovec
*iov
, int *niov
,
109 int maxiov __unused
, int *auxfd __unused
, int *nauxfd __unused
)
111 int sz
= physical_MaxDeviceSize();
113 iov
[*niov
].iov_base
= realloc(d
, sz
);
114 if (iov
[*niov
].iov_base
== NULL
) {
115 log_Printf(LogALERT
, "Failed to allocate memory: %d\n", sz
);
116 AbortProgram(EX_OSERR
);
118 iov
[*niov
].iov_len
= sz
;
122 static const struct device baseatmdevice
= {
126 { CD_NOTREQUIRED
, 0 },
144 atm_iov2device(int type
, struct physical
*p
, struct iovec
*iov
, int *niov
,
145 int maxiov __unused
, int *auxfd __unused
, int *nauxfd __unused
)
147 if (type
== ATM_DEVICE
) {
148 struct atmdevice
*dev
= (struct atmdevice
*)iov
[(*niov
)++].iov_base
;
150 dev
= realloc(dev
, sizeof *dev
); /* Reduce to the correct size */
152 log_Printf(LogALERT
, "Failed to allocate memory: %d\n",
154 AbortProgram(EX_OSERR
);
157 /* Refresh function pointers etc */
158 memcpy(&dev
->dev
, &baseatmdevice
, sizeof dev
->dev
);
160 physical_SetupStack(p
, dev
->dev
.name
, PHYSICAL_FORCE_SYNCNOACF
);
167 static struct atmdevice
*
168 atm_CreateDevice(struct physical
*p
, const char *iface
, unsigned vpi
,
171 struct atmdevice
*dev
;
172 struct sockaddr_natm sock
;
174 if ((dev
= calloc(1, sizeof *dev
)) == NULL
) {
175 log_Printf(LogWARN
, "%s: Cannot allocate an atm device: %s\n",
176 p
->link
.name
, strerror(errno
));
180 sock
.snatm_len
= sizeof sock
;
181 sock
.snatm_family
= AF_NATM
;
182 strncpy(sock
.snatm_if
, iface
, IFNAMSIZ
);
183 sock
.snatm_vpi
= vpi
;
184 sock
.snatm_vci
= vci
;
186 log_Printf(LogPHASE
, "%s: Connecting to %s:%u.%u\n", p
->link
.name
,
189 p
->fd
= socket(PF_NATM
, SOCK_DGRAM
, PROTO_NATMAAL5
);
191 log_Printf(LogDEBUG
, "%s: Opened atm socket %s\n", p
->link
.name
,
193 if (connect(p
->fd
, (struct sockaddr
*)&sock
, sizeof sock
) == 0)
196 log_Printf(LogWARN
, "%s: connect: %s\n", p
->name
.full
, strerror(errno
));
198 log_Printf(LogWARN
, "%s: socket: %s\n", p
->name
.full
, strerror(errno
));
208 atm_Create(struct physical
*p
)
210 struct atmdevice
*dev
;
213 if (p
->fd
< 0 && !strncasecmp(p
->name
.full
, PPPOA
, PPPOA_LEN
)
214 && p
->name
.full
[PPPOA_LEN
] == ':') {
218 if (sscanf(p
->name
.full
+ PPPOA_LEN
+ 1, "%25[A-Za-z0-9]:%u.%u", iface
,
220 log_Printf(LogWARN
, "Malformed ATM device name \'%s\', "
221 "PPPoA:if:vpi.vci expected\n", p
->name
.full
);
225 dev
= atm_CreateDevice(p
, iface
, vpi
, vci
);
229 memcpy(&dev
->dev
, &baseatmdevice
, sizeof dev
->dev
);
230 physical_SetupStack(p
, dev
->dev
.name
, PHYSICAL_FORCE_SYNCNOACF
);
231 if (p
->cfg
.cd
.necessity
!= CD_DEFAULT
)
232 log_Printf(LogWARN
, "Carrier settings ignored\n");